Browse Source

feat:图表主题配置

Roc 1 year ago
parent
commit
53cd57fee3

+ 511 - 0
controllers/data_manage/chart_theme.go

@@ -0,0 +1,511 @@
+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
+
+	// 图表额外数据参数
+	extraConfigStr := ``
+
+	edbInfoIdList := make([]int, 0) // 指标列表
+	switch chartType {
+	case 1, 4, 6: // 曲线图、堆积柱状图、组合图
+		edbInfoIdList = []int{1, 2, 3, 4, 5}
+	case 2: // 季节性
+		dateType = 20 // 季节性图
+		edbInfoIdList = []int{6}
+	case 5: // 散点图
+		edbInfoIdList = []int{7, 8}
+	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":""}`
+	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":"0.3686","XMaxValue":"0.3686","YMinValue":"-0.1398","YMaxValue":"-0.1398","SeriesList":[{"Name":"2021-11-21","NameEn":"2021-11-21","IsNameDefault":true,"Color":"#00f","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}]}`
+	default:
+		br.Msg = "暂不支持该类型"
+		br.IsSendEmail = false
+		return
+	}
+	calendar := "公历"
+
+	chartInfo := new(data_manage.ChartInfoView)
+
+	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"
+	}
+
+	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, ``, ``, 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
+	}
+	// 单位
+	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
+	}
+
+	if req.Config == `` {
+		br.Msg = "请填写配置"
+		br.IsSendEmail = false
+		return
+	}
+
+	chartTheme := &chart_theme.ChartTheme{
+		ChartThemeId:     0,
+		ChartThemeName:   req.ChartThemeName,
+		ChartThemeTypeId: req.ChartThemeTypeId,
+		Config:           req.Config,
+		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
+	}
+
+	// 更新
+	chartTheme.ChartThemeName = req.ChartThemeName
+	chartTheme.Config = req.Config
+	chartTheme.ModifyTime = time.Now()
+	err = chartTheme.Update([]string{"ChartThemeName", "Config", "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
+	}
+
+	// 更新
+	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 = "配置成功"
+}

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

@@ -0,0 +1,132 @@
+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"`
+	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
+}
+
+// ChartThemeConfigItem
+// @Description: 图表主题配置
+type ChartThemeItem struct {
+	ChartThemeId        int       `description:"图表主题类型ID" orm:"column(chart_theme_id);pk"`
+	ChartThemeName      string    `description:"图表主题名称"`
+	ChartThemeTypeId    int       `description:"图表主题类型ID"`
+	Config              string    `description:"配置"`
+	IsDelete            int       `description:"是否删除,0:未删除;1:已删除"`
+	SysUserId           int       `description:"操作人"`
+	SysUserRealName     string    `description:"操作人的真实名称"`
+	ModifyTime          time.Time `description:"修改时间"`
+	CreateTime          time.Time `description:"创建时间"`
+	DefaultChartThemeId int       `description:"默认使用的图表主题ID"`
+}
+
+// GetChartThemeConfigItemList
+// @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
+}

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

@@ -0,0 +1,87 @@
+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) (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=? `
+
+	sql += ` ORDER BY data_time ASC `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, endInfoId).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
+}

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

@@ -0,0 +1,61 @@
+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
+// @param endInfoId int
+// @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
+}
+
+// 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
+}

+ 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"`
+	Config           string `description:"配置的值"`
+}
+
+// EditThemeReq
+// @Description: 编辑主题请求参数
+type EditThemeReq struct {
+	ChartThemeId   int    `description:"主题id"`
+	ChartThemeName string `description:"主题名称"`
+	Config         string `description:"配置的值"`
+}
+
+// DeleteThemeReq
+// @Description: 删除主题请求参数
+type DeleteThemeReq struct {
+	ChartThemeId int `description:"配置id"`
+}
+
+// SetDefaultThemeReq
+// @Description: 配置默认主题请求参数
+type SetDefaultThemeReq struct {
+	ChartThemeId     int `description:"主题id"`
+	ChartThemeTypeId int `description:"主题类型id"`
+}

+ 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"
@@ -174,6 +175,9 @@ func init() {
 	//初始化AI
 	initAi()
 
+	// 初始化图表主题
+	initChartTheme()
+
 	// 初始化部分数据表变量(直接init会有顺序问题=_=!)
 	data_manage.InitEdbSourceVar()
 }
@@ -505,3 +509,12 @@ func initAi() {
 		new(aimod.AiChat),
 	)
 }
+
+// initChartTheme 初始化图表主题
+func initChartTheme() {
+	orm.RegisterModel(
+		new(chart_theme.ChartTheme),            // 图表主题
+		new(chart_theme.ChartThemeType),        // 图表主题类型
+		new(chart_theme.ChartThemeDefaultData), //默认数据
+	)
+}

+ 63 - 0
routers/commentsRouter.go

@@ -2248,6 +2248,69 @@ 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: "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:EdbClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbClassifyController"],
         beego.ControllerComments{
             Method: "AddEdbClassify",

+ 1 - 0
routers/router.go

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

+ 546 - 0
services/data/chart_theme.go

@@ -0,0 +1,546 @@
+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 = v.IsAxis
+		item.EdbInfoType = v.EdbInfoType
+		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 = v.ChartWidth
+		item.IsOrder = v.IsOrder
+		item.MaxData = v.MaxData
+		item.MinData = v.MinData
+		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)
+		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
+}