Просмотр исходного кода

Merge branch 'feature/eta1.8.5_excel_balance' into debug

# Conflicts:
#	models/data_manage/my_chart.go
xyxie 10 месяцев назад
Родитель
Сommit
9073525b13

+ 7 - 7
controllers/data_manage/data_manage_permission/data_manage_permission.go

@@ -51,7 +51,7 @@ func (c *DataMangePermissionController) SetEdbChartPermission() {
 	}
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
-	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -114,7 +114,7 @@ func (c *DataMangePermissionController) SetPermissionEdbChartClassifyIsPermissio
 	}
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
-	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -172,7 +172,7 @@ func (c *DataMangePermissionController) SetEdbChartClassifyPermission() {
 	}
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
-	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -231,7 +231,7 @@ func (c *DataMangePermissionController) GetEdbChartPermission() {
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
 	subSource, _ := c.GetInt("SubSource")
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -290,7 +290,7 @@ func (c *DataMangePermissionController) GetEdbChartClassifyPermission() {
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
 	subSource, _ := c.GetInt("SubSource")
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -306,7 +306,7 @@ func (c *DataMangePermissionController) GetEdbChartClassifyPermission() {
 	}
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -364,7 +364,7 @@ func (c *DataMangePermissionController) GetEdbChartNoPermission() {
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
 	subSource, _ := c.GetInt("SubSource")
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return

+ 4 - 4
controllers/data_manage/data_manage_permission/data_move.go

@@ -40,7 +40,7 @@ func (c *DataMangePermissionController) EdbChartClassifyList() {
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
 	subSource, _ := c.GetInt("SubSource")
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -90,7 +90,7 @@ func (c *DataMangePermissionController) SecretEdbChartClassifyList() {
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
 	subSource, _ := c.GetInt("SubSource")
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -163,7 +163,7 @@ func (c *DataMangePermissionController) MoveEdbChartList() {
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
 	subSource, _ := c.GetInt("SubSource")
-	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if source == 6 && (subSource <= utils.EXCEL_DEFAULT || subSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return
@@ -254,7 +254,7 @@ func (c *DataMangePermissionController) MoveEdbChartUser() {
 	}
 
 	// 子来源(目前作用于ETA表格,2024-3-26 14:12:09)
-	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.CUSTOM_ANALYSIS_TABLE) {
+	if req.Source == 6 && (req.SubSource <= utils.EXCEL_DEFAULT || req.SubSource > utils.BALANCE_TABLE) {
 		br.Msg = "错误的子来源"
 		br.IsSendEmail = false
 		return

+ 79 - 5
controllers/data_manage/excel/balance_table.go

@@ -8,8 +8,9 @@ import (
 	"eta/eta_api/models/data_manage/excel/request"
 	"eta/eta_api/models/data_manage/excel/response"
 	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
-	excel2 "eta/eta_api/services/data/excel"
+	excelService "eta/eta_api/services/data/excel"
 	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"strconv"
@@ -135,7 +136,7 @@ func (c *ExcelInfoController) Rename() {
 			br.ErrMsg = "获取ETA表格权限失败,Err:" + err.Error()
 			return
 		}
-		button := excel2.GetExcelInfoOpButton(sysUser, excelInfo.SysUserId, excelInfo.Source, haveOperaAuth)
+		button := excelService.GetExcelInfoOpButton(sysUser, excelInfo.SysUserId, excelInfo.Source, haveOperaAuth)
 		if !button.OpButton {
 			br.Msg = "无操作权限"
 			br.Msg = "无操作权限"
@@ -226,7 +227,7 @@ func (c *ExcelInfoController) SaveExcelWorker() {
 			br.ErrMsg = "获取ETA表格权限失败,Err:" + err.Error()
 			return
 		}
-		button := excel2.GetExcelInfoOpButton(sysUser, excelInfo.SysUserId, excelInfo.Source, haveOperaAuth)
+		button := excelService.GetExcelInfoOpButton(sysUser, excelInfo.SysUserId, excelInfo.Source, haveOperaAuth)
 		if !button.OpButton {
 			br.Msg = "无操作权限"
 			br.Msg = "无操作权限"
@@ -330,7 +331,7 @@ func (c *ExcelInfoController) GetWorker() {
 // @Description 新增图表接口
 // @Param	request	body data_manage.AddChartInfoReq true "type json string"
 // @Success 200 {object} data_manage.AddChartInfoResp
-// @router /excel_info/chart_info/add [post]
+// @router /excel_info/balance/chart_add [post]
 func (this *ExcelInfoController) ChartInfoAdd() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
@@ -371,7 +372,7 @@ func (this *ExcelInfoController) ChartInfoAdd() {
 		return
 	}
 
-	chartInfo, err, errMsg, isSendEmail := excel2.AddBalanceTableChart(req, sysUser)
+	chartInfo, err, errMsg, isSendEmail := data.AddBalanceExcelChart(req, sysUser)
 	if err != nil {
 		br.Msg = "保存失败"
 		if errMsg != `` {
@@ -423,3 +424,76 @@ func (this *ExcelInfoController) ChartInfoAdd() {
 	br.Data = resp
 	br.IsAddLog = true
 }
+
+// GetBalanceChartList
+// @Title 获取平衡表表关联的图表
+// @Description 获取平衡表表关联的图表
+// @Param	request	body request.MixedTableCellDataReq true "type json string"
+// @router /excel_info/balance/chart_list [get]
+func (c *ExcelInfoController) GetBalanceChartList() {
+	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
+	}
+
+	excelInfoId, _ := c.GetInt("ExcelInfoId")
+	if excelInfoId <= 0 {
+		br.Msg = "请选择平衡表"
+		return
+	}
+	// 查询所有子表
+	excelInfo, err := excel.GetExcelInfoById(excelInfoId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "表格不存在"
+			return
+		}
+		br.Msg = "查询子表失败"
+		br.ErrMsg = "查询子表失败,Err:" + err.Error()
+		return
+	}
+	list := make([]*data_manage.ChartInfoDetailResp, 0)
+	chartInfoList, mappingListMap, dataListMap, err, errMsg := excelService.GetBalanceExcelChartList(excelInfo)
+	if err != nil {
+		if errMsg != "" {
+			br.Msg = errMsg
+			br.ErrMsg = err.Error()
+			return
+		} else {
+			br.Msg = "查询图表失败"
+			br.ErrMsg = "查询图表失败,Err:" + err.Error()
+		}
+		return
+	}
+	for _, chartInfo := range chartInfoList {
+		mappingList, ok := mappingListMap[chartInfo.ChartInfoId]
+		if !ok {
+			br.Msg = "未找到图表关联的指标信息"
+			return
+		}
+		var chartInfoResp *data_manage.ChartInfoDetailResp
+		chartInfoResp, err, errMsg = data.GetBalanceExcelChartDetail(chartInfo, mappingList, sysUser, dataListMap)
+		if err != nil {
+			br.Msg = "查询图表详情失败"
+			br.ErrMsg = "查询图表详情失败,Err:" + err.Error()
+			return
+		}
+		list = append(list, chartInfoResp)
+	}
+
+	ret := &data_manage.BalanceTableChartListResp{List: list}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "查询成功"
+	br.Data = ret
+}

+ 1 - 1
controllers/data_manage/excel/excel_info.go

@@ -1106,7 +1106,7 @@ func (c *ExcelInfoController) Delete() {
 		var nextItem *excel3.ExcelInfo
 		var condition string
 		var pars []interface{}
-		condition += " AND excel_classify_id=? "
+		condition += " AND excel_classify_id=? AND parent_id=0"
 		pars = append(pars, excelInfo.ExcelClassifyId)
 
 		condition += " AND sort>=? "

+ 3 - 0
models/data_manage/chart_info.go

@@ -720,6 +720,9 @@ type ChartInfoDetailResp struct {
 	CorrelationChartInfo *CorrelationInfo `description:"相关性图表信息"`
 	DataResp             interface{}      `description:"图表数据,根据图的类型而定的,没有确定的数据格式"`
 }
+type BalanceTableChartListResp struct {
+	List []*ChartInfoDetailResp
+}
 
 // XData 商品价格曲线的的x轴数据
 type XData struct {

+ 21 - 1
models/data_manage/excel/excel_chart_edb.go

@@ -93,7 +93,7 @@ func (e *ExcelChartEdb) AddChartEdbAndData(list []*AddChartEdbAndDataItem, chart
 
 	//更新图表id
 	sql := `update excel_chart_edb set chart_info_id = ? where excel_chart_edb_id in (` + utils.GetOrmInReplace(len(updateIds)) + `)`
-	_, err = o.Raw(sql, chartInfoId).Exec()
+	_, err = o.Raw(sql, chartInfoId, updateIds).Exec()
 	return
 }
 
@@ -146,3 +146,23 @@ func addChartEdbAndData(o orm.TxOrmer, chartEdb *ExcelChartEdb, dateList []strin
 	}
 	return
 }
+
+func GetExcelChartEdbMappingByExcelInfoId(excelInfoId int) (list []*ExcelChartEdb, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *
+             FROM excel_chart_edb 
+			 WHERE excel_info_id=? 
+             ORDER BY excel_chart_edb_id ASC `
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&list)
+	return
+}
+
+func GetExcelChartInfoByExcelInfoId(excelInfoId int, charInfoIds []int) (list []*ExcelChartEdb, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *
+             FROM chart_info 
+			 WHERE source=11 and chart_info_id in (utils.) 
+             ORDER BY excel_chart_edb_id ASC `
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&list)
+	return
+}

+ 14 - 0
models/data_manage/excel/excel_info.go

@@ -29,6 +29,8 @@ type ExcelInfo struct {
 	BalanceType        int       `description:"平衡表类型:0 动态表,1静态表"`
 	UpdateUserId       int       `description:"更新人id"`
 	UpdateUserRealName string    `description:"更新人真实姓名"`
+	RelExcelInfoId     int       `description:"平衡表里静态表关联的动态表excel id"`
+	VersionName        string    `description:"静态表版本名称"`
 }
 
 // Update 更新 excel表格基础信息
@@ -593,6 +595,18 @@ func GetNoContentExcelListByExcelInfoIdList(excelInfoIdList []string) (items []*
 	return
 }
 
+func GetNoContentExcelListByExcelInfoIdAndParentId(excelInfoIdList []string) (items []*MyExcelInfoList, err error) {
+	num := len(excelInfoIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE excel_info_id in (` + utils.GetOrmInReplace(num) + `) OR parent_id in (` + utils.GetOrmInReplace(num) + `)   order by excel_info_id DESC `
+	_, err = o.Raw(sql, excelInfoIdList, excelInfoIdList).QueryRows(&items)
+
+	return
+}
+
 // GetNoContentExcelListByUserId
 // @Description: 根据ETA表格ID列表获取列表信息
 // @param userIdList []int

+ 16 - 4
models/data_manage/excel/request/balance_table.go

@@ -2,7 +2,7 @@ package request
 
 import "eta/eta_api/models/data_manage"
 
-type AddBalanceTableChartItem struct {
+type AddBalanceTableChartEdbItem struct {
 	DateSequenceStr string   `description:"日期序列"`
 	DateSequenceVal []string `description:"日期序列的值列表"`
 	DataSequenceStr string   `description:"数据序列"`
@@ -17,6 +17,18 @@ type AddBalanceTableChartItem struct {
 	LeadUnit        string   `description:"领先单位"`
 	FromTag         string   `description:"标签"`
 	ExcelChartEdbId int
+
+	/*	ChartStyle        string  `description:"图表类型"`
+		ChartColor        string  `description:"颜色"`
+		PredictChartColor string  `description:"预测数据的颜色"`
+		ChartWidth        float64 `description:"线条大小"`
+		Source            int     `description:"1:ETA图库;2:商品价格曲线"`
+		EdbAliasName      string  `description:"中文别名"`
+		IsConvert         int     `description:"是否数据转换 0不转 1转"`
+		ConvertType       int     `description:"数据转换类型 1乘 2除 3对数"`
+		ConvertValue      float64 `description:"数据转换值"`
+		ConvertUnit       string  `description:"数据转换单位"`
+		ConvertEnUnit     string  `description:"数据转换单位"`*/
 }
 
 type AddBalanceTableChartReq struct {
@@ -41,13 +53,13 @@ type AddBalanceTableChartReq struct {
 	ExtraConfig       string                      `description:"图表额外配置信息,json字符串"`
 	ChartImage        string                      `description:"封面图" json:"-"`
 	SeasonExtraConfig data_manage.SeasonExtraItem `description:"季节性图表中的配置,json数据"`
-	StartYear         int                         `description:"当选择的日期类型为最近N年类型时,即date_type=20, 用start_year表示N"`
-	//ChartThemeId      int             `description:"图表应用主题ID"`
+	//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:"标识区"`
 	//Unit              string          `description:"中文单位名称"`
 	//UnitEn            string          `description:"英文单位名称"`
-	ChartEdbList []AddBalanceTableChartItem
+	ChartEdbInfoList []AddBalanceTableChartEdbItem
 }

+ 11 - 0
models/data_manage/my_chart.go

@@ -903,6 +903,17 @@ func GetChartInfoByIdList(chartInfoIdList []int) (items []*ChartInfo, err error)
 	return
 }
 
+func GetChartInfoViewByIdList(chartInfoIdList []int) (items []*ChartInfoView, err error) {
+	num := len(chartInfoIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM chart_info WHERE chart_info_id in (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, chartInfoIdList).QueryRows(&items)
+	return
+}
+
 // MyChartClassifyItem 我的图表分类信息
 type MyChartClassifyItem struct {
 	MyChartClassifyId   int    `description:"分类ID"`

+ 18 - 0
routers/commentsRouter.go

@@ -817,6 +817,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "ChartInfoAdd",
+            Router: `/excel_info/balance/chart_add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "GetBalanceChartList",
+            Router: `/excel_info/balance/chart_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
         beego.ControllerComments{
             Method: "GetBaseEdbInfo",

+ 111 - 0
services/data/chart_info.go

@@ -3096,3 +3096,114 @@ func getEdbConvertDataMapList(chartInfoId, chartType int, calendar, startDate, e
 
 	return
 }
+
+// GetChartEdbDataV2 获取图表的指标数据
+func GetChartEdbDataV2(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*data_manage.ChartEdbInfoMapping, extraConfigStr string, seasonExtraConfig string, chartInfoData ChartInfoDataShow) (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
+	case utils.CHART_TYPE_RADAR:
+		var barConfig data_manage.RadarChartInfoReq
+		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
+	default:
+		xEdbIdValue = make([]int, 0)
+		yDataList = make([]data_manage.YData, 0)
+	}
+
+	// 指标对应的所有数据
+	edbDataListMap, edbList, err := chartInfoData.GetEdbDataMapList(chartInfoId, 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 = GetSectionScatterChartData(chartInfoId, 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
+		}
+	case utils.CHART_TYPE_RADAR: //雷达图
+		radarConf := extraConfig.(data_manage.RadarChartInfoReq)
+		xEdbIdValue, dataResp, err = RadarChartData(mappingList, edbDataListMap, radarConf)
+	}
+	return
+}

+ 684 - 0
services/data/chart_info_excel_balance.go

@@ -0,0 +1,684 @@
+package data
+
+import (
+	"encoding/json"
+	"errors"
+	"eta/eta_api/models/data_manage"
+	excelModel "eta/eta_api/models/data_manage/excel"
+	"eta/eta_api/models/data_manage/excel/request"
+	"eta/eta_api/models/system"
+	"eta/eta_api/utils"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// AddBalanceExcelChart 添加平衡表图表
+func AddBalanceExcelChart(req request.AddBalanceTableChartReq, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
+	// 获取表格信息
+	excelInfo, err := excelModel.GetExcelInfoById(req.ExcelInfoId)
+	if err != nil {
+		errMsg = "找不到该EXCEL"
+		err = fmt.Errorf("找不到该EXCEL!%s", err.Error())
+		return
+	}
+
+	if excelInfo.Source != utils.BALANCE_TABLE {
+		errMsg = "EXCEL类型错误!"
+		err = fmt.Errorf("EXCEL类型错误!")
+		return
+	}
+	if len(req.ChartEdbInfoList) == 0 {
+		errMsg = "图表数据不能为空!"
+		err = fmt.Errorf("图表数据不能为空!%s", err.Error())
+		return
+	}
+	chartEdbList := make([]*excelModel.AddChartEdbAndDataItem, 0)
+	for _, chartEdb := range req.ChartEdbInfoList {
+		excelEdb := new(excelModel.ExcelChartEdb)
+		excelEdb.EdbName = chartEdb.EdbName
+		randStr := utils.GetRandDigit(4)
+		excelEdb.EdbCode = `T` + time.Now().Format("060102150405") + "_" + randStr
+		excelEdb.ExcelInfoId = excelInfo.ExcelInfoId
+		excelEdb.DateSequence = chartEdb.DateSequenceStr
+		excelEdb.DataSequence = chartEdb.DataSequenceStr
+		excelEdb.SysUserId = sysUser.AdminId
+		excelEdb.SysUserRealName = sysUser.RealName
+		excelEdb.MaxData = chartEdb.MaxData
+		excelEdb.MinData = chartEdb.MinData
+		excelEdb.IsOrder = chartEdb.IsOrder
+		excelEdb.IsAxis = chartEdb.IsAxis
+		excelEdb.FromTag = chartEdb.FromTag
+		excelEdb.EdbInfoType = chartEdb.EdbInfoType
+		excelEdb.LeadValue = chartEdb.LeadValue
+		excelEdb.LeadUnit = chartEdb.LeadUnit
+		excelEdb.CreateTime = time.Now()
+		excelEdb.ModifyTime = time.Now()
+		var dateList []string
+		var dataList []float64
+		if excelInfo.BalanceType == 1 {
+			// 如果是静态表,则直接使用前端传输的数据落到数据库里
+			/*dateList, dataList, err, errMsg = utils.HandleEdbSequenceVal(chartEdb.DateSequenceVal, chartEdb.DataSequenceVal)
+			if err != nil {
+				errMsg = "时间序列或数据序列异常!"
+				err = fmt.Errorf("时间序列或数据序列异常!%s", err.Error())
+				return
+			}*/
+		}
+
+		// 处理日期列表和值列表
+		addItem := &excelModel.AddChartEdbAndDataItem{
+			ChartEdb: excelEdb,
+			DateList: dateList,
+			ValList:  dataList,
+		}
+		chartEdbList = append(chartEdbList, addItem)
+	}
+	chartInfo, err, errMsg, isSendEmail = addBalanceExcelChart(req, sysUser.AdminId, sysUser.RealName)
+	if err != nil {
+		errMsg = "新增图表失败!"
+		err = fmt.Errorf("新增图表失败!%s, %s", errMsg, err.Error())
+		return
+	}
+	obj := new(excelModel.ExcelChartEdb)
+	err = obj.AddChartEdbAndData(chartEdbList, chartInfo)
+	if err != nil {
+		errMsg = "新增图表失败!"
+		err = fmt.Errorf("新增图表数据失败!%s", err.Error())
+		return
+	}
+	return
+}
+
+func addBalanceExcelChart(req request.AddBalanceTableChartReq, sysUserId int, sysUserRealName string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
+	isSendEmail = true // 默认错误的时候要发送邮件
+
+	req.ChartName = strings.Trim(req.ChartName, " ")
+	if req.ChartName == "" {
+		errMsg = "请填写图表名称!"
+		err = fmt.Errorf(errMsg)
+		isSendEmail = false
+		return
+	}
+	chartType := req.ChartType
+	extraConfig := req.ExtraConfig
+	// todo 查找默认主题设置
+	// 季节性图表额外配置信息
+	var seasonExtraConfig string
+
+	if len(req.ChartEdbInfoList) <= 0 {
+		errMsg = "请选择指标!"
+		err = fmt.Errorf(errMsg)
+		return
+	}
+	if chartType == 2 {
+		// 处理季节性图表横轴配置
+		{
+			if req.SeasonExtraConfig.XEndDate != "" {
+				if req.SeasonExtraConfig.XStartDate > req.SeasonExtraConfig.XEndDate && req.SeasonExtraConfig.JumpYear != 1 {
+					errMsg = "季节性图表配置信息异常:横坐标日期配置错误"
+					err = fmt.Errorf("季节性图表配置信息异常: 横坐标日期配置错误")
+					return
+				}
+				seasonExtra, tErr := json.Marshal(req.SeasonExtraConfig)
+				if tErr != nil {
+					errMsg = "季节性图表配置信息异常"
+					err = fmt.Errorf("季节性图表配置信息异常,Err:" + tErr.Error())
+					return
+				}
+
+				seasonExtraConfig = string(seasonExtra)
+			}
+		}
+	}
+
+	// 图表额外配置
+	extraConfig, err, errMsg = HandleExtraConfig(chartType, extraConfig)
+	if err != nil {
+		if errMsg == `` {
+			errMsg = "指标异常!"
+		}
+		err = fmt.Errorf("指标异常!Err:" + err.Error())
+		return
+	}
+
+	//判断图表是否存在
+	var condition string
+	var pars []interface{}
+
+	// 图表名称在不同图分类下不允许重复 需求调整时间:2022年11月07日09:47:07
+	condition += " AND chart_classify_id=0 "
+
+	condition += " AND chart_name=? AND source = ? "
+	pars = append(pars, req.ChartName, utils.CHART_SOURCE_BALANCE_EXCEL)
+
+	count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
+	if err != nil {
+		errMsg = "判断图表名称是否存在失败"
+		err = fmt.Errorf("判断图表名称是否存在失败,Err:" + err.Error())
+		return
+	}
+
+	if count > 0 {
+		errMsg = "图表已存在,请重新填写"
+		err = fmt.Errorf("判断图表名称是否存在失败")
+		isSendEmail = false
+		return
+	}
+	// todo 判断是否是禁用的图表
+	//	disableVal := data.CheckIsDisableChart(edbInfoIdArr)
+
+	chartInfo = new(data_manage.ChartInfo)
+	chartInfo.ChartName = req.ChartName
+	//chartInfo.EdbInfoIds = edbInfoIdStr
+	//chartInfo.ChartClassifyId = req.ChartClassifyId
+	chartInfo.SysUserId = sysUserId
+	chartInfo.SysUserRealName = sysUserRealName
+	chartInfo.CreateTime = time.Now()
+	chartInfo.ModifyTime = time.Now()
+	chartInfo.IsSetName = 0
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
+
+	// todo 判断是否需要重新计算用户的start_date
+	chartInfo.DateType = 3
+
+	if chartType == 0 {
+		chartType = 1
+	}
+	chartInfo.ChartType = chartType
+
+	calendar := req.Calendar
+	if calendar == "" {
+		calendar = "公历"
+	}
+
+	chartInfo.Calendar = calendar
+	/*	chartInfo.StartDate = req.StartDate
+		chartInfo.EndDate = req.EndDate
+		chartInfo.SeasonStartDate = req.StartDate
+		chartInfo.SeasonEndDate = req.EndDate*/
+	chartInfo.LeftMin = req.LeftMin
+	chartInfo.LeftMax = req.LeftMax
+	chartInfo.RightMin = req.RightMin
+	chartInfo.RightMax = req.RightMax
+	chartInfo.Right2Min = req.Right2Min
+	chartInfo.Right2Max = req.Right2Max
+	chartInfo.MinMaxSave = req.MinMaxSave
+	//chartInfo.Disabled = disableVal
+	//chartInfo.BarConfig = barChartConf
+	chartInfo.ExtraConfig = extraConfig
+	chartInfo.SeasonExtraConfig = seasonExtraConfig
+	//chartInfo.StartYear = req.StartYear
+	chartInfo.Source = utils.CHART_SOURCE_BALANCE_EXCEL
+	//	chartInfo.ChartThemeId = req.ChartThemeId
+	chartInfo.SourcesFrom = req.SourcesFrom
+	/*	chartInfo.Instructions = req.Instructions
+		chartInfo.MarkersLines = req.MarkersLines
+		chartInfo.MarkersAreas = req.MarkersAreas
+		chartInfo.Unit = req.Unit
+		chartInfo.UnitEn = req.UnitEn*/
+	/*newId, err := data_manage.AddChartInfo(chartInfo)
+	if err != nil {
+		errMsg = `保存失败`
+		err = fmt.Errorf("保存失败,Err:" + err.Error())
+		return
+	}
+	chartInfo.ChartInfoId = int(newId)*/
+
+	//添加es数据
+	//go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+
+	return
+}
+
+func GetBalanceExcelChartDetail(chartInfo *data_manage.ChartInfoView, mappingListTmp []*excelModel.ExcelChartEdb, sysUser *system.Admin, dataListMap map[int][]*data_manage.EdbDataList) (resp *data_manage.ChartInfoDetailResp, err error, errMsg string) {
+	// todo 图表权限处理
+	chartInfoId := chartInfo.ChartInfoId
+	resp = new(data_manage.ChartInfoDetailResp)
+
+	// 获取主题样式
+	chartTheme, err := GetChartThemeConfig(chartInfo.ChartThemeId, chartInfo.Source, chartInfo.ChartType)
+	if err != nil {
+		errMsg = "获取失败"
+		err = fmt.Errorf(" 获取主题信息失败 Err:%s", err.Error())
+		return
+	}
+	chartInfo.ChartThemeStyle = chartTheme.Config
+	chartInfo.ChartThemeId = chartTheme.ChartThemeId
+
+	dateType := chartInfo.DateType
+	fmt.Println("dateType:", dateType)
+
+	chartType := chartInfo.ChartType
+	startDate := chartInfo.StartDate
+	endDate := chartInfo.EndDate
+	seasonStartDate := chartInfo.SeasonStartDate
+	seasonEndDate := chartInfo.SeasonEndDate
+	//startYear := chartInfo.StartYear
+
+	calendar := chartInfo.Calendar
+
+	if calendar == "" {
+		calendar = "公历"
+	}
+
+	mappingList := make([]*data_manage.ChartEdbInfoMapping, 0)
+	//循环组装映射关系
+	for _, v := range mappingListTmp {
+		mapping := &data_manage.ChartEdbInfoMapping{
+			EdbInfoId:         v.ExcelChartEdbId,
+			SourceName:        "",
+			Source:            0,
+			SubSource:         0,
+			EdbCode:           v.EdbCode,
+			EdbName:           v.EdbName,
+			EdbAliasName:      v.EdbName,
+			EdbNameEn:         "",
+			EdbAliasNameEn:    "",
+			EdbType:           0,
+			Frequency:         "",
+			FrequencyEn:       "",
+			Unit:              "",
+			UnitEn:            "",
+			StartDate:         "",
+			EndDate:           "",
+			ModifyTime:        v.ModifyTime.Format(utils.FormatDateTime),
+			ChartEdbMappingId: v.ExcelChartEdbId,
+			ChartInfoId:       chartInfoId,
+			MaxData:           v.MaxData,
+			MinData:           v.MinData,
+			IsOrder:           v.IsOrder,
+			IsAxis:            v.IsAxis,
+			//EdbInfoType:         0,
+			//EdbInfoCategoryType: 0,
+			LeadValue:         v.LeadValue,
+			LeadUnit:          v.LeadUnit,
+			LeadUnitEn:        "",
+			ChartStyle:        "",
+			ChartColor:        "",
+			PredictChartColor: "",
+			ChartWidth:        0,
+			ChartType:         0,
+			LatestDate:        "",
+			LatestValue:       0,
+			MoveLatestDate:    "",
+			UniqueCode:        "",
+			MinValue:          0,
+			MaxValue:          0,
+			DataList:          nil,
+			IsNullData:        false,
+			MappingSource:     0,
+			RegionType:        "",
+			ClassifyId:        0,
+			IsConvert:         0,
+			ConvertType:       0,
+			ConvertValue:      0,
+			ConvertUnit:       "",
+			ConvertEnUnit:     "",
+			IsJoinPermission:  0,
+			HaveOperaAuth:     true,
+		}
+		mappingList = append(mappingList, mapping)
+	}
+	if chartType == 2 {
+		startDate = seasonStartDate
+		endDate = seasonEndDate
+		if dateType <= 0 {
+			if startDate != "" {
+				dateType = 5
+			} else {
+				dateType = utils.DateTypeNYears
+			}
+		}
+	} else {
+		if dateType <= 0 {
+			dateType = 3
+		}
+	}
+	/*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, startDate, endDate, startYear, yearMax)*/
+
+	if chartInfo.ChartType == 2 {
+		chartInfo.StartDate = startDate
+		chartInfo.EndDate = endDate
+	}
+	// 图表额外数据参数
+	extraConfigStr := chartInfo.ExtraConfig
+	// 柱方图的一些配置
+	var barConfig data_manage.BarChartInfoReq
+	if chartInfo != nil && chartInfo.ChartType == 7 {
+		if chartInfo.BarConfig == `` {
+			err = fmt.Errorf("柱方图未配置")
+			errMsg = "柱方图未配置"
+			return
+		}
+		err = json.Unmarshal([]byte(chartInfo.BarConfig), &barConfig)
+		if err != nil {
+			err = fmt.Errorf("柱方图配置异常 json.Unmarshal Err:%s", err.Error())
+			errMsg = "柱方图配置异常"
+			return
+		}
+		extraConfigStr = chartInfo.BarConfig
+	}
+	// 获取表格数据
+
+	excelChartInfoDataShow := new(ExcelChartInfoDataShow)
+	excelChartInfoDataShow.DataListMap = dataListMap
+
+	if chartInfo.HaveOperaAuth || true {
+		// 获取图表中的指标数据
+		edbList, xEdbIdValue, yDataList, dataResp, e, msg := GetChartEdbDataV2(chartInfoId, chartType, calendar, startDate, endDate, mappingList, extraConfigStr, chartInfo.SeasonExtraConfig, excelChartInfoDataShow)
+		if e != nil {
+			err = fmt.Errorf("获取图表,指标数据失败,Err:%s", e.Error())
+			errMsg = msg
+			return
+		}
+		// 单位
+		if chartType == utils.CHART_TYPE_BAR && len(yDataList) > 0 {
+			chartInfo.Unit = yDataList[0].Unit
+			chartInfo.UnitEn = yDataList[0].UnitEn
+		}
+		warnEdbList := make([]string, 0)
+		for _, v := range edbList {
+			if v.IsNullData {
+				warnEdbList = append(warnEdbList, v.EdbName+"("+v.EdbCode+")")
+			}
+		}
+		if len(warnEdbList) > 0 {
+			chartInfo.WarnMsg = `图表引用指标异常,异常指标:` + strings.Join(warnEdbList, ",")
+		}
+		if chartInfoId > 0 && chartInfo != nil {
+			//判断是否加入我的图库
+			{
+				var myChartCondition string
+				var myChartPars []interface{}
+				myChartCondition += ` AND a.admin_id=? `
+				myChartPars = append(myChartPars, sysUser.AdminId)
+				myChartCondition += ` AND a.chart_info_id=? `
+				myChartPars = append(myChartPars, chartInfo.ChartInfoId)
+
+				myChartList, e := data_manage.GetMyChartByCondition(myChartCondition, myChartPars)
+				if e != nil && e.Error() != utils.ErrNoRow() {
+					errMsg = "获取失败"
+					err = fmt.Errorf("获取我的图表信息失败,GetMyChartByCondition,Err:" + e.Error())
+					return
+				}
+				if myChartList != nil && len(myChartList) > 0 {
+					chartInfo.IsAdd = true
+					chartInfo.MyChartId = myChartList[0].MyChartId
+					chartInfo.MyChartClassifyId = myChartList[0].MyChartClassifyId
+				}
+			}
+		}
+		//判断是否需要展示英文标识
+		chartInfo.IsEnChart = CheckIsEnChart(chartInfo.ChartNameEn, edbList, chartInfo.Source, chartInfo.ChartType)
+
+		// 图表的指标来源
+		sourceNameList, sourceNameEnList := GetEdbSourceByEdbInfoIdList(edbList)
+
+		chartInfo.ChartSource = strings.Join(sourceNameList, ",")
+		chartInfo.ChartSourceEn = strings.Join(sourceNameEnList, ",")
+
+		// todo 指标权限
+		{
+			for _, item := range edbList {
+				// 数据权限
+				item.HaveOperaAuth = true
+			}
+		}
+
+		resp.EdbInfoList = edbList
+		resp.XEdbIdValue = xEdbIdValue
+		resp.YDataList = yDataList
+		resp.DataResp = dataResp
+	} else {
+		resp.EdbInfoList = mappingList
+	}
+
+	//图表操作权限
+	chartInfo.IsEdit = CheckOpChartPermission(sysUser, chartInfo.SysUserId, chartInfo.HaveOperaAuth)
+	chartInfo.Button = data_manage.ChartViewButton{
+		IsEdit:    chartInfo.IsEdit,
+		IsEnChart: chartInfo.IsEnChart,
+		IsAdd:     chartInfo.IsAdd,
+		IsCopy:    true,
+		IsSetName: chartInfo.IsSetName,
+	}
+
+	resp.ChartInfo = chartInfo
+	resp.BarChartInfo = barConfig
+	return
+}
+
+// GetBalanceExcelEdbDataMapList 获取指标最后的基础数据
+func GetBalanceExcelEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*data_manage.ChartEdbInfoMapping, seasonExtraConfig string, dataListMap map[int][]*data_manage.EdbDataList) (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
+		if chartInfoId <= 0 {
+			item.IsAxis = 1
+			item.LeadValue = 0
+			item.LeadUnit = ""
+			item.ChartEdbMappingId = 0
+			item.ChartInfoId = 0
+			item.IsOrder = false
+			item.EdbInfoType = 1
+			item.ChartStyle = ""
+			item.ChartColor = ""
+			item.ChartWidth = 0
+			item.MaxData = v.MaxValue
+			item.MinData = v.MinValue
+		} else {
+			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
+		item.EdbAliasName = v.EdbAliasName
+		item.IsConvert = v.IsConvert
+		item.ConvertType = v.ConvertType
+		item.ConvertValue = v.ConvertValue
+		item.ConvertUnit = v.ConvertUnit
+		item.ConvertEnUnit = v.ConvertEnUnit
+		item.IsJoinPermission = v.IsJoinPermission
+
+		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
+			}
+		}
+		//fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
+		calendarPreYear := 0
+		if calendar == "农历" {
+			newStartDateReal, err := time.Parse(utils.FormatDate, startDateReal)
+			if err != nil {
+				fmt.Println("time.Parse:" + err.Error())
+			}
+			calendarPreYear = newStartDateReal.Year() - 1
+			newStartDateReal = newStartDateReal.AddDate(-1, 0, 0)
+			startDateReal = newStartDateReal.Format(utils.FormatDate)
+		}
+		dataList := make([]*data_manage.EdbDataList, 0)
+		dataListTmp, ok := dataListMap[v.EdbInfoId]
+		if ok {
+			dataList = dataListTmp
+		} else {
+			err = errors.New(fmt.Sprint("获取失败,指标类型异常", v.EdbInfoId))
+			return
+		}
+		if v.IsConvert == 1 {
+			switch v.ConvertType {
+			case 1:
+				for i, data := range dataList {
+					dataList[i].Value = data.Value * v.ConvertValue
+				}
+				//item.MaxData = item.MaxData * v.ConvertValue
+				//item.MinData = item.MinData * v.ConvertValue
+			case 2:
+				for i, data := range dataList {
+					dataList[i].Value = data.Value / v.ConvertValue
+				}
+				//item.MaxData = item.MaxData / v.ConvertValue
+				//item.MinData = item.MinData / v.ConvertValue
+			case 3:
+				for i, data := range dataList {
+					if data.Value <= 0 {
+						err = errors.New("数据中含有负数或0,无法对数运算")
+						return
+					}
+					dataList[i].Value = math.Log(data.Value) / math.Log(v.ConvertValue)
+				}
+				//item.MaxData = math.Log(item.MaxData) / math.Log(v.ConvertValue)
+				//item.MinData = math.Log(item.MinData) / math.Log(v.ConvertValue)
+			}
+		}
+
+		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
+			}
+
+			if calendar == "农历" {
+				if len(dataList) <= 0 {
+					result := new(data_manage.EdbDataResult)
+					item.DataList = result
+				} else {
+					result, tmpErr := data_manage.AddCalculateQuarterV6(dataList)
+					if tmpErr != nil {
+						err = errors.New("获取农历数据失败,Err:" + tmpErr.Error())
+						return
+					}
+					quarterDataList, tErr := GetSeasonEdbInfoDataListByXDateNong(result, latestDate, seasonExtraConfig, calendarPreYear)
+					if tErr != nil {
+						err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
+						return
+					}
+					item.DataList = quarterDataList
+				}
+
+			} else {
+				quarterDataList, tErr := GetSeasonEdbInfoDataListByXDate(dataList, latestDate, seasonExtraConfig)
+				if tErr != nil {
+					err = errors.New("获取季节性图表数据失败,Err:" + tErr.Error())
+					return
+				}
+				item.DataList = quarterDataList
+			}
+
+		} else if chartType == 7 || chartType == utils.CHART_TYPE_RADAR { //柱方图
+			//item.DataList = dataList
+		} else {
+			item.DataList = dataList
+		}
+		edbList = append(edbList, item)
+	}
+
+	return
+}

+ 30 - 0
services/data/chart_info_interface.go

@@ -0,0 +1,30 @@
+package data
+
+import (
+	"eta/eta_api/models/data_manage"
+)
+
+type ChartInfoDataShow interface {
+	GetEdbDataMapList(chartInfoId, chartType int, calendar, startDate, endDate string, mappingList []*data_manage.ChartEdbInfoMapping, seasonExtraConfig string) (edbDataListMap map[int][]*data_manage.EdbDataList, edbList []*data_manage.ChartEdbInfoMapping, err error)
+}
+
+type BaseChartInfoDataShow struct {
+}
+
+// GetEdbDataMapList 获取指标最后的基础数据
+func (e *BaseChartInfoDataShow) GetEdbDataMapList(chartInfoId, 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, edbList, err = GetEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig)
+	return
+}
+
+type ExcelChartInfoDataShow struct {
+	DataListMap map[int][]*data_manage.EdbDataList
+}
+
+// GetEdbDataMapList 获取指标最后的基础数据
+func (e *ExcelChartInfoDataShow) GetEdbDataMapList(chartInfoId, 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, edbList, err = GetBalanceExcelEdbDataMapList(chartInfoId, chartType, calendar, startDate, endDate, mappingList, seasonExtraConfig, e.DataListMap)
+	return
+}

+ 4 - 0
services/data/data_manage_permission/data_move.go

@@ -429,6 +429,10 @@ func GetMoveEdbChartList(source, subSource, userId int, keyword, classify string
 		condition += " AND source = ? "
 		pars = append(pars, subSource)
 
+		if source == utils.BALANCE_TABLE {
+			condition += " AND parent_id = 0 "
+		}
+
 		total, err = excel.GetExcelInfoCountByCondition(condition, pars)
 		if err != nil {
 			return

+ 7 - 1
services/data/data_manage_permission/edb_permission.go

@@ -119,7 +119,13 @@ func SetEdbChartPermission(source, subSource, userId int, authUserList []int, is
 	case 6:
 		// ETA表格
 		content += `(ETA表格)`
-		tmpList, tmpErr := excel.GetNoContentExcelListByExcelInfoIdList(dataIdList)
+		tmpList := make([]*excel.MyExcelInfoList, 0)
+		var tmpErr error
+		if subSource == utils.BALANCE_TABLE {
+			tmpList, tmpErr = excel.GetNoContentExcelListByExcelInfoIdAndParentId(dataIdList)
+		} else {
+			tmpList, tmpErr = excel.GetNoContentExcelListByExcelInfoIdList(dataIdList)
+		}
 		if tmpErr != nil {
 			err = tmpErr
 			return

+ 27 - 0
services/data/data_manage_permission/excel.go

@@ -153,3 +153,30 @@ func CheckExcelPermission(excelIsJoinPermission, excelClassifyIsJoinPermission,
 
 	return
 }
+
+func CheckBalanceExcelPermissionByExcelInfoId(excelInfo *excel.ExcelInfo, excelIsJoinPermission, userId int) (hasAuth bool, err error) {
+	// 查询父级ID
+	if excelInfo.Source != utils.BALANCE_TABLE {
+		return
+	}
+	parentId := excelInfo.ParentId
+	if excelInfo.BalanceType == 1 { //静态表关联的动态表的权限
+		parentId = excelInfo.RelExcelInfoId
+	}
+	parentExcelInfo, err := excel.GetExcelInfoById(parentId)
+	if err != nil {
+		err = fmt.Errorf("查询表格信息出错 err: %v", err)
+		return
+	}
+	excelClassifyId := parentExcelInfo.ExcelClassifyId
+	excelInfoId := parentExcelInfo.ExcelInfoId
+	currClassify, err := excel.GetExcelClassifyById(excelClassifyId)
+	if err != nil {
+		return
+	}
+	if currClassify != nil {
+		return CheckExcelPermission(excelIsJoinPermission, currClassify.IsJoinPermission, userId, excelInfoId, excelClassifyId)
+	}
+
+	return
+}

+ 277 - 194
services/data/excel/balance_table.go

@@ -2,252 +2,335 @@ package excel
 
 import (
 	"encoding/json"
+	"errors"
 	"eta/eta_api/models/data_manage"
 	excelModel "eta/eta_api/models/data_manage/excel"
 	"eta/eta_api/models/data_manage/excel/request"
-	"eta/eta_api/models/system"
-	"eta/eta_api/services/data"
 	"eta/eta_api/utils"
 	"fmt"
-	"sort"
+	"github.com/xuri/excelize/v2"
 	"strconv"
-	"strings"
 	"time"
 )
 
-// AddBalanceTableChart 添加平衡表图表
-func AddBalanceTableChart(req request.AddBalanceTableChartReq, sysUser *system.Admin) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
-	// 获取表格信息
-	excelInfo, err := excelModel.GetExcelInfoById(req.ExcelInfoId)
+// 将表格信息转化成指标数据
+func GetBalanceExcelData(excelDetail *excelModel.ExcelInfo) (newDataMap map[int]map[int]request.MixedTableCellDataReq, allRows, allCols int, err error, errMsg string) {
+	var result request.MixedTableReq
+	err = json.Unmarshal([]byte(excelDetail.Content), &result)
 	if err != nil {
-		errMsg = "找不到该EXCEL!err:" + err.Error()
-		err = fmt.Errorf("找不到该EXCEL!")
+		err = errors.New("表格json转结构体失败,Err:" + err.Error())
 		return
 	}
-
-	if excelInfo.Source != utils.BALANCE_TABLE {
-		err = fmt.Errorf("EXCEL类型错误!")
-		return
-	}
-	if len(req.ChartEdbList) == 0 {
-		errMsg = "图表数据不能为空!" + err.Error()
-		err = fmt.Errorf("图表数据不能为空!")
+	newData, tmpErr, tmpErrMsg := GetMixedTableCellData(result)
+	if tmpErr != nil {
+		errMsg = "获取失败"
+		if tmpErrMsg != `` {
+			errMsg = tmpErrMsg
+		}
+		err = errors.New("获取最新的数据失败,Err:" + tmpErr.Error())
 		return
 	}
-	chartEdbList := make([]*excelModel.AddChartEdbAndDataItem, 0)
-	for _, chartEdb := range req.ChartEdbList {
-		excelEdb := new(excelModel.ExcelChartEdb)
-		excelEdb.EdbName = chartEdb.EdbName
-		randStr := utils.GetRandDigit(4)
-		excelEdb.EdbCode = `T` + time.Now().Format("060102150405") + "_" + randStr
-		excelEdb.ExcelInfoId = excelInfo.ExcelInfoId
-		excelEdb.DateSequence = chartEdb.DateSequenceStr
-		excelEdb.DataSequence = chartEdb.DataSequenceStr
-		excelEdb.SysUserId = sysUser.AdminId
-		excelEdb.SysUserRealName = sysUser.RealName
-		excelEdb.MaxData = chartEdb.MaxData
-		excelEdb.MinData = chartEdb.MinData
-		excelEdb.IsOrder = chartEdb.IsOrder
-		excelEdb.IsAxis = chartEdb.IsAxis
-		excelEdb.FromTag = chartEdb.FromTag
-		excelEdb.EdbInfoType = chartEdb.EdbInfoType
-		excelEdb.LeadValue = chartEdb.LeadValue
-		excelEdb.LeadUnit = chartEdb.LeadUnit
-		var dateList []string
-		var dataList []float64
-		if excelInfo.BalanceType == 1 {
-			// 如果是静态表,则直接使用前端传输的数据落到数据库里
-			dateList, dataList, err, errMsg = HandleEdbSequenceVal(chartEdb.DateSequenceVal, chartEdb.DataSequenceVal)
-			if err != nil {
-				errMsg = "时间序列或数据序列异常!" + err.Error()
-				err = fmt.Errorf("时间序列或数据序列异常!")
-				return
-			}
-		}
 
-		// 处理日期列表和值列表
-		addItem := &excelModel.AddChartEdbAndDataItem{
-			ChartEdb: excelEdb,
-			DateList: dateList,
-			ValList:  dataList,
+	allRows = len(newData)
+	allCols = 0
+	newDataMap = make(map[int]map[int]request.MixedTableCellDataReq)
+	for r, row := range newData {
+		tmp := len(row)
+		if tmp > allCols {
+			allCols = tmp
+		}
+		colMap := make(map[int]request.MixedTableCellDataReq)
+		for c, col := range row {
+			colMap[c] = col
 		}
-		chartEdbList = append(chartEdbList, addItem)
+		newDataMap[r] = colMap
 	}
-	// todo 处理图表
-	chartInfo, err, errMsg, isSendEmail = addBalanceTableChart(req, sysUser.AdminId, sysUser.RealName)
+	return
+}
+
+func GetBalanceExcelChartList(excelInfo *excelModel.ExcelInfo) (list []*data_manage.ChartInfoView, mappingListMap map[int][]*excelModel.ExcelChartEdb, dataListMap map[int][]*data_manage.EdbDataList, err error, errMsg string) {
+	newExcelDataMap, excelAllRows, excelAllCols, err, errMsg := GetBalanceExcelData(excelInfo)
 	if err != nil {
-		errMsg += "新增图表失败!" + err.Error()
-		err = fmt.Errorf("新增图表失败!")
 		return
 	}
-	obj := new(excelModel.ExcelChartEdb)
-	err = obj.AddChartEdbAndData(chartEdbList, chartInfo)
+	dataListMap = make(map[int][]*data_manage.EdbDataList)
+	// 相关联指标
+	mappingListTmp, err := excelModel.GetExcelChartEdbMappingByExcelInfoId(excelInfo.ExcelInfoId)
 	if err != nil {
-		errMsg = err.Error()
-		err = fmt.Errorf("新增图表失败!")
+		errMsg = "获取失败"
+		err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error())
 		return
 	}
-
+	mappingListMap = make(map[int][]*excelModel.ExcelChartEdb, 0)
+	charInfoIds := make([]int, 0)
+	for _, mapping := range mappingListTmp {
+		mappingListMap[mapping.ChartInfoId] = append(mappingListMap[mapping.ChartInfoId], mapping)
+		err, errMsg = GetBalanceExcelEdbData(mapping, newExcelDataMap, dataListMap, excelAllRows, excelAllCols)
+		if err != nil {
+			err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error())
+			return
+		}
+	}
+	for k, _ := range mappingListMap {
+		charInfoIds = append(charInfoIds, k)
+	}
+	list = make([]*data_manage.ChartInfoView, 0)
+	if len(charInfoIds) > 0 {
+		chartInfoList, e := data_manage.GetChartInfoViewByIdList(charInfoIds)
+		if e != nil {
+			errMsg = "获取失败"
+			err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error())
+			return
+		}
+		list = chartInfoList
+		/*for _, chartInfo := range chartInfoList {
+			mappingList, ok := mappingListMap[chartInfo.ChartInfoId]
+			if !ok {
+				err = fmt.Errorf("未找到图表关联的指标信息")
+				return
+			}
+			var chartInfoResp *data_manage.ChartInfoDetailResp
+			chartInfoResp, err, errMsg = GetBalanceExcelChartDetail(chartInfo, mappingList, sysUser, dataListMap)
+			if err != nil {
+				return
+			}
+			list = append(list, chartInfoResp)
+		}*/
+	}
 	return
 }
 
-func addBalanceTableChart(req request.AddBalanceTableChartReq, sysUserId int, sysUserRealName string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
-	isSendEmail = true // 默认错误的时候要发送邮件
-
-	req.ChartName = strings.Trim(req.ChartName, " ")
-	if req.ChartName == "" {
-		errMsg = "请填写图表名称!"
-		err = fmt.Errorf(errMsg)
-		isSendEmail = false
-		return
-	}
-	chartType := req.ChartType
-	extraConfig := req.ExtraConfig
-	// 季节性图表额外配置信息
-	var seasonExtraConfig string
-	// 关联指标
-	var edbInfoIdArr []int
-
-	if len(req.ChartEdbList) <= 0 {
-		errMsg = "请选择指标!"
-		err = fmt.Errorf(errMsg)
-		return
-	}
-	if chartType == 2 {
-		/*existCount, tmpErr := data_manage.GetEdbDataQuarterCount(edbInfoId)
+// 将表格信息转化成指标数据
+func GetBalanceExcelEdbData(excelEdbMappingItem *excelModel.ExcelChartEdb, newMixedTableCellDataListMap map[int]map[int]request.MixedTableCellDataReq, dataListMap map[int][]*data_manage.EdbDataList, allRows, allCols int) (err error, errMsg string) {
+	var dateList, dataList []string
+	// 日期序列
+	{
+		_, startColumnName, endColumnName, startNum, endNum, isAll, isRow, isColumn, tmpErr := GetSheetStr(excelEdbMappingItem.DateSequence)
 		if tmpErr != nil {
-			errMsg = "保存失败"
-			err = fmt.Errorf("判断季节性图表,指标数据是否存在失败,Err:" + tmpErr.Error())
+			err = tmpErr
 			return
 		}
-		if existCount <= 0 {
-			go data_manage.AddCalculateQuarter(edbInfoId, edbInfo.Source, edbInfo.EdbCode)
-		}*/
 
-		// 处理季节性图表横轴配置
-		{
-			if req.SeasonExtraConfig.XEndDate != "" {
-				if req.SeasonExtraConfig.XStartDate > req.SeasonExtraConfig.XEndDate && req.SeasonExtraConfig.JumpYear != 1 {
-					errMsg = "季节性图表配置信息异常:横坐标日期配置错误"
-					err = fmt.Errorf("季节性图表配置信息异常: 横坐标日期配置错误")
+		startNum = startNum - 1
+		endNum = endNum - 1
+		// 选择行的数据
+		if isRow {
+			// 因为是选择一行的数据,所以开始行和结束行时一样的
+			//endNum = startNum - 1
+
+			// 开始列名、结束列
+			var startColumn, endColumn int
+			if isAll {
+				// 结束列(其实也就是整列的个数)
+				endColumn = allCols - 1
+			} else {
+				tmpStartColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
+				if tmpErr != nil {
+					errMsg = "列名异常:" + startColumnName
+					err = errors.New(errMsg)
+					return
+				}
+
+				tmpEndColumn, tmpErr := excelize.ColumnNameToNumber(endColumnName)
+				if tmpErr != nil {
+					errMsg = "列名异常:" + endColumnName
+					err = errors.New(errMsg)
 					return
 				}
-				seasonExtra, tErr := json.Marshal(req.SeasonExtraConfig)
-				if tErr != nil {
-					errMsg = "季节性图表配置信息异常"
-					err = fmt.Errorf("季节性图表配置信息异常,Err:" + tErr.Error())
+				startColumn = tmpStartColumn - 1
+				endColumn = tmpEndColumn - 1
+			}
+
+			// 最大列数,如果设置的超过了最大列数,那么结束列就是最大列数
+			maxCol := allCols
+			if endColumn > maxCol {
+				endColumn = maxCol - 1
+			}
+
+			// 长度固定,避免一直申请内存空间
+			dateList = make([]string, endColumn-startColumn+1)
+
+			i := 0
+			for currColumn := startColumn; currColumn <= endColumn; currColumn++ {
+				currCell, ok := newMixedTableCellDataListMap[startNum][currColumn]
+				if !ok {
+					errMsg = fmt.Sprintf("第%d列,第%d行数据异常", currColumn, startNum)
+					err = errors.New(errMsg)
 					return
 				}
+				dateList[i] = currCell.ShowValue
+				i++
+			}
+
+		} else if isColumn { // 选择列的数据
+			if isAll {
+				// 选择一整列的话,结束行得根据实际情况调整(其实也就是整个sheet有多少行)
+				endNum = allRows - 1
+			}
+
+			startColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
+			if tmpErr != nil {
+				errMsg = "列名异常:" + startColumnName
+				err = errors.New(errMsg)
+				return
+			}
+			startColumn = startColumn - 1
 
-				seasonExtraConfig = string(seasonExtra)
+			// 最大行数,如果设置的超过了最大行数,那么结束行就是最大行数
+			maxRow := allRows
+			if endNum > maxRow {
+				endNum = maxRow - 1
+			}
+			// 长度固定,避免一直申请内存空间
+			dateList = make([]string, endNum-startNum+1)
+			i := 0
+			for currRow := startNum; currRow <= endNum; currRow++ {
+				currCell, ok := newMixedTableCellDataListMap[currRow][startColumn]
+				if !ok {
+					errMsg = fmt.Sprintf("第%d列,第%d行数据异常", currRow, startColumn)
+					err = errors.New(errMsg)
+					return
+				}
+				//dateList = append(dateList, currCell.Value)
+				dateList[i] = currCell.ShowValue
+				i++
 			}
 		}
+
 	}
 
-	// 图表额外配置
-	extraConfig, err, errMsg = data.HandleExtraConfig(chartType, extraConfig)
-	if err != nil {
-		if errMsg == `` {
-			errMsg = "指标异常!"
+	// 数据序列
+	{
+		_, startColumnName, endColumnName, startNum, endNum, isAll, isRow, isColumn, tmpErr := GetSheetStr(excelEdbMappingItem.DataSequence)
+		if tmpErr != nil {
+			err = tmpErr
+			return
 		}
-		err = fmt.Errorf("指标异常!Err:" + err.Error())
-		return
-	}
 
-	sort.Ints(edbInfoIdArr)
-	var edbInfoIdArrStr []string
-	for _, v := range edbInfoIdArr {
-		edbInfoIdArrStr = append(edbInfoIdArrStr, strconv.Itoa(v))
-	}
-	edbInfoIdStr := strings.Join(edbInfoIdArrStr, ",")
+		startNum = startNum - 1
+		endNum = endNum - 1
+		// 选择行的数据
+		if isRow {
+			// 开始列名、结束列
+			var startColumn, endColumn int
+			if isAll {
+				// 结束列(其实也就是整列的个数)
+				endColumn = allCols - 1
+			} else {
 
-	//判断图表是否存在
-	var condition string
-	var pars []interface{}
+				tmpStartColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
+				if tmpErr != nil {
+					errMsg = "列名异常:" + startColumnName
+					err = errors.New(errMsg)
+					return
+				}
 
-	// 图表名称在不同图分类下不允许重复 需求调整时间:2022年11月07日09:47:07
-	//condition += " AND chart_classify_id=? "
-	//pars = append(pars, req.ChartClassifyId)
+				tmpEndColumn, tmpErr := excelize.ColumnNameToNumber(endColumnName)
+				if tmpErr != nil {
+					errMsg = "列名异常:" + endColumnName
+					err = errors.New(errMsg)
+					return
+				}
+				startColumn = tmpStartColumn - 1
+				endColumn = tmpEndColumn - 1
+			}
 
-	condition += " AND chart_name=? AND source = ? "
-	pars = append(pars, req.ChartName, utils.CHART_SOURCE_DEFAULT)
+			// 最大列数,如果设置的超过了最大列数,那么结束列就是最大列数
+			maxCol := allCols
+			if endColumn > maxCol {
+				endColumn = maxCol - 1
+			}
+			// 长度固定,避免一直申请内存空间
+			dataList = make([]string, endColumn-startColumn+1)
+			i := 0
+			for currColumn := startColumn; currColumn <= endColumn; currColumn++ {
+				currCell, ok := newMixedTableCellDataListMap[startNum][currColumn]
+				if !ok {
+					errMsg = fmt.Sprintf("第%d列,第%d行数据异常", startColumn, currColumn)
+					err = errors.New(errMsg)
+					return
+				}
+				//dataList = append(dataList, currCell.Value)
+				dataList[i] = currCell.ShowValue
+				i++
+			}
 
-	count, err := data_manage.GetChartInfoCountByCondition(condition, pars)
-	if err != nil {
-		errMsg = "判断图表名称是否存在失败"
-		err = fmt.Errorf("判断图表名称是否存在失败,Err:" + err.Error())
-		return
-	}
+		} else if isColumn { // 选择列的数据
+			if isAll {
+				// 选择一整列的话,结束行得根据实际情况调整(其实也就是整个sheet有多少行)
+				endNum = allRows - 1
+			}
 
-	if count > 0 {
-		errMsg = "图表已存在,请重新填写"
-		err = fmt.Errorf("判断图表名称是否存在失败")
-		isSendEmail = false
-		return
-	}
-	// todo 判断是否是禁用的图表
-	//	disableVal := data.CheckIsDisableChart(edbInfoIdArr)
-
-	chartInfo = new(data_manage.ChartInfo)
-	chartInfo.ChartName = req.ChartName
-	chartInfo.EdbInfoIds = edbInfoIdStr
-	//chartInfo.ChartClassifyId = req.ChartClassifyId
-	chartInfo.SysUserId = sysUserId
-	chartInfo.SysUserRealName = sysUserRealName
-	chartInfo.CreateTime = time.Now()
-	chartInfo.ModifyTime = time.Now()
-	chartInfo.IsSetName = 0
-	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
-	chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
-
-	// todo 判断是否需要重新计算用户的start_date
-	chartInfo.DateType = 3
-
-	if chartType == 0 {
-		chartType = 1
-	}
-	chartInfo.ChartType = chartType
+			startColumn, tmpErr := excelize.ColumnNameToNumber(startColumnName)
+			if tmpErr != nil {
+				errMsg = "列名异常:" + startColumnName
+				err = errors.New(errMsg)
+				return
+			}
+			startColumn = startColumn - 1
+
+			// 最大行数,如果设置的超过了最大行数,那么结束行就是最大行数
+			maxRow := allRows
+			if endNum > maxRow {
+				endNum = maxRow - 1
+			}
 
-	calendar := req.Calendar
-	if calendar == "" {
-		calendar = "公历"
+			// 长度固定,避免一直申请内存空间
+			dataList = make([]string, endNum-startNum+1)
+			i := 0
+			for currRow := startNum; currRow <= endNum; currRow++ {
+				currCell, ok := newMixedTableCellDataListMap[currRow][startColumn]
+				if !ok {
+					errMsg = fmt.Sprintf("第%d列,第%d行数据异常", currRow, startColumn)
+					err = errors.New(errMsg)
+					return
+				}
+				//dataList = append(dataList, currCell.Value)
+				dataList[i] = currCell.ShowValue
+				i++
+			}
+		}
 	}
 
-	chartInfo.Calendar = calendar
-	/*	chartInfo.StartDate = req.StartDate
-		chartInfo.EndDate = req.EndDate
-		chartInfo.SeasonStartDate = req.StartDate
-		chartInfo.SeasonEndDate = req.EndDate*/
-	chartInfo.LeftMin = req.LeftMin
-	chartInfo.LeftMax = req.LeftMax
-	chartInfo.RightMin = req.RightMin
-	chartInfo.RightMax = req.RightMax
-	chartInfo.Right2Min = req.Right2Min
-	chartInfo.Right2Max = req.Right2Max
-	chartInfo.MinMaxSave = req.MinMaxSave
-	//chartInfo.Disabled = disableVal
-	//chartInfo.BarConfig = barChartConf
-	chartInfo.ExtraConfig = extraConfig
-	chartInfo.SeasonExtraConfig = seasonExtraConfig
-	chartInfo.StartYear = req.StartYear
-	chartInfo.Source = utils.CHART_SOURCE_EXCEL_BALANCE
-	//	chartInfo.ChartThemeId = req.ChartThemeId
-	chartInfo.SourcesFrom = req.SourcesFrom
-	/*	chartInfo.Instructions = req.Instructions
-		chartInfo.MarkersLines = req.MarkersLines
-		chartInfo.MarkersAreas = req.MarkersAreas
-		chartInfo.Unit = req.Unit
-		chartInfo.UnitEn = req.UnitEn*/
-	newId, err := data_manage.AddChartInfo(chartInfo)
+	//fmt.Println(dateList, dataList)
+	//fmt.Println("日期序列结束")
+
+	// 将excel中的日期、数据系列处理
+	//newDateList, newDataList, err, errMsg := excel2.HandleEdbSequenceVal(dateList, dataList)
+	newDateList, newDataList := dateList, dataList
 	if err != nil {
-		errMsg = `保存失败`
-		err = fmt.Errorf("保存失败,Err:" + err.Error())
+		err = fmt.Errorf(" 处理日期和数据系列失败 %s", err.Error())
 		return
 	}
-	chartInfo.ChartInfoId = int(newId)
-
-	//添加es数据
-	//go EsAddOrEditChartInfo(chartInfo.ChartInfoId)
+	newDataMap := make(map[int]float64, len(newDataList))
+	for i, v := range newDataList {
+		val, e := strconv.ParseFloat(v, 64)
+		if e != nil {
+			err = fmt.Errorf(" 处理日期和数据系列失败 %s", e.Error())
+			return
+		}
+		newDataMap[i] = val
+	}
+	//组装成excelEdbData
+	list := make([]*data_manage.EdbDataList, 0)
 
+	for i, v := range newDateList {
+		// todo 处理DataTimestamp
+		dataTime, e := time.ParseInLocation(utils.FormatDate, v, time.Local)
+		if e != nil {
+			err = errors.New("time.Parse Err:" + err.Error())
+			return
+		}
+		timestamp := dataTime.UnixNano() / 1e6
+		tmp := &data_manage.EdbDataList{
+			EdbDataId:     i,
+			EdbInfoId:     excelEdbMappingItem.ExcelChartEdbId,
+			DataTime:      v,
+			DataTimestamp: timestamp,
+			Value:         newDataMap[i],
+		}
+		list = append(list, tmp)
+	}
+	dataListMap[excelEdbMappingItem.ExcelChartEdbId] = list
 	return
 }

+ 2 - 0
services/data/excel/excel_op.go

@@ -55,6 +55,8 @@ func Delete(excelInfo *excelModel.ExcelInfo, sysUser *system.Admin) (err error,
 		}
 	}
 
+	// todo 如果父级删除是否删除子表和静态表,同时删除图表和图表数据
+
 	// 标记删除
 	excelInfo.IsDelete = 1
 	excelInfo.ModifyTime = time.Now()

+ 1 - 1
utils/constants.go

@@ -277,7 +277,7 @@ const (
 	CHART_SOURCE_LINE_FEATURE_PERCENTILE         = 8  // 统计特征-百分位图表
 	CHART_SOURCE_LINE_FEATURE_FREQUENCY          = 9  // 统计特征-频率分布图表
 	CHART_SOURCE_CROSS_HEDGING                   = 10 // 跨品种分析图表
-	CHART_SOURCE_EXCEL_BALANCE                   = 11 // 平衡表图表
+	CHART_SOURCE_BALANCE_EXCEL                   = 11 // 平衡表图表
 )
 
 // 批量配置图表的位置来源