Browse Source

Merge remote-tracking branch 'origin/eta/1.4.1'

# Conflicts:
#	models/business_conf.go
#	models/db.go
Roc 1 year ago
parent
commit
4ef19eadd3
29 changed files with 2149 additions and 10 deletions
  1. 64 0
      controllers/data_manage/chart_info.go
  2. 661 0
      controllers/data_manage/chart_theme.go
  3. 31 1
      controllers/data_manage/correlation/correlation_chart_info.go
  4. 31 1
      controllers/data_manage/cross_variety/chart_info.go
  5. 29 0
      controllers/data_manage/future_good/future_good_chart_info.go
  6. 21 1
      controllers/data_manage/future_good/future_good_profit_chart_info.go
  7. 31 1
      controllers/data_manage/line_equation/line_chart_info.go
  8. 25 0
      controllers/data_manage/line_feature/chart_info.go
  9. 1 1
      controllers/data_manage/multiple_graph_config.go
  10. 3 0
      models/business_conf.go
  11. 1 0
      models/data_manage/chart_edb_mapping.go
  12. 38 2
      models/data_manage/chart_info.go
  13. 151 0
      models/data_manage/chart_theme/chart_theme.go
  14. 92 0
      models/data_manage/chart_theme/chart_theme_default_data.go
  15. 90 0
      models/data_manage/chart_theme/chart_theme_type.go
  16. 30 0
      models/data_manage/chart_theme/request/theme.go
  17. 7 0
      models/data_manage/cross_variety/request/chart.go
  18. 6 0
      models/data_manage/line_equation/request/line_equation.go
  19. 13 0
      models/db.go
  20. 81 0
      routers/commentsRouter.go
  21. 1 0
      routers/router.go
  22. 91 0
      services/data/chart_info.go
  23. 595 0
      services/data/chart_theme.go
  24. 11 1
      services/data/correlation/chart_info.go
  25. 6 0
      services/data/cross_variety/chart.go
  26. 1 1
      services/data/edb_info.go
  27. 5 0
      services/data/line_equation/chart_info.go
  28. 5 0
      services/data/line_feature/chart_info.go
  29. 28 1
      utils/constants.go

+ 64 - 0
controllers/data_manage/chart_info.go

@@ -786,6 +786,16 @@ func (this *ChartInfoController) ChartInfoDetail() {
 			return
 		}
 		chartType = chartInfo.ChartType
+
+		// 获取主题样式
+		chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+			return
+		}
+		chartInfo.ChartThemeStyle = chartTheme.Config
+		chartInfo.ChartThemeId = chartTheme.ChartThemeId
 	}
 
 	mappingList := make([]*data_manage.ChartEdbInfoMapping, 0)
@@ -900,6 +910,11 @@ func (this *ChartInfoController) ChartInfoDetail() {
 			}
 		}
 	}
+	
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
 
 	//图表操作权限
 	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId)
@@ -1093,6 +1108,11 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp := new(data_manage.ChartInfoDetailResp)
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
@@ -1145,6 +1165,16 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 		return
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	dateType := chartInfo.DateType
 	fmt.Println("dateType:", dateType)
 
@@ -1285,6 +1315,11 @@ func (this *ChartInfoController) ChartInfoDetailV2() {
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp := new(data_manage.ChartInfoDetailResp)
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
@@ -2009,6 +2044,16 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		}
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	chartInfoId := chartInfo.ChartInfoId
 
 	dateType := chartInfo.DateType
@@ -2139,6 +2184,11 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.XEdbIdValue = xEdbIdValue
 	resp.YDataList = yDataList
@@ -2462,6 +2512,11 @@ func (this *ChartInfoController) CopyChartInfo() {
 		ExtraConfig:       oldChartInfo.ExtraConfig,
 		SeasonExtraConfig: oldChartInfo.SeasonExtraConfig,
 		StartYear:         oldChartInfo.StartYear,
+		ChartThemeId:      oldChartInfo.ChartThemeId,
+		SourcesFrom:       oldChartInfo.SourcesFrom,
+		Instructions:      oldChartInfo.Instructions,
+		MarkersLines:      oldChartInfo.MarkersLines,
+		MarkersAreas:      oldChartInfo.MarkersAreas,
 	}
 	newId, err := data_manage.AddChartInfo(chartInfo)
 	if err != nil {
@@ -2633,6 +2688,10 @@ func (this *ChartInfoController) PreviewBarChartInfo() {
 	if len(warnEdbList) > 0 {
 		chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
 	}
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
 
 	//图表操作权限
 	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId)
@@ -2719,6 +2778,11 @@ func (this *ChartInfoController) PreviewSectionScatterChartInfo() {
 		chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	//图表操作权限
 	chartInfo.IsEdit = data.CheckOpChartPermission(sysUser, chartInfo.SysUserId)
 	//判断是否需要展示英文标识

+ 661 - 0
controllers/data_manage/chart_theme.go

@@ -0,0 +1,661 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/chart_theme"
+	"eta/eta_api/models/data_manage/chart_theme/request"
+	"eta/eta_api/services/data"
+	"eta/eta_api/utils"
+	"time"
+)
+
+// ChartThemeController
+// @Description: 图表主题配置模块
+type ChartThemeController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 获取主题列表
+// @Description 获取主题列表接口
+// @Param   ChartThemeTypeId   query   int  true       "图表主题类型id"
+// @Success 200 {object} []*chart_theme.ChartTheme
+// @router /chart/theme/list [get]
+func (c *ChartThemeController) List() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	chartThemeTypeId, _ := c.GetInt("ChartThemeTypeId")
+	if chartThemeTypeId <= 0 {
+		br.Msg = "请选择图表样式类型"
+		br.ErrMsg = "请选择图表样式类型"
+		br.IsSendEmail = false
+		return
+	}
+	list, err := chart_theme.GetChartThemeItemList(chartThemeTypeId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表样式类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// TypeList
+// @Title 获取主题类型列表
+// @Description 获取主题类型列表接口
+// @Success 200 {object} []*chart_theme.ChartThemeType
+// @router /chart/theme/type/list [get]
+func (c *ChartThemeController) TypeList() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	list, err := chart_theme.GetAllChartThemeTypeList()
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表样式类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// GetThemePreviewData
+// @Title 获取默认的预览图表数据
+// @Description 获取默认的预览图表数据接口
+// @Param   ChartThemeTypeId   query   int  true       "图表主题类型id"
+// @Success 200 {object} data_manage.ChartInfoDetailResp
+// @router /chart/theme/preview_data [get]
+func (c *ChartThemeController) GetThemePreviewData() {
+	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"
+		br.Ret = 408
+		return
+	}
+	chartThemeTypeId, _ := c.GetInt("ChartThemeTypeId")
+	if chartThemeTypeId <= 0 {
+		br.Msg = "请选择图表样式类型"
+		br.ErrMsg = "请选择图表样式类型"
+		br.IsSendEmail = false
+		return
+	}
+
+	chartThemeType, err := chart_theme.GetChartThemeTypeById(chartThemeTypeId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表样式类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	dateType := 3 // 曲线图
+	startYear := 5
+
+	chartType := chartThemeType.ChartType
+
+	chartInfo := new(data_manage.ChartInfoView)
+	// 图表额外数据参数
+	extraConfigStr := ``
+
+	// 开始时间,结束时间
+	var tmpStartDate, tmpEndDate string
+
+	edbInfoIdList := make([]int, 0) // 指标列表
+	switch chartType {
+	case 1: // 曲线图
+		edbInfoIdList = []int{1, 2, 3, 4, 5}
+		chartInfo.ChartName = "曲线图"
+	case 4: // 堆积柱状图
+		edbInfoIdList = []int{1, 2, 3, 4, 5}
+		chartInfo.ChartName = "堆积柱状图"
+		dateType = 5
+		tmpStartDate = `2021-03-05`
+	case 6: // 组合图
+		edbInfoIdList = []int{1, 2, 3, 4, 5}
+		chartInfo.ChartName = "组合图"
+		dateType = 5
+		tmpStartDate = `2021-03-05`
+	case 2: // 季节性
+		dateType = 20 // 季节性图
+		edbInfoIdList = []int{6}
+		chartInfo.ChartName = "季节性图"
+	case 5: // 散点图
+		edbInfoIdList = []int{7, 8}
+		chartInfo.ChartName = "散点图"
+	case 7: // 柱形图
+		edbInfoIdList = []int{1, 2, 3, 4, 5}
+		extraConfigStr = `{"EdbInfoIdList":[{"EdbInfoId":1,"Name":"指标1","NameEn":"","Source":0},{"EdbInfoId":2,"Name":"指标2","NameEn":"","Source":0},{"EdbInfoId":3,"Name":"指标3","NameEn":"","Source":0},{"EdbInfoId":4,"Name":"指标4","NameEn":"","Source":0},{"EdbInfoId":5,"Name":"指标5","NameEn":"","Source":0}],"DateList":[{"Type":2,"Date":"","Value":100,"Color":"#00f","Name":""},{"Type":1,"Date":"","Value":0,"Color":"#f00","Name":""}],"Sort":{"Sort":0,"DateIndex":0},"XEdbList":null,"YEdbList":null,"Unit":"千桶","UnitEn":""}`
+		chartInfo.ChartName = "柱形图"
+	case 10: // 截面散点图
+		edbInfoIdList = []int{9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
+		extraConfigStr = `{"XName":"123","XNameEn":"123","XUnitName":"无","XUnitNameEn":"none","YName":"321","YNameEn":"321","YUnitName":"无","YUnitNameEn":"none","XMinValue":"230","XMaxValue":"395","YMinValue":"380","YMaxValue":"850","SeriesList":[{"Name":"2021-11-21","NameEn":"2021-11-21","IsNameDefault":true,"Color":"","EdbInfoList":[{"XEdbInfoId":9,"YEdbInfoId":14,"Name":"指标1","NameEn":"","XDateType":1,"XDate":"","XDateValue":0,"YDateType":1,"YDate":"","YDateValue":0,"IsShow":false},{"XEdbInfoId":10,"YEdbInfoId":15,"Name":"指标2","NameEn":"指标2","XDateType":1,"XDate":"","XDateValue":0,"YDateType":1,"YDate":"","YDateValue":0,"IsShow":false},{"XEdbInfoId":11,"YEdbInfoId":16,"Name":"指标3","NameEn":"","XDateType":1,"XDate":"","XDateValue":0,"YDateType":1,"YDate":"","YDateValue":0,"IsShow":false},{"XEdbInfoId":12,"YEdbInfoId":17,"Name":"指标4","NameEn":"指标4","XDateType":1,"XDate":"","XDateValue":0,"YDateType":1,"YDate":"","YDateValue":0,"IsShow":false},{"XEdbInfoId":13,"YEdbInfoId":18,"Name":"指标5","NameEn":"","XDateType":1,"XDate":"","XDateValue":0,"YDateType":1,"YDate":"","YDateValue":0,"IsShow":false}],"ShowTrendLine":false,"ShowFitEquation":false,"ShowRSquare":false}]}`
+		chartInfo.ChartName = "截面散点图"
+	default:
+		br.Msg = "暂不支持该类型"
+		br.IsSendEmail = false
+		return
+	}
+	calendar := "公历"
+
+	mappingList, err := chart_theme.GetChartEdbMappingListByEdbInfoId(edbInfoIdList)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+		return
+	}
+	switch chartType {
+	case 6: // 组合图
+		mappingList[0].ChartStyle = "spline"
+		mappingList[1].ChartStyle = "spline"
+		mappingList[2].ChartStyle = "spline"
+		mappingList[3].ChartStyle = "column"
+		mappingList[4].ChartStyle = "column"
+	}
+	chartInfo.Source = chartThemeType.ChartSource
+	chartInfo.ChartType = chartThemeType.ChartType
+
+	yearMax := 0
+	if dateType == utils.DateTypeNYears {
+		for _, v := range mappingList {
+			if v.LatestDate != "" {
+				lastDateT, tErr := time.Parse(utils.FormatDate, v.LatestDate)
+				if tErr != nil {
+					br.Msg = "获取失败"
+					br.ErrMsg = "获取图表日期信息失败,Err:" + tErr.Error()
+					return
+				}
+				if lastDateT.Year() > yearMax {
+					yearMax = lastDateT.Year()
+				}
+			}
+		}
+	}
+	// 开始/结束日期
+	startDate, endDate := utils.GetDateByDateTypeV2(dateType, tmpStartDate, tmpEndDate, startYear, yearMax)
+
+	// 获取图表中的指标数据
+	edbList, xEdbIdValue, yDataList, dataResp, err, errMsg := data.GetThemePreviewChartEdbData(chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig)
+	if err != nil {
+		br.Msg = "获取失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	switch chartType {
+	case 6: // 组合图
+		edbList[0].MaxData = 1000
+	case 4: // 堆积柱状图
+		edbList[0].MaxData = 2500
+	}
+
+	// 单位
+	if chartType == utils.CHART_TYPE_BAR && len(yDataList) > 0 {
+		chartInfo.Unit = yDataList[0].Unit
+		chartInfo.UnitEn = yDataList[0].UnitEn
+	}
+
+	resp := new(data_manage.ChartInfoDetailResp)
+	resp.ChartInfo = chartInfo
+	resp.EdbInfoList = edbList
+	resp.XEdbIdValue = xEdbIdValue
+	resp.YDataList = yDataList
+	resp.DataResp = dataResp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+
+}
+
+// Add
+// @Title 新增主题
+// @Description
+// @Param	request	body request.DeleteThemeConfReq true "type json string"
+// @Success 200 Ret=200 添加成功
+// @router /chart/theme/add [post]
+func (c *ChartThemeController) Add() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	var req request.AddThemeReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartThemeTypeId <= 0 {
+		br.Msg = "请选择图表类型"
+		br.IsSendEmail = false
+		return
+	}
+
+	req.ChartThemeName = utils.TrimLRStr(req.ChartThemeName)
+	if req.ChartThemeName == `` {
+		br.Msg = "请输入主题名称"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取系统默认配置
+	systemChartTheme, err := chart_theme.GetSystemChartTheme(req.ChartThemeTypeId)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,查询系统默认配置异常,Err:" + err.Error()
+		return
+	}
+
+	chartTheme := &chart_theme.ChartTheme{
+		ChartThemeId:     0,
+		ChartThemeName:   req.ChartThemeName,
+		ChartThemeTypeId: req.ChartThemeTypeId,
+		Config:           systemChartTheme.Config,
+		ChartImage:       systemChartTheme.ChartImage,
+		IsDelete:         0,
+		SysUserId:        sysUser.AdminId,
+		SysUserRealName:  sysUser.RealName,
+		ModifyTime:       time.Now(),
+		CreateTime:       time.Now(),
+	}
+
+	// 添加入库
+	err = chartTheme.Add()
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "添加成功"
+}
+
+// Edit
+// @Title 新增主题
+// @Description
+// @Param	request	body request.DeleteThemeConfReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /chart/theme/edit [post]
+func (c *ChartThemeController) Edit() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	var req request.EditThemeReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartThemeId < 0 {
+		br.Msg = "请选择配置"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取配置
+	chartTheme, err := chart_theme.GetChartThemeId(req.ChartThemeId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "主题不存在或已删除"
+			br.ErrMsg = "主题不存在或已删除"
+			br.IsSendEmail = false
+		} else {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表配置信息失败,Err:" + err.Error()
+		}
+		return
+	}
+
+	// 更新
+	if req.ChartThemeName != `` {
+		chartTheme.ChartThemeName = req.ChartThemeName
+	}
+	if req.Config != `` {
+		chartTheme.Config = req.Config
+	}
+	if req.ChartImage != `` {
+		chartTheme.ChartImage = req.ChartImage
+	}
+	chartTheme.ModifyTime = time.Now()
+	err = chartTheme.Update([]string{"ChartThemeName", "Config", "ChartImage", "ModifyTime"})
+	if err != nil {
+		br.Msg = "修改失败"
+		br.ErrMsg = "修改失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "修改成功"
+}
+
+// Delete
+// @Title 删除主题
+// @Description
+// @Param	request	body request.DeleteThemeConfReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /chart/theme/delete [post]
+func (c *ChartThemeController) Delete() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	var req request.DeleteThemeReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartThemeId < 0 {
+		br.Msg = "请选择配置"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取配置
+	chartTheme, err := chart_theme.GetChartThemeId(req.ChartThemeId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "主题不存在或已删除"
+			br.ErrMsg = "主题不存在或已删除"
+			br.IsSendEmail = false
+		} else {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表配置信息失败,Err:" + err.Error()
+		}
+		return
+	}
+	if chartTheme.IsSystemTheme == 1 {
+		br.Msg = "系统默认配置,无法删除"
+		br.ErrMsg = "系统默认配置,无法删除"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 根据给定的图表主题类型ID获取图表主题类型
+	chartThemeType, err := chart_theme.GetChartThemeTypeById(chartTheme.ChartThemeTypeId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表主题类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	// 判断是否是配置为默认设置,如果已经设置了,那么不能删除
+	if chartThemeType.DefaultChartThemeId == chartTheme.ChartThemeId {
+		br.Msg = "该主题已经配置为默认设置,不允许删除"
+		br.ErrMsg = "该主题已经配置为默认设置,不允许删除"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 更新
+	chartTheme.IsDelete = 1
+	err = chartTheme.Update([]string{"IsDelete"})
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "删除成功"
+}
+
+// SetDefaultTheme
+// @Title 配置默认主题
+// @Description 配置默认主题
+// @Param	request	body request.DeleteThemeConfReq true "type json string"
+// @Success 200 Ret=200 配置成功
+// @router /chart/theme/set_default [post]
+func (c *ChartThemeController) SetDefaultTheme() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	var req request.SetDefaultThemeReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartThemeId < 0 {
+		br.Msg = "请选择配置"
+		br.IsSendEmail = false
+		return
+	}
+	if req.ChartThemeTypeId < 0 {
+		br.Msg = "请选择图表类型"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取图表配置
+	chartTheme, err := chart_theme.GetChartThemeId(req.ChartThemeId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "主题不存在或已删除"
+			br.ErrMsg = "主题不存在或已删除"
+			br.IsSendEmail = false
+		} else {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表配置信息失败,Err:" + err.Error()
+		}
+		return
+	}
+
+	// 获取图表类型
+	chartThemeType, err := chart_theme.GetChartThemeTypeById(req.ChartThemeTypeId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "获取图表类型不存在或已删除"
+			br.ErrMsg = "获取图表类型不存在或已删除"
+			br.IsSendEmail = false
+		} else {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取图表配置信息失败,Err:" + err.Error()
+		}
+		return
+	}
+
+	// 判断主题与图表类型是否相符
+	if chartTheme.ChartThemeTypeId != chartThemeType.ChartThemeTypeId {
+		br.Msg = "主题与图表类型不符"
+		br.ErrMsg = "主题与图表类型不符"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 更新
+	chartThemeType.DefaultChartThemeId = chartTheme.ChartThemeId
+	chartThemeType.ModifyTime = time.Now()
+	err = chartThemeType.Update([]string{"DefaultChartThemeId", "ModifyTime"})
+	if err != nil {
+		br.Msg = "配置失败"
+		br.ErrMsg = "配置失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "配置成功"
+}
+
+// TypeListBySource
+// @Title 根据来源获取主题类型列表
+// @Description 获取主题类型列表接口
+// @Param   Source   query   int  true       "图表主题类型id"
+// @Success 200 {object} []*chart_theme.ChartThemeType
+// @router /chart/theme/type/list_by_source [get]
+func (c *ChartThemeController) TypeListBySource() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	source, _ := c.GetInt("Source")
+	if source <= 0 {
+		br.Msg = "请选择来源"
+		br.ErrMsg = "请选择来源"
+		br.IsSendEmail = false
+		return
+	}
+
+	list, err := chart_theme.GetChartThemeTypeListBySource(source)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表样式类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// ListBySource
+// @Title 根据来源获取主题列表
+// @Description 获取主题列表接口
+// @Param   ChartType   query   int  true       "图表类型"
+// @Param   Source   query   int  true       "来源"
+// @Success 200 {object} []*chart_theme.ChartTheme
+// @router /chart/theme/list_by_source [get]
+func (c *ChartThemeController) ListBySource() {
+	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"
+		br.Ret = 408
+		return
+	}
+
+	chartType, _ := c.GetInt("ChartType")
+	if chartType < 0 {
+		br.Msg = "请选择图表类型"
+		br.ErrMsg = "请选择图表类型"
+		br.IsSendEmail = false
+		return
+	}
+	source, _ := c.GetInt("Source")
+	if chartType < 0 {
+		br.Msg = "请选择图表来源"
+		br.ErrMsg = "请选择图表来源"
+		br.IsSendEmail = false
+		return
+	}
+
+	chartThemeType, err := chart_theme.GetChartThemeTypeByChartTypeAndSource(chartType, source)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表样式类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	list, err := chart_theme.GetChartThemeItemList(chartThemeType.ChartThemeTypeId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表样式类型信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}

+ 31 - 1
controllers/data_manage/correlation/correlation_chart_info.go

@@ -672,6 +672,16 @@ func (this *CorrelationChartInfoController) Detail() {
 		return
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	// 相关性图表信息
 	correlationChart := new(data_manage.ChartInfoCorrelation)
 	if e := correlationChart.GetItemById(chartInfoId); e != nil {
@@ -772,6 +782,11 @@ func (this *CorrelationChartInfoController) Detail() {
 	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList[0:1], chartInfo.Source, chartInfo.ChartType)
 	chartInfo.UnitEn = edbInfoMappingA.UnitEn
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	isSaveAs := true
 	if chartInfo.Source == utils.CHART_SOURCE_ROLLING_CORRELATION {
 		isSaveAs = false
@@ -1067,7 +1082,7 @@ func (this *CorrelationChartInfoController) Copy() {
 		},
 	}
 
-	chartInfo, err, errMsg, isSendEmail := correlationServ.CopyChartInfo(multipleGraphConfigChartMapping.MultipleGraphConfigId, req.ChartClassifyId, req.ChartName, correlationChartInfoReq, sysUser)
+	chartInfo, err, errMsg, isSendEmail := correlationServ.CopyChartInfo(multipleGraphConfigChartMapping.MultipleGraphConfigId, req.ChartClassifyId, req.ChartName, correlationChartInfoReq, oldChartInfo, sysUser)
 
 	if err != nil {
 		br.Msg = "保存失败"
@@ -1149,6 +1164,16 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		}
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	chartInfoId := chartInfo.ChartInfoId
 
 	// 相关性图表信息
@@ -1265,6 +1290,11 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
 	resp.XEdbIdValue = xEdbIdValue

+ 31 - 1
controllers/data_manage/cross_variety/chart_info.go

@@ -481,6 +481,16 @@ func (c *ChartInfoController) Detail() {
 		return
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 5)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	if chartInfo.ExtraConfig == `` {
 		br.Msg = "图表配置信息异常"
 		br.ErrMsg = "图表配置信息异常"
@@ -740,6 +750,11 @@ func (c *ChartInfoController) Copy() {
 	}
 	config.ChartName = req.ChartName
 	config.ChartImage = oldChartInfo.ChartImage
+	config.ChartThemeId = oldChartInfo.ChartThemeId
+	config.SourcesFrom = oldChartInfo.SourcesFrom
+	config.Instructions = oldChartInfo.Instructions
+	config.MarkersLines = oldChartInfo.MarkersLines
+	config.MarkersAreas = oldChartInfo.MarkersAreas
 
 	// 添加图表
 	chartInfo, err, errMsg, isSendEmail := cross_variety.AddChartInfo(config, sysUser)
@@ -1483,6 +1498,16 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		}
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 5)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	chartInfoId := chartInfo.ChartInfoId
 
 	if chartInfo.ExtraConfig == `` {
@@ -1491,7 +1516,7 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		return
 	}
 	var config request.ChartConfigReq
-	err := json.Unmarshal([]byte(chartInfo.ExtraConfig), &config)
+	err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &config)
 	if err != nil {
 		msg = "解析跨品种分析配置失败"
 		errMsg = "解析跨品种分析配置失败,Err:" + err.Error()
@@ -1543,6 +1568,11 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.DataResp = dataResp
 	resp.EdbInfoList = edbList

+ 29 - 0
controllers/data_manage/future_good/future_good_chart_info.go

@@ -1264,6 +1264,15 @@ func (this *FutureGoodChartInfoController) ChartInfoDetail() {
 		}
 		chartType = chartInfo.ChartType
 	}
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
 
 	switch chartInfo.Source {
 	case utils.CHART_SOURCE_FUTURE_GOOD:
@@ -1395,6 +1404,11 @@ func getFutureGoodChartInfo(chartInfo *data_manage.ChartInfoView, chartType, dat
 	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList[0:1], chartInfo.Source, chartInfo.ChartType)
 	chartInfo.UnitEn = baseEdbInfo.UnitEn
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp := new(data_manage.ChartInfoDetailResp)
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
@@ -1519,6 +1533,16 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		}
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	chartInfoId := chartInfo.ChartInfoId
 
 	startDate := chartInfo.StartDate
@@ -1629,6 +1653,11 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList[0:1], chartInfo.Source, chartInfo.ChartType)
 	chartInfo.UnitEn = baseEdbInfo.UnitEn
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
 	resp.XEdbIdValue = xEdbIdValue

+ 21 - 1
controllers/data_manage/future_good/future_good_profit_chart_info.go

@@ -1080,6 +1080,11 @@ func getFutureGoodProfitChartInfo(chartInfo *data_manage.ChartInfoView, sysUser
 	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList[0:1], chartInfo.Source, chartInfo.ChartType)
 	chartInfo.UnitEn = baseEdbInfo.UnitEn
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp := new(data_manage.ChartInfoDetailResp)
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
@@ -1142,9 +1147,19 @@ func GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo *data_manage.Cha
 
 	chartInfoId := chartInfo.ChartInfoId
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	// 商品利润曲线图的一些配置
 	var extraConf request.ChartInfoReq
-	err := json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConf)
+	err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConf)
 	if err != nil {
 		msg = "商品利润曲线图配置异常"
 		errMsg = "商品利润曲线图配置异常,Err:" + err.Error()
@@ -1240,6 +1255,11 @@ func GetFutureGoodProfitChartInfoDetailFromUniqueCode(chartInfo *data_manage.Cha
 	chartInfo.IsEnChart = data.CheckIsEnChart(chartInfo.ChartNameEn, edbList[0:1], chartInfo.Source, chartInfo.ChartType)
 	chartInfo.UnitEn = baseEdbInfo.UnitEn
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
 	resp.DataResp = response.ProfitFutureGoodChartResp{

+ 31 - 1
controllers/data_manage/line_equation/line_chart_info.go

@@ -751,6 +751,16 @@ func (this *LineEquationChartInfoController) Detail() {
 		return
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	if chartInfo.ExtraConfig == `` {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取配置信息失败,图表的额外配置信息为空"
@@ -1086,6 +1096,11 @@ func (this *LineEquationChartInfoController) Copy() {
 		LeftMin:         oldChartInfo.LeftMin,
 		LeftMax:         oldChartInfo.LeftMax,
 		ChartImage:      oldChartInfo.ChartImage,
+		ChartThemeId:    oldChartInfo.ChartThemeId,
+		SourcesFrom:     oldChartInfo.SourcesFrom,
+		Instructions:    oldChartInfo.Instructions,
+		MarkersLines:    oldChartInfo.MarkersLines,
+		MarkersAreas:    oldChartInfo.MarkersAreas,
 	})
 
 	resp := new(data_manage.AddChartInfoResp)
@@ -1172,13 +1187,23 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		}
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	if chartInfo.ExtraConfig == `` {
 		msg = "获取失败"
 		errMsg = "获取配置信息失败"
 		return
 	}
 	var lineChartInfoConfig request.LineChartInfoReq
-	err := json.Unmarshal([]byte(chartInfo.ExtraConfig), &lineChartInfoConfig)
+	err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &lineChartInfoConfig)
 	if err != nil {
 		msg = "获取失败"
 		errMsg = "获取图表配置信息失败, Err:" + err.Error()
@@ -1253,6 +1278,11 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
 	resp.DataResp = resultResp

+ 25 - 0
controllers/data_manage/line_feature/chart_info.go

@@ -1792,6 +1792,16 @@ func (this *LineFeaturesChartInfoController) Detail() {
 		return
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	// 获取图表关联指标
 	edbMappingList, err := data_manage.GetChartEdbMappingList(chartInfoId)
 	if err != nil {
@@ -2274,6 +2284,16 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		}
 	}
 
+	// 获取主题样式
+	chartTheme, err := data.GetChartThemeConfig(chartInfo.ChartThemeId, utils.CHART_SOURCE_DEFAULT, 1)
+	if err != nil {
+		msg = "获取失败"
+		errMsg = "获取主题信息失败,Err:" + err.Error()
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
 	if chartInfo.ExtraConfig == `` {
 		msg = "获取失败"
 		errMsg = "获取配置信息失败,图表的额外配置信息为空"
@@ -2390,6 +2410,11 @@ func GetChartInfoDetailFromUniqueCode(chartInfo *data_manage.ChartInfoView, isCa
 		IsSetName: chartInfo.IsSetName,
 	}
 
+	// 图表的指标来源
+	sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
+	chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+	chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
 	resp.ChartInfo = chartInfo
 	resp.EdbInfoList = edbList
 	resp.DataResp = resultResp

+ 1 - 1
controllers/data_manage/multiple_graph_config.go

@@ -1088,7 +1088,7 @@ func CopyMultipleGraphConfigSaveChart(req request.SaveMultipleGraphChartReq, thi
 				},
 			}
 
-			chartInfo, err, errMsg, isSendEmail = correlationServ.CopyChartInfo(multipleGraphConfigChartMapping.MultipleGraphConfigId, req.ClassifyId, req.ChartName, correlationChartInfoReq, sysUser)
+			chartInfo, err, errMsg, isSendEmail = correlationServ.CopyChartInfo(multipleGraphConfigChartMapping.MultipleGraphConfigId, req.ClassifyId, req.ChartName, correlationChartInfoReq, oldChartInfo, sysUser)
 		}
 	default:
 		br.Msg = "错误的来源"

+ 3 - 0
models/business_conf.go

@@ -17,6 +17,9 @@ const (
 	BusinessConfEnPptCoverImgs    = "EnPptCoverImgs"
 	BusinessConfIsReportApprove   = "IsReportApprove"
 	BusinessConfReportApproveType = "ReportApproveType"
+	BusinessConfCompanyName      = "CompanyName"
+	BusinessConfCompanyWatermark = "CompanyWatermark"
+	BusinessConfWatermarkChart   = "WatermarkChart"
 )
 
 const (

+ 1 - 0
models/data_manage/chart_edb_mapping.go

@@ -29,6 +29,7 @@ type ChartEdbMapping struct {
 	PredictChartColor string    `description:"预测数据的颜色"`
 	ChartWidth        float64   `description:"线条大小"`
 	Source            int       `description:"1:ETA图库;2:商品价格曲线"`
+	EdbAliasName      string    `description:"中文别名"`
 }
 
 func AddChartEdbMapping(items []*ChartEdbMapping) (err error) {

+ 38 - 2
models/data_manage/chart_info.go

@@ -42,6 +42,11 @@ type ChartInfo struct {
 	ExtraConfig       string `description:"图表额外配置,json数据"`
 	SeasonExtraConfig string `description:"季节性图表中的配置,json数据"`
 	StartYear         int    `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId      int    `description:"图表应用主题ID"`
+	SourcesFrom       string `description:"图表来源"`
+	Instructions      string `description:"图表说明"`
+	MarkersLines      string `description:"标识线"`
+	MarkersAreas      string `description:"标识区"`
 }
 
 type ChartInfoMore struct {
@@ -169,6 +174,7 @@ type ChartSaveItem struct {
 	PredictChartColor string  `description:"预测数据的颜色"`
 	ChartWidth        float64 `description:"线条大小"`
 	Source            int     `description:"1:ETA图库;2:商品价格曲线"`
+	EdbAliasName      string  `description:"中文别名"`
 }
 
 func DeleteChartInfoAndData(chartInfoId int) (err error) {
@@ -224,6 +230,11 @@ type EditChartInfoReq struct {
 	ExtraConfig          string                  `description:"图表额外配置信息,json字符串"`
 	SeasonExtraConfig    SeasonExtraItem         `description:"季节性图表中的配置,json数据"`
 	StartYear            int                     `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId         int                     `description:"图表应用主题ID"`
+	SourcesFrom          string                  `description:"图表来源"`
+	Instructions         string                  `description:"图表说明"`
+	MarkersLines         string                  `description:"标识线"`
+	MarkersAreas         string                  `description:"标识区"`
 }
 
 type EditChartEnInfoReq struct {
@@ -685,6 +696,11 @@ func EditChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr string, calenda
 	pars = append(pars, req.ExtraConfig)
 	pars = append(pars, seasonExtra)
 	pars = append(pars, req.StartYear)
+	pars = append(pars, req.ChartThemeId)
+	pars = append(pars, req.SourcesFrom)
+	pars = append(pars, req.Instructions)
+	pars = append(pars, req.MarkersLines)
+	pars = append(pars, req.MarkersAreas)
 
 	sql := ` UPDATE  chart_info
 			SET
@@ -697,7 +713,12 @@ func EditChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr string, calenda
               bar_config = ?,
               extra_config = ?, 
               season_extra_config = ?,
- 			  start_year = ?
+ 			  start_year = ?,
+ 			  chart_theme_id = ?,
+ 			  sources_from = ?,
+ 			  instructions = ?,
+ 			  markers_lines = ?,
+ 			  markers_areas = ?
 			`
 	if calendar != "" {
 		sql += `,calendar = ? `
@@ -765,7 +786,8 @@ func EditChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr string, calenda
 			tmpChartEdbMapping.ChartColor = v.ChartColor
 			tmpChartEdbMapping.PredictChartColor = v.PredictChartColor
 			tmpChartEdbMapping.ChartWidth = v.ChartWidth
-			_, err = to.Update(tmpChartEdbMapping, "ModifyTime", "MaxData", "MinData", "IsOrder", "IsAxis", "EdbInfoType", "LeadValue", "LeadUnit", "ChartStyle", "ChartColor", "PredictChartColor", "ChartWidth")
+			tmpChartEdbMapping.EdbAliasName = v.EdbAliasName
+			_, err = to.Update(tmpChartEdbMapping, "ModifyTime", "MaxData", "MinData", "IsOrder", "IsAxis", "EdbInfoType", "LeadValue", "LeadUnit", "ChartStyle", "ChartColor", "PredictChartColor", "ChartWidth", "EdbAliasName")
 			if err != nil {
 				fmt.Println("chart_edb_mapping Err:" + err.Error())
 				return err
@@ -790,6 +812,7 @@ func EditChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr string, calenda
 			mapItem.PredictChartColor = v.PredictChartColor
 			mapItem.ChartWidth = v.ChartWidth
 			mapItem.Source = utils.CHART_SOURCE_DEFAULT
+			mapItem.EdbAliasName = v.EdbAliasName
 			tmpId, err := to.Insert(mapItem)
 			if err != nil {
 				fmt.Println("AddChartEdbMapping Err:" + err.Error())
@@ -1041,6 +1064,11 @@ type AddChartInfoReq struct {
 	ChartImage           string                  `description:"封面图" json:"-"`
 	SeasonExtraConfig    SeasonExtraItem         `description:"季节性图表中的配置,json数据"`
 	StartYear            int                     `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId         int                     `description:"图表应用主题ID"`
+	SourcesFrom          string                  `description:"图表来源"`
+	Instructions         string                  `description:"图表说明"`
+	MarkersLines         string                  `description:"标识线"`
+	MarkersAreas         string                  `description:"标识区"`
 }
 
 type PreviewChartInfoReq struct {
@@ -1342,9 +1370,17 @@ type ChartInfoView struct {
 	Source            int    `description:"1:ETA图库;2:商品价格曲线;3:相关性图表"`
 	//CorrelationLeadUnit string `description:"相关性图表-领先单位"`
 	ExtraConfig       string          `description:"图表额外配置,json数据"`
+	ChartSource       string          `description:"图表来源str"`
+	ChartSourceEn     string          `description:"图表来源(英文)"`
 	Button            ChartViewButton `description:"操作按钮"`
 	SeasonExtraConfig string          `description:"季节性图表中的配置,json数据"`
 	StartYear         int             `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
+	ChartThemeId      int             `description:"图表应用主题ID"`
+	ChartThemeStyle   string          `description:"图表应用主题样式"`
+	SourcesFrom       string          `description:"图表来源"`
+	Instructions      string          `description:"图表说明"`
+	MarkersLines      string          `description:"标识线"`
+	MarkersAreas      string          `description:"标识区"`
 }
 
 type ChartViewButton struct {

+ 151 - 0
models/data_manage/chart_theme/chart_theme.go

@@ -0,0 +1,151 @@
+package chart_theme
+
+import (
+	"errors"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartTheme
+// @Description: 图表主题表
+type ChartTheme struct {
+	ChartThemeId     int       `description:"图表主题类型ID" orm:"column(chart_theme_id);pk"`
+	ChartThemeName   string    `description:"图表主题名称"`
+	ChartThemeTypeId int       `description:"图表主题类型ID"`
+	ChartImage       string    `description:"缩略图"`
+	Config           string    `description:"配置"`
+	IsDelete         int       `description:"是否删除,0:未删除;1:已删除"`
+	SysUserId        int       `description:"操作人"`
+	SysUserRealName  string    `description:"操作人的真实名称"`
+	IsSystemTheme    int       `description:"是否是系统主题,0:不是;1:是"`
+	ModifyTime       time.Time `description:"修改时间"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+// GetChartThemeId
+// @Description: 根据id获取主题
+// @author: Roc
+// @datetime 2023-12-14 16:05:36
+// @param chartThemeId int
+// @return item *ChartTheme
+// @return err error
+func GetChartThemeId(chartThemeId int) (item *ChartTheme, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme where chart_theme_id = ? AND is_delete = 0`
+	err = o.Raw(sql, chartThemeId).QueryRow(&item)
+
+	return
+}
+
+// Add
+// @Description: 添加
+// @author: Roc
+// @receiver m
+// @datetime 2023-12-14 16:11:10
+// @param cols []string
+// @return err error
+func (m *ChartTheme) Add() (err error) {
+	if m.ChartThemeId > 0 {
+		err = errors.New("该配置已存在")
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	lastId, err := o.Insert(m)
+	if err != nil {
+		return
+	}
+	m.ChartThemeId = int(lastId)
+
+	return
+}
+
+// Update
+// @Description: 更新
+// @author: Roc
+// @receiver m
+// @datetime 2023-12-14 16:11:10
+// @param cols []string
+// @return err error
+func (m *ChartTheme) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(m, cols...)
+	return
+}
+
+// GetChartThemeListByTypeId
+// @Description: 根据图表类型获取关联的图表主题列表
+// @author: Roc
+// @datetime 2023-12-13 17:39:48
+// @return list []*ChartTheme
+// @return err error
+func GetChartThemeListByTypeId(chartThemeTypeId int) (list []*ChartTheme, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme WHERE chart_theme_type_id = ? AND  is_delete=0 ORDER BY chart_theme_id ASC `
+	_, err = o.Raw(sql, chartThemeTypeId).QueryRows(&list)
+
+	return
+}
+
+// GetAllChartThemeList
+// @Description: 获取所有图表主题列表
+// @author: Roc
+// @datetime 2023-12-13 17:39:48
+// @return list []*ChartTheme
+// @return err error
+func GetAllChartThemeList() (list []*ChartTheme, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme WHERE  is_delete=0 ORDER BY chart_theme_id ASC `
+	_, err = o.Raw(sql).QueryRows(&list)
+
+	return
+}
+
+// ChartThemeItem
+// @Description: 图表主题配置
+type ChartThemeItem struct {
+	ChartThemeId     int    `description:"图表主题类型ID" orm:"column(chart_theme_id);pk"`
+	ChartThemeName   string `description:"图表主题名称"`
+	ChartThemeTypeId int    `description:"图表主题类型ID"`
+	Config           string `description:"配置"`
+	ChartImage       string `description:"缩略图"`
+	//IsDelete            int       `description:"是否删除,0:未删除;1:已删除"`
+	IsSystemTheme       int       `description:"是否是系统主题,0:不是;1:是"`
+	SysUserId           int       `description:"操作人"`
+	SysUserRealName     string    `description:"操作人的真实名称"`
+	ModifyTime          time.Time `description:"修改时间"`
+	CreateTime          time.Time `description:"创建时间"`
+	DefaultChartThemeId int       `description:"默认使用的图表主题ID"`
+}
+
+// GetChartThemeItemList
+// @Description: 根据图表类型id获取配置列表
+// @author: Roc
+// @datetime 2023-12-14 14:26:35
+// @param chartThemeTypeId int
+// @return list []*ChartThemeConfig
+// @return err error
+func GetChartThemeItemList(chartThemeTypeId int) (list []*ChartThemeItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT a.*,b.default_chart_theme_id FROM chart_theme a 
+         JOIN chart_theme_type b on a.chart_theme_type_id =b.chart_theme_type_id 
+         WHERE a.chart_theme_type_id = ? AND a.is_delete=0 ORDER BY a.chart_theme_id ASC `
+	_, err = o.Raw(sql, chartThemeTypeId).QueryRows(&list)
+
+	return
+}
+
+// GetSystemChartTheme
+// @Description: 根据图表类型id获取系统配置
+// @author: Roc
+// @datetime 2023-12-14 14:26:35
+// @param chartThemeTypeId int
+// @return item *ChartTheme
+// @return err error
+func GetSystemChartTheme(chartThemeTypeId int) (item *ChartTheme, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT a.* FROM chart_theme a
+         WHERE a.chart_theme_type_id = ? AND a.is_system_theme=1 ORDER BY a.chart_theme_id ASC `
+	err = o.Raw(sql, chartThemeTypeId).QueryRow(&item)
+
+	return
+}

+ 92 - 0
models/data_manage/chart_theme/chart_theme_default_data.go

@@ -0,0 +1,92 @@
+package chart_theme
+
+import (
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/utils"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartThemeDefaultData
+// @Description: 图表默认数据
+type ChartThemeDefaultData struct {
+	EdbDataId     int       `description:"指标数据ID" orm:"column(edb_data_id);pk"`
+	EdbInfoId     int       `description:"指标ID"`
+	EdbCode       string    `description:"指标编码"`
+	DataTime      string    //`json:"-" description:"数据日期"`
+	DataTimestamp int64     `description:"数据日期"`
+	Value         float64   `description:"数据值"`
+	ModifyTime    time.Time `description:"修改时间"`
+	CreateTime    time.Time `description:"创建时间"`
+}
+
+// GetChartThemeDefaultDataList
+// @Description: 获取指标的数据(日期正序返回)
+// @author: Roc
+// @datetime 2023-12-13 16:40:14
+// @param endInfoId int
+// @return list []*ChartThemeDefaultData
+// @return err error
+func GetChartThemeDefaultDataList(endInfoId int) (list []*ChartThemeDefaultData, err error) {
+	sql := `SELECT * FROM chart_theme_default_data WHERE edb_info_id=? `
+
+	sql += ` ORDER BY data_time ASC `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, endInfoId).QueryRows(&list)
+	return
+}
+
+// Update
+// @Description: 更新
+// @author: Roc
+// @receiver m
+// @datetime 2023-12-13 16:40:04
+// @param cols []string
+// @return err error
+func (m *ChartThemeDefaultData) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(m, cols...)
+
+	return
+}
+
+// GetChartThemeDefaultDataItemList
+// @Description: 获取指标的数据(日期正序返回)
+// @author: Roc
+// @datetime 2023-12-13 16:40:22
+// @param endInfoId int
+// @return list []*ChartThemeDefaultDataItem
+// @return err error
+func GetChartThemeDefaultDataItemList(endInfoId int, startDate string) (list []*data_manage.EdbDataList, err error) {
+	sql := `SELECT edb_data_id,edb_info_id,data_time,value,data_timestamp FROM chart_theme_default_data WHERE edb_info_id=? `
+	var pars []interface{}
+	if startDate != "" {
+		sql += ` AND data_time>=? `
+		pars = append(pars, startDate)
+	}
+
+	sql += ` ORDER BY data_time ASC `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, endInfoId, pars).QueryRows(&list)
+	return
+}
+
+// GetChartEdbMappingListByEdbInfoId
+// @Description: 返回模拟的mapping假数据
+// @author: Roc
+// @datetime 2023-12-14 10:03:20
+// @param edbInfoIdList []int
+// @return list []*data_manage.ChartEdbInfoMapping
+// @return err error
+func GetChartEdbMappingListByEdbInfoId(edbInfoIdList []int) (list []*data_manage.ChartEdbInfoMapping, err error) {
+	num := len(edbInfoIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM chart_theme_default_edb_info WHERE edb_info_id IN(` + utils.GetOrmInReplace(num) + `)
+              `
+	_, err = o.Raw(sql, edbInfoIdList).QueryRows(&list)
+
+	return
+}

+ 90 - 0
models/data_manage/chart_theme/chart_theme_type.go

@@ -0,0 +1,90 @@
+package chart_theme
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartThemeType
+// @Description: 图表主题类型表
+type ChartThemeType struct {
+	ChartThemeTypeId    int       `description:"图表主题类型ID" orm:"column(chart_theme_type_id);pk"`
+	ChartTypeName       string    `description:"类型名称"`
+	ChartType           int       `description:"图表类型"`
+	ChartSource         int       `description:"图表来源"`
+	DefaultChartThemeId int       `description:"默认使用的主题id"`
+	ModifyTime          time.Time `description:"修改时间"`
+	CreateTime          time.Time `description:"创建时间"`
+}
+
+// Update
+// @Description: 更新
+// @author: Roc
+// @receiver m
+// @datetime 2023-12-14 16:11:10
+// @param cols []string
+// @return err error
+func (m *ChartThemeType) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(m, cols...)
+	return
+}
+
+// GetAllChartThemeTypeList
+// @Description: 获取所有图表主题类型列表
+// @author: Roc
+// @datetime 2023-12-13 17:31:03
+// @return list []*ChartThemeType
+// @return err error
+func GetAllChartThemeTypeList() (list []*ChartThemeType, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme_type ORDER BY chart_theme_type_id ASC `
+	_, err = o.Raw(sql).QueryRows(&list)
+
+	return
+}
+
+// GetChartThemeTypeListBySource
+// @Description: 根据来源获取图表主题类型列表
+// @author: Roc
+// @datetime 2023-12-13 17:31:03
+// @param source int
+// @return list []*ChartThemeType
+// @return err error
+func GetChartThemeTypeListBySource(source int) (list []*ChartThemeType, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme_type WHERE chart_source = ?  ORDER BY chart_theme_type_id ASC `
+	_, err = o.Raw(sql, source).QueryRows(&list)
+
+	return
+}
+
+// GetChartThemeTypeById
+// @Description: 通过类型id获取类型
+// @author: Roc
+// @datetime 2023-12-14 09:53:58
+// @param chartThemeTypeId int
+// @return item *ChartThemeType
+// @return err error
+func GetChartThemeTypeById(chartThemeTypeId int) (item *ChartThemeType, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme_type where chart_theme_type_id = ? `
+	err = o.Raw(sql, chartThemeTypeId).QueryRow(&item)
+
+	return
+}
+
+// GetChartThemeTypeByChartTypeAndSource
+// @Description: 通过图表类型和来源获取类型
+// @author: Roc
+// @datetime 2023-12-14 09:53:58
+// @param chartThemeTypeId int
+// @return item *ChartThemeType
+// @return err error
+func GetChartThemeTypeByChartTypeAndSource(chartType, source int) (item *ChartThemeType, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_theme_type where chart_type = ? AND chart_source = ? `
+	err = o.Raw(sql, chartType, source).QueryRow(&item)
+
+	return
+}

+ 30 - 0
models/data_manage/chart_theme/request/theme.go

@@ -0,0 +1,30 @@
+package request
+
+// AddThemeReq
+// @Description: 新增主题请求参数
+type AddThemeReq struct {
+	ChartThemeName   string `description:"主题名称"`
+	ChartThemeTypeId int    `description:"图表类型id"`
+}
+
+// EditThemeReq
+// @Description: 编辑主题请求参数
+type EditThemeReq struct {
+	ChartThemeId   int    `description:"主题id"`
+	ChartThemeName string `description:"主题名称"`
+	Config         string `description:"配置的值"`
+	ChartImage     string `description:"缩略图"`
+}
+
+// DeleteThemeReq
+// @Description: 删除主题请求参数
+type DeleteThemeReq struct {
+	ChartThemeId int `description:"配置id"`
+}
+
+// SetDefaultThemeReq
+// @Description: 配置默认主题请求参数
+type SetDefaultThemeReq struct {
+	ChartThemeId     int `description:"主题id"`
+	ChartThemeTypeId int `description:"主题类型id"`
+}

+ 7 - 0
models/data_manage/cross_variety/request/chart.go

@@ -31,6 +31,13 @@ type AddChartReq struct {
 	CalculateUnit  string            `description:"计算频度"`
 	DateConfigList []ChartConfigDate `description:"日期配置列表"`
 	VarietyList    []int
+
+	// 主题相关
+	ChartThemeId int    `description:"图表应用主题ID"`
+	SourcesFrom  string `description:"图表来源"`
+	Instructions string `description:"图表说明"`
+	MarkersLines string `description:"标识线"`
+	MarkersAreas string `description:"标识区"`
 }
 
 // EditChartReq

+ 6 - 0
models/data_manage/line_equation/request/line_equation.go

@@ -23,6 +23,12 @@ type AddChart struct {
 	LeftMin         string `description:"图表左侧最小值"`
 	LeftMax         string `description:"图表左侧最大值"`
 	ChartImage      string `description:"图表截图,复制的时候才用到" json:"-"`
+
+	ChartThemeId int    `description:"图表应用主题ID"`
+	SourcesFrom  string `description:"图表来源"`
+	Instructions string `description:"图表说明"`
+	MarkersLines string `description:"标识线"`
+	MarkersAreas string `description:"标识区"`
 }
 
 // EditChartEnInfoReq 编辑图表英文信息

+ 13 - 0
models/db.go

@@ -4,6 +4,7 @@ import (
 	"eta/eta_api/models/aimod"
 	"eta/eta_api/models/company"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/chart_theme"
 	"eta/eta_api/models/data_manage/cross_variety"
 	"eta/eta_api/models/data_manage/excel"
 	future_good2 "eta/eta_api/models/data_manage/future_good"
@@ -178,6 +179,9 @@ func init() {
 	// 报告审批
 	initReportApprove()
 
+	// 初始化图表主题
+	initChartTheme()
+
 	// 初始化部分数据表变量(直接init会有顺序问题=_=!)
 	data_manage.InitEdbSourceVar()
 }
@@ -521,3 +525,12 @@ func initReportApprove() {
 		new(report_approve.ReportApproveMessage), // 审批消息表
 	)
 }
+
+// initChartTheme 初始化图表主题
+func initChartTheme() {
+	orm.RegisterModel(
+		new(chart_theme.ChartTheme),            // 图表主题
+		new(chart_theme.ChartThemeType),        // 图表主题类型
+		new(chart_theme.ChartThemeDefaultData), //默认数据
+	)
+}

+ 81 - 0
routers/commentsRouter.go

@@ -2266,6 +2266,87 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/chart/theme/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/chart/theme/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/chart/theme/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/chart/theme/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "ListBySource",
+            Router: `/chart/theme/list_by_source`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "GetThemePreviewData",
+            Router: `/chart/theme/preview_data`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "SetDefaultTheme",
+            Router: `/chart/theme/set_default`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "TypeList",
+            Router: `/chart/theme/type/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ChartThemeController"],
+        beego.ControllerComments{
+            Method: "TypeListBySource",
+            Router: `/chart/theme/type/list_by_source`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbClassifyController"],
         beego.ControllerComments{
             Method: "AddEdbClassify",

+ 1 - 0
routers/router.go

@@ -161,6 +161,7 @@ func init() {
 				&data_manage.PredictEdbInfoController{},
 				&data_manage.BaseFromNationalStatisticsController{},
 				&data_manage.JiaYueEdbSourceController{},
+				&data_manage.ChartThemeController{},
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 91 - 0
services/data/chart_info.go

@@ -3,6 +3,7 @@ package data
 import (
 	"encoding/json"
 	"errors"
+	"eta/eta_api/models"
 	"eta/eta_api/models/company"
 	"eta/eta_api/models/data_manage"
 	"eta/eta_api/models/system"
@@ -448,6 +449,7 @@ func getEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate
 		item.LatestDate = v.LatestDate
 		item.UniqueCode = v.UniqueCode
 		item.MoveLatestDate = v.LatestDate
+		item.EdbAliasName = v.EdbAliasName
 
 		var startDateReal string
 		var diffSeconds int64
@@ -1821,6 +1823,24 @@ func AddChartInfo(req data_manage.AddChartInfoReq, sysUserId int, sysUserRealNam
 		isSendEmail = false
 		return
 	}
+	//if req.ChartThemeId <= 0 {
+	//	errMsg = "请选择主题"
+	//	err = errors.New(errMsg)
+	//	isSendEmail = false
+	//	return
+	//}
+	//
+	//// 判断主题是否存在
+	//_, err = chart_theme.GetChartThemeId(req.ChartThemeId)
+	//if err != nil {
+	//	if err.Error() == utils.ErrNoRow() {
+	//		errMsg = "主题不存在"
+	//		err = errors.New(errMsg)
+	//		return
+	//	}
+	//	errMsg = "获取主题信息失败"
+	//	return
+	//}
 
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
@@ -2083,6 +2103,11 @@ func AddChartInfo(req data_manage.AddChartInfoReq, sysUserId int, sysUserRealNam
 	chartInfo.SeasonExtraConfig = seasonExtraConfig
 	chartInfo.StartYear = req.StartYear
 	chartInfo.Source = utils.CHART_SOURCE_DEFAULT
+	chartInfo.ChartThemeId = req.ChartThemeId
+	chartInfo.SourcesFrom = req.SourcesFrom
+	chartInfo.Instructions = req.Instructions
+	chartInfo.MarkersLines = req.MarkersLines
+	chartInfo.MarkersAreas = req.MarkersAreas
 	newId, err := data_manage.AddChartInfo(chartInfo)
 	if err != nil {
 		errMsg = `保存失败`
@@ -2112,6 +2137,7 @@ func AddChartInfo(req data_manage.AddChartInfoReq, sysUserId int, sysUserRealNam
 		mapItem.PredictChartColor = v.PredictChartColor
 		mapItem.ChartWidth = v.ChartWidth
 		mapItem.Source = utils.CHART_SOURCE_DEFAULT
+		mapItem.EdbAliasName = v.EdbAliasName
 		mapList = append(mapList, mapItem)
 	}
 	err = data_manage.AddChartEdbMapping(mapList)
@@ -2144,6 +2170,24 @@ func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin) (cha
 		isSendEmail = false
 		return
 	}
+	//if req.ChartThemeId <= 0 {
+	//	errMsg = "请选择主题!"
+	//	err = errors.New(errMsg)
+	//	isSendEmail = false
+	//	return
+	//}
+	//
+	//// 判断主题是否存在
+	//_, err = chart_theme.GetChartThemeId(req.ChartThemeId)
+	//if err != nil {
+	//	if err.Error() == utils.ErrNoRow() {
+	//		errMsg = "主题不存在"
+	//		err = errors.New(errMsg)
+	//		return
+	//	}
+	//	errMsg = "获取主题信息失败"
+	//	return
+	//}
 
 	chartClassify, err := data_manage.GetChartClassifyById(req.ChartClassifyId)
 	if err != nil {
@@ -2423,3 +2467,50 @@ func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin) (cha
 
 	return
 }
+
+// GetEdbSourceByEdbInfoIdList 获取关联指标的来源
+func GetEdbSourceByEdbInfoIdList(chartEdbInfoMappingList []*data_manage.ChartEdbInfoMapping) (sourceNameList, sourceNameEnList []string) {
+	sourceNameList = make([]string, 0)
+	sourceNameEnList = make([]string, 0)
+	sourceMap := make(map[int]string)
+	for _, v := range chartEdbInfoMappingList {
+		// 指标类型:1:基础指标,2:计算指标
+		if v.EdbType == 2 || v.EdbInfoCategoryType == 1 {
+			//sourceMap[0] = "弘则研究"
+			baseEdbInfoArr, _, _ := data_manage.GetRefreshEdbInfoFromBase(v.EdbInfoId, v.Source)
+			for _, baseEdbInfo := range baseEdbInfoArr {
+				if baseEdbInfo.EdbInfoType == 0 { //普通指标才参与,预测指标不参与
+					sourceMap[baseEdbInfo.Source] = baseEdbInfo.SourceName
+				}
+			}
+		} else {
+			sourceMap[v.Source] = v.SourceName
+		}
+	}
+
+	for source, sourceName := range sourceMap {
+		if utils.InArrayByInt([]int{utils.DATA_SOURCE_MANUAL, utils.DATA_SOURCE_MYSTEEL_CHEMICAL}, source) {
+			continue
+		}
+		sourceNameList = append(sourceNameList, sourceName)
+
+		sourceNameEn, ok := utils.DataSourceEnMap[source]
+		if !ok {
+			sourceNameEn = sourceName
+		}
+		sourceNameEnList = append(sourceNameEnList, sourceNameEn)
+	}
+	//sourceNameList = append(sourceNameList, utils.ChartDefaultNameCn)
+	//sourceNameEnList = append(sourceNameEnList, utils.ChartDefaultNameEn)
+
+	// 图表来源
+	conf, e := models.GetBusinessConf()
+	if e != nil {
+		return
+	}
+	if conf[models.BusinessConfCompanyName] != "" {
+		sourceNameList = append(sourceNameList, conf[models.BusinessConfCompanyName])
+		sourceNameEnList = append(sourceNameEnList, conf[models.BusinessConfCompanyName])
+	}
+	return
+}

+ 595 - 0
services/data/chart_theme.go

@@ -0,0 +1,595 @@
+package data
+
+import (
+	"encoding/json"
+	"errors"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/chart_theme"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/shopspring/decimal"
+	"math"
+	"time"
+)
+
+// GetThemePreviewChartEdbData 获取图表的指标数据
+func GetThemePreviewChartEdbData(chartType int, calendar, startDate, endDate string, mappingList []*data_manage.ChartEdbInfoMapping, extraConfigStr string, seasonExtraConfig string) (edbList []*data_manage.ChartEdbInfoMapping, xEdbIdValue []int, yDataList []data_manage.YData, dataResp interface{}, err error, errMsg string) {
+	edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
+	xEdbIdValue = make([]int, 0)
+	yDataList = make([]data_manage.YData, 0)
+
+	var extraConfig interface{}
+	switch chartType {
+	case 7: // 柱形图
+		var barConfig data_manage.BarChartInfoReq
+		if extraConfigStr == `` {
+			errMsg = "柱方图未配置"
+			err = errors.New(errMsg)
+			return
+		}
+		err = json.Unmarshal([]byte(extraConfigStr), &barConfig)
+		if err != nil {
+			errMsg = "柱方图配置异常"
+			err = errors.New(errMsg)
+			return
+		}
+		extraConfig = barConfig
+	case 10: // 截面散点图
+		var tmpExtraConfig data_manage.SectionScatterReq
+		if extraConfigStr == `` {
+			errMsg = "截面散点图未配置"
+			err = errors.New(errMsg)
+			return
+		}
+		err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
+		if err != nil {
+			errMsg = "截面散点配置异常"
+			err = errors.New(errMsg)
+			return
+		}
+
+		extraConfig = tmpExtraConfig
+
+	default:
+		xEdbIdValue = make([]int, 0)
+		yDataList = make([]data_manage.YData, 0)
+	}
+
+	// 指标对应的所有数据
+	edbDataListMap, edbList, err := getThemePreviewEdbDataMapList(chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
+	if err != nil {
+		return
+	}
+
+	// 特殊图形数据处理
+	switch chartType {
+	case 7: // 柱形图
+		barChartConf := extraConfig.(data_manage.BarChartInfoReq)
+		xEdbIdValue, yDataList, err = BarChartData(mappingList, edbDataListMap, barChartConf.DateList, barChartConf.Sort)
+
+		for k := range yDataList {
+			yDataList[k].Unit = barChartConf.Unit
+			yDataList[k].UnitEn = barChartConf.UnitEn
+		}
+
+		for _, v := range edbList {
+			// 指标别名
+			if barChartConf.EdbInfoIdList != nil && len(barChartConf.EdbInfoIdList) > 0 {
+				for _, reqEdb := range barChartConf.EdbInfoIdList {
+					if v.EdbInfoId == reqEdb.EdbInfoId {
+						v.EdbAliasName = reqEdb.Name
+					}
+				}
+			}
+		}
+	case 10: // 截面散点图
+		sectionScatterConf := extraConfig.(data_manage.SectionScatterReq)
+		xEdbIdValue, dataResp, err = getThemePreviewSectionScatterChartData(mappingList, edbDataListMap, sectionScatterConf)
+
+		var tmpExtraConfig data_manage.SectionScatterReq
+		if extraConfigStr == `` {
+			errMsg = "截面散点图未配置"
+			err = errors.New(errMsg)
+			return
+		}
+		err = json.Unmarshal([]byte(extraConfigStr), &tmpExtraConfig)
+		if err != nil {
+			errMsg = "截面散点配置异常"
+			err = errors.New(errMsg)
+			return
+		}
+
+		// 这个数据没有必要返回给前端
+		for _, v := range edbList {
+			v.DataList = nil
+		}
+	}
+
+	return
+}
+
+func getThemePreviewEdbDataMapList(chartType int, calendar, startDate, endDate string, mappingList []*data_manage.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*data_manage.EdbDataList, edbList []*data_manage.ChartEdbInfoMapping, err error) {
+	// 指标对应的所有数据
+	edbDataListMap = make(map[int][]*data_manage.EdbDataList)
+
+	for _, v := range mappingList {
+		//fmt.Println("v:", v.EdbInfoId)
+		item := new(data_manage.ChartEdbInfoMapping)
+		item.EdbInfoId = v.EdbInfoId
+		item.SourceName = v.SourceName
+		item.Source = v.Source
+		item.EdbCode = v.EdbCode
+		item.EdbName = v.EdbName
+		item.EdbNameEn = v.EdbNameEn
+		item.Frequency = v.Frequency
+		item.EdbType = v.EdbType
+		item.FrequencyEn = GetFrequencyEn(v.Frequency)
+		if v.Unit != `无` {
+			item.Unit = v.Unit
+		}
+		item.UnitEn = v.UnitEn
+		item.StartDate = v.StartDate
+		item.EndDate = v.EndDate
+		item.ModifyTime = v.ModifyTime
+		item.EdbInfoCategoryType = v.EdbInfoCategoryType
+		item.PredictChartColor = v.PredictChartColor
+		item.ClassifyId = v.ClassifyId
+		item.IsAxis = 1
+		item.EdbInfoType = 1
+		item.LeadValue = v.LeadValue
+		item.LeadUnit = v.LeadUnit
+		item.LeadUnitEn = GetLeadUnitEn(v.LeadUnit)
+		item.ChartEdbMappingId = v.ChartEdbMappingId
+		item.ChartInfoId = v.ChartInfoId
+		item.ChartStyle = v.ChartStyle
+		item.ChartColor = v.ChartColor
+		item.ChartWidth = 0
+		item.IsOrder = false
+		item.MaxData = v.MaxValue
+		item.MinData = v.MinValue
+		item.LatestValue = v.LatestValue
+		item.LatestDate = v.LatestDate
+		item.UniqueCode = v.UniqueCode
+		item.MoveLatestDate = v.LatestDate
+
+		var startDateReal string
+		var diffSeconds int64
+		if chartType == 2 { //季节性图
+			startDateReal = startDate
+		} else {
+			if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 { //领先指标
+				var startTimeRealTemp time.Time
+				startDateParse, _ := time.Parse(utils.FormatDate, startDate)
+				switch v.LeadUnit {
+				case "天":
+					startTimeRealTemp = startDateParse.AddDate(0, 0, -v.LeadValue)
+				case "月":
+					startTimeRealTemp = startDateParse.AddDate(0, -v.LeadValue, 0)
+				case "季":
+					startTimeRealTemp = startDateParse.AddDate(0, -3*v.LeadValue, 0)
+				case "周":
+					startTimeRealTemp = startDateParse.AddDate(0, 0, -7*v.LeadValue)
+				case "年":
+					startTimeRealTemp = startDateParse.AddDate(-v.LeadValue, 0, 0)
+				}
+				if startTimeRealTemp.Before(startDateParse) {
+					startDateReal = startTimeRealTemp.Format(utils.FormatDate)
+					diffSeconds = (int64(startTimeRealTemp.UnixNano()) - int64(startDateParse.UnixNano())) / 1e6
+				} else {
+					startDateReal = startDate
+					diffSeconds = 0
+				}
+
+				// 预测指标的开始日期也要偏移
+				{
+					day, tmpErr := utils.GetDaysBetween2Date(utils.FormatDate, startDate, startDateReal)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					moveLatestDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, item.MoveLatestDate, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					item.MoveLatestDate = moveLatestDateTime.AddDate(0, 0, day).Format(utils.FormatDate)
+				}
+			} else {
+				startDateReal = startDate
+			}
+		}
+
+		dataList := make([]*data_manage.EdbDataList, 0)
+		dataList, err = chart_theme.GetChartThemeDefaultDataItemList(v.EdbInfoId, startDateReal)
+		if err != nil {
+			return
+		}
+		edbDataListMap[v.EdbInfoId] = dataList
+
+		if diffSeconds != 0 && v.EdbInfoType == 0 {
+			dataListLen := len(dataList)
+			for i := 0; i < dataListLen; i++ {
+				dataList[i].DataTimestamp = dataList[i].DataTimestamp - diffSeconds
+			}
+		}
+
+		if chartType == 2 {
+			latestDate, tmpErr := time.Parse(utils.FormatDate, v.LatestDate)
+			if tmpErr != nil {
+				//item.DataList = dataList
+				item.IsNullData = true
+				edbList = append(edbList, item)
+				continue
+			}
+
+			quarterDataList, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDate, seasonExtraConfig)
+			if tErr != nil {
+				err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
+				return
+			}
+			item.DataList = quarterDataList
+		} else if chartType == 7 { //柱方图
+			//item.DataList = dataList
+		} else {
+			item.DataList = dataList
+		}
+		edbList = append(edbList, item)
+	}
+
+	return
+}
+
+func getThemePreviewSectionScatterChartData(mappingList []*data_manage.ChartEdbInfoMapping, edbDataListMap map[int][]*data_manage.EdbDataList, extraConfig data_manage.SectionScatterReq) (edbIdList []int, chartDataResp data_manage.SectionScatterInfoResp, err error) {
+	// 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
+	edbDataMap := make(map[int]map[string]float64)
+	for edbInfoId, edbDataList := range edbDataListMap {
+		edbDateData := make(map[string]float64)
+		for _, edbData := range edbDataList {
+			edbDateData[edbData.DataTime] = edbData.Value
+		}
+		edbDataMap[edbInfoId] = edbDateData
+	}
+
+	// edbIdList 指标展示顺序;x轴的指标顺序
+	edbIdList = make([]int, 0)
+	edbMappingMap := make(map[int]*data_manage.ChartEdbInfoMapping)
+	for _, v := range mappingList {
+		edbIdList = append(edbIdList, v.EdbInfoId)
+		edbMappingMap[v.EdbInfoId] = v
+	}
+	//SectionScatterSeriesInfoResp
+
+	dataListResp := make([]data_manage.SectionScatterSeriesItemResp, 0) //y轴的数据列表
+
+	for _, seriesItem := range extraConfig.SeriesList {
+		var maxDate time.Time
+		// 系列中的指标数据
+		tmpSeriesEdbInfoList := make([]data_manage.SectionScatterEdbItemResp, 0)
+
+		var minXVal, maxXVal, minYVal, maxYVal float64
+		for _, edbConf := range seriesItem.EdbInfoList {
+			tmpItem := data_manage.SectionScatterEdbItemResp{
+				IsShow: edbConf.IsShow,
+				Name:   edbConf.Name,
+				NameEn: edbConf.NameEn,
+			} //单个坐标点的数据
+
+			//X轴的数据
+			{
+				edbInfoId := edbConf.XEdbInfoId //X轴的指标
+				edbMappingInfo, ok := edbMappingMap[edbInfoId]
+				if !ok {
+					continue
+				}
+				findDate := edbConf.XDate             //需要的日期值
+				dataList := edbDataListMap[edbInfoId] //指标的所有数据值
+				if len(dataList) <= 0 {
+					// 没有数据的指标id
+					//findDataList = append(findDataList, 0)
+					continue
+				}
+
+				tmpItem.XEdbInfoId = edbInfoId
+				tmpItem.XName = edbMappingInfo.EdbName
+				tmpItem.XNameEn = edbMappingInfo.EdbNameEn
+
+				switch edbConf.XDateType {
+				case 1: //最新值
+					findDate = dataList[len(dataList)-1].DataTime
+				case 2: //近期几天
+					findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					findDateTime = findDateTime.AddDate(0, 0, -edbConf.XDateValue)
+
+					lenData := len(dataList) - 1
+					for i := lenData; i >= 0; i-- {
+						currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
+						if tmpErr != nil {
+							err = tmpErr
+							return
+						}
+						if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
+							findDate = dataList[i].DataTime
+							break
+						}
+					}
+				case 3: // 固定日期
+					//最早的日期
+					minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					//寻找固定日期的数据
+					findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.XDate, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
+						tmpDate := tmpDateTime.Format(utils.FormatDate)
+						if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
+							findDate = tmpDate
+							break
+						}
+					}
+				default:
+					err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.XDate))
+					return
+				}
+				findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
+				if maxDate.IsZero() {
+					maxDate = findDateTime
+				} else {
+					if findDateTime.After(maxDate) {
+						maxDate = findDateTime
+					}
+				}
+				if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
+					tmpItem.XDate = findDate
+					tmpItem.XValue = tmpValue
+				} else {
+					continue
+				}
+			}
+
+			//Y轴的数据
+			{
+				edbInfoId := edbConf.YEdbInfoId //Y轴的指标
+				edbMappingInfo, ok := edbMappingMap[edbInfoId]
+				if !ok {
+					continue
+				}
+				findDate := edbConf.YDate             //需要的日期值
+				dataList := edbDataListMap[edbInfoId] //指标的所有数据值
+				if len(dataList) <= 0 {
+					// 没有数据的指标id
+					//findDataList = append(findDataList, 0)
+					continue
+				}
+
+				tmpItem.YEdbInfoId = edbInfoId
+				tmpItem.YName = edbMappingInfo.EdbName
+				tmpItem.YNameEn = edbMappingInfo.EdbNameEn
+
+				switch edbConf.YDateType {
+				case 1: //最新值
+					findDate = dataList[len(dataList)-1].DataTime
+				case 2: //近期几天
+					findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[len(dataList)-1].DataTime, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					findDateTime = findDateTime.AddDate(0, 0, -edbConf.YDateValue)
+
+					lenData := len(dataList) - 1
+					for i := lenData; i >= 0; i-- {
+						currDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[i].DataTime, time.Local)
+						if tmpErr != nil {
+							err = tmpErr
+							return
+						}
+						if currDateTime.Equal(findDateTime) || currDateTime.Before(findDateTime) {
+							findDate = dataList[i].DataTime
+							break
+						}
+					}
+				case 3: // 固定日期
+					//最早的日期
+					minDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					//寻找固定日期的数据
+					findDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, edbConf.YDate, time.Local)
+					if tmpErr != nil {
+						err = tmpErr
+						return
+					}
+					for tmpDateTime := findDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
+						tmpDate := tmpDateTime.Format(utils.FormatDate)
+						if _, ok := edbDataMap[edbInfoId][tmpDate]; ok { //如果能找到数据,那么就返回
+							findDate = tmpDate
+							break
+						}
+					}
+				default:
+					err = errors.New(fmt.Sprint("日期类型异常,Type:", edbConf.YDate))
+					return
+				}
+				findDateTime, _ := time.ParseInLocation(utils.FormatDate, findDate, time.Local)
+				if maxDate.IsZero() {
+					maxDate = findDateTime
+				} else {
+					if findDateTime.After(maxDate) {
+						maxDate = findDateTime
+					}
+				}
+				if tmpValue, ok := edbDataMap[edbInfoId][findDate]; ok {
+					tmpItem.YDate = findDate
+					tmpItem.YValue = tmpValue
+				} else {
+					continue
+				}
+			}
+
+			// 获取当前系列的X轴的最大最小值
+			{
+				if tmpItem.XValue < minXVal {
+					minXVal = tmpItem.XValue
+				}
+				if tmpItem.XValue > maxXVal {
+					maxXVal = tmpItem.XValue
+				}
+				if tmpItem.YValue < minYVal {
+					minYVal = tmpItem.YValue
+				}
+				if tmpItem.YValue > maxYVal {
+					maxYVal = tmpItem.YValue
+				}
+			}
+			tmpSeriesEdbInfoList = append(tmpSeriesEdbInfoList, tmpItem)
+		}
+
+		trendLimitData := make([]data_manage.CoordinatePoint, 0) //趋势线的前后坐标点
+		var trendLine, rSquare string
+		// 生成线性方程式
+		var a, b float64
+		{
+			coordinateData := make([]utils.Coordinate, 0)
+			for _, tmpSeriesEdbInfo := range tmpSeriesEdbInfoList {
+				tmpCoordinate1 := utils.Coordinate{
+					X: tmpSeriesEdbInfo.XValue,
+					Y: tmpSeriesEdbInfo.YValue,
+				}
+				coordinateData = append(coordinateData, tmpCoordinate1)
+			}
+
+			// 只有存在两个坐标点的时候,才能去计算线性方程和R平方
+			if len(coordinateData) >= 2 {
+				a, b = utils.GetLinearResult(coordinateData)
+				if !math.IsNaN(a) && !math.IsNaN(b) {
+					if b > 0 {
+						trendLine = fmt.Sprintf("y=%sx+%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
+					} else {
+						trendLine = fmt.Sprintf("y=%sx%s", utils.SubFloatToString(a, 4), utils.SubFloatToString(b, 4))
+					}
+
+					minYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(minXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
+					maxYVal, _ = decimal.NewFromFloat(a).Mul(decimal.NewFromFloat(maxXVal)).Add(decimal.NewFromFloat(b)).Round(4).Float64()
+				}
+
+				// 计算R平方
+				rSquare = fmt.Sprint(utils.CalculationDecisive(coordinateData))
+			}
+
+			trendLimitData = append(trendLimitData, data_manage.CoordinatePoint{
+				X: minXVal,
+				Y: minYVal,
+			}, data_manage.CoordinatePoint{
+				X: maxXVal,
+				Y: maxYVal,
+			})
+		}
+
+		dataListResp = append(dataListResp, data_manage.SectionScatterSeriesItemResp{
+			Name:            seriesItem.Name,
+			NameEn:          seriesItem.NameEn,
+			IsNameDefault:   seriesItem.IsNameDefault,
+			Color:           seriesItem.Color,
+			EdbInfoList:     tmpSeriesEdbInfoList,
+			ShowTrendLine:   seriesItem.ShowTrendLine,
+			ShowFitEquation: seriesItem.ShowFitEquation,
+			ShowRSquare:     seriesItem.ShowRSquare,
+			TrendLine:       trendLine,
+			RSquare:         rSquare,
+			TrendLimitData:  trendLimitData,
+		})
+	}
+
+	// 截面散点图点击详情时自动更新系列名
+	if len(extraConfig.SeriesList) > 0 {
+		// 默认名字的时候才自动更新
+		if extraConfig.SeriesList[0].IsNameDefault {
+			firstXEdbInfoId := extraConfig.SeriesList[0].EdbInfoList[0].XEdbInfoId
+			if v, ok := edbMappingMap[firstXEdbInfoId]; ok {
+				extraConfig.SeriesList[0].Name = v.LatestDate
+				extraConfig.SeriesList[0].NameEn = v.LatestDate
+				dataListResp[0].Name = v.LatestDate
+				dataListResp[0].NameEn = v.LatestDate
+			}
+
+		}
+	}
+
+	chartDataResp = data_manage.SectionScatterInfoResp{
+		XName:       extraConfig.XName,
+		XNameEn:     extraConfig.XNameEn,
+		XUnitName:   extraConfig.XUnitName,
+		XUnitNameEn: extraConfig.XUnitNameEn,
+		YName:       extraConfig.YName,
+		YNameEn:     extraConfig.YNameEn,
+		YUnitName:   extraConfig.YUnitName,
+		YUnitNameEn: extraConfig.YUnitNameEn,
+		XMinValue:   extraConfig.XMinValue,
+		XMaxValue:   extraConfig.XMaxValue,
+		YMinValue:   extraConfig.YMinValue,
+		YMaxValue:   extraConfig.YMaxValue,
+		DataList:    dataListResp,
+	}
+	return
+}
+
+// GetChartThemeConfig
+// @Description: 根据主题id获取主题信息,如果获取不到的话,那么就获取默认的主题
+// @author: Roc
+// @datetime 2023-12-19 14:31:17
+// @param chartThemeId int
+// @param chartType int
+// @param source int
+// @return chartTheme *chart_theme.ChartTheme
+// @return err error
+func GetChartThemeConfig(chartThemeId, source, chartType int) (chartTheme *chart_theme.ChartTheme, err error) {
+	chartTheme, err = chart_theme.GetChartThemeId(chartThemeId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+
+	err = nil
+
+	// 如果找到了,那么就返回
+	if chartTheme != nil {
+		return
+	}
+
+	// 没有找到的话,那么就找默认的主题
+
+	// 查找主题类型id
+	chartThemeType, err := chart_theme.GetChartThemeTypeByChartTypeAndSource(chartType, source)
+	if err != nil {
+		return
+	}
+
+	// 寻找默认的主题id
+	chartTheme, err = chart_theme.GetChartThemeId(chartThemeType.DefaultChartThemeId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		return
+	}
+
+	err = nil
+
+	// 如果找到了,那么就返回
+	if chartTheme != nil {
+		return
+	}
+
+	// 如果还是没找到,那就系统的主题id
+	chartTheme, err = chart_theme.GetSystemChartTheme(chartThemeType.ChartThemeTypeId)
+
+	return
+}

+ 11 - 1
services/data/correlation/chart_info.go

@@ -806,6 +806,11 @@ func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.A
 	chartInfo.RightMax = req.RightMax
 	chartInfo.Disabled = disableVal
 	chartInfo.Source = source
+	chartInfo.ChartThemeId = req.ChartThemeId
+	chartInfo.SourcesFrom = req.SourcesFrom
+	chartInfo.Instructions = req.Instructions
+	chartInfo.MarkersLines = req.MarkersLines
+	chartInfo.MarkersAreas = req.MarkersAreas
 
 	// 指标信息
 	mapList := make([]*data_manage.ChartEdbMapping, 0)
@@ -1140,7 +1145,7 @@ func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin) (cha
 }
 
 // CopyChartInfo 复制图表
-func CopyChartInfo(configId, classifyId int, chartName string, correlationChartInfoReq data_manage.CorrelationChartInfoReq, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
+func CopyChartInfo(configId, classifyId int, chartName string, correlationChartInfoReq data_manage.CorrelationChartInfoReq, oldChartInfo *data_manage.ChartInfo, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
 	configSource := 2
 	isSendEmail = true
 	// 获取相关性图的配置
@@ -1165,6 +1170,11 @@ func CopyChartInfo(configId, classifyId int, chartName string, correlationChartI
 		ChartType:            utils.CHART_TYPE_CURVE,
 		Calendar:             "公历",
 		CorrelationChartInfo: correlationChartInfoReq,
+		ChartThemeId:         oldChartInfo.ChartThemeId,
+		SourcesFrom:          oldChartInfo.SourcesFrom,
+		Instructions:         oldChartInfo.Instructions,
+		MarkersLines:         oldChartInfo.MarkersLines,
+		MarkersAreas:         oldChartInfo.MarkersAreas,
 	}
 	chartSource := utils.CHART_SOURCE_CORRELATION // 默认是相关性图
 	chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, chartSource, sysUser)

+ 6 - 0
services/data/cross_variety/chart.go

@@ -608,6 +608,12 @@ func AddChartInfo(req request.AddChartReq, sysUser *system.Admin) (chartInfo *da
 	//chartInfo.Disabled = disableVal
 	chartInfo.Source = source
 	chartInfo.ExtraConfig = string(extraConfigByte)
+	chartInfo.ChartImage = req.ChartImage
+	chartInfo.ChartThemeId = req.ChartThemeId
+	chartInfo.SourcesFrom = req.SourcesFrom
+	chartInfo.Instructions = req.Instructions
+	chartInfo.MarkersLines = req.MarkersLines
+	chartInfo.MarkersAreas = req.MarkersAreas
 
 	// 图表品种
 	chartVarietyMappingList := make([]*cross_varietyModel.ChartVarietyMapping, 0)

+ 1 - 1
services/data/edb_info.go

@@ -2922,7 +2922,7 @@ func GetBaseIndexTableName(source int) (tableName string) {
 	return
 }
 
-// EdbInfoAdd 添加指标到指标库
+// EdbInfoWsdAdd 添加指标到指标库
 func EdbInfoWsdAdd(item *data_manage.EdbInfo) (edbInfo *data_manage.EdbInfo, err error, errMsg string, isSendEmail bool) {
 	isSendEmail = true
 	//判断指标名称是否存在

+ 5 - 0
services/data/line_equation/chart_info.go

@@ -493,6 +493,11 @@ func BatchAddChartInfo(batchAddChartReq []request.AddChart, lineChartInfoConfig
 			BarConfig:       "",
 			Source:          source,
 			ExtraConfig:     string(tmpLineChartInfoConfigByte),
+			ChartThemeId:    v.ChartThemeId,
+			SourcesFrom:     v.SourcesFrom,
+			Instructions:    v.Instructions,
+			MarkersLines:    v.MarkersLines,
+			MarkersAreas:    v.MarkersAreas,
 		}
 
 		// 指标信息

+ 5 - 0
services/data/line_feature/chart_info.go

@@ -606,6 +606,11 @@ func CopyChartInfo(configId, configSource, classifyId int, chartName string, edb
 		Calendar:        "公历",
 		ExtraConfig:     oldChartInfo.ExtraConfig,
 		ChartImage:      oldChartInfo.ChartImage,
+		ChartThemeId:    oldChartInfo.ChartThemeId,
+		SourcesFrom:     oldChartInfo.SourcesFrom,
+		Instructions:    oldChartInfo.Instructions,
+		MarkersLines:    oldChartInfo.MarkersLines,
+		MarkersAreas:    oldChartInfo.MarkersAreas,
 	}
 	chartSource := oldChartInfo.Source // 默认是相关性图
 	chartInfo, err, errMsg, isSendEmail = AddChartInfo(addChartReq, edbInfoMapping, chartSource, sysUser)

+ 28 - 1
utils/constants.go

@@ -362,10 +362,37 @@ const (
 
 const (
 	WindDbWsd = "wsd"
-	ThsDs = "thsds"
+	ThsDs     = "thsds"
 )
 
 const (
 	UserLoginSalt = "MiQM9yusNA9T2uIH"         // 用户登录盐值
 	DesKeySalt    = "JMCqSoUrTAmyNNIRb0TtlrPk" // DesKey盐值
 )
+
+// DataSourceEnMap 指标来源的英文名称
+var DataSourceEnMap = map[int]string{
+	DATA_SOURCE_WIND:             "Wind",
+	DATA_SOURCE_THS:              "iFind",
+	DATA_SOURCE_PB:               "Bloomberg",
+	DATA_SOURCE_PB_FINANCE:       "Bloomberg Finance",
+	DATA_SOURCE_LT:               "Reuters",
+	DATA_SOURCE_MANUAL:           "Horizon Insights",
+	DATA_SOURCE_LZ:               "OilChem",
+	DATA_SOURCE_YS:               "SMM",
+	DATA_SOURCE_GL:               "MySteel",
+	DATA_SOURCE_ZZ:               "Zhengzhou Commodity Exchange",
+	DATA_SOURCE_DL:               "Dalian Commodity Exchange",
+	DATA_SOURCE_SH:               "Shanghai Futures Exchange",
+	DATA_SOURCE_CFFEX:            "China Financial Futures Exchange",
+	DATA_SOURCE_SHFE:             "Shanghai International Energy Exchange",
+	DATA_SOURCE_GIE:              "Eurostat",
+	DATA_SOURCE_COAL:             "China Coal Transport & Distribution Association",
+	DATA_SOURCE_GOOGLE_TRAVEL:    "Our World in Data",
+	DATA_SOURCE_EIA_STEO:         "Energy Information Administration",
+	DATA_SOURCE_COM_TRADE:        "United Nations",
+	DATA_SOURCE_SCI:              "Sublime China Information",
+	DATA_SOURCE_BAIINFO:          "BAIINFO",
+	DATA_SOURCE_MYSTEEL_CHEMICAL: "Horizon Insights",
+	DATA_SOURCE_FUBAO:            "FuBao",
+}