فهرست منبع

Merge branch 'feature/eta_forum3_chart_classify' of eta_forum/eta_forum_hub into master

xyxie 4 روز پیش
والد
کامیت
bb3319b761

+ 91 - 0
controllers/chart_classify.go

@@ -0,0 +1,91 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta/eta_forum_hub/models"
+	"eta/eta_forum_hub/services"
+)
+
+type ChartClassifyController struct {
+	BaseAuthController
+}
+
+// Save 新增或者更新分类
+// @Title 新增或者更新分类
+// @Description 新增或者更新分类
+// @Param   request	body models.ChartClassifySyncReq true "type json string"
+// @Success 200 {object} models.BaseResponse
+// @router /save [post]
+func (this *ChartClassifyController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	
+	var req models.ChartClassify
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartClassifyId == 0 {
+		br.Msg = "请输入分类id"
+		br.ErrMsg = "请输入分类id"
+		return
+	}
+	if req.IsSelected != 1 {
+		br.Msg = "只有精选资源才可以更新"
+		return
+	}
+	err = services.AddOrUpdateChartClassify(&req)
+	if err != nil {
+		br.Msg = "新增或者更新分类失败"
+		br.ErrMsg = "新增或者更新分类失败, Err:" + err.Error()
+		return
+	}
+	
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+}
+
+// BatchSave 批量同步分类
+// @Title 批量同步分类
+// @Description 批量同步分类
+// @Param   request	body models.ChartClassifySyncReq true "type json string"
+// @Success 200 {object} models.BaseResponse
+// @router /batch_save [post]
+func (this *ChartClassifyController) BatchSave() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	
+	var req models.ChartClassifySyncReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if len(req.List) == 0 {
+		br.Msg = "请输入列表"
+		br.ErrMsg = "请输入列表"
+		return
+	}
+	err, isSendEmail := services.BatchAddOrUpdateChartClassify(&req)
+	if err != nil {
+		br.Msg = "新增或者更新用户失败"
+		br.ErrMsg = "新增或者更新用户失败, Err:" + err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+	
+}

+ 3 - 2
controllers/chart_info.go

@@ -6,9 +6,10 @@ import (
 	"eta/eta_forum_hub/services"
 	"eta/eta_forum_hub/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 type ChartInfoController struct {
@@ -464,7 +465,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *models.ChartInfoView, key strin
 	var dateMax time.Time
 	if dateType == utils.DateTypeNYears {
 		for _, v := range mappingList {
-			if v.LatestDate != "" {
+			if v.LatestDate != "" && v.LatestDate != "0000-00-00" {
 				lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
 				if tErr != nil {
 					msg = "获取失败"

+ 213 - 0
controllers/edb_data.go

@@ -0,0 +1,213 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta/eta_forum_hub/models"
+	"eta/eta_forum_hub/services"
+	"eta/eta_forum_hub/utils"
+	"fmt"
+	"strconv"
+	"time"
+)
+
+type EdbDataController struct {
+	BaseAuthController
+}
+// 根据binlog监听记录,更新指标数据
+// SaveByBinlog 根据binlog监听记录,更新指标数据
+// @Title 根据binlog监听记录,更新指标数据
+// @Description 根据binlog监听记录,更新指标数据
+// @Param   request	body models.EdbDataBinlogReq true "type json string"
+// @Success 200 {object} models.BaseResponse
+// @router /save_by_binlog [post]
+func (this *EdbDataController) SaveByBinlog() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req models.EdbDataBinlogReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if len(req.List) == 0 {
+		br.Msg = "参数异常!"
+		br.ErrMsg = "参数异常,请检查!"
+		return
+	}
+
+	edbInfoIdMap := make(map[int]*models.AddEdbDataBinlogReq)
+	reqList := make([]*models.EdbDataBinlogItem, 0)
+	// 判断指标库里是否存在这些指标,如果不存在,则丢弃,无需处理
+	edbInfoIds := make([]int, 0)
+	idMap := make(map[int]bool)
+	for _, item := range req.List {
+		// 解析json
+		var dataItem models.EdbDataBinlogItem
+		err := json.Unmarshal([]byte(item.Item), &dataItem)
+		if err != nil {
+			utils.FileLog.Info("解析binlog数据失败,Err:" + err.Error(), "item", item)
+			continue
+		}
+		dataItem.OpType = item.OpType
+		reqList = append(reqList, &dataItem)
+		if _, ok := idMap[dataItem.EdbInfoId]; !ok {
+			idMap[dataItem.EdbInfoId] = true
+			edbInfoIds = append(edbInfoIds, dataItem.EdbInfoId)
+		}
+	}
+	// 查询指标信息
+	edbInfoList, err := models.GetEdbInfoByIdList(edbInfoIds)
+	if err != nil {
+		br.Msg = "指标信息查询异常!"
+		br.ErrMsg = "指标信息查询失败,Err:" + err.Error()
+		return
+	}
+	existEdbInfoMap := make(map[int]*models.EdbInfo)
+	for _, item := range edbInfoList {
+		existEdbInfoMap[item.EdbInfoId] = item
+	}
+	// edbInfoList := []*models.EdbInfo{
+	// 	{
+	// 		EdbInfoId: 1,
+	// 		EdbCode:   "test_code_1",
+	// 		EdbType:   1,
+	// 	},
+	// 	{
+	// 		EdbInfoId: 2,
+	// 		EdbCode:   "test_code_2",
+	// 		EdbType:   1,
+	// 	},
+	// }
+	// existEdbInfoMap := make(map[int]*models.EdbInfo)
+	// for _, item := range edbInfoList {
+	// 	existEdbInfoMap[item.EdbInfoId] = item
+	// }
+	edbDataIdMap := make(map[string]*models.EdbDataBaseWithOpType)
+	for _, item := range reqList {
+		edbInfo, ok := existEdbInfoMap[item.EdbInfoId]
+		if !ok {
+			continue
+		}
+		if _, ok := edbInfoIdMap[item.EdbInfoId]; !ok {
+			tmp := &models.AddEdbDataBinlogReq{
+				EdbInfoId: item.EdbInfoId,
+				EdbCode: item.EdbCode,
+				EdbType: edbInfo.EdbType,
+			}
+			edbInfoIdMap[item.EdbInfoId] = tmp
+		}
+		value, ok := item.Value.(float64)
+		if !ok {
+			valueStr, ok:= item.Value.(string)
+			if !ok {
+				utils.FileLog.Info("binlog数据类型异常,Err:" + err.Error(), "item", item)
+				continue
+			}
+			value, err = strconv.ParseFloat(valueStr, 64)
+			if err != nil {
+				utils.FileLog.Info("binlog数据类型转换异常,Err:" + err.Error(), "item", item)
+				continue
+			}
+		}
+		createTime, _ := time.ParseInLocation("2006-01-02 15:04:05", item.CreateTime, time.Local)
+		modifyTime, _ := time.ParseInLocation("2006-01-02 15:04:05", item.ModifyTime, time.Local)
+		dataItem := &models.EdbDataBaseWithOpType{
+			EdbDataBase: &models.EdbDataBase{
+				EdbInfoId: item.EdbInfoId,
+				EdbCode: item.EdbCode,
+				Value: strconv.FormatFloat(value, 'f', -1, 64),
+				DataTimestamp: item.DataTimestamp,
+				DataTime: item.DataTime,
+				CreateTime: createTime,
+				ModifyTime: modifyTime,
+			},
+			OpType: item.OpType,
+		}
+		if _, ok := edbDataIdMap[fmt.Sprintf("%d_%s", item.EdbInfoId, item.DataTime)]; ok {
+			edbDataIdMap[fmt.Sprintf("%d_%s", item.EdbInfoId, item.DataTime)] = dataItem
+		} else {
+			edbDataIdMap[fmt.Sprintf("%d_%s", item.EdbInfoId, item.DataTime)] = dataItem
+		}
+		//edbInfoIdMap[item.EdbInfoId].DataList = append(edbInfoIdMap[item.EdbInfoId].DataList, dataItem)
+	}
+
+	edbDataMinDataTimeMap := make(map[int]string)
+	edbDataMaxDataTimeMap := make(map[int]string)
+	for _, item := range edbDataIdMap {
+		edbInfoIdMap[item.EdbInfoId].DataList = append(edbInfoIdMap[item.EdbInfoId].DataList, item)
+		if edbDataMinDataTimeMap[item.EdbInfoId] == "" || edbDataMinDataTimeMap[item.EdbInfoId] > item.DataTime {
+			edbDataMinDataTimeMap[item.EdbInfoId] = item.DataTime
+		}
+		if edbDataMaxDataTimeMap[item.EdbInfoId] == "" || edbDataMaxDataTimeMap[item.EdbInfoId] < item.DataTime {
+			edbDataMaxDataTimeMap[item.EdbInfoId] = item.DataTime
+		}
+	}
+
+	for _, item := range edbInfoIdMap {
+		minDataTime := edbDataMinDataTimeMap[item.EdbInfoId]
+		maxDataTime := edbDataMaxDataTimeMap[item.EdbInfoId]
+		if item.EdbType == 1 {
+			err := services.AddOrUpdateEdbDataWithOpType(item.EdbInfoId, item.DataList, minDataTime, maxDataTime)
+			if err != nil {
+				br.Msg = "更新指标数据失败!"
+				br.ErrMsg = "更新指标数据失败,Err:" + err.Error()
+				return
+			}
+		} else {
+			err := services.AddOrUpdateEdbDataCalculateWithOpType(item.EdbInfoId, item.DataList, minDataTime, maxDataTime)
+			if err != nil {
+				br.Msg = "更新指标数据失败!"
+				br.ErrMsg = "更新指标数据失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	return
+}
+
+// TestSaveByBinlog 测试SaveByBinlog接口的测试数据
+// @Title 测试SaveByBinlog接口的测试数据
+// @Description 测试SaveByBinlog接口的测试数据
+// @Success 200 {object} models.BaseResponse
+// @router /test_save_by_binlog [get]
+func (this *EdbDataController) TestSaveByBinlog() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	// 构造测试数据
+	testData := models.EdbDataBinlogReq{
+		List: []*models.EdbDataBinlogDataReq{
+			{
+				OpType: "INSERT",
+				Item: `{"create_time":"2024-10-12 17:03:04","data_time":"2024-09-08","data_timestamp":1725724800000,"edb_code":"test_code_1","edb_data_id":1001,"edb_info_id":1,"modify_time":"2024-10-14 13:37:30","value":71988}`,
+			},
+			{
+				OpType: "UPDATE",
+				Item: `{"create_time":"2024-10-12 17:03:04","data_time":"2024-09-09","data_timestamp":1725811200000,"edb_code":"test_code_1","edb_data_id":1002,"edb_info_id":1,"modify_time":"2024-10-14 13:37:30","value":72500}`,
+			},
+			{
+				OpType: "DELETE",
+				Item: `{"create_time":"2024-10-12 17:03:04","data_time":"2024-09-10","data_timestamp":1725897600000,"edb_code":"test_code_2","edb_data_id":2001,"edb_info_id":2,"modify_time":"2024-10-14 13:37:30","value":85600}`,
+			},
+		},
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取测试数据成功"
+	br.Data = testData
+	return
+}
+
+

+ 14 - 15
models/chart_classify.go

@@ -3,8 +3,9 @@ package models
 import (
 	"eta/eta_forum_hub/utils"
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
 )
 
 type ChartClassify struct {
@@ -21,6 +22,11 @@ type ChartClassify struct {
 	Sort              int       `description:"排序字段,越小越靠前,默认值:10"`
 	Source            int       `description:"1:ETA图库;2:商品价格曲线"`
 	IsJoinPermission  int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	ChartClassifyNameEn string    `description:"分类名称英文"`
+	RootId              int       `description:"根级id"`
+	LevelPath         string    `description:"层级路径"`
+	IsSelected        int       `description:"是否精选资源:0否,1是"`
+	ResourceStatus    int       `description:"在ETA投研资源库中的状态:0:初始状态,1上架,2下架"`
 }
 
 func AddChartClassify(item *ChartClassify) (lastId int64, err error) {
@@ -93,18 +99,7 @@ func GetChartInfoCountByClassifyId(classifyId int) (count int, err error) {
 
 func DeleteChartClassify(classifyId int) (err error) {
 	o := orm.NewOrm()
-	sql := ` DELETE FROM chart_classify
-				WHERE chart_classify_id IN(
-				SELECT t.chart_classify_id FROM
-				(
-				SELECT rd.*
-				FROM (SELECT * FROM chart_classify WHERE parent_id IS NOT NULL) rd,
-				(SELECT @pid := ?) pd
-				WHERE FIND_IN_SET(parent_id, @pid) > 0
-				AND @pid := CONCAT(@pid, ',', chart_classify_id)
-				UNION SELECT * FROM chart_classify WHERE chart_classify_id = @pid
-				)AS t
-				) `
+	sql := `DELETE FROM chart_classify WHERE chart_classify_id = ?`
 	_, err = o.Raw(sql, classifyId).Exec()
 	return
 }
@@ -120,9 +115,9 @@ func GetChartClassifyByParentId(parentId, source int) (items []*ChartClassifyIte
 
 // GetChartClassifyAll
 // @param source int 1:ETA图库;2:商品价格曲线;3:相关性图表
-func GetChartClassifyAll(source int) (items []*ChartClassifyItems, err error) {
+func GetChartClassifyAll(source int) (items []*ChartClassify, err error) {
 	o := orm.NewOrm()
-	sql := ` SELECT * FROM chart_classify WHERE parent_id<>0 AND source = ? order by sort asc,chart_classify_id asc`
+	sql := ` SELECT * FROM chart_classify WHERE source = ? order by sort asc,chart_classify_id asc`
 	_, err = o.Raw(sql, source).QueryRows(&items)
 	return
 }
@@ -348,3 +343,7 @@ func GetChartClassifyBySourceAndIsJoinPermission(source, isJoinPermission int) (
 	_, err = o.Raw(sql, source, isJoinPermission).QueryRows(&items)
 	return
 }
+
+type ChartClassifySyncReq struct {
+	List []*ChartClassify
+}

+ 113 - 0
models/chart_description.go

@@ -0,0 +1,113 @@
+package models
+
+import (
+	"eta/eta_forum_hub/utils"
+	"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"`     // 关系建立时间
+}
+
+type ChartDescriptionReq struct {
+	Id               int       
+	Description      string      // 图表id
+	ChartInfoId      int       
+	SysUserId        int         // 创建人id
+	SysUserRealName  string    	 // 创建人姓名
+	AdminName        string   	 // 创建人姓名
+	ModifyTime       time.Time 	 // 变更时间
+	CreateTime       time.Time 	 // 关系建立时间  
+}
+
+// GetChartDescriptionByChartInfoId 根据图表ID获取图表简介
+func GetChartDescriptionByChartInfoId(chartInfoId int) (item []*ChartDescription, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM chart_description WHERE chart_info_id = ? order by create_time desc, id desc`
+	_, err = o.Raw(sql, chartInfoId).QueryRows(&item)
+	return
+}
+
+// 批量更新
+func BatchUpdateChartDescription(chartInfoId int, descriptionList []*ChartDescription) (err error) {
+	o := orm.NewOrm()
+	// 用事务
+	tx, err := o.Begin()
+	if err != nil {
+		return err
+	}
+	defer func ()  {
+		if err != nil {
+			tx.Rollback()
+		}else{
+			tx.Commit()
+		}	
+	}()
+
+	
+	// 批量更新
+	if len(descriptionList) == 0 {
+		// 删除所有记录
+		sql := `DELETE FROM chart_description WHERE chart_info_id = ?`
+		_, err = tx.Raw(sql, chartInfoId).Exec()
+		return
+	}
+	// 删除数组
+	deleteIdMap := make(map[int]bool)
+	// 查询现有记录
+	existingRecords := make(map[int]*ChartDescription)
+	var existing []*ChartDescription
+	sql := `SELECT * FROM chart_description WHERE chart_info_id = ?`
+	_, err = o.Raw(sql, chartInfoId).QueryRows(&existing)
+	if err != nil {
+		return err
+	}
+	for _, record := range existing {
+		existingRecords[record.Id] = record
+		deleteIdMap[record.Id] = true
+	}
+
+	// 分离需要更新和插入的记录
+	var toInsert []*ChartDescription
+	for _, desc := range descriptionList {
+		delete(deleteIdMap, desc.Id)
+		if _, exists := existingRecords[desc.Id]; exists {
+			// 更新
+			sql := "UPDATE chart_description SET description = ?, sys_user_id = ?, sys_user_real_name = ?, modify_time = ? WHERE id = ?"
+			_, err = tx.Raw(sql, desc.Description, desc.SysUserId, desc.SysUserRealName, desc.ModifyTime, desc.Id).Exec()
+			if err != nil {
+				return err
+			}
+		} else {
+			toInsert = append(toInsert, desc)
+		}
+	}
+
+	// 批量插入
+	if len(toInsert) > 0 {
+		_, err := tx.InsertMulti(len(toInsert), toInsert)
+		if err != nil {
+			return err
+		}
+	}
+	
+	// 删除数组中为true的记录
+	deleteIds := make([]int, 0)
+	for id, _ := range deleteIdMap {
+		deleteIds = append(deleteIds, id)
+	}
+	if len(deleteIds) > 0 {
+		sql := `DELETE FROM chart_description WHERE id IN (`+utils.GetOrmInReplace(len(deleteIds))+`) AND chart_info_id = ?`
+		_, err = tx.Raw(sql, deleteIds, chartInfoId).Exec()
+	}
+	
+	return
+}

+ 43 - 6
models/chart_info.go

@@ -5,11 +5,12 @@ import (
 	"eta/eta_forum_hub/models/system"
 	"eta/eta_forum_hub/utils"
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 type ChartInfo struct {
@@ -420,6 +421,7 @@ type ChartEdbInfoMapping struct {
 	ChartColor          string  `description:"颜色"`
 	PredictChartColor   string  `description:"预测数据的颜色"`
 	ChartWidth          float64 `description:"线条大小"`
+	ChartScale          float64 `description:"参考刻度线"`
 	ChartType           int     `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图"`
 	LatestDate          string  `description:"数据最新日期"`
 	LatestValue         float64 `description:"数据最新值"`
@@ -1023,7 +1025,7 @@ type AddChartInfoReq struct {
 
 type AddChartReq struct {
 	ChartInfo               *ChartInfo
-	Description             string `description:"逻辑简述"`
+	Description             []*ChartDescriptionReq `description:"逻辑简述"`
 	EdbInfoList             []*EdbInfo
 	ChartThemeList          []*ChartTheme
 	EdbInfoDataList         []*AddEdbDataReq
@@ -1036,9 +1038,10 @@ type AddChartReq struct {
 }
 
 type AddEdbDataReq struct {
-	EdbCode  string
-	EdbType  int
-	DataList []*EdbDataBase
+	EdbInfoId int
+	EdbCode   string
+	EdbType   int
+	DataList  []*EdbDataBase
 }
 
 type EdbDataBase struct {
@@ -1052,6 +1055,18 @@ type EdbDataBase struct {
 	DataTimestamp int64
 }
 
+type EdbDataBaseWithOpType struct {
+	*EdbDataBase
+	OpType    string
+}
+
+type AddEdbDataBinlogReq struct {
+	EdbInfoId int
+	EdbCode   string
+	EdbType   int
+	DataList  []*EdbDataBaseWithOpType
+}
+
 type DeleteChartReq struct {
 	ChartInfoId int `description:"图表id"`
 }
@@ -2158,3 +2173,25 @@ type ChartListResp struct {
 	ChartInfoList []*ChartInfo
 	Paging        *paging.PagingItem `description:"分页数据"`
 }
+
+// {"create_time":"2024-10-12 17:03:04","data_time":"2024-09-08","data_timestamp":1725724800000,"edb_code":"smmsmmgd1djt","edb_data_id":88546,"edb_info_id":105933,"modify_time":"2024-10-14 13:37:30","value":71988}
+type EdbDataBinlogItem struct {
+	CreateTime    string    	`json:"create_time"`
+	DataTime      string    	`json:"data_time"`
+	DataTimestamp int64     	`json:"data_timestamp"`
+	EdbCode       string    	`json:"edb_code"`
+	EdbDataId     int      	`json:"edb_data_id"`
+	EdbInfoId     int      	`json:"edb_info_id"`
+	ModifyTime    string    	`json:"modify_time"`
+	Value         interface{}    	`json:"value"`
+	OpType        string    	`json:"OpType"`
+}
+
+type EdbDataBinlogDataReq struct {
+	Item 	 string  `description:"指标数据列表"`
+	OpType   string  `description:"操作类型"`
+}
+
+type EdbDataBinlogReq struct {
+	List []*EdbDataBinlogDataReq `description:"指标数据列表"`
+}

+ 1 - 0
models/db.go

@@ -47,6 +47,7 @@ func initChart() {
 		new(ChartThemeType),
 		new(ChartSeries),
 		new(ChartSeriesEdbMapping),
+		new(ChartDescription),
 	)
 }
 

+ 11 - 4
models/mgodb/edb_data_base.go

@@ -86,17 +86,24 @@ func DeleteEdbInfoDataByEdbInfoId(edbInfoId int) (err error) {
 }
 
 // 删除
-func DeleteEdbInfoDataByEdbInfoIdAndDate(edbCode string, dataTime []time.Time) (err error) {
-	filter := bson.D{{"edb_code", edbCode}, {"data_time", bson.D{{"$in", dataTime}}}}
+func DeleteEdbInfoDataByEdbCodeAndDateList(edbCode string, dataTimeList []time.Time) (err error) {
+	filter := bson.D{{"edb_code", edbCode}, {"data_time", bson.D{{"$in", dataTimeList}}}}
+	db := NewMgo(utils.MgoDataDbName, "edb_data_base", utils.MgoDataCli)
+	_, err = db.DeleteMany(filter)
+	return
+}
+
+func DeleteEdbInfoDataByEdbInfoIdAndDateList(edbInfoId int, dataTimeList []time.Time) (err error) {
+	filter := bson.D{{"edb_info_id", edbInfoId}, {"data_time", bson.D{{"$in", dataTimeList}}}}
 	db := NewMgo(utils.MgoDataDbName, "edb_data_base", utils.MgoDataCli)
 	_, err = db.DeleteMany(filter)
 	return
 }
 
 // 更新指标的值
-func ModifyValueEdbDataValue(edbDataId primitive.ObjectID, value float64) (err error) {
+func ModifyValueEdbDataValue(edbDataId primitive.ObjectID, value float64, modifyTime time.Time) (err error) {
 	filter := bson.D{{"_id", edbDataId}}
-	update := bson.D{{"$set", bson.D{{"value", value}, {"modify_time", time.Now()}}}}
+	update := bson.D{{"$set", bson.D{{"value", value}, {"modify_time", modifyTime}}}}
 	db := NewMgo(utils.MgoDataDbName, "edb_data_base", utils.MgoDataCli)
 	_, err = db.UpdateOne(filter, update)
 	return

+ 10 - 3
models/mgodb/edb_data_calculate.go

@@ -68,21 +68,28 @@ func DeleteEdbInfoCalculateDataByEdbInfoId(edbInfoId int) (err error) {
 }
 
 // 更新指标的值
-func ModifyValueEdbCalculateDataValue(edbDataId primitive.ObjectID, value float64) (err error) {
+func ModifyValueEdbCalculateDataValue(edbDataId primitive.ObjectID, value float64, modifyTime time.Time) (err error) {
 	filter := bson.D{{"_id", edbDataId}}
-	update := bson.D{{"$set", bson.D{{"value", value}, {"modify_time", time.Now()}}}}
+	update := bson.D{{"$set", bson.D{{"value", value}, {"modify_time", modifyTime}}}}
 	db := NewMgo(utils.MgoDataDbName, "edb_data_calculate", utils.MgoDataCli)
 	_, err = db.UpdateOne(filter, update)
 	return
 }
 
-func DeleteEdbCalculateDataByEdbInfoIdAndDate(edbCode string, dataTime []time.Time) (err error) {
+func DeleteEdbCalculateDataByEdbCodeAndDateList(edbCode string, dataTime []time.Time) (err error) {
 	filter := bson.D{{"edb_code", edbCode}, {"data_time", bson.D{{"$in", dataTime}}}}
 	db := NewMgo(utils.MgoDataDbName, "edb_data_calculate", utils.MgoDataCli)
 	_, err = db.DeleteMany(filter)
 	return
 }
 
+func DeleteEdbCalculateDataByEdbInfoIdAndDateList(edbInfoId int, dataTime []time.Time) (err error) {
+	filter := bson.D{{"edb_info_id", edbInfoId}, {"data_time", bson.D{{"$in", dataTime}}}}
+	db := NewMgo(utils.MgoDataDbName, "edb_data_calculate", utils.MgoDataCli)
+	_, err = db.DeleteMany(filter)
+	return
+}
+
 // GetEdbCalculateDataList 获取指标的数据(日期正序返回)
 func GetEdbCalculateDataList(endInfoId int, startDate, endDate time.Time) (list []*EdbDataBase, err error) {
 	findOptions := options.Find()

+ 1 - 1
models/mgodb/mgo.go

@@ -61,7 +61,7 @@ func (m *mgo) InsertMany(value []interface{}) (insertManyResult *mongo.InsertMan
 		return
 	}
 
-	fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
+	//fmt.Println("Inserted multiple documents: ", insertManyResult.InsertedIDs)
 	return
 }
 

+ 7 - 0
models/system/admin.go

@@ -246,6 +246,13 @@ func GetAdminByAdminName(adminName string) (item *Admin, err error) {
 	return
 }
 
+// GetAdminListByAdminName 账号获取用户列表
+func GetAdminListByAdminName(adminNames []string) (items []*Admin, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM admin WHERE admin_name in (` + utils.GetOrmInReplace(len(adminNames)) + `) `
+	_, err = o.Raw(sql, adminNames).QueryRows(&items)
+	return
+}	
 // GetAdminByAdminNameAndBusinessCode 账号获取用户
 func GetAdminByAdminNameAndBusinessCode(adminName, businessCode string) (item *Admin, err error) {
 	o := orm.NewOrm()

+ 36 - 0
routers/commentsRouter.go

@@ -241,6 +241,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:ChartClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:ChartClassifyController"],
+        beego.ControllerComments{
+            Method: "BatchSave",
+            Router: `/batch_save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:ChartClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:ChartClassifyController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:ChartCollectController"] = append(beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:ChartCollectController"],
         beego.ControllerComments{
             Method: "ChartList",
@@ -322,4 +340,22 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:EdbDataController"] = append(beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:EdbDataController"],
+        beego.ControllerComments{
+            Method: "SaveByBinlog",
+            Router: `/save_by_binlog`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:EdbDataController"] = append(beego.GlobalControllerRouter["eta/eta_forum_hub/controllers:EdbDataController"],
+        beego.ControllerComments{
+            Method: "TestSaveByBinlog",
+            Router: `/test_save_by_binlog`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
 }

+ 11 - 0
routers/router.go

@@ -11,6 +11,7 @@ import (
 	"eta/eta_forum_hub/controllers"
 	"eta/eta_forum_hub/controllers/eta_trial"
 	"eta/eta_forum_hub/controllers/system"
+
 	"github.com/beego/beego/v2/server/web"
 )
 
@@ -49,6 +50,16 @@ func init() {
 				&eta_trial.EtaTrialController{},
 			),
 		),
+		web.NSNamespace("/chart_classify",
+			web.NSInclude(
+				&controllers.ChartClassifyController{},
+			),
+		),
+		web.NSNamespace("/edb_data",
+			web.NSInclude(
+				&controllers.EdbDataController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 122 - 0
services/chart_classify.go

@@ -0,0 +1,122 @@
+package services
+
+import (
+	"eta/eta_forum_hub/models"
+	"eta/eta_forum_hub/services/alarm_msg"
+	"eta/eta_forum_hub/utils"
+	"fmt"
+	"time"
+)
+
+// 批量新增或更新图表分类
+func BatchAddOrUpdateChartClassify(req *models.ChartClassifySyncReq) (err error, isSendEmail bool) {
+	defer func() {
+		if err != nil {
+			utils.FileLog.Info("新增或更新图表分类, BatchAddOrUpdateChartClassify  Err: " + err.Error())
+			go alarm_msg.SendAlarmMsg("新增或更新图表分类, BatchAddOrUpdateChartClassify  Err: "+err.Error(), 3)
+		}
+	}()
+	isSendEmail = true
+	if len(req.List) == 0 {
+		return
+	}
+
+	// 构建待删除列表
+	deleteList := make(map[int]int)
+
+	// 获取现有分类数据
+	classifyList, err := models.GetChartClassifyAll(1)
+	if err != nil {
+		err = fmt.Errorf("获取图表分类数据失败,%v", err)
+		return
+	}
+
+	classifyMap := make(map[int]*models.ChartClassify)
+	for _, v := range classifyList {
+		deleteList[v.ChartClassifyId] = v.ChartClassifyId
+		classifyMap[v.ChartClassifyId] = v
+	}
+
+	// 处理请求列表
+	for _, item := range req.List {
+		classify, exists := classifyMap[item.ChartClassifyId]
+		if exists {
+			delete(deleteList, item.ChartClassifyId) 
+		} else {
+			classify = new(models.ChartClassify)
+		}
+
+		// 更新字段
+		classify.ChartClassifyId = item.ChartClassifyId
+		classify.ChartClassifyName = item.ChartClassifyName
+		classify.ParentId = item.ParentId
+		classify.Sort = item.Sort
+		classify.HasData = item.HasData
+		classify.Level = item.Level
+		classify.UniqueCode = item.UniqueCode
+		classify.Source = item.Source
+		classify.IsJoinPermission = item.IsJoinPermission
+		classify.ChartClassifyNameEn = item.ChartClassifyNameEn
+		classify.LevelPath = item.LevelPath
+		classify.IsSelected = item.IsSelected
+		classify.ResourceStatus = item.ResourceStatus
+		classify.SysUserId = item.SysUserId
+		classify.SysUserRealName = item.SysUserRealName
+		classify.ModifyTime = time.Now()
+
+		if !exists {
+			classify.CreateTime = time.Now()
+			_, err = models.AddChartClassify(classify)
+			if err != nil {
+				err = fmt.Errorf("新增图表分类失败,Err:%s", err.Error())
+				return
+			}
+		} else {
+			err = classify.Update([]string{})
+			if err != nil {
+				err = fmt.Errorf("更新图表分类失败,Err:%s", err.Error())
+				return
+			}
+		}
+	}
+
+	// 删除不在请求中的分类
+	for _, id := range deleteList {
+		err = models.DeleteChartClassify(id)
+		if err != nil {
+			err = fmt.Errorf("删除图表分类失败,Err:%s", err.Error())
+			return
+		}
+	}
+	return
+}
+
+
+// 新增或者更新图表分类
+func AddOrUpdateChartClassify(req *models.ChartClassify) (err error) {
+	defer func() {
+		if err != nil {
+			utils.FileLog.Info("新增或者更新图表分类, AddOrUpdateChartClassify  Err: " + err.Error())
+			go alarm_msg.SendAlarmMsg("新增或者更新图表分类, AddOrUpdateChartClassify  Err: "+err.Error(), 3)
+		}
+	}()
+	// 查询分类id是否存在
+	exist, err := models.GetChartClassifyById(req.ChartClassifyId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("查询分类id是否存在失败,Err:%s", err.Error())
+		return
+	}
+	isAdd := false
+	if exist == nil {
+		isAdd = true
+	}
+	if isAdd {
+		req.CreateTime = time.Now()
+		req.ModifyTime = time.Now()
+		_, err = models.AddChartClassify(req)
+	} else {
+		exist.ModifyTime = time.Now()
+		err = exist.Update([]string{})
+	}
+	return
+}

+ 84 - 5
services/chart_info.go

@@ -38,8 +38,8 @@ func AddChartInfo(req *models.AddChartReq, sysUserId int, sysUserRealName string
 	var pars []interface{}
 
 	// todo 判断同一个平台上的图表是否重复
-	condition += " AND chart_name=? AND source = ? "
-	pars = append(pars, req.ChartInfo.ChartName, req.ChartInfo.Source)
+	condition += " AND chart_info_id=?"
+	pars = append(pars, req.ChartInfo.ChartInfoId)
 
 	count, err := models.GetChartInfoCountByCondition(condition, pars)
 	if err != nil {
@@ -110,8 +110,9 @@ func AddChartInfo(req *models.AddChartReq, sysUserId int, sysUserRealName string
 			chartInfo.UploadUserRealName = uploader.RealName
 		}
 	}
-
+	chartInfo.ChartInfoId = req.ChartInfo.ChartInfoId
 	chartInfo.ChartName = req.ChartInfo.ChartName
+	chartInfo.ChartClassifyId = req.ChartInfo.ChartClassifyId
 	chartInfo.EdbInfoIds = edbInfoIdStr
 
 	chartInfo.CreateTime = time.Now()
@@ -151,8 +152,8 @@ func AddChartInfo(req *models.AddChartReq, sysUserId int, sysUserRealName string
 	chartInfo.MarkersAreas = req.ChartInfo.MarkersAreas
 	chartInfo.Unit = req.ChartInfo.Unit
 	chartInfo.UnitEn = req.ChartInfo.UnitEn
-	chartInfo.Description = req.Description
 	chartInfo.ChartImage = req.ChartInfo.ChartImage
+	chartInfo.Sort = req.ChartInfo.Sort
 	/*newId, err := models.AddChartInfo(chartInfo)
 	if err != nil {
 		errMsg = `保存失败`
@@ -251,6 +252,13 @@ func AddChartInfo(req *models.AddChartReq, sysUserId int, sysUserRealName string
 			return
 		}
 	}
+	// 添加图表简介
+	err, errMsg = addOrUpdateChartDescriptionList(chartInfo.ChartInfoId, req.Description)
+	if err != nil {
+		errMsg = "保存失败"
+		err = errors.New("保存失败,Err:" + err.Error())
+		return
+	}
 	//添加es数据
 	go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
 
@@ -346,6 +354,7 @@ func UpdateChartInfoAndEdbInfo(req *models.AddChartReq, sysUserId int, sysUserRe
 	edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
 
 	chartInfo.ChartName = req.ChartInfo.ChartName
+	chartInfo.ChartClassifyId = req.ChartInfo.ChartClassifyId
 	chartInfo.EdbInfoIds = edbInfoIdStr
 	chartInfo.ModifyTime = time.Now()
 	chartInfo.IsSetName = req.ChartInfo.IsSetName
@@ -381,6 +390,7 @@ func UpdateChartInfoAndEdbInfo(req *models.AddChartReq, sysUserId int, sysUserRe
 	chartInfo.ChartImage = req.ChartInfo.ChartImage
 	chartInfo.SysUserId = req.ChartInfo.SysUserId
 	chartInfo.SysUserRealName = req.ChartInfo.SysUserRealName
+	chartInfo.Sort = req.ChartInfo.Sort
 	// 查询创建者信息
 	if req.CreatorInfo != nil {
 		creator, _ := system.GetAdminByAdminName(req.CreatorInfo.AdminName)
@@ -547,6 +557,13 @@ func UpdateChartInfoAndEdbInfo(req *models.AddChartReq, sysUserId int, sysUserRe
 			return
 		}
 	}
+	// 更新图表简介
+	err, errMsg = addOrUpdateChartDescriptionList(chartInfo.ChartInfoId, req.Description)
+	if err != nil {
+		errMsg = "保存失败"
+		err = errors.New("保存失败,Err:" + err.Error())
+		return
+	}
 	//添加es数据
 	go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
 	go EsAddOrEditChartCollectByChartInfoId(chartInfo.ChartInfoId)
@@ -602,7 +619,14 @@ func DeleteChart(chartInfoId int) (err error, errMsg string) {
 		err = fmt.Errorf("删除指标数据失败, Err:" + err.Error())
 		return
 	}
-
+	// 删除图表简介
+	descriptionList := make([]*models.ChartDescriptionReq, 0)
+	err, errMsg = addOrUpdateChartDescriptionList(chartInfo.ChartInfoId, descriptionList)
+	if err != nil {
+		errMsg = "删除失败"
+		err = errors.New("删除图表简介失败,Err:" + err.Error())
+		return
+	}
 	go EsDeleteChartInfo(chartInfo.ChartInfoId)
 	go func() {
 		var e error
@@ -727,3 +751,58 @@ func transferChartConfigEdbInfoId(chartInfo *models.ChartInfo, newEdbInfoIdMap m
 	}
 	return
 }
+
+
+func addOrUpdateChartDescriptionList(chartInfoId int, reqDescription []*models.ChartDescriptionReq) (err error, errMsg string) {
+	descriptionList := make([]*models.ChartDescription, 0)
+	if len(reqDescription) == 0 {
+		err = models.BatchUpdateChartDescription(chartInfoId, descriptionList)
+		if err != nil {
+			errMsg = "保存失败"
+			err = errors.New("保存失败,Err:" + err.Error())
+			return
+		}
+	}
+	// 更换成社区的创建人
+	oldAdminIdMap := make(map[string]int)
+	adminNames := make([]string, 0)
+	for _, v := range reqDescription {
+		adminNames = append(adminNames, v.AdminName)
+	}
+	if len(adminNames) > 0 {
+		adminList, e := system.GetAdminListByAdminName(adminNames)
+		if e != nil {
+			errMsg = "获取创建人信息失败"
+			err = errors.New("获取创建人信息失败,Err:" + e.Error())
+			return
+		}
+		for _, v := range reqDescription {
+			for _, admin := range adminList {
+				oldAdminIdMap[v.AdminName] = admin.AdminId
+			}
+		}
+	}
+	
+	for _, v := range reqDescription {
+		if oldAdminId, ok := oldAdminIdMap[v.AdminName]; ok {
+			v.SysUserId = oldAdminId
+		}else{
+			v.SysUserId = 0
+		}
+		descriptionList = append(descriptionList, &models.ChartDescription{
+			ChartInfoId: chartInfoId,
+			Description: v.Description,
+			SysUserId: v.SysUserId,
+			SysUserRealName: v.AdminName,
+			ModifyTime: time.Now(),
+			CreateTime: time.Now(),
+		})
+	}
+	err = models.BatchUpdateChartDescription(chartInfoId, descriptionList)
+	if err != nil {
+		errMsg = "保存失败"
+		err = errors.New("保存失败,Err:" + err.Error())
+		return
+	}
+	return
+}

+ 118 - 38
services/chart_info_show.go

@@ -363,7 +363,16 @@ func GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*models.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*models.EdbDataList, edbList []*models.ChartEdbInfoMapping, err error) {
 	// 指标对应的所有数据
 	edbDataListMap = make(map[int][]*models.EdbDataList)
-
+	// 设置季节性图的左右轴
+	seasonXStartDateWithYear := ""
+	seasonXEndDateWithYear := ""
+	// 如果是季节性图则进入特殊排序
+	if chartType == 2 {
+		// 根据设置的左右轴,对mappingList进行排序,1左轴排在前面,0右轴排在前面
+		sort.Slice(mappingList, func(i, j int) bool {
+			return mappingList[i].IsAxis > mappingList[j].IsAxis
+		})
+	}
 	for _, v := range mappingList {
 		//fmt.Println("v:", v.EdbInfoId)
 		item := new(models.ChartEdbInfoMapping)
@@ -397,6 +406,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 			item.ChartStyle = ""
 			item.ChartColor = ""
 			item.ChartWidth = 0
+			item.ChartScale = 0
 			item.MaxData = v.MaxValue
 			item.MinData = v.MinValue
 		} else {
@@ -410,6 +420,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 			item.ChartStyle = v.ChartStyle
 			item.ChartColor = v.ChartColor
 			item.ChartWidth = v.ChartWidth
+			item.ChartScale = v.ChartScale
 			item.IsOrder = v.IsOrder
 			item.MaxData = v.MaxData
 			item.MinData = v.MinData
@@ -436,7 +447,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 		} else {
 			if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
 				var startTimeRealTemp time.Time
-				startDateParse, _ := time.Parse(utils.FormatDate, startDate)
+				startDateParse, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
 				switch v.LeadUnit {
 				case "天":
 					startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
@@ -457,8 +468,8 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 					diffSeconds = 0
 				}
 
-				// todo 预测指标的开始日期也要偏移
-				/*{
+				// 预测指标的开始日期也要偏移
+				{
 					day, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
 					if tmpErr != nil {
 						err = tmpErr
@@ -470,7 +481,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 						return
 					}
 					item.MoveLatestDate = moveLatestDateTime.AddDate(0, 0, day).Format(utils.FormatDate)
-				}*/
+				}
 			} else {
 				startDateReal = startDate
 			}
@@ -489,8 +500,6 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 		dataList := make([]*models.EdbDataList, 0)
 		dataList, err = GetEdbDataList(v.EdbInfoId, v.EdbType, startDateReal, endDate)
 		if err != nil {
-			// 获取指标数据失败
-			err = fmt.Errorf("获取指标数据失败 GetEdbDataList error, %v", err)
 			return
 		}
 
@@ -531,7 +540,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 		}
 
 		if chartType == 2 && item.IsAxis == 1 {
-			latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
+			latestDate, tmpErr := time.ParseInLocation(utils.FormatDate, v.LatestDate, time.Local)
 			if tmpErr != nil {
 				//item.DataList = dataList
 				item.IsNullData = true
@@ -551,42 +560,87 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 						err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
 						return
 					}
-					quarterDataList, tErr := GetSeasonEdbInfoDataListByXDateNong(result, latestDate, seasonExtraConfig, calendarPreYear)
+					quarterDataList, seasonXStartDateWithYearTmp, seasonXEndDateWithYearTmp, tErr := GetSeasonEdbInfoDataListByXDateNong(result, latestDate, seasonExtraConfig, calendarPreYear)
 					if tErr != nil {
 						err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
 						return
 					}
 					item.DataList = quarterDataList
+					seasonXStartDateWithYear = seasonXStartDateWithYearTmp
+					seasonXEndDateWithYear = seasonXEndDateWithYearTmp
 				}
 
 			} else {
-				quarterDataList, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDate, seasonExtraConfig)
+				quarterDataList, seasonXStartDateWithYearTmp, seasonXEndDateWithYearTmp, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDate, seasonExtraConfig)
 				if tErr != nil {
 					err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
 					return
 				}
 				item.DataList = quarterDataList
+				seasonXStartDateWithYear = seasonXStartDateWithYearTmp
+				seasonXEndDateWithYear = seasonXEndDateWithYearTmp
 			}
 
 		} else if chartType == 2 && item.IsAxis == 0 {
-			// 右轴数据处理,只要最新一年
-			latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
-			if tmpErr != nil {
-				//item.DataList = dataList
-				item.IsNullData = true
-				edbList = append(edbList, item)
-				continue
-				err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
-				return
-			}
+			// 右轴数据处理
+			// xStartDate := "01-01"
+
+			// jumpYear := 0
+			// var seasonExtra models.SeasonExtraItem
+			// if seasonExtraConfig != "" {
+			// 	err = json.Unmarshal([]byte(seasonExtraConfig), &seasonExtra)
+			// 	if err != nil {
+			// 		return
+			// 	}
+			// }
+
+			// if seasonExtra.XStartDate != "" {
+			// 	xStartDate = seasonExtra.XStartDate
+			// 	jumpYear = seasonExtra.JumpYear
+			// }
+
+			// length := len(dataList)
+			// if length == 0 {
+			// 	return
+			// }
+			// latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
+			// if tmpErr != nil {
+			// 	//item.DataList = dataList
+			// 	item.IsNullData = true
+			// 	edbList = append(edbList, item)
+			// 	continue
+			// 	err = errors.New(fmt.Sprint("获取最后实际数据的日期失败,Err:" + tmpErr.Error() + ";LatestDate:" + v.LatestDate))
+			// 	return
+			// }
+
+			// var rightAxisDate time.Time
+			// if jumpYear == 1 {
+			// 	latestDate = latestDate.AddDate(-1, 0, 0)
+			// }
+			// latestDateStr := fmt.Sprintf("%d-%s", latestDate.Year(), xStartDate)
+			// rightAxisDate, err = time.Parse(utils.FormatDate, latestDateStr)
+			// if err != nil {
+			// 	return
+			// }
+			// nowYear := time.Now().Year()
 			newDataList := make([]*models.EdbDataList, 0)
+			seasonXStartDateWithYearT, _ := time.ParseInLocation(utils.FormatDate, seasonXStartDateWithYear, time.Local)
+			seasonXEndDateWithYearT, _ := time.ParseInLocation(utils.FormatDate, seasonXEndDateWithYear, time.Local)
 			for _, v := range dataList {
-				dataTime, e := time.Parse(utils.FormatDate, v.DataTime)
+				dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
 				if e != nil {
 					err = errors.New("季节性图处理右轴指标数据转换日期失败,Err:" + e.Error())
 					return
 				}
-				if dataTime.Year() == latestDate.Year() {
+				//dataTimeT, _ := time.Parse(utils.FormatDate, v.DataTime)
+				// year := dataTimeT.Year()
+				// newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
+				// v.DataTimestamp = newItemDate.UnixNano() / 1e6
+				// if dataTime.Equal(rightAxisDate) || dataTime.After(rightAxisDate) {
+				// 	newDataList = append(newDataList, v)
+				// }
+				// 如果数据时间在横轴的开始日期和结束日期之间,则加入到数据列表中
+				if (dataTime.After(seasonXStartDateWithYearT) && dataTime.Before(seasonXEndDateWithYearT)) || dataTime.Equal(seasonXStartDateWithYearT) || dataTime.Equal(seasonXEndDateWithYearT) {
 					newDataList = append(newDataList, v)
 				}
 			}
@@ -603,7 +657,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 }
 
 // GetSeasonEdbInfoDataListByXDate 季节性图的指标数据根据横轴展示
-func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate time.Time, seasonExtraConfig string) (quarterDataListSort models.QuarterDataList, err error) {
+func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate time.Time, seasonExtraConfig string) (quarterDataListSort models.QuarterDataList, xStartDateWithYear string, xEndDateWithYear string, err error) {
 	xStartDate := "01-01"
 	xEndDate := "12-31"
 	jumpYear := 0
@@ -639,7 +693,7 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 	//根据数据确定最早的年份,和最近年份
 	//根据横轴的日期,汇总所有的年份
 	startDate := dataList[0].DataTime
-	startDateT, tmpErr := time.Parse(utils.FormatDate, startDate)
+	startDateT, tmpErr := time.ParseInLocation(utils.FormatDate, startDate,time.Local)
 	if tmpErr != nil {
 		err = tmpErr
 		return
@@ -647,13 +701,14 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 	startYear := startDateT.Year()
 	//获取数据的最新日期
 	lastDate := dataList[length-1].DataTime
-	lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
+	lastDateT, tmpErr := time.ParseInLocation(utils.FormatDate, lastDate,time.Local)
 	if tmpErr != nil {
 		err = tmpErr
 		return
 	}
 	endYear := lastDateT.Year()
-	nowYear := time.Now().Year()
+	nowYear := endYear
+	chartLegendMaxYear := 0
 	dataMap := make(map[string]models.QuarterXDateItem, 0)
 
 	quarterDataList := make([]*models.QuarterData, 0)
@@ -672,13 +727,13 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 		name := fmt.Sprintf("%s_%s", startStr, endStr)
 		showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
 
-		startT, tEr := time.Parse(utils.FormatDate, startStr)
+		startT, tEr := time.ParseInLocation(utils.FormatDate, startStr,time.Local)
 		if tEr != nil {
 			err = tEr
 			return
 		}
 
-		endT, tEr := time.Parse(utils.FormatDate, endStr)
+		endT, tEr := time.ParseInLocation(utils.FormatDate, endStr,time.Local)
 		if tEr != nil {
 			err = tEr
 			return
@@ -699,25 +754,32 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 			EndDate:   endT,
 			ShowName:  showName,
 		}
+		chartLegendMaxYear = endT.Year()
 		dataMap[name] = item
 		chartLegendMap[name] = idx
 		idx++
 		fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
+		xStartDateWithYear = startStr
+		xEndDateWithYear = endStr
 		if lastDateT.Before(endT) {
 			//如果最新的日期在起始日之前,则跳出循环
 			break
 		}
 	}
 	lenYear := len(dataMap)
+	if chartLegendMaxYear > endYear {
+		chartLegendMaxYear = endYear
+	}
 	for k, v := range dataMap {
 		if i, ok := chartLegendMap[k]; ok {
-			v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			//v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			v.ChartLegend = strconv.Itoa(chartLegendMaxYear - lenYear + i)
 		}
 		dataMap[k] = v
 	}
 
 	for _, v := range dataList {
-		dataTimeT, _ := time.Parse(utils.FormatDate, v.DataTime)
+		dataTimeT, _ := time.ParseInLocation(utils.FormatDate, v.DataTime,time.Local)
 		year := dataTimeT.Year()
 		newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
 		for k, dateItem := range dataMap {
@@ -732,7 +794,7 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 				if jumpYear == 1 {
 					//计算前一年最大的日期, 只补齐数据到去年
 					beforeYearMaxDate := fmt.Sprintf("%d-12-31", dateItem.StartDate.Year())
-					beforeYearMaxDateT, _ := time.Parse(utils.FormatDate, beforeYearMaxDate)
+					beforeYearMaxDateT, _ := time.ParseInLocation(utils.FormatDate, beforeYearMaxDate,time.Local)
 					if dataTimeT.Before(beforeYearMaxDateT) || dataTimeT == beforeYearMaxDateT {
 						newItemDate = dataTimeT.AddDate(nowYear-year-1, 0, 0)
 					} else {
@@ -762,6 +824,9 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 	}
 	for k, v := range dataMap {
 		itemList := quarterMap[k]
+		/*if len(itemList) == 0 {
+			continue
+		}*/
 		quarterItem := new(models.QuarterData)
 		quarterItem.Years = v.ShowName
 		quarterItem.ChartLegend = v.ChartLegend
@@ -791,7 +856,7 @@ func GetSeasonEdbInfoDataListByXDate(dataList []*models.EdbDataList, latestDate
 }
 
 // GetSeasonEdbInfoDataListByXDateNong 季节性图的指标数据根据横轴选择农历时展示
-func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate time.Time, seasonExtraConfig string, calendarPreYear int) (quarterDataListSort models.QuarterDataList, err error) {
+func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate time.Time, seasonExtraConfig string, calendarPreYear int) (quarterDataListSort models.QuarterDataList, xStartDateWithYear string, xEndDateWithYear string, err error) {
 	xStartDate := "01-01"
 	xEndDate := "12-31"
 	jumpYear := 0
@@ -837,13 +902,14 @@ func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate
 	//获取数据的最新日期
 	lastDate := result.List[length-1].Items[itemLength-1].DataTime
 	maxY := result.List[length-1].Year
-	lastDateT, tmpErr := time.Parse(utils.FormatDate, lastDate)
+	lastDateT, tmpErr := time.ParseInLocation(utils.FormatDate, lastDate,time.Local)
 	if tmpErr != nil {
 		err = tmpErr
 		return
 	}
 	endYear := lastDateT.Year()
-	nowYear := time.Now().Year()
+	nowYear := endYear
+	chartLegendMaxYear := 0
 	dataMap := make(map[string]models.QuarterXDateItem, 0)
 
 	quarterDataList := make([]*models.QuarterData, 0)
@@ -863,13 +929,13 @@ func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate
 		endStr := fmt.Sprintf("%d-%s", currentEndYear, xEndDate)
 		showName := fmt.Sprintf("%d_%d", currentStartYear, currentEndYear)
 
-		startT, tEr := time.Parse(utils.FormatDate, startStr)
+		startT, tEr := time.ParseInLocation(utils.FormatDate, startStr,time.Local)
 		if tEr != nil {
 			err = tEr
 			return
 		}
 
-		endT, tEr := time.Parse(utils.FormatDate, endStr)
+		endT, tEr := time.ParseInLocation(utils.FormatDate, endStr,time.Local)
 		if tEr != nil {
 			err = tEr
 			return
@@ -888,21 +954,28 @@ func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate
 			EndDate:   endT,
 			ShowName:  showName,
 		}
+		chartLegendMaxYear = endT.Year()
 		dataMap[showName] = item
 		fmt.Println("年份" + showName + "日期" + startStr + " " + endStr)
 		startTmpT = startT
 		endTmpT = endT
 		chartLegendMap[showName] = idx
 		idx++
+		xStartDateWithYear = startStr
+		xEndDateWithYear = endStr
 		if lastDateT.Before(endT) {
 			//如果最新的日期在起始日之前,则跳出循环
 			break
 		}
 	}
 	lenYear := len(dataMap)
+	if chartLegendMaxYear > endYear {
+		chartLegendMaxYear = endYear
+	}
 	for k, v := range dataMap {
 		if i, ok := chartLegendMap[k]; ok {
-			v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			//v.ChartLegend = strconv.Itoa(endYear - lenYear + i)
+			v.ChartLegend = strconv.Itoa(chartLegendMaxYear - lenYear + i)
 		}
 		dataMap[k] = v
 	}
@@ -955,7 +1028,11 @@ func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate
 				DataTimestamp: item.DataTimestamp,
 				Value:         item.Value,
 			}
-			dataTimeT, _ := time.Parse(utils.FormatDate, item.DataTime)
+			dataTimeT, _ := time.ParseInLocation(utils.FormatDate, item.DataTime,time.Local)
+			// year := dataTimeT.Year()
+			// newItemDate := dataTimeT.AddDate(nowYear-year, 0, 0)
+			// timestamp := newItemDate.UnixNano() / 1e6
+			// tmpVal.DataTimestamp = timestamp
 			if (startTmpT.Before(dataTimeT) && endTmpT.After(dataTimeT)) || startTmpT == dataTimeT || endTmpT == dataTimeT {
 				tmpV := &tmpVal
 				if findVal, ok := quarterMap[name]; !ok {
@@ -979,6 +1056,9 @@ func GetSeasonEdbInfoDataListByXDateNong(result *data.EdbDataResult, latestDate
 
 	for k, v := range dataMap {
 		itemList := quarterMap[k]
+		/*if len(itemList) == 0 {
+			continue
+		}*/
 		quarterItem := new(models.QuarterData)
 		quarterItem.Years = v.ShowName
 		quarterItem.ChartLegend = v.ChartLegend

+ 216 - 15
services/edb_data.go

@@ -5,20 +5,21 @@ import (
 	"eta/eta_forum_hub/models/mgodb"
 	"eta/eta_forum_hub/utils"
 	"fmt"
-	"github.com/shopspring/decimal"
 	"strconv"
 	"time"
+
+	"github.com/shopspring/decimal"
 )
 
 func BatchAddOrUpdateEdbData(req []*models.AddEdbDataReq) (err error) {
 	for _, reqData := range req {
 		if reqData.EdbType == 1 {
-			err = AddOrUpdateEdbData(reqData.EdbCode, reqData.DataList)
+			err = AddOrUpdateEdbData(reqData.EdbInfoId, reqData.EdbCode, reqData.DataList)
 			if err != nil {
 				return
 			}
 		} else {
-			err = AddOrUpdateEdbDataCalculate(reqData.EdbCode, reqData.DataList)
+			err = AddOrUpdateEdbDataCalculate(reqData.EdbInfoId, reqData.EdbCode, reqData.DataList)
 			if err != nil {
 				return
 			}
@@ -27,7 +28,11 @@ func BatchAddOrUpdateEdbData(req []*models.AddEdbDataReq) (err error) {
 	return
 }
 
-func AddOrUpdateEdbData(edbCode string, dataList []*models.EdbDataBase) (err error) {
+func AddOrUpdateEdbData(edbInfoId int, edbCode string, dataList []*models.EdbDataBase) (err error) {
+	// 指标数据为空则不更新
+	if len(dataList) == 0 {
+		return
+	}
 	addList := make([]interface{}, 0)
 	existList, err := mgodb.GetEdbDataBaseByEdbCode(edbCode)
 	if err != nil {
@@ -54,13 +59,13 @@ func AddOrUpdateEdbData(edbCode string, dataList []*models.EdbDataBase) (err err
 		}
 		if oldObj, ok := existMap[v.DataTime]; !ok {
 			tmp := &mgodb.EdbDataBase{
-				EdbInfoId:     0,
+				EdbInfoId:     edbInfoId,
 				EdbCode:       v.EdbCode,
 				DataTime:      dataTime,
 				Value:         val,
 				Status:        v.Status,
-				CreateTime:    time.Now(),
-				ModifyTime:    time.Now(),
+				CreateTime:    v.CreateTime,
+				ModifyTime:    v.ModifyTime,
 				DataTimestamp: v.DataTimestamp,
 			}
 			addList = append(addList, tmp)
@@ -75,7 +80,7 @@ func AddOrUpdateEdbData(edbCode string, dataList []*models.EdbDataBase) (err err
 		} else {
 			delete(deleteMap, v.DataTime)
 			if val != oldObj.Value {
-				err = mgodb.ModifyValueEdbDataValue(oldObj.EdbDataId, val)
+				err = mgodb.ModifyValueEdbDataValue(oldObj.EdbDataId, val, v.ModifyTime)
 				if err != nil {
 					err = fmt.Errorf("更新指标数据出错 error, %v", err)
 					return
@@ -97,7 +102,7 @@ func AddOrUpdateEdbData(edbCode string, dataList []*models.EdbDataBase) (err err
 		}
 		removeNum := len(removeDateList)
 		if removeNum > 0 {
-			err = mgodb.DeleteEdbInfoDataByEdbInfoIdAndDate(edbCode, removeDateList)
+			err = mgodb.DeleteEdbInfoDataByEdbCodeAndDateList(edbCode, removeDateList)
 			if err != nil {
 				err = fmt.Errorf("删除多余日期失败,error, %v", err)
 				return
@@ -112,7 +117,11 @@ func AddOrUpdateEdbData(edbCode string, dataList []*models.EdbDataBase) (err err
 	return
 }
 
-func AddOrUpdateEdbDataCalculate(edbCode string, dataList []*models.EdbDataBase) (err error) {
+func AddOrUpdateEdbDataCalculate(edbInfoId int, edbCode string, dataList []*models.EdbDataBase) (err error) {
+	// 指标数据为空则不更新
+	if len(dataList) == 0 {
+		return
+	}
 	addList := make([]interface{}, 0)
 	existList, err := mgodb.GetEdbDataCalculateByEdbCode(edbCode)
 	if err != nil {
@@ -139,13 +148,13 @@ func AddOrUpdateEdbDataCalculate(edbCode string, dataList []*models.EdbDataBase)
 		}
 		if oldObj, ok := existMap[v.DataTime]; !ok {
 			tmp := &mgodb.EdbDataBase{
-				EdbInfoId:     0,
+				EdbInfoId:     edbInfoId,
 				EdbCode:       v.EdbCode,
 				DataTime:      dataTime,
 				Value:         val,
 				Status:        v.Status,
-				CreateTime:    time.Now(),
-				ModifyTime:    time.Now(),
+				CreateTime:    v.CreateTime,
+				ModifyTime:    v.ModifyTime,
 				DataTimestamp: v.DataTimestamp,
 			}
 			addList = append(addList, tmp)
@@ -160,7 +169,7 @@ func AddOrUpdateEdbDataCalculate(edbCode string, dataList []*models.EdbDataBase)
 		} else {
 			delete(deleteMap, v.DataTime)
 			if val != oldObj.Value {
-				err = mgodb.ModifyValueEdbCalculateDataValue(oldObj.EdbDataId, val)
+				err = mgodb.ModifyValueEdbCalculateDataValue(oldObj.EdbDataId, val, v.ModifyTime)
 				if err != nil {
 					err = fmt.Errorf("更新指标数据出错 error, %v", err)
 					return
@@ -182,7 +191,7 @@ func AddOrUpdateEdbDataCalculate(edbCode string, dataList []*models.EdbDataBase)
 		}
 		removeNum := len(removeDateList)
 		if removeNum > 0 {
-			err = mgodb.DeleteEdbCalculateDataByEdbInfoIdAndDate(edbCode, removeDateList)
+			err = mgodb.DeleteEdbCalculateDataByEdbCodeAndDateList(edbCode, removeDateList)
 			if err != nil {
 				err = fmt.Errorf("删除多余日期失败,error, %v", err)
 				return
@@ -361,3 +370,195 @@ func GetEdbDataTbzForSeason(frequency string, tmpDataList []*models.EdbDataList,
 
 	return
 }
+
+// AddOrUpdateEdbDataWithOpType 根据操作类型,更新指标数据
+func AddOrUpdateEdbDataWithOpType(edbInfoId int, dataList []*models.EdbDataBaseWithOpType, minDataTime string, maxDataTime string) (err error) {
+	// 指标数据为空则不更新
+	if len(dataList) == 0 {
+		return
+	}
+	addList := make([]interface{}, 0)
+	minDataTimeT, err := time.ParseInLocation(utils.FormatDate, minDataTime, time.Local)
+	if err != nil {
+		err = fmt.Errorf("日期格式错误 error, %v", err)
+		return
+	}
+	maxDataTimeT, err := time.ParseInLocation(utils.FormatDate, maxDataTime, time.Local)
+	if err != nil {
+		err = fmt.Errorf("日期格式错误 error, %v", err)
+		return
+	}
+	existList, err := mgodb.GetEdbDataList(edbInfoId, minDataTimeT, maxDataTimeT)
+	if err != nil {
+		err = fmt.Errorf("查询指标数据出错 error, %v", err)
+		return
+	}
+	existMap := make(map[string]*mgodb.EdbDataBase, len(existList))
+	removeDateList := make([]time.Time, 0)
+	for _, exist := range existList {
+		tmp := exist.DataTime.Format(utils.FormatDate)
+		existMap[tmp] = exist
+	}
+	for _, v := range dataList {
+		dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
+		if e != nil {
+			err = fmt.Errorf("时间格式化出错 error, %v", e)
+			return
+		}
+		val, e := strconv.ParseFloat(v.Value, 64)
+		if e != nil {
+			err = fmt.Errorf("指标数据格式化出错 error, %v", e)
+			return
+		}
+		if oldObj, ok := existMap[v.DataTime]; !ok {
+			if v.OpType == "insert"  || v.OpType == "update" {
+				tmp := &mgodb.EdbDataBase{
+					EdbInfoId:     v.EdbInfoId,
+					EdbCode:       v.EdbCode,
+					DataTime:      dataTime,
+					Value:         val,
+					Status:        v.Status,
+					CreateTime:    v.CreateTime,
+					ModifyTime:    v.ModifyTime,
+					DataTimestamp: v.DataTimestamp,
+				}
+				addList = append(addList, tmp)
+				if len(addList) >500 {
+					err = mgodb.InsertEdbDataBatch(addList)
+					if err != nil {
+						err = fmt.Errorf("批量新增指标数据失败 error, %v", e)
+						return
+					}
+					addList = make([]interface{}, 0)
+					continue
+				}
+			}
+		} else {
+			if v.OpType != "delete" {
+				if v.ModifyTime.After(oldObj.ModifyTime) || oldObj.Value != val {
+					err = mgodb.ModifyValueEdbDataValue(oldObj.EdbDataId, val, v.ModifyTime)
+					if err != nil {
+						err = fmt.Errorf("更新指标数据出错 error, %v", err)
+						return
+					}
+				}
+			}else if v.OpType == "delete" {
+				removeDateList = append(removeDateList, dataTime)
+				// 删除数据
+				// err = mgodb.DeleteEdbInfoDataByEdbInfoIdAndDate(v.EdbCode, v.DataTime)
+				// if err != nil {
+				// 	err = fmt.Errorf("删除指标数据出错 error, %v", err)
+				// 	return
+			}
+		}
+	}
+
+	//遍历deletemap,找出需要删除的日期
+	
+	removeNum := len(removeDateList)
+	if removeNum > 0 {
+		err = mgodb.DeleteEdbInfoDataByEdbInfoIdAndDateList(edbInfoId, removeDateList)
+		if err != nil {
+			err = fmt.Errorf("删除多余日期失败,error, %v", err)
+			return
+		}
+	}
+	
+
+	if len(addList) > 0 {
+		err = mgodb.InsertEdbDataBatch(addList)
+	}
+
+	return
+}
+
+func AddOrUpdateEdbDataCalculateWithOpType(edbInfoId int, dataList []*models.EdbDataBaseWithOpType, minDataTime string, maxDataTime string) (err error) {
+	// 指标数据为空则不更新
+	if len(dataList) == 0 {
+		return
+	}
+	addList := make([]interface{}, 0)
+	minDataTimeT, err := time.ParseInLocation(utils.FormatDate, minDataTime, time.Local)
+	if err != nil {
+		err = fmt.Errorf("日期格式错误 error, %v", err)
+		return
+	}
+	maxDataTimeT, err := time.ParseInLocation(utils.FormatDate, maxDataTime, time.Local)
+	if err != nil {
+		err = fmt.Errorf("日期格式错误 error, %v", err)
+		return
+	}
+	existList, err := mgodb.GetEdbCalculateDataList(edbInfoId, minDataTimeT, maxDataTimeT)
+	if err != nil {
+		err = fmt.Errorf("查询指标数据出错 error, %v", err)
+		return
+	}
+	existMap := make(map[string]*mgodb.EdbDataBase, len(existList))
+	removeDateList := make([]time.Time, 0)
+	for _, exist := range existList {
+		tmp := exist.DataTime.Format(utils.FormatDate)
+		existMap[tmp] = exist
+	}
+	for _, v := range dataList {
+		dataTime, e := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
+		if e != nil {
+			err = fmt.Errorf("时间格式化出错 error, %v", e)
+			return
+		}
+		val, e := strconv.ParseFloat(v.Value, 64)
+		if e != nil {
+			err = fmt.Errorf("指标数据格式化出错 error, %v", e)
+			return
+		}
+		if oldObj, ok := existMap[v.DataTime]; !ok {
+			if v.OpType == "insert"  || v.OpType == "update" {
+				tmp := &mgodb.EdbDataBase{
+						EdbInfoId:     v.EdbInfoId,
+						EdbCode:       v.EdbCode,
+						DataTime:      dataTime,
+						Value:         val,
+						Status:        v.Status,
+						CreateTime:    v.CreateTime,
+						ModifyTime:    v.ModifyTime,
+						DataTimestamp: v.DataTimestamp,
+					}
+				addList = append(addList, tmp)
+				if len(addList) >500 {
+					err = mgodb.InsertEdbCalculateDataBatch(addList)
+					if err != nil {
+						err = fmt.Errorf("批量新增指标数据失败 error, %v", e)
+						return
+					}
+					addList = make([]interface{}, 0)
+					continue
+				}
+			}
+		} else {
+			if v.OpType != "delete" {
+				if v.ModifyTime.After(oldObj.ModifyTime) || oldObj.Value != val {
+					err = mgodb.ModifyValueEdbCalculateDataValue(oldObj.EdbDataId, val, v.ModifyTime)
+					if err != nil {
+						err = fmt.Errorf("更新指标数据出错 error, %v", err)
+						return
+					}
+				}
+			} else if v.OpType == "delete" {
+				removeDateList = append(removeDateList, dataTime)
+			}
+		}
+	}
+	//遍历deleteMap,找出需要删除的日期
+	removeNum := len(removeDateList)
+	if removeNum > 0 {
+		err = mgodb.DeleteEdbCalculateDataByEdbInfoIdAndDateList(edbInfoId, removeDateList)
+		if err != nil {
+			err = fmt.Errorf("删除多余日期失败,error, %v", err)
+			return
+		}
+	}
+
+	if len(addList) > 0 {
+		err = mgodb.InsertEdbCalculateDataBatch(addList)
+	}
+	return
+}

+ 26 - 16
services/edb_info.go

@@ -73,7 +73,8 @@ func BatchAddOrUpdateEdbInfo(edbList []*models.EdbInfo, edbMapping []*models.Edb
 func AddOrUpdateEdbInfo(edbItem *models.EdbInfo, sysUserId int, sysUserRealName string) (edbInfo *models.EdbInfo, err error, errMsg string, isSendEmail bool) {
 	isSendEmail = true
 	//判断指标是否存在
-	edbInfo, err = models.GetEdbInfoByEdbCode(edbItem.EdbCode)
+	//edbInfo, err = models.GetEdbInfoByEdbCode(edbItem.EdbCode)
+	edbInfo, err = models.GetEdbInfoById(edbItem.EdbInfoId)
 	if err != nil {
 		if err.Error() == utils.ErrNoRow() {
 			err = nil
@@ -147,6 +148,7 @@ func AddOrUpdateEdbInfo(edbItem *models.EdbInfo, sysUserId int, sysUserRealName
 		}
 	} else {
 		edbInfo = new(models.EdbInfo)
+		edbInfo.EdbInfoId = edbItem.EdbInfoId
 		edbInfo.Source = edbItem.Source
 		edbInfo.SourceName = edbItem.SourceName
 		edbInfo.EdbType = edbItem.EdbType
@@ -203,21 +205,21 @@ func AddOrUpdateEdbInfo(edbItem *models.EdbInfo, sysUserId int, sysUserRealName
 		}
 		edbInfo.EdbInfoId = int(edbInfoId)
 	}
-	if edbInfo.EdbType == 1 {
-		err = mgodb.ModifyEdbDataEdbInfoId(edbInfoId, edbInfo.EdbCode)
-		if err != nil {
-			errMsg = "保存失败"
-			err = errors.New("更新指标数据失败,Err:" + err.Error())
-			return
-		}
-	} else {
-		err = mgodb.ModifyEdbCalculateDataEdbInfoId(edbInfoId, edbInfo.EdbCode)
-		if err != nil {
-			errMsg = "保存失败"
-			err = errors.New("更新指标数据失败,Err:" + err.Error())
-			return
-		}
-	}
+	// if edbInfo.EdbType == 1 {
+	// 	err = mgodb.ModifyEdbDataEdbInfoId(edbInfoId, edbInfo.EdbCode)
+	// 	if err != nil {
+	// 		errMsg = "保存失败"
+	// 		err = errors.New("更新指标数据失败,Err:" + err.Error())
+	// 		return
+	// 	}
+	// } else {
+	// 	err = mgodb.ModifyEdbCalculateDataEdbInfoId(edbInfoId, edbInfo.EdbCode)
+	// 	if err != nil {
+	// 		errMsg = "保存失败"
+	// 		err = errors.New("更新指标数据失败,Err:" + err.Error())
+	// 		return
+	// 	}
+	// }
 
 	// 更新es
 	go AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
@@ -240,6 +242,14 @@ func BatchDeleteEdbInfo(edbInfoIds []int) (err error, errMsg string) {
 
 // 删除单个指标
 func DeleteEdbInfo(edbInfoId int) (err error, errMsg string) {
+	defer func() {
+		if err != nil {
+			utils.FileLog.Error("删除指标失败,Err:" + err.Error(), "edbInfoId", edbInfoId)
+		}
+		if errMsg != "" {
+			utils.FileLog.Error("删除指标失败,ErrMsg:" + errMsg, "edbInfoId", edbInfoId)
+		}
+	}()
 	//判断指标是否存在
 	info, err := models.GetEdbInfoById(edbInfoId)
 	if err != nil {

+ 17 - 0
utils/common.go

@@ -1336,3 +1336,20 @@ func (ms MapSorter) Less(i, j int) bool {
 func (ms MapSorter) Swap(i, j int) {
 	ms[i], ms[j] = ms[j], ms[i]
 }
+
+
+// GetDaysBetween2Date 计算两个日期之间相差几天
+func GetDaysBetween2Date(format, date1Str, date2Str string) (int, error) {
+	// 将字符串转化为Time格式
+	date1, err := time.ParseInLocation(format, date1Str, time.Local)
+	if err != nil {
+		return 0, err
+	}
+	// 将字符串转化为Time格式
+	date2, err := time.ParseInLocation(format, date2Str, time.Local)
+	if err != nil {
+		return 0, err
+	}
+	//计算相差天数
+	return int(date1.Sub(date2).Hours() / 24), nil
+}