Przeglądaj źródła

fix:英文版二期

Roc 10 miesięcy temu
rodzic
commit
12050d28d1

+ 10 - 0
controllers/base_auth.go

@@ -13,6 +13,7 @@ import (
 
 type BaseAuthController struct {
 	web.Controller
+	Lang string `description:"当前语言类型,中文:zh;英文:en;默认:zh"`
 }
 
 func (c *BaseAuthController) Prepare() {
@@ -23,6 +24,15 @@ func (c *BaseAuthController) Prepare() {
 	fmt.Println("Url:", uri+";ip:"+ip)
 	if method != "HEAD" {
 		if method == "POST" || method == "GET" {
+			// 当前语言
+			{
+				lang := c.Ctx.Input.Header("Lang")
+				if lang == "" {
+					lang = utils.ZhLangVersion
+				}
+				c.Lang = lang
+			}
+
 			//authorization := this.Ctx.Input.Header("authorization")
 			//if authorization == "" {
 			//	authorization = this.Ctx.Input.Header("Authorization")

+ 10 - 0
controllers/base_common.go

@@ -12,6 +12,7 @@ import (
 
 type BaseCommonController struct {
 	web.Controller
+	Lang string `description:"当前语言类型,中文:zh;英文:en;默认:zh"`
 }
 
 func (c *BaseCommonController) Prepare() {
@@ -22,6 +23,15 @@ func (c *BaseCommonController) Prepare() {
 	} else {
 		requestBody, _ = url.QueryUnescape(string(c.Ctx.Input.RequestBody))
 	}
+	// 当前语言
+	{
+		lang := c.Ctx.Input.Header("Lang")
+		if lang == "" {
+			lang = utils.ZhLangVersion
+		}
+		c.Lang = lang
+	}
+
 	ip := c.Ctx.Input.IP()
 	utils.ApiLog.Info("uri:%s, requestBody:%s, responseBody:%s, ip:%s", c.Ctx.Input.URI(), requestBody, ip)
 }

+ 5 - 6
controllers/excel_info.go

@@ -5,8 +5,7 @@ import (
 	"eta/eta_chart_lib/models"
 	"eta/eta_chart_lib/models/request"
 	"eta/eta_chart_lib/models/response"
-	"eta/eta_chart_lib/services/data"
-	"eta/eta_chart_lib/services/data/table"
+	excel2 "eta/eta_chart_lib/services/data/excel"
 	"eta/eta_chart_lib/services/excel"
 	"eta/eta_chart_lib/utils"
 	"fmt"
@@ -103,20 +102,20 @@ func (this *ExcelInfoController) GetTableDetail() {
 			return
 		}
 	case utils.TIME_TABLE:
-		var tableDataConfig data.TableDataConfig
+		var tableDataConfig excel2.TableDataConfig
 		err = json.Unmarshal([]byte(excelInfo.Content), &tableDataConfig)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "表格json转结构体失败,Err:" + err.Error()
 			return
 		}
-		result, err := data.GetDataByTableDataConfig(tableDataConfig)
+		result, err := excel2.GetDataByTableDataConfig(tableDataConfig)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取最新的表格数据失败,Err:" + err.Error()
 			return
 		}
-		tableData, err = excel.GetTableDataByCustomData(excelInfo.ExcelType, result)
+		tableData, err = excel.GetTableDataByCustomData(excelInfo.ExcelType, result, this.Lang)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "转换成table失败,Err:" + err.Error()
@@ -130,7 +129,7 @@ func (this *ExcelInfoController) GetTableDetail() {
 			br.ErrMsg = "表格json转结构体失败,Err:" + err.Error()
 			return
 		}
-		newResult, tmpErr, tmpErrMsg := table.GetMixedTableCellData(result)
+		newResult, tmpErr, tmpErrMsg := excel2.GetMixedTableCellData(result)
 		if tmpErr != nil {
 			br.Msg = "获取失败"
 			if tmpErrMsg != `` {

+ 2 - 0
models/data_manage/edb_info.go

@@ -13,9 +13,11 @@ type EdbInfo struct {
 	Source           int    `description:"来源id"`
 	EdbCode          string `description:"指标编码"`
 	EdbName          string `description:"指标名称"`
+	EdbNameEn        string `description:"英文指标名称"`
 	EdbNameSource    string `description:"指标名称来源"`
 	Frequency        string `description:"频率"`
 	Unit             string `description:"单位"`
+	UnitEn           string `description:"英文单位"`
 	StartDate        string `description:"起始日期"`
 	EndDate          string `description:"终止日期"`
 	ClassifyId       int    `description:"分类id"`

+ 228 - 0
models/data_manage/excel/excel_classify.go

@@ -0,0 +1,228 @@
+package excel
+
+import (
+	"eta/eta_chart_lib/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ExcelClassify excel表格分类
+type ExcelClassify struct {
+	ExcelClassifyId   int       `orm:"column(excel_classify_id);pk"`
+	Source            int       `description:"表格来源,1:excel插件的表格,2:自定义表格,3:混合表格,4:自定义分析,默认:1"`
+	ExcelClassifyName string    `description:"分类名称"`
+	ParentId          int       `description:"父级id"`
+	SysUserId         int       `description:"创建人id"`
+	SysUserRealName   string    `description:"创建人姓名"`
+	Level             int       `description:"层级"`
+	UniqueCode        string    `description:"唯一编码"`
+	Sort              int       `description:"排序字段,越小越靠前,默认值:10"`
+	IsDelete          int       `description:"排序字段,越小越靠前,默认值:10"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"修改时间"`
+	IsJoinPermission  int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+}
+
+// AddExcelClassify 添加excel分类
+func AddExcelClassify(item *ExcelClassify) (lastId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err = o.Insert(item)
+	if err != nil {
+		return
+	}
+	item.ExcelClassifyId = int(lastId)
+
+	return
+}
+
+// GetExcelClassifyCount 获取同级分类下存在同名分类的数量
+func GetExcelClassifyCount(ExcelClassifyName string, parentId, source int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT COUNT(1) AS count FROM excel_classify WHERE parent_id=? AND source = ? AND excel_classify_name=? AND is_delete=0 `
+	err = o.Raw(sql, parentId, source, ExcelClassifyName).QueryRow(&count)
+	return
+}
+
+func GetExcelClassifyById(classifyId int) (item *ExcelClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_classify WHERE excel_classify_id=? AND is_delete=0 `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+// GetExcelClassifyByIdList
+// @Description: 根据分类id列表获取所有分类信息
+// @author: Roc
+// @datetime 2024-04-07 16:24:04
+// @param classifyIdList []int
+// @return items []*ExcelClassify
+// @return err error
+func GetExcelClassifyByIdList(classifyIdList []int) (items []*ExcelClassify, err error) {
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_classify WHERE excel_classify_id in (` + utils.GetOrmInReplace(num) + `) AND is_delete=0 `
+	_, err = o.Raw(sql, classifyIdList).QueryRows(&items)
+	return
+}
+
+// GetExcelClassifyBySourceAndIsJoinPermission
+// @Description: 根据分类id列表获取所有分类信息
+// @author: Roc
+// @datetime 2024-04-07 16:24:04
+// @param classifyIdList []int
+// @return items []*ExcelClassify
+// @return err error
+func GetExcelClassifyBySourceAndIsJoinPermission(source, isJoinPermission int) (items []*ExcelClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_classify WHERE source = ? AND is_join_permission = ? `
+	_, err = o.Raw(sql, source, isJoinPermission).QueryRows(&items)
+
+	return
+}
+
+func GetChildClassifyById(classifyId int) (items []*ExcelClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_classify WHERE parent_id=? AND is_delete=0 `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+func GetExcelClassifyByParentId(parentId, source int) (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE parent_id=? AND source = ? AND is_delete=0 order by sort asc,excel_classify_id asc`
+	_, err = o.Raw(sql, parentId, source).QueryRows(&items)
+	return
+}
+
+func GetExcelClassifyBySource(source int) (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE  source = ? AND is_delete=0 order by sort asc,excel_classify_id asc`
+	_, err = o.Raw(sql, source).QueryRows(&items)
+	return
+}
+
+func GetExcelClassifyBySourceOrderByLevel(source int) (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE  source = ? AND is_delete=0 order by level asc, sort asc,excel_classify_id asc`
+	_, err = o.Raw(sql, source).QueryRows(&items)
+	return
+}
+func GetExcelClassifyAll() (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE parent_id<>0 AND is_delete=0 order by sort asc,excel_classify_id asc`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+type ExcelClassifyItems struct {
+	ExcelClassifyId   int `description:"分类id"`
+	ExcelInfoId       int `description:"表格id"`
+	ExcelClassifyName string
+	ParentId          int
+	Level             int    `description:"层级"`
+	Sort              int    `description:"排序字段,越小越靠前,默认值:10"`
+	UniqueCode        string `description:"唯一编码"`
+	SysUserId         int    `description:"创建人id"`
+	SysUserRealName   string `description:"创建人姓名"`
+	StartDate         string `description:"自定义开始日期"`
+	Children          []*ExcelClassifyItems
+	IsJoinPermission  int  `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth     bool `description:"是否有数据权限"`
+}
+
+func GetExcelClassifyByCondition(condition string, pars []interface{}) (item *ExcelClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// GetNextExcelClassifyByCondition 获取下一个分类
+func GetNextExcelClassifyByCondition(condition string, pars []interface{}) (item *ExcelClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += " ORDER BY sort asc , create_time ASC LIMIT 1 "
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// GetFirstExcelClassifyByParentId 获取当前父级图表分类下的排序第一条的数据
+func GetFirstExcelClassifyByParentId(parentId int) (item *ExcelClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_classify WHERE parent_id=? AND is_delete=0 order by sort asc,excel_classify_id asc limit 1`
+	err = o.Raw(sql, parentId).QueryRow(&item)
+	return
+}
+
+// UpdateExcelClassifySortByParentId 根据图表父类id更新排序
+func UpdateExcelClassifySortByParentId(parentId, classifyId, nowSort int, updateSort string, source int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update excel_classify set sort = ` + updateSort + ` WHERE parent_id=? and source=? and sort > ? AND is_delete=0 `
+	if classifyId > 0 {
+		sql += ` or ( excel_classify_id > ` + fmt.Sprint(classifyId) + ` and sort= ` + fmt.Sprint(nowSort) + `)`
+	}
+	_, err = o.Raw(sql, parentId, source, nowSort).Exec()
+	return
+}
+
+// Update 更新图表分类基础信息
+func (ExcelClassify *ExcelClassify) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(ExcelClassify, cols...)
+	return
+}
+
+// GetExcelClassifyMaxSort 获取图表分类下最大的排序数
+func GetExcelClassifyMaxSort(parentId int, source int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT Max(sort) AS sort FROM excel_classify WHERE parent_id=? AND source = ? AND is_delete=0 `
+	err = o.Raw(sql, parentId, source).QueryRow(&sort)
+	return
+}
+
+type ExcelClassifyView struct {
+	ExcelClassifyId   int    `orm:"column(excel_classify_id);pk"`
+	ExcelClassifyName string `description:"分类名称"`
+	ParentId          int    `description:"父级id"`
+}
+
+func GetExcelClassifyViewById(classifyId int) (item *ExcelClassifyView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_classify WHERE excel_classify_id=? AND is_delete=0 `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+// ExcelClassifyItemBySort 自定义比较函数,按年龄从小到大排序
+func ExcelClassifyItemBySort(p1, p2 *ExcelClassifyItems) bool {
+	return p1.Sort < p2.Sort
+}
+
+// GetClassifyByIdList
+// @Description: 根据分类ID列表获取分类列表
+// @author: Roc
+// @datetime 2024-04-02 19:40:30
+// @param classifyIdList []int
+// @return items []*ExcelClassify
+// @return err error
+func GetClassifyByIdList(classifyIdList []int) (items []*ExcelClassify, err error) {
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_classify WHERE excel_classify_id in (` + utils.GetOrmInReplace(num) + `) AND is_delete=0 `
+	_, err = o.Raw(sql, classifyIdList).QueryRows(&items)
+
+	return
+}

+ 37 - 0
models/data_manage/excel/excel_draft.go

@@ -0,0 +1,37 @@
+package excel
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ExcelDraft 沙盘推演草稿表
+type ExcelDraft struct {
+	ExcelDraftId int       `orm:"column(excel_draft_id);pk" description:"excel表格草稿记录id"`
+	ExcelId      int       `description:"excel表格id"`
+	Name         string    `description:"excel表格名称"`
+	Content      string    `description:"excel数据"`
+	OpUserId     int       `description:"最近一次编辑操作的用户id"`
+	OpUserName   string    `description:"最近一次编辑的用户名称(冗余字段,避免查表)"`
+	CreateTime   time.Time `description:"创建时间"`
+}
+
+// AddExcelDraft 添加一个新的excel表格草稿
+func AddExcelDraft(excelDraft *ExcelDraft) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	// 新增草稿
+	id, err := o.Insert(excelDraft)
+	if err != nil {
+		return
+	}
+	excelDraft.ExcelDraftId = int(id)
+	return
+}
+
+// GetLastExcelDraftById 根据沙盘id获取最后一条沙盘草稿详情
+func GetLastExcelDraftById(excelId int) (excelDraft *ExcelDraft, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `select * from excel_draft where excel_id = ? order by excel_draft_id desc `
+	err = o.Raw(sql, excelId).QueryRow(&excelDraft)
+	return
+}

+ 142 - 0
models/data_manage/excel/excel_edb_mapping.go

@@ -0,0 +1,142 @@
+package excel
+
+import (
+	"eta/eta_chart_lib/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ExcelEdbMapping excel与指标的关系表
+type ExcelEdbMapping struct {
+	ExcelEdbMappingId int       `orm:"column(excel_edb_mapping_id);pk"`
+	ExcelInfoId       int       `description:"excel的id"`
+	Source            int       `description:"表格来源,1:excel插件的表格,2:自定义表格,3:混合表格,4:自定义分析,默认:1"`
+	EdbInfoId         int       `description:"计算指标id"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"修改时间"`
+}
+
+// AddExcelEdbMappingMulti 批量添加excel与指标的关系
+func AddExcelEdbMappingMulti(items []*ExcelEdbMapping) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+// Add 添加excel与指标的关系
+func (e *ExcelEdbMapping) Add() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Insert(e)
+	return
+}
+
+// GetExcelEdbMappingByEdbInfoId 根据指标id获取配置关系
+func GetExcelEdbMappingByEdbInfoId(edbInfoId int) (item *ExcelEdbMapping, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *  FROM excel_edb_mapping WHERE 1=1 AND edb_info_id = ? `
+
+	err = o.Raw(sql, edbInfoId).QueryRow(&item)
+	return
+}
+
+// GetExcelEdbMappingByExcelInfoId 根据excel的id获取配置关系
+func GetExcelEdbMappingByExcelInfoId(excelInfoId int) (items []*ExcelEdbMapping, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *  FROM excel_edb_mapping AS a 
+           join edb_info as b on a.edb_info_id = b.edb_info_id
+           WHERE 1=1 AND a.excel_info_id = ? `
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&items)
+
+	return
+}
+
+type ExcelEdbMappingItem struct {
+	EdbInfoId        int    `description:"指标id"`
+	UniqueCode       string `description:"唯一编码"`
+	EdbName          string `description:"指标名称"`
+	ClassifyId       int    `description:"分类id"`
+	Frequency        string `description:"频度"`
+	Unit             string `description:"单位"`
+	CalculateFormula string `json:"-"`
+	DateSequenceStr  string `description:"日期序列公式"`
+	DataSequenceStr  string `description:"数据序列公式"`
+}
+
+// CalculateFormula 计算公式
+type CalculateFormula struct {
+	DateSequenceStr string `json:"DateSequenceStr"`
+	DataSequenceStr string `json:"DataSequenceStr"`
+}
+
+// GetAllExcelEdbMappingItemByExcelInfoId 根据品种id获取所有的指标结果集
+func GetAllExcelEdbMappingItemByExcelInfoId(excelInfoId int) (items []*ExcelEdbMappingItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT a.edb_info_id,a.unique_code,a.edb_name,a.classify_id,a.frequency,a.unit,calculate_formula FROM edb_info AS a 
+         JOIN excel_edb_mapping AS b ON a.edb_info_id=b.edb_info_id 
+         WHERE b.excel_info_id = ? ORDER BY b.excel_edb_mapping_id ASC `
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&items)
+	return
+}
+
+// GetNoCustomAnalysisExcelEdbMappingCount 根据指标id获取非自定义分析的关联关系
+func GetNoCustomAnalysisExcelEdbMappingCount(edbInfoId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM excel_edb_mapping a 
+                          join excel_info b on a.excel_info_id=b.excel_info_id
+                          WHERE edb_info_id=? AND a.source != 4 AND b.is_delete = 0`
+	err = o.Raw(sql, edbInfoId).QueryRow(&count)
+	return
+}
+
+// GetAllExcelEdbMappingByExcelInfoId 根据excel的id获取所有的指标
+func GetAllExcelEdbMappingByExcelInfoId(excelInfoId int) (items []*ExcelEdbMapping, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT a.* FROM  excel_edb_mapping a
+         WHERE a.excel_info_id = ? ORDER BY a.excel_edb_mapping_id ASC `
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&items)
+	return
+}
+
+// DeleteCustomAnalysisExcelEdbMappingByEdbInfoId
+// @Description: 根据指标id删除与自定义分析表格的关系
+// @author: Roc
+// @datetime 2023-11-02 13:20:02
+// @param excelInfoId int
+// @return err error
+func DeleteCustomAnalysisExcelEdbMappingByEdbInfoId(excelInfoId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `DELETE FROM excel_edb_mapping WHERE source = ? AND edb_info_id = ? LIMIT 1`
+	_, err = o.Raw(sql, utils.CUSTOM_ANALYSIS_TABLE, excelInfoId).Exec()
+
+	return
+}
+
+// GetExcelEdbMappingItemByExcelInfoIdOrKeyword 根据表格ID或关键词获取指标
+func GetExcelEdbMappingItemByExcelInfoIdOrKeyword(excelInfoId int, keyword string) (items []*ExcelEdbMappingItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	cond := `b.excel_info_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, excelInfoId)
+	if keyword != "" {
+		cond += ` AND (a.edb_code LIKE ? OR a.edb_name LIKE ?)`
+		pars = append(pars, keyword, keyword)
+	}
+	sql := fmt.Sprintf(`SELECT
+			a.edb_info_id,
+			a.unique_code,
+			a.edb_name,
+			a.classify_id,
+			a.frequency,
+			a.unit,
+			calculate_formula
+		FROM
+			edb_info AS a
+		JOIN excel_edb_mapping AS b ON a.edb_info_id = b.edb_info_id
+		WHERE
+			%s
+		ORDER BY
+			b.excel_edb_mapping_id ASC`, cond)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}

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

@@ -0,0 +1,625 @@
+package excel
+
+import (
+	"eta/eta_chart_lib/utils"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ExcelInfo excel表格详情表
+type ExcelInfo struct {
+	ExcelInfoId      int       `orm:"column(excel_info_id);pk"`
+	Source           int       `description:"表格来源,1:excel插件的表格,2:自定义表格,3:混合表格,4:自定义分析,默认:1"`
+	ExcelType        int       `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName        string    `description:"表格名称"`
+	UniqueCode       string    `description:"表格唯一编码"`
+	ExcelClassifyId  int       `description:"表格分类id"`
+	SysUserId        int       `description:"操作人id"`
+	SysUserRealName  string    `description:"操作人真实姓名"`
+	Content          string    `description:"表格内容"`
+	ExcelImage       string    `description:"表格图片"`
+	FileUrl          string    `description:"表格下载地址"`
+	Sort             int       `description:"排序字段,数字越小越排前面"`
+	IsDelete         int       `description:"是否删除,0:未删除,1:已删除"`
+	ModifyTime       time.Time `description:"最近修改日期"`
+	CreateTime       time.Time `description:"创建日期"`
+	IsJoinPermission int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+}
+
+// Update 更新 excel表格基础信息
+func (excelInfo *ExcelInfo) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(excelInfo, cols...)
+	return
+}
+
+type MyExcelInfoList struct {
+	ExcelInfoId      int       `orm:"column(excel_info_id);pk"`
+	Source           int       `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
+	ExcelType        int       `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName        string    `description:"表格名称"`
+	UniqueCode       string    `description:"表格唯一编码"`
+	ExcelClassifyId  int       `description:"表格分类id"`
+	SysUserId        int       `description:"操作人id"`
+	SysUserRealName  string    `description:"操作人真实姓名"`
+	ExcelImage       string    `description:"表格图片"`
+	FileUrl          string    `description:"表格下载地址"`
+	Sort             int       `description:"排序字段,数字越小越排前面"`
+	ModifyTime       time.Time `description:"最近修改日期"`
+	CreateTime       time.Time `description:"创建日期"`
+	IsJoinPermission int       `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth    bool      `description:"是否有数据权限"`
+}
+
+// AddExcelInfo 新增表格
+func AddExcelInfo(excelInfo *ExcelInfo, excelEdbMappingList []*ExcelEdbMapping) (err error) {
+	o, err := orm.NewOrmUsingDB("data").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+		} else {
+			_ = o.Commit()
+		}
+	}()
+	// 表格信息入库
+	lastId, err := o.Insert(excelInfo)
+	if err != nil {
+		return
+	}
+	excelInfo.ExcelInfoId = int(lastId)
+
+	// excel与指标的关联关系
+	dataNum := len(excelEdbMappingList)
+	if dataNum > 0 {
+		for k, v := range excelEdbMappingList {
+			v.ExcelInfoId = excelInfo.ExcelInfoId
+			excelEdbMappingList[k] = v
+		}
+		_, err = o.InsertMulti(dataNum, excelEdbMappingList)
+	}
+
+	return
+}
+
+// EditExcelInfo 编辑表格
+func EditExcelInfo(excelInfo *ExcelInfo, updateExcelInfoParams []string, excelEdbMappingList []*ExcelEdbMapping) (err error) {
+	o, err := orm.NewOrmUsingDB("data").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+		} else {
+			_ = o.Commit()
+		}
+	}()
+
+	// ETA表格信息变更
+	_, err = o.Update(excelInfo, updateExcelInfoParams...)
+	if err != nil {
+		return
+	}
+
+	// 删除关系表
+	sql := `DELETE FROM excel_edb_mapping WHERE excel_info_id=? `
+	_, err = o.Raw(sql, excelInfo.ExcelInfoId).Exec()
+
+	// excel与指标的关联关系
+	dataNum := len(excelEdbMappingList)
+	if dataNum > 0 {
+		for k, v := range excelEdbMappingList {
+			v.ExcelInfoId = excelInfo.ExcelInfoId
+			excelEdbMappingList[k] = v
+		}
+		_, err = o.InsertMulti(dataNum, excelEdbMappingList)
+	}
+
+	return
+}
+
+// GetExcelInfoAll 获取所有表格列表,用于分类展示
+func GetExcelInfoAll() (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,excel_classify_id,excel_name AS excel_classify_name,
+             unique_code,sys_user_id,sys_user_real_name,is_join_permission
+            FROM excel_info where is_delete=0 ORDER BY sort asc,create_time ASC `
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// GetNoContentExcelInfoAll 获取不含content的表格列表 用于分类展示
+func GetNoContentExcelInfoAll(source, userId int) (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,excel_classify_id,excel_name AS excel_classify_name,
+             unique_code,sys_user_id,sys_user_real_name,sort,is_join_permission
+            FROM excel_info where is_delete=0 AND source = ?  `
+
+	pars := []interface{}{source}
+
+	if userId > 0 {
+		sql += ` AND sys_user_id = ? `
+		pars = append(pars, userId)
+	}
+	sql += `  ORDER BY sort asc,excel_info_id desc `
+	_, err = o.Raw(sql, pars...).QueryRows(&items)
+	return
+}
+
+// GetAllExcelInfoBySource 根据来源获取包含content的表格列表
+func GetAllExcelInfoBySource(source int) (items []*ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info where is_delete=0  AND source = ?  ORDER BY sort asc,create_time desc `
+	_, err = o.Raw(sql, source).QueryRows(&items)
+	return
+}
+
+// GetExcelInfoById 根据id 获取eta表格详情
+func GetExcelInfoById(excelInfoId int) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE excel_info_id=? AND is_delete=0 `
+	err = o.Raw(sql, excelInfoId).QueryRow(&item)
+	return
+}
+
+// GetExcelInfoByUnicode 编码获取表格
+func GetExcelInfoByUnicode(unicode string) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE unique_code = ? AND is_delete = 0 `
+	err = o.Raw(sql, unicode).QueryRow(&item)
+	return
+}
+
+func GetExcelInfoViewById(excelInfoId int) (item *ExcelInfoView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE excel_info_id=? AND is_delete=0 `
+	err = o.Raw(sql, excelInfoId).QueryRow(&item)
+	return
+}
+
+func GetExcelInfoCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM excel_info WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetNoContentExcelInfoListByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*ExcelClassifyItems, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT excel_info_id,excel_classify_id,excel_name AS excel_classify_name,
+             unique_code,sys_user_id,sys_user_real_name,sort,is_join_permission FROM excel_info WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+
+	sql += ` AND is_delete=0 ORDER BY excel_info_id DESC LIMIT ?,? `
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+func GetExcelInfoByCondition(condition string, pars []interface{}) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// GetNextExcelInfoByCondition 根据条件获取下一个表格
+func GetNextExcelInfoByCondition(condition string, pars []interface{}) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += " ORDER BY sort asc , create_time desc LIMIT 1 "
+	err = o.Raw(sql, pars).QueryRow(&item)
+	return
+}
+
+// GetNextExcelInfo 根据分类id获取下一个excel表格
+func GetNextExcelInfo(classifyId, classifySort, source int) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT b.* FROM excel_classify AS a
+			INNER JOIN excel_info AS b ON a.excel_classify_id=b.excel_classify_id
+			WHERE (a.sort>? OR (a.sort=? and a.excel_classify_id>?) ) AND a.is_delete=0 AND b.is_delete=0
+			AND a.source = ? AND b.source = ? 
+			ORDER BY a.sort ASC,b.sort asc,b.create_time desc
+			LIMIT 1 `
+	err = o.Raw(sql, classifySort, classifySort, classifyId, source, source).QueryRow(&item)
+	return
+}
+
+// EditExcelInfoImage 修改excel表格的图片
+func EditExcelInfoImage(excelInfoId int, imageUrl string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+
+	sql := ` UPDATE  excel_info SET excel_image=?, modify_time = NOW() WHERE excel_info_id = ? AND is_delete=0 `
+	_, err = o.Raw(sql, imageUrl, excelInfoId).Exec()
+	if err != nil {
+		fmt.Println("EditExcelInfoImage Err:", err.Error())
+		return err
+	}
+
+	return
+}
+
+// GetExcelInfoByUniqueCode 根据unique_code来获取excel表格详情
+func GetExcelInfoByUniqueCode(uniqueCode string) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE unique_code=? AND is_delete=0 `
+	err = o.Raw(sql, uniqueCode).QueryRow(&item)
+	return
+}
+
+// GetFirstExcelInfoByClassifyId 获取当前分类下,且排序数相同 的排序第一条的数据
+func GetFirstExcelInfoByClassifyId(classifyId int) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE excel_classify_id=? AND is_delete=0 order by sort asc,excel_info_id desc limit 1`
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+// UpdateExcelInfoSortByClassifyId 根据表格id更新排序
+func UpdateExcelInfoSortByClassifyId(classifyId, nowSort, prevExcelInfoId int, updateSort string, source int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update excel_info set sort = ` + updateSort + ` WHERE excel_classify_id=? AND source=? AND is_delete=0 AND ( sort > ? `
+	// todo 前一个兄弟节点后移
+	if prevExcelInfoId > 0 {
+		sql += ` or (excel_info_id < ` + fmt.Sprint(prevExcelInfoId) + ` and sort = ` + fmt.Sprint(nowSort) + `)`
+	}
+	sql += `)`
+	_, err = o.Raw(sql, classifyId, source, nowSort).Exec()
+	return
+}
+
+type ExcelInfoView struct {
+	ExcelInfoId       int    `orm:"column(excel_info_id);pk"`
+	ExcelName         string `description:"来源名称"`
+	ExcelClassifyId   int    `description:"表格分类id"`
+	ExcelClassifyName string `description:"表格名称"`
+	SysUserId         int
+	SysUserRealName   string
+	UniqueCode        string `description:"表格唯一编码"`
+	CreateTime        time.Time
+	ModifyTime        time.Time
+	DateType          int    `description:"日期类型:1:00年至今,2:10年至今,3:15年至今,4:年初至今,5:自定义时间"`
+	StartDate         string `description:"自定义开始日期"`
+	EndDate           string `description:"自定义结束日期"`
+	IsSetName         int    `description:"设置名称"`
+	EdbInfoIds        string `description:"指标id"`
+	ExcelType         int    `description:"生成样式:1:曲线图,2:季节性图"`
+	Calendar          string `description:"公历/农历"`
+	SeasonStartDate   string `description:"季节性图开始日期"`
+	SeasonEndDate     string `description:"季节性图开始日期"`
+	ExcelImage        string `description:"表格图片"`
+	Sort              int    `description:"排序字段,数字越小越排前面"`
+	IsAdd             bool   `description:"true:已加入我的图库,false:未加入我的图库"`
+	MyExcelId         int
+	MyExcelClassifyId string `description:"我的表格分类,多个用逗号隔开"`
+	ExcelClassify     []*ExcelClassifyView
+	EdbEndDate        string `description:"指标最新更新日期"`
+	LeftMin           string `description:"表格左侧最小值"`
+	LeftMax           string `description:"表格左侧最大值"`
+	RightMin          string `description:"表格右侧最小值"`
+	RightMax          string `description:"表格右侧最大值"`
+}
+
+// GetExcelInfoByClassifyIdAndName 根据分类id和表格名获取表格信息
+func GetExcelInfoByClassifyIdAndName(classifyId int, excelName string) (item *ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE excel_classify_id = ? and excel_name=? AND is_delete=0 `
+	err = o.Raw(sql, classifyId, excelName).QueryRow(&item)
+	return
+}
+
+// GetNoContentExcelListByCondition 获取没有content的excel表格列表数据
+func GetNoContentExcelListByCondition(condition string, pars []interface{}, startSize, pageSize int) (item []*MyExcelInfoList, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,source,excel_type,excel_name,unique_code,excel_classify_id,sys_user_id,sys_user_real_name,excel_image,file_url,sort,create_time,modify_time,is_join_permission
+FROM excel_info WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	//sql += " ORDER BY sort ASC,chart_info_id DESC LIMIT ?,? "
+	sql += " ORDER BY create_time DESC LIMIT ?,? "
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&item)
+	return
+}
+
+func GetExcelListCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM excel_info WHERE 1=1 AND is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+// GetExcelViewInfoByExcelInfoId 根据excelInfoId 获取ETA表格详情
+func GetExcelViewInfoByExcelInfoId(excelInfoId int) (item *MyExcelInfoList, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,source,excel_type,excel_name,unique_code,excel_classify_id,sys_user_id,sys_user_real_name,excel_image,file_url,sort,create_time,modify_time,is_join_permission FROM excel_info WHERE excel_info_id = ? AND is_delete=0 `
+	err = o.Raw(sql, excelInfoId).QueryRow(&item)
+	return
+}
+
+// GetExcelInfoCountByClassifyId 根据分类id获取名下表格数量
+func GetExcelInfoCountByClassifyId(classifyId int) (total int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT count(1) total FROM excel_info WHERE excel_classify_id = ? AND is_delete=0 `
+	err = o.Raw(sql, classifyId).QueryRow(&total)
+	return
+}
+
+// UpdateExcelInfoClassifyId 更改表格分类
+func UpdateExcelInfoClassifyId(classifyId, excelInfoId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update excel_info set excel_classify_id = ? WHERE excel_info_id=? `
+	_, err = o.Raw(sql, classifyId, excelInfoId).Exec()
+
+	return
+}
+
+// GetNoContentExcelInfoByName 根据名称 获取eta表格详情
+func GetNoContentExcelInfoByName(excelName string, source int) (item *MyExcelInfoList, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,source,excel_type,excel_name,unique_code,excel_classify_id,sys_user_id,sys_user_real_name,excel_image,file_url,sort,create_time,modify_time,is_join_permission 
+ FROM excel_info WHERE excel_name = ? AND source = ? AND is_delete=0 `
+	err = o.Raw(sql, excelName, source).QueryRow(&item)
+
+	return
+}
+
+// GetNoContentExcelInfoByUniqueCode 根据unique_code来获取excel表格详情
+func GetNoContentExcelInfoByUniqueCode(uniqueCode string) (item *MyExcelInfoList, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,source,excel_type,excel_name,unique_code,excel_classify_id,sys_user_id,sys_user_real_name,excel_image,file_url,sort,create_time,modify_time,is_join_permission 
+ FROM excel_info WHERE unique_code=? AND is_delete=0 `
+	err = o.Raw(sql, uniqueCode).QueryRow(&item)
+	return
+}
+
+// GetNoContentExcelInfoByExcelId 根据表格id来获取excel表格详情
+func GetNoContentExcelInfoByExcelId(excelInfoId int) (item *MyExcelInfoList, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,source,excel_type,excel_name,unique_code,excel_classify_id,sys_user_id,sys_user_real_name,excel_image,file_url,sort,create_time,modify_time,is_join_permission 
+ FROM excel_info WHERE excel_info_id=? AND is_delete=0 `
+	err = o.Raw(sql, excelInfoId).QueryRow(&item)
+	return
+}
+
+// AddExcelInfoAndSheet 新增excel
+func AddExcelInfoAndSheet(excelInfo *ExcelInfo, sheetParamsList []AddExcelSheetParams) (err error) {
+	o, err := orm.NewOrmUsingDB("data").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+		} else {
+			_ = o.Commit()
+		}
+	}()
+
+	// 表格信息入库
+	lastId, err := o.Insert(excelInfo)
+	if err != nil {
+		return
+	}
+	excelInfo.ExcelInfoId = int(lastId)
+
+	// sheet信息入库
+	for _, sheetInfo := range sheetParamsList {
+		dataNum := len(sheetInfo.DataList)
+
+		//sheet信息入库
+		excelSheetInfo := &ExcelSheet{
+			ExcelSheetId: 0,
+			ExcelInfoId:  excelInfo.ExcelInfoId,
+			SheetName:    sheetInfo.SheetName,
+			PageNum:      dataNum,
+			Index:        sheetInfo.Index,
+			Sort:         sheetInfo.Sort,
+			Config:       sheetInfo.Config,
+			CalcChain:    sheetInfo.CalcChain,
+			ModifyTime:   time.Now(),
+			CreateTime:   time.Now(),
+		}
+		sheetId, tmpErr := o.Insert(excelSheetInfo)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		excelSheetInfo.ExcelSheetId = int(sheetId)
+
+		// data信息入库
+		if dataNum > 0 {
+			for k, _ := range sheetInfo.DataList {
+				sheetInfo.DataList[k].ExcelSheetId = excelSheetInfo.ExcelSheetId
+				sheetInfo.DataList[k].ExcelInfoId = excelSheetInfo.ExcelInfoId
+			}
+			_, tmpErr = o.InsertMulti(dataNum, sheetInfo.DataList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+		}
+	}
+
+	return
+}
+
+// SaveExcelInfoAndSheet 编辑保存
+func SaveExcelInfoAndSheet(excelInfo *ExcelInfo, updateExcelInfoParam []string, sheetParamsList []AddExcelSheetParams) (err error) {
+	o, err := orm.NewOrmUsingDB("data").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+		} else {
+			_ = o.Commit()
+		}
+	}()
+
+	// 表格信息入库
+	_, err = o.Update(excelInfo, updateExcelInfoParam...)
+	if err != nil {
+		return
+	}
+
+	// 先删除历史的sheet信息
+	sql := `DELETE FROM excel_sheet WHERE excel_info_id = ?`
+	_, err = o.Raw(sql, excelInfo.ExcelInfoId).Exec()
+	if err != nil {
+		return
+	}
+
+	// 再删除历史sheet中的cell data信息
+	sql = `DELETE FROM excel_sheet_data WHERE excel_info_id = ?`
+	_, err = o.Raw(sql, excelInfo.ExcelInfoId).Exec()
+	if err != nil {
+		return
+	}
+
+	// sheet信息入库
+	for _, sheetInfo := range sheetParamsList {
+		dataNum := len(sheetInfo.DataList)
+
+		//sheet信息入库
+		excelSheetInfo := &ExcelSheet{
+			ExcelSheetId: 0,
+			ExcelInfoId:  excelInfo.ExcelInfoId,
+			SheetName:    sheetInfo.SheetName,
+			PageNum:      dataNum,
+			Index:        sheetInfo.Index,
+			Sort:         sheetInfo.Sort,
+			Config:       sheetInfo.Config,
+			CalcChain:    sheetInfo.CalcChain,
+			ModifyTime:   time.Now(),
+			CreateTime:   time.Now(),
+		}
+		sheetId, tmpErr := o.Insert(excelSheetInfo)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		excelSheetInfo.ExcelSheetId = int(sheetId)
+
+		// data信息入库
+		if dataNum > 0 {
+			for k, _ := range sheetInfo.DataList {
+				sheetInfo.DataList[k].ExcelSheetId = excelSheetInfo.ExcelSheetId
+				sheetInfo.DataList[k].ExcelInfoId = excelSheetInfo.ExcelInfoId
+			}
+			_, tmpErr = o.InsertMulti(dataNum, sheetInfo.DataList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+		}
+	}
+
+	return
+}
+
+// BatchRefreshExcelReq 批量刷新表格请求
+type BatchRefreshExcelReq struct {
+	ExcelCodes      []string `description:"表格编码"`
+	ReportId        int      `description:"报告ID"`
+	ReportChapterId int      `description:"报告章节ID"`
+	Source          string   `description:"来源,枚举值:report、english_report、smart_report"`
+}
+
+// GetExcelMaxSortByClassifyId 获取当前分类下,且排序数最大的excel
+func GetExcelMaxSortByClassifyId(classifyId int, source int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT Max(sort) AS sort FROM excel_info WHERE excel_classify_id=? AND source = ? AND is_delete=0 order by sort desc,excel_info_id desc limit 1`
+	err = o.Raw(sql, classifyId, source).QueryRow(&sort)
+	return
+}
+
+// GetNoContentExcelListByExcelInfoIdList
+// @Description: 根据ETA表格ID列表获取列表信息
+// @param excelInfoIdList []string
+// @return items
+// @return err
+func GetNoContentExcelListByExcelInfoIdList(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) + `) order by excel_info_id DESC `
+	_, err = o.Raw(sql, excelInfoIdList).QueryRows(&items)
+
+	return
+}
+
+// GetNoContentExcelListByUserId
+// @Description: 根据ETA表格ID列表获取列表信息
+// @param userIdList []int
+// @return items
+// @return err
+func GetNoContentExcelListByUserId(userIdList []int) (items []*MyExcelInfoList, err error) {
+	num := len(userIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM excel_info WHERE excel_info_id in (` + utils.GetOrmInReplace(num) + `) order by excel_info_id DESC `
+	_, err = o.Raw(sql, userIdList).QueryRows(&items)
+
+	return
+}
+
+// ModifyExcelInfoUserIdByCodeList
+// @Description: 根据编码列表修改表格信息
+// @author: Roc
+// @datetime 2024-03-26 14:16:30
+// @param excelIdList []string
+// @param userId int
+// @param userName string
+// @return err error
+func ModifyExcelInfoUserIdByCodeList(excelIdList []string, userId int, userName string) (err error) {
+	num := len(excelIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE excel_info SET sys_user_id=?,sys_user_real_name=? WHERE excel_info_id in (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, userId, userName, excelIdList).Exec()
+	return
+}
+
+// ModifyExcelInfoUserIdByOldUserId
+// @Description:  根据旧的用户id修改创建人
+// @author: Roc
+// @datetime 2024-03-25 19:14:59
+// @param oldUserId int
+// @param userId int
+// @param userName string
+// @return err error
+func ModifyExcelInfoUserIdByOldUserId(oldUserIdList []int, userId int, userName string) (err error) {
+	num := len(oldUserIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE excel_info SET sys_user_id=?,sys_user_real_name=? WHERE is_delete=0 AND sys_user_id in (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, userId, userName, oldUserIdList).Exec()
+	return
+}

+ 98 - 0
models/data_manage/excel/excel_sheet.go

@@ -0,0 +1,98 @@
+package excel
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ExcelSheet excel表格详情表
+type ExcelSheet struct {
+	ExcelSheetId int       `orm:"column(excel_sheet_id);pk"`
+	ExcelInfoId  int       `description:"excel的id"`
+	SheetName    string    `description:"sheet名称"`
+	PageNum      int       `description:"总页码数"`
+	Index        string    `description:"excel数据中的index"`
+	Sort         int       `description:"排序"`
+	Config       string    `description:"配置信息"`
+	CalcChain    string    `description:"计算公式"`
+	ModifyTime   time.Time `description:"最近修改日期"`
+	CreateTime   time.Time `description:"创建日期"`
+}
+
+// Update 更新 excel表格的sheet基础信息
+func (excelSheet *ExcelSheet) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(excelSheet, cols...)
+
+	return
+}
+
+// AddExcelSheet 新增excel表格的sheet基础信息
+func AddExcelSheet(excelInfo *ExcelSheet) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	// 表格信息入库
+	lastId, err := o.Insert(excelInfo)
+	if err != nil {
+		return
+	}
+	excelInfo.ExcelInfoId = int(lastId)
+
+	return
+}
+
+// GetAllSheetList 根据excel_id获取所有的sheet
+func GetAllSheetList(excelInfoId int) (item []*ExcelSheet, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *
+FROM excel_sheet WHERE 1=1 AND excel_info_id = ? `
+	sql += " ORDER BY sort asc "
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&item)
+	return
+}
+
+// SheetItem excel表格详情表
+type SheetItem struct {
+	ExcelSheetId int             `orm:"column(excel_sheet_id);pk" json:"-"`
+	ExcelInfoId  int             `description:"excel的id"  json:"-"`
+	SheetName    string          `description:"sheet名称"`
+	PageNum      int             `description:"数据总页码数"`
+	Index        string          `description:"excel数据中的index"`
+	Sort         int             `description:"排序"`
+	Config       string          `description:"sheet配置"`
+	CalcChain    string          `description:"计算公式"`
+	ModifyTime   time.Time       `description:"最近修改日期" json:"-"`
+	CreateTime   time.Time       `description:"创建日期"`
+	Data         *ExcelSheetData `description:"excel的数据"`
+}
+
+// GetAllSheetItemList 根据excel_id获取所有的sheet详情
+func GetAllSheetItemList(excelInfoId int) (item []*SheetItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *
+FROM excel_sheet WHERE 1=1 AND excel_info_id = ? `
+	sql += " ORDER BY sort asc "
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&item)
+	return
+}
+
+// GetAllNoConfigSheetItemList 根据excel_id获取所有的sheet详情
+func GetAllNoConfigSheetItemList(excelInfoId int) (item []*SheetItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_sheet_id,excel_info_id,sheet_name,sort,page_num,create_time
+FROM excel_sheet WHERE 1=1 AND excel_info_id = ? `
+	sql += " ORDER BY sort asc "
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&item)
+	return
+}
+
+// AddExcelSheetParams excel表格详情表
+type AddExcelSheetParams struct {
+	ExcelSheetId int               `orm:"column(excel_sheet_id);pk"`
+	ExcelInfoId  int               `description:"excel的id"`
+	SheetName    string            `description:"sheet名称"`
+	Index        string            `description:"excel数据中的index"`
+	Sort         int               `description:"排序"`
+	Config       string            `description:"配置信息"`
+	CalcChain    string            `description:"计算公式"`
+	DataList     []*ExcelSheetData `description:"excel的数据"`
+}

+ 63 - 0
models/data_manage/excel/excel_sheet_data.go

@@ -0,0 +1,63 @@
+package excel
+
+import (
+	"eta/eta_chart_lib/utils"
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ExcelSheetData excel表格详情表
+type ExcelSheetData struct {
+	ExcelDataId  int       `orm:"column(excel_data_id);pk"`
+	ExcelInfoId  int       `description:"数据归属的excel_info的id"`
+	ExcelSheetId int       `description:"数据归属sheet"`
+	Sort         int       `description:"数据排序"`
+	Data         string    `description:"数据,分页存储"`
+	ModifyTime   time.Time `description:"最近修改日期"`
+	CreateTime   time.Time `description:"创建日期"`
+}
+
+// Update 更新 excel表格的sheet基础信息
+func (ExcelSheetData *ExcelSheetData) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(ExcelSheetData, cols...)
+
+	return
+}
+
+// AddExcelSheetData 新增excel表格的sheet基础信息
+func AddExcelSheetData(excelInfo *ExcelSheetData) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	// 表格信息入库
+	lastId, err := o.Insert(excelInfo)
+	if err != nil {
+		return
+	}
+	excelInfo.ExcelInfoId = int(lastId)
+
+	return
+}
+
+// GetSheetDataListBySheetIdListAndPage 根据sheet_id列表和页码获取所有的sheet数据详情
+func GetSheetDataListBySheetIdListAndPage(excelSheetIdList []int, page int) (items []*ExcelSheetData, err error) {
+	num := len(excelSheetIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *
+FROM excel_sheet_data WHERE 1=1 AND excel_sheet_id in (` + utils.GetOrmInReplace(num) + `) AND sort = ? `
+	_, err = o.Raw(sql, excelSheetIdList, page).QueryRows(&items)
+
+	return
+}
+
+// GetAllSheetDataListByExcelInfoId 根据表格id获取所有的sheet的所有数据详情
+func GetAllSheetDataListByExcelInfoId(excelInfoId int) (items []*ExcelSheetData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *
+FROM excel_sheet_data WHERE 1=1 AND excel_info_id = ? ORDER BY sort ASC `
+	_, err = o.Raw(sql, excelInfoId).QueryRows(&items)
+
+	return
+}

+ 45 - 0
models/data_manage/excel/request/excel.go

@@ -0,0 +1,45 @@
+package request
+
+// SaveExcelInfoReq 编辑表格请求
+type SaveExcelInfoReq struct {
+	ExcelInfoId     int         `description:"表格ID"`
+	ExcelName       string      `description:"表格名称"`
+	Source          int         `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
+	ExcelType       int         `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelImage      string      `description:"表格截图"`
+	ExcelClassifyId int         `description:"分类id"`
+	Content         string      `description:"Excel表格内容"`
+	TableData       interface{} `description:"自定义表格的数据内容"`
+	OpSheetList     []SheetOp   `description:"sheet操作"`
+}
+
+type SheetOp struct {
+	SheetIndex int    `description:"对应的sheet下标"`
+	SheetName  string `description:"对应的sheet名称"`
+	OpType     string `description:"操作类型,新增:add;替换:replace,追加:append"`
+}
+
+type AddEdb struct {
+	ExcelInfoId     int      `description:"表格ID"`
+	DateSequenceStr string   `description:"日期序列"`
+	DateSequenceVal []string `description:"日期序列的值列表"`
+	DataSequenceStr string   `description:"数据序列"`
+	DataSequenceVal []string `description:"数据序列的值列表"`
+	EdbName         string   `description:"指标名称"`
+	ClassifyId      int      `description:"分类id"`
+	Frequency       string   `description:"频率"`
+	Unit            string   `description:"单位"`
+}
+
+type EditEdb struct {
+	ExcelInfoId     int      `description:"表格ID"`
+	EdbInfoId       int      `description:"指标ID"`
+	DateSequenceStr string   `description:"日期序列"`
+	DateSequenceVal []string `description:"日期序列的值列表"`
+	DataSequenceStr string   `description:"数据序列"`
+	DataSequenceVal []string `description:"数据序列的值列表"`
+	EdbName         string   `description:"指标名称"`
+	ClassifyId      int      `description:"分类id"`
+	Frequency       string   `description:"频率"`
+	Unit            string   `description:"单位"`
+}

+ 38 - 0
models/data_manage/excel/request/excel_classify.go

@@ -0,0 +1,38 @@
+package request
+
+// AddExcelClassifyReq 添加excel分类请求
+type AddExcelClassifyReq struct {
+	ExcelClassifyName string `description:"分类名称"`
+	ParentId          int    `description:"父级id,第一级传0"`
+	Level             int    `description:"层级,第一级传0,其余传上一级的层级" json:"-"`
+	Source            int    `description:"1:excel插件的表格,2:自定义表格,3:混合表格,默认:1"`
+}
+
+// EditExcelClassifyReq 修改excel分类请求
+type EditExcelClassifyReq struct {
+	ExcelClassifyName string `description:"分类名称"`
+	ExcelClassifyId   int    `description:"分类名称"`
+}
+
+// MoveExcelClassifyReq 移动图表分类请求参数
+type MoveExcelClassifyReq struct {
+	ClassifyId       int `description:"分类id"`
+	ParentClassifyId int `description:"父级分类id"`
+	PrevClassifyId   int `description:"上一个兄弟节点分类id"`
+	NextClassifyId   int `description:"下一个兄弟节点分类id"`
+
+	ExcelInfoId     int `description:"excel表格ID"`
+	PrevExcelInfoId int `description:"上一个excel表格ID"`
+	NextExcelInfoId int `description:"下一个excel表格ID"`
+	Source          int
+}
+
+type DeleteExcelClassifyReq struct {
+	ExcelClassifyId int `description:"分类id"`
+	ExcelInfoId     int `description:"表格id"`
+}
+
+type ExcelClassifyDeleteCheckReq struct {
+	ExcelClassifyId int `description:"分类id"`
+	ExcelInfoId     int `description:"表格id"`
+}

+ 141 - 0
models/data_manage/excel/request/excel_info.go

@@ -0,0 +1,141 @@
+package request
+
+// MoveExcelInfoReq 移动excel表格请求
+type MoveExcelInfoReq struct {
+	ExcelClassifyId int `description:"excel表格分类id"`
+	ExcelInfoId     int `description:"excel表格ID"`
+	PrevExcelInfoId int `description:"上一个excel表格ID"`
+	NextExcelInfoId int `description:"下一个excel表格ID"`
+}
+
+// DeleteExcelInfoReq 删除表格请求
+type DeleteExcelInfoReq struct {
+	ExcelInfoId int `description:"表格ID"`
+}
+
+// AddExcelInfoReq 新增表格请求
+type AddExcelInfoReq struct {
+	ExcelInfoId     int         `description:"表格ID"`
+	ExcelName       string      `description:"表格名称"`
+	Source          int         `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
+	ExcelType       int         `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelImage      string      `description:"表格截图"`
+	ExcelClassifyId int         `description:"分类id"`
+	Content         string      `description:"Excel表格内容"`
+	TableData       interface{} `description:"自定义表格的数据内容"`
+}
+
+// EditExcelInfoReq 编辑表格请求
+type EditExcelInfoReq struct {
+	ExcelInfoId     int         `description:"ETA表格ID"`
+	ExcelType       int         `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName       string      `description:"表格名称"`
+	ExcelImage      string      `description:"表格截图"`
+	ExcelClassifyId int         `description:"分类id"`
+	Content         string      `description:"Excel表格内容"`
+	TableData       interface{} `description:"自定义表格的数据内容"`
+}
+
+// SetExcelInfoImageReq 设置excel表格图片请求
+type SetExcelInfoImageReq struct {
+	ExcelInfoId int    `description:"表格ID"`
+	ImageUrl    string `description:"表格图片地址"`
+}
+
+// AddExcelDraftReq 新增表格草稿请求
+type AddExcelDraftReq struct {
+	ExcelInfoId     int    `description:"ETA表格ID"`
+	ExcelName       string `description:"表格名称"`
+	ExcelClassifyId int    `description:"分类id"`
+	Content         string `description:"Excel表格内容"`
+}
+
+// CalculateReq 公式计算
+type CalculateReq struct {
+	CalculateFormula string             `description:"计算公式"`
+	TagMap           map[string]float64 `description:"标签与值的关系"`
+}
+
+// GetOtherEdbDateDataReq 获取其他指标的指定日期的数据
+type GetOtherEdbDateDataReq struct {
+	EdbInfoId int      `description:"指标id"`
+	SortType  string   `description:"如何排序,是正序还是倒序,枚举值:asc 正序,desc 倒序,不传默认倒序"`
+	DateList  []string `description:"日期列表,从小到大"`
+}
+
+// GetFutureDateDataReq 获取未来日期的数据
+type GetFutureDateDataReq struct {
+	EdbInfoIdList []int  `description:"指标id列表,从左至右,从上到下的顺序"`
+	DateType      int    `description:"日期类型,1:期数,2:截止日期"`
+	Num           int    `description:"需要添加的期数"`
+	StartDate     string `description:"开始日期"`
+	EndDate       string `description:"结束日期"`
+}
+
+// GetHistoryDateDataReq 获取历史日期的数据
+type GetHistoryDateDataReq struct {
+	EdbInfoIdList []int  `description:"指标id列表,从左至右,从上到下的顺序"`
+	Num           int    `description:"需要添加的期数"`
+	EndDate       string `description:"结束日期"`
+}
+
+// TableSaveReq 表格保存
+type TableSaveReq struct {
+	ExcelName       string      `description:"表格名称"`
+	ExcelImage      string      `description:"表格截图"`
+	ExcelClassifyId int         `description:"分类id"`
+	TableData       interface{} `description:"表格数据"`
+}
+
+// TableDataReq 自定义表格请求参数
+type TableDataReq struct {
+	EdbInfoIdList []int             `description:"指标id列表,从左至右,从上到下的顺序"`
+	Sort          int               `description:"日期排序,1:倒序,2:正序"`
+	Data          []EdbInfoData     `description:"数据列表"`
+	TextRowData   [][]ManualDataReq `description:"文本列表"`
+}
+
+// EdbInfoData 自定义表格的数据
+type EdbInfoData struct {
+	EdbInfoId        int             `description:"指标ID"`
+	Tag              string          `description:"标签"`
+	EdbName          string          `description:"指标名称"`
+	EdbNameEn        string          `description:"英文指标名称"`
+	EdbAliasName     string          `description:"指标别名"`
+	Frequency        string          `description:"频度"`
+	Unit             string          `description:"单位"`
+	UnitEn           string          `description:"英文单位"`
+	ClassifyId       int             `description:"所属分类" json:"-"`
+	IsJoinPermission int             `description:"是否加入权限管控,0:不加入;1:加入;默认:0" json:"-"`
+	HaveOperaAuth    bool            `description:"是否有数据权限,默认:false"`
+	Data             []ManualDataReq `description:"单元格数据列表"`
+}
+
+// ManualDataReq 自定义表格的单元格数据
+type ManualDataReq struct {
+	DataType            int               `description:"数据类型,1:普通的,2:插值法,3:手动输入,4:公式计算,5:预测值"`
+	DataTime            string            `description:"所属日期"`
+	DataTimeType        int               `description:"日期类型,1:实际日期;2:未来日期"`
+	ShowValue           string            `description:"展示值"`
+	Value               string            `description:"实际值(计算公式)"`
+	RelationEdbInfoList []RelationEdbInfo `description:"关联指标(计算公式中关联的指标,用于计算的时候去匹配)"`
+}
+
+// RelationEdbInfo 自定义表格中单元格的关联指标
+type RelationEdbInfo struct {
+	Tag string `description:"指标标签"`
+	Row string `description:"第几行"`
+}
+
+// CopyExcelInfoReq 复制表格请求
+type CopyExcelInfoReq struct {
+	ExcelInfoId     int    `description:"ETA表格ID"`
+	ExcelName       string `description:"表格名称"`
+	ExcelClassifyId int    `description:"分类id"`
+}
+
+// MarkEditExcel 标记编辑表格的请求数据
+type MarkEditExcel struct {
+	ExcelInfoId int `description:"表格id"`
+	Status      int `description:"标记状态,1:编辑中,2:编辑完成"`
+}

+ 166 - 0
models/data_manage/excel/request/mixed_table.go

@@ -0,0 +1,166 @@
+package request
+
+// 单元格的数据类型
+const (
+	DateDT                   = iota + 1 //日期
+	EdbDT                               // 2 指标类型
+	CustomTextDT                        // 3 自定义文本
+	InsertDataDT                        // 4 插值(插入指标值,表格上,自动判断日期和指标的交集位置,插入值)
+	PopInsertDataDT                     // 5 弹框插值(在表格上选择日期,然后空白单元格选择弹框并选择指标,插入该指标与该日期的值)
+	FormulateCalculateDataDT            // 6 公式计算(A+B这种)
+	InsertEdbCalculateDataDT            // 7 插入指标系统计算公式生成的值
+	DateCalculateDataDT                 // 8 日期计算
+)
+
+// 单元格的日期类型类型
+const (
+	CustomDateT = iota //手动输入日期
+	SystemDateT        // 系统日期
+	EdbDateDT          // 导入指标日期(指标库的最新日期)
+
+)
+
+// 单元格的日期类型类型
+const (
+	SystemCurrDateT      = iota + 1 //系统当前日期
+	SystemCalculateDateT            // 系统日期计算后的日期
+	SystemFrequencyDateT            // 导入系统日期相关的指定频率(所在周/旬/月/季/半年/年的最后/最早一天)
+)
+
+// MixedTableReq 混合表格保存请求参数
+type MixedTableReq struct {
+	CellRelation string                    `description:"单元格关系"`
+	Data         [][]MixedTableCellDataReq `description:"混合表格单元格参数"`
+}
+
+// MixedTableCellDataReq 混合表格单元格参数
+type MixedTableCellDataReq struct {
+	Uid             string      `description:"单元格唯一标识"`
+	DataType        int         `description:"数据类型,1:日期,2:指标,3:自定义文本,4:插值"`
+	DataTime        string      `description:"所属日期"`
+	DataTimeType    int         `description:"日期类型:0:手动输入日期(固定日期);1:导入系统日期;;3:导入指标日期(指标库的最新日期);"`
+	EdbInfoId       int         `description:"指标id"`
+	ShowValue       string      `description:"展示值"`
+	Value           string      `description:"实际值和配置"`
+	Extra           string      `description:"额外参数"`
+	ShowStyle       string      `description:"展示的样式配置"`
+	ShowFormatValue interface{} `description:"样式处理后的值"`
+}
+
+// CellRelationConf
+// @Description: 单元格的关系配置结构体
+type CellRelationConf struct {
+	CellRelation
+	//Type         int          `json:"type" description:"数据类型,跟MixedTableCellDataReq的DataType保持一致"`
+	//Key          string       `json:"key" description:"单元格的唯一标识"`
+	RelationDate CellRelation `json:"relation_date"`
+	RelationEdb  CellRelation `json:"relation_edb"`
+}
+
+// CellRelation
+// @Description: 单元格的关系结构体
+type CellRelation struct {
+	Type int    `json:"type" description:"数据类型,跟MixedTableCellDataReq的DataType保持一致"`
+	Key  string `json:"key" description:"单元格的唯一标识"`
+}
+
+// SystemDateConf
+// @Description: 系统导入日期配置
+type SystemDateConf struct {
+	Source             int    `description:"类型,1:导入系统日期;2:导入系统日期计算后的日期;3:导入系统日期相关的指定频率"`
+	CalculateNum       int    `description:"计算频度的数量"`
+	CalculateFrequency string `description:"计算频度"`
+	Frequency          string `description:"指定频度"`
+	Day                string `description:"指定日期"`
+}
+
+// EdbDateConf
+// @Description: 导入指标日期配置
+type EdbDateConf struct {
+	EdbInfoId int `description:"指标id"`
+	EdbDateChangeConf
+}
+
+// EdbDateExtraConf
+// @Description: 导入指标日期前移和日期变换
+type EdbDateChangeConf struct {
+	MoveForward int `description:"前移的期数"`
+	DateChange  []*EdbDateConfDateChange
+}
+
+type EdbDateConfDateChange struct {
+	Year         int
+	Month        int
+	Day          int
+	Frequency    string `description:"频度变换"`
+	FrequencyDay string `description:"频度的固定日期"`
+	ChangeType   int    `description:"日期变换类型1日期位移,2指定频率"`
+}
+
+// MixedDateCalculateReq 混合表格日期计算
+type MixedDateCalculateReq struct {
+	Formula  string                   `description:"计算公式"`
+	DateList []MixDateCalculateTagReq `description:"表格中的单元格"`
+}
+
+// MixDateCalculateConf 混合表格中的日期计算
+type MixDateCalculateConf struct {
+	Formula          string                `description:"计算公式"`
+	RelationCellList []MixDateCalculateTag `description:"表格中的单元格"`
+}
+
+// MixDateCalculateTag 混合表格中的日期计算的关联单元格
+type MixDateCalculateTag struct {
+	Uid string `description:"单元格唯一值"`
+	Tag string `description:"单元格对应标签"`
+}
+
+// MixDateCalculateTagReq 混合表格中的日期计算的关联单元格
+type MixDateCalculateTagReq struct {
+	Date string `description:"日期"`
+	Tag  string `description:"指标对应标签"`
+}
+
+// MixCellShowStyle 混合表格 单元格样式展示计算
+type MixCellShowStyle struct {
+	Pn int    `description:"小数点位数增加或减少,正数表述增加,负数表示减少" json:"pn"`
+	Nt string `description:"变换类型:number 小数点位数改变,percent百分比," json:"nt"`
+}
+
+type DateDataBeforeAfterReq struct {
+	EdbInfoId   int
+	Date        string
+	Num         int
+	MoveForward int `description:"前移的期数"`
+	DateChange  []*EdbDateConfDateChange
+}
+
+// CalculateConf
+// @Description: 计算公式
+type CalculateConf struct {
+	EdbInfoId     int         `description:"指标id"`
+	DataTime      string      `description:"所属日期,这个日期有传递的话,那么就取上下两期+自己的数据;没有传就默认最近5期的数据"`
+	Frequency     string      `description:"需要转换的频度"`
+	Formula       interface{} `description:"计算公式,默认是string,实际上还需要转成其他样式"`
+	Calendar      string      `description:"公历/农历"`
+	MoveType      int         `description:"移动方式:1:领先(默认),2:滞后"`
+	MoveFrequency string      `description:"移动频度"`
+	Source        int         `description:"1:累计值转月;2:累计值转季;3:同比值;4:同差值;5:N数值移动平均数计算;6:环比值;7:环差值;8:升频;9:降频;10:时间移位;11:超季节性;12:年化;13:累计值;14:累计值年初至今;15:指数修匀;16:日均值"`
+
+	EdbDateChangeConf
+}
+
+// BaseCalculateConf
+// @Description: 基础计算公式(A+B)
+type BaseCalculateConf struct {
+	Formula             string         `description:"计算公式,默认是string,实际上还需要转成其他样式"`
+	RelationEdbInfoList []RelationCell `description:"关联单元格(计算公式中关联的单元格,用于计算的时候去匹配)"`
+}
+
+// RelationCell
+// @Description: 关联单元格的信息
+type RelationCell struct {
+	Tag string `description:"指标标签"`
+	Row string `description:"第几行"`
+	Key string `json:"key" description:"单元格的唯一标识"`
+}

+ 14 - 0
models/data_manage/excel/response/excel_classify.go

@@ -0,0 +1,14 @@
+package response
+
+import (
+	"eta/eta_chart_lib/models/data_manage/excel"
+)
+
+type ExcelClassifyListResp struct {
+	AllNodes []*excel.ExcelClassifyItems
+}
+
+type ExcelClassifyDeleteCheckResp struct {
+	DeleteStatus int    `description:"检测状态:0:默认值,如果为0,继续走其他校验,1:该分类下关联图表不可删除,2:确认删除当前目录及包含的子目录吗"`
+	TipsMsg      string `description:"提示信息"`
+}

+ 91 - 0
models/data_manage/excel/response/excel_info.go

@@ -0,0 +1,91 @@
+package response
+
+import (
+	excel2 "eta/eta_chart_lib/models/data_manage/excel"
+	"eta/eta_chart_lib/models/data_manage/excel/request"
+	"eta/eta_chart_lib/services/excel"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+// AddExcelInfoResp 添加excel表格的返回
+type AddExcelInfoResp struct {
+	ExcelInfoId int    `description:"表格id"`
+	UniqueCode  string `description:"表格唯一编码"`
+}
+
+// ExcelListResp 表格列表返回数据
+type ExcelListResp struct {
+	Paging *paging.PagingItem
+	List   []*excel2.MyExcelInfoList
+}
+
+// ExcelTableDetailResp  excel表格详情
+type ExcelTableDetailResp struct {
+	UniqueCode string `description:"表格唯一code"`
+	ExcelImage string `description:"表格截图"`
+	ExcelName  string `description:"表格名称"`
+	TableInfo  excel.TableData
+	Config     ExcelTableDetailConfigResp
+}
+
+// ExcelTableDetailConfigResp
+// @Description: Excel表格的配置信息
+type ExcelTableDetailConfigResp struct {
+	FontSize int
+}
+
+// TableCellResp 单元格
+type TableCellResp struct {
+	DataType  int    `description:"数据类型,1:普通的,2:插值法,3:手动输入,4:公式计算"`
+	DataTime  string `description:"所属日期"`
+	ShowValue string `description:"展示的值"`
+	Value     string `description:"实际值(计算公式)"`
+}
+
+type TableDataItem struct {
+	EdbInfoId int                     `description:"指标id"`
+	Data      []request.ManualDataReq `description:"数据列表"`
+}
+
+// TableDetailResp  excel表格详情
+type TableDetailResp struct {
+	ExcelInfo excel2.ExcelInfo     `description:"表格基础信息"`
+	TableData request.TableDataReq `description:"表格内容"`
+}
+
+// ExcelInfoDetail excel表格详情(前端使用)
+type ExcelInfoDetail struct {
+	ExcelInfoId      int                   `orm:"column(excel_info_id);pk"`
+	Source           int                   `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
+	ExcelType        int                   `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName        string                `description:"表格名称"`
+	UniqueCode       string                `description:"表格唯一编码"`
+	ExcelClassifyId  int                   `description:"表格分类id"`
+	SysUserId        int                   `description:"操作人id"`
+	SysUserRealName  string                `description:"操作人真实姓名"`
+	Content          string                `description:"表格内容"`
+	ExcelImage       string                `description:"表格图片"`
+	FileUrl          string                `description:"表格下载地址"`
+	Sort             int                   `description:"排序字段,数字越小越排前面"`
+	IsDelete         int                   `description:"是否删除,0:未删除,1:已删除"`
+	ModifyTime       time.Time             `description:"最近修改日期"`
+	CreateTime       time.Time             `description:"创建日期"`
+	TableData        interface{}           `description:"表格内容"`
+	Button           ExcelInfoDetailButton `description:"操作权限"`
+	CanEdit          bool                  `description:"是否可编辑"`
+	Editor           string                `description:"编辑人"`
+	IsJoinPermission int                   `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth    bool                  `description:"是否有数据权限"`
+}
+
+// ExcelInfoDetailButton 操作按钮
+type ExcelInfoDetailButton struct {
+	RefreshButton    bool `description:"是否可刷新"`
+	CopyButton       bool `description:"是否可另存为"`
+	DownloadButton   bool `description:"是否可下载"`
+	OpButton         bool `description:"是否可编辑"`
+	DeleteButton     bool `description:"是否可删除"`
+	OpEdbButton      bool `description:"是否可生成指标"`
+	RefreshEdbButton bool `description:"是否可刷新指标"`
+}

+ 34 - 0
models/data_manage/excel/response/sheet.go

@@ -0,0 +1,34 @@
+package response
+
+import (
+	"eta/eta_chart_lib/models/data_manage/excel"
+	"time"
+)
+
+// FindExcelInfoResp 根据名称获取excel的信息
+type FindExcelInfoResp struct {
+	IsFind    bool               `description:"是否存在同名文件"`
+	ExcelInfo FindExcelInfo      `description:"表格详情"`
+	SheetList []*excel.SheetItem `description:"sheet列表"`
+}
+
+// FindExcelInfo excel的数据详情
+type FindExcelInfo struct {
+	ExcelInfoId     int                   `orm:"column(excel_info_id);pk"`
+	Source          int                   `description:"表格来源,1:excel插件的表格,2:自定义表格,默认:1"`
+	ExcelType       int                   `description:"表格类型,1:指标列,2:日期列,默认:1"`
+	ExcelName       string                `description:"表格名称"`
+	UniqueCode      string                `description:"表格唯一编码"`
+	ExcelClassifyId int                   `description:"表格分类id"`
+	SysUserId       int                   `description:"操作人id"`
+	SysUserRealName string                `description:"操作人真实姓名"`
+	ExcelImage      string                `description:"表格图片"`
+	FileUrl         string                `description:"表格下载地址"`
+	Sort            int                   `description:"排序字段,数字越小越排前面"`
+	ModifyTime      time.Time             `description:"最近修改日期"`
+	CreateTime      time.Time             `description:"创建日期"`
+	Button          ExcelInfoDetailButton `description:"操作权限"`
+	CanEdit         bool                  `description:"是否可编辑"`
+	Editor          string                `description:"编辑人"`
+	HaveOperaAuth   bool                  `description:"是否有数据权限,默认:false"`
+}

+ 2 - 0
models/request/excel_info.go

@@ -11,9 +11,11 @@ type EdbInfoData struct {
 	EdbInfoId    int             `description:"指标ID"`
 	Tag          string          `description:"标签"`
 	EdbName      string          `description:"指标名称"`
+	EdbNameEn    string          `description:"英文指标名称"`
 	EdbAliasName string          `description:"指标别名"`
 	Frequency    string          `description:"频度"`
 	Unit         string          `description:"单位"`
+	UnitEn       string          `description:"英文单位"`
 	Data         []ManualDataReq `description:"单元格数据列表"`
 }
 

+ 1117 - 0
services/data/excel/excel_info.go

@@ -0,0 +1,1117 @@
+package excel
+
+import (
+	"errors"
+	"eta/eta_chart_lib/models"
+	"eta/eta_chart_lib/models/data_manage"
+	"eta/eta_chart_lib/models/request"
+	"eta/eta_chart_lib/services/data"
+	"eta/eta_chart_lib/utils"
+	"fmt"
+	"sort"
+	"time"
+)
+
+// GetFirstEdbDataList 获取第一列的数据
+func GetFirstEdbDataList(edbInfo *data_manage.EdbInfo, num int, manualDateList []string) (resultDataList []request.ManualDataReq, err error) {
+	var dataList []*models.EdbDataList
+	switch edbInfo.EdbInfoType {
+	case 0:
+		dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
+	case 1:
+		_, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
+	default:
+		err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
+
+		return
+	}
+
+	// 获取需要的期数
+	lenData := len(dataList)
+	if lenData <= 0 {
+		return
+	}
+
+	tmpManualDateNum := 0 // 手工数据的期数
+	lenManualDate := len(manualDateList)
+	if lenManualDate > 0 {
+		sortDateList := manualDateList
+		baseDateList := utils.StrArr{}
+		baseDateList = append(baseDateList, sortDateList...)
+		sort.Sort(baseDateList)
+		sortDateList = append([]string{}, baseDateList...)
+
+		lastData := dataList[lenData-1]
+		lastDataDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		// 遍历倒序后的日期,然后匹配在实际数据之后日期的个数
+		for _, tmpDateStr := range sortDateList {
+			tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			if tmpDate.After(lastDataDate) {
+				tmpManualDateNum++
+				continue
+			}
+
+			break
+		}
+
+	}
+
+	// 需要的期数减去手工数据的期数,这才是A列指标需要的数据
+	num = num - tmpManualDateNum
+	if num > lenData {
+		num = lenData
+	}
+
+	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
+	for i := 1; i <= num; i++ {
+		dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
+		dataType := 1
+		// 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
+		if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
+			dataType = 5
+		}
+
+		resultDataList = append(resultDataList, request.ManualDataReq{
+			DataType:     dataType,
+			DataTime:     dataList[lenData-i].DataTime,
+			ShowValue:    fmt.Sprint(dataList[lenData-i].Value),
+			Value:        fmt.Sprint(dataList[lenData-i].Value),
+			DataTimeType: 1,
+		})
+	}
+
+	return
+}
+
+// GetOtherEdbDataList 获取其他列的数据
+func GetOtherEdbDataList(edbInfo *data_manage.EdbInfo, dateList []string) (resultDataList []request.ManualDataReq, err error) {
+	lenDate := len(dateList)
+	if lenDate <= 0 {
+		return
+	}
+	sortDateList := dateList
+	baseDateList := utils.StrArr{}
+	baseDateList = append(baseDateList, sortDateList...)
+	sort.Sort(baseDateList)
+	sortDateList = append([]string{}, baseDateList...)
+
+	endDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[0], time.Local)
+	if err != nil {
+		return
+	}
+
+	firstDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[lenDate-1], time.Local)
+	if err != nil {
+		return
+	}
+
+	var dataList []*models.EdbDataList
+	switch edbInfo.EdbInfoType {
+	case 0:
+		dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
+	case 1:
+		_, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
+	default:
+		err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
+
+		return
+	}
+
+	// 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
+	baseDataList := make([]*models.EdbDataList, 0)
+	var lastData *models.EdbDataList
+	var isInsert bool
+	for _, data := range dataList {
+		tmpDate := data.DataTime
+		tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		if tmpDateTime.Before(firstDateTime) {
+			lastData = data
+			continue
+		}
+
+		// 如果是第一次写入数据
+		if !isInsert && lastData != nil {
+			baseDataList = append(baseDataList, lastData)
+		}
+
+		if tmpDateTime.After(endDateTime) {
+			baseDataList = append(baseDataList, data)
+			break
+		}
+		baseDataList = append(baseDataList, data)
+		isInsert = true
+	}
+
+	// 实际数据的日期map
+	realValMap := make(map[string]string)
+	for _, v := range baseDataList {
+		realValMap[v.DataTime] = v.DataTime
+	}
+
+	// 插值法处理
+	handleDataMap := make(map[string]float64)
+	err = data.HandleDataByLinearRegression(baseDataList, handleDataMap)
+	if err != nil {
+		return
+	}
+
+	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
+	// 对于不存在的数据做补充
+	for _, date := range sortDateList {
+		dataType := 1
+		if _, ok := realValMap[date]; !ok {
+			dataType = 2
+		} else {
+			dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
+			// 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
+			if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
+				dataType = 5
+			}
+		}
+		var value, showValue string
+		if tmpVal, ok := handleDataMap[date]; ok {
+			value = fmt.Sprint(tmpVal)
+			showValue = value
+		} else {
+			dataType = 3
+		}
+		resultDataList = append(resultDataList, request.ManualDataReq{
+			DataType:  dataType,
+			DataTime:  date,
+			ShowValue: showValue,
+			Value:     value,
+		})
+	}
+
+	return
+}
+
+// GetFirstHistoryEdbDataList 获取指标的历史的数据
+func GetFirstHistoryEdbDataList(edbInfo *data_manage.EdbInfo, num int, endDate string) (resultDataList []request.ManualDataReq, err error) {
+	endDateTime, err := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
+	if err != nil {
+		return
+	}
+
+	var dataList []*models.EdbDataList
+	switch edbInfo.EdbInfoType {
+	case 0:
+		dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, endDate)
+	case 1:
+		_, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, endDate, true)
+	default:
+		err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
+
+		return
+	}
+
+	// 获取需要的期数
+	lenData := len(dataList)
+	if lenData <= 0 {
+		return
+	}
+	lastData := dataList[lenData-1]
+	lastDataDateTime, err := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
+	if err != nil {
+		return
+	}
+	if endDateTime.Equal(lastDataDateTime) || lastDataDateTime.After(endDateTime) {
+		dataList = dataList[:lenData-1]
+		lenData = len(dataList)
+	}
+	if num > lenData {
+		num = lenData
+	}
+
+	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
+	for i := 1; i <= num; i++ {
+		dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
+		dataType := 1
+		// 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
+		if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
+			dataType = 5
+		}
+
+		resultDataList = append(resultDataList, request.ManualDataReq{
+			DataType:  dataType,
+			DataTime:  dataList[lenData-i].DataTime,
+			ShowValue: fmt.Sprint(dataList[lenData-i].Value),
+			Value:     fmt.Sprint(dataList[lenData-i].Value),
+		})
+	}
+
+	return
+}
+
+//type TableDataConfig struct {
+//	EdbInfoIdList    []int                     `description:"指标id列表,从左至右,从上到下的顺序"`
+//	Sort             int                       `description:"日期排序,0:倒序,1:正序"`
+//	Data             []ManualData              `description:"数据列表"`
+//	Num              int                       `description:"实际数据需要列出来的期数"`
+//	RemoveDate       []string                  `description:"不展示的日期"`
+//	ManualDate       []string                  `description:"手动配置的日期(未来的日期)"`
+//	TableEdbInfoList []TableEdbInfo            `description:"表格内指标信息"`
+//	TextRowData      [][]request.ManualDataReq `description:"文本列表"`
+//}
+//
+//type TableEdbInfo struct {
+//	EdbInfoId    int    `description:"指标ID"`
+//	Tag          string `description:"标签"`
+//	EdbName      string `description:"指标名称"`
+//	EdbAliasName string `description:"指标别名"`
+//	Frequency    string `description:"频度"`
+//	Unit         string `description:"单位"`
+//}
+//
+//type ManualData struct {
+//	DataType            int                       `description:"数据类型,1:普通的,2:插值法,3:手动输入,4:公式计算"`
+//	DataTime            string                    `description:"所属日期"`
+//	DataTimeType        int                       `description:"日期类型,1:实际日期;2:未来日期"`
+//	ShowValue           string                    `description:"展示值"`
+//	Value               string                    `description:"实际值(计算公式)"`
+//	EdbInfoId           int                       `description:"指标id"`
+//	Tag                 string                    `description:"下标"`
+//	RelationEdbInfoList []request.RelationEdbInfo `description:"关联指标(计算公式中关联的指标,用于计算的时候去匹配)"`
+//}
+//
+//func GetTableDataConfig(reqData request.TableDataReq) (tableDataConfig TableDataConfig, err error) {
+//	// 指标数据
+//	tableDataConfig.EdbInfoIdList = reqData.EdbInfoIdList
+//	tableDataConfig.Sort = reqData.Sort
+//
+//	// 开始日期
+//	var startDate string
+//	// A列的指标id
+//	var firstEdbInfoId int
+//	// 手工操作的数据列
+//	manualDataList := make([]ManualData, 0)
+//	// 指标配置列表
+//	tableEdbInfoList := make([]TableEdbInfo, 0)
+//
+//	// 第一列的日期map
+//	firstDateMap := make(map[string]string)
+//	manualDateMap := make(map[string]string)
+//
+//	for _, v := range reqData.Data {
+//		// 指标信息
+//		tmpTableEdbInfo := TableEdbInfo{
+//			EdbInfoId:    v.EdbInfoId,
+//			Tag:          v.Tag,
+//			EdbName:      v.EdbName,
+//			EdbAliasName: v.EdbAliasName,
+//			Frequency:    v.Frequency,
+//			Unit:         v.Unit,
+//		}
+//		tableEdbInfoList = append(tableEdbInfoList, tmpTableEdbInfo)
+//
+//		// 确定数据A列
+//		if v.Tag == "A" {
+//			firstEdbInfoId = v.EdbInfoId
+//			lenData := len(v.Data)
+//			if lenData <= 0 {
+//				err = errors.New("A列不能为空")
+//				return
+//			}
+//			index := 0
+//			if reqData.Sort == 1 {
+//				// 倒序
+//				index = lenData - 1
+//			}
+//
+//			startDate = v.Data[index].DataTime
+//
+//			// 存在的日期列表
+//			for _, data := range v.Data {
+//				firstDateMap[data.DataTime] = data.DataTime
+//
+//				if data.DataTimeType == 2 {
+//					manualDateMap[data.DataTime] = data.DataTime
+//				}
+//			}
+//		}
+//
+//		for _, data := range v.Data {
+//			if data.DataType == 3 || data.DataType == 4 {
+//				tmpManualData := ManualData{
+//					DataType:            data.DataType,
+//					DataTime:            data.DataTime,
+//					DataTimeType:        data.DataTimeType,
+//					ShowValue:           data.ShowValue,
+//					Value:               data.Value,
+//					EdbInfoId:           v.EdbInfoId,
+//					Tag:                 v.Tag,
+//					RelationEdbInfoList: data.RelationEdbInfoList,
+//				}
+//				if data.DataType == 4 {
+//					tmpManualData.ShowValue = ``
+//				}
+//				manualDataList = append(manualDataList, tmpManualData)
+//			}
+//		}
+//	}
+//
+//	// 实际期数
+//	var num int
+//	removeDate := make([]string, 0)
+//
+//	// 获取期数
+//	{
+//		firstDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//
+//		edbInfo, tmpErr := data_manage.GetEdbInfoById(firstEdbInfoId)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//
+//		var firstDataList []*models.EdbDataList
+//		switch edbInfo.EdbInfoType {
+//		case 0:
+//			firstDataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
+//		case 1:
+//			_, firstDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
+//		default:
+//			err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
+//			return
+//		}
+//
+//		// 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
+//		baseDataList := make([]*models.EdbDataList, 0)
+//		for _, data := range firstDataList {
+//			tmpDate := data.DataTime
+//			tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			if tmpDateTime.Before(firstDateTime) {
+//				continue
+//			}
+//			baseDataList = append(baseDataList, data)
+//		}
+//
+//		// 开始日期到现在的实际期数
+//		num = len(baseDataList)
+//
+//		// 筛选出需要删除的日期
+//		for _, tmpData := range baseDataList {
+//			//firstDateMap{}
+//			if _, ok := firstDateMap[tmpData.DataTime]; !ok {
+//				removeDate = append(removeDate, tmpData.DataTime)
+//			}
+//		}
+//	}
+//
+//	tableDataConfig.Num = num
+//	tableDataConfig.RemoveDate = removeDate
+//	tableDataConfig.Data = manualDataList
+//	tableDataConfig.TableEdbInfoList = tableEdbInfoList
+//	tableDataConfig.TextRowData = reqData.TextRowData
+//
+//	return
+//}
+//
+//func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp request.TableDataReq, err error) {
+//	// 没有选择指标的情况下,直接返回吧
+//	if len(tableDataConfig.EdbInfoIdList) <= 0 {
+//		return
+//	}
+//
+//	// 实际期数没有的情况下,直接返回吧
+//	if tableDataConfig.Num <= 0 {
+//		return
+//	}
+//
+//	// 获取所有的指标信息
+//	edbInfoMap := make(map[int]*data_manage.EdbInfo)
+//	edbInfoIdList := make([]int, 0)
+//	// 标签与指标id的map
+//	tagEdbInfoIdMap := make(map[string]int)
+//	{
+//		for _, tableEdbInfo := range tableDataConfig.TableEdbInfoList {
+//			edbInfoIdList = append(edbInfoIdList, tableEdbInfo.EdbInfoId)
+//			tagEdbInfoIdMap[tableEdbInfo.Tag] = tableEdbInfo.EdbInfoId
+//		}
+//		edbInfoList, tmpErr := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//		for _, v := range edbInfoList {
+//			edbInfoMap[v.EdbInfoId] = v
+//		}
+//	}
+//
+//	manualDateMap := make(map[string]string, 0)
+//	manualDateList := make([]string, 0)
+//	for _, v := range tableDataConfig.Data {
+//		if _, ok := manualDateMap[v.DataTime]; !ok {
+//			manualDateMap[v.DataTime] = v.DataTime
+//			manualDateList = append(manualDateList, v.DataTime)
+//		}
+//	}
+//
+//	// 寻找A列的数据列表
+//	firstEdbInfo, ok := edbInfoMap[tableDataConfig.TableEdbInfoList[0].EdbInfoId]
+//	if !ok {
+//		err = errors.New("找不到A列指标")
+//		return
+//	}
+//	baseFirstEdbInfoDataList, err := GetFirstEdbDataList(firstEdbInfo, tableDataConfig.Num, manualDateList)
+//	if err != nil {
+//		return
+//	}
+//	// A列找不到数据,那么就直接返回吧
+//	if len(baseFirstEdbInfoDataList) <= 0 {
+//		return
+//	}
+//
+//	firstEdbInfoDataList := make([]request.ManualDataReq, 0)
+//	if tableDataConfig.RemoveDate != nil && len(tableDataConfig.RemoveDate) > 0 {
+//		for _, v := range baseFirstEdbInfoDataList {
+//			if utils.InArrayByStr(tableDataConfig.RemoveDate, v.DataTime) {
+//				continue
+//			}
+//			firstEdbInfoDataList = append(firstEdbInfoDataList, v)
+//		}
+//	} else {
+//		firstEdbInfoDataList = baseFirstEdbInfoDataList
+//	}
+//	if len(firstEdbInfoDataList) <= 0 {
+//		return
+//	}
+//	// 实际数据的最后一天
+//	lastRealDateTime, err := time.ParseInLocation(utils.FormatDate, firstEdbInfoDataList[0].DataTime, time.Local)
+//	if err != nil {
+//		return
+//	}
+//
+//	dateMap := make(map[string]string)
+//	dateList := make([]string, 0)
+//	edbInfoIdDateDataMap := make(map[int]map[string]request.ManualDataReq)
+//	firstDateDataMap := make(map[string]request.ManualDataReq)
+//	for _, v := range firstEdbInfoDataList {
+//		dateList = append(dateList, v.DataTime)
+//		dateMap[v.DataTime] = v.DataTime
+//		firstDateDataMap[v.DataTime] = v
+//	}
+//
+//	// 将手工数据的日期填补进去(未来的日期,过去的就不管了)
+//	for _, manualData := range tableDataConfig.Data {
+//		if !utils.InArrayByStr(dateList, manualData.DataTime) {
+//			tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, manualData.DataTime, time.Local)
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			if tmpDateTime.After(lastRealDateTime) {
+//				dateList = append(dateList, manualData.DataTime)
+//			}
+//		}
+//	}
+//
+//	edbInfoIdDateDataMap[firstEdbInfo.EdbInfoId] = firstDateDataMap
+//
+//	for k, edbInfoId := range tableDataConfig.EdbInfoIdList {
+//		if k == 0 {
+//			continue
+//		}
+//
+//		tmpEdbInfo, ok := edbInfoMap[edbInfoId]
+//		if !ok {
+//			err = errors.New("找不到A列指标")
+//			return
+//		}
+//		otherDataList, tmpErr := GetOtherEdbDataList(tmpEdbInfo, dateList)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//
+//		tmpDateDataMap := make(map[string]request.ManualDataReq)
+//		for _, v := range otherDataList {
+//			tmpDateDataMap[v.DataTime] = v
+//		}
+//		edbInfoIdDateDataMap[tmpEdbInfo.EdbInfoId] = tmpDateDataMap
+//	}
+//
+//	for _, v := range tableDataConfig.Data {
+//		tmpDate := v.DataTime
+//		if _, ok := dateMap[tmpDate]; !ok {
+//			dateMap[v.DataTime] = tmpDate
+//		}
+//
+//		edbInfoIdDateData, ok := edbInfoIdDateDataMap[v.EdbInfoId]
+//		if !ok {
+//			edbInfoIdDateData = make(map[string]request.ManualDataReq)
+//		}
+//
+//		// 判断是否存在该日期的数据(不存在,那么插入数据吧,存在就不管了)
+//		if _, ok = edbInfoIdDateData[tmpDate]; !ok {
+//			edbInfoIdDateData[tmpDate] = request.ManualDataReq{
+//				DataType:  v.DataType,
+//				DataTime:  v.DataTime,
+//				ShowValue: v.ShowValue,
+//				Value:     v.Value,
+//			}
+//		}
+//		edbInfoIdDateDataMap[v.EdbInfoId] = edbInfoIdDateData
+//	}
+//
+//	// 获取数据的日期排序
+//	sortDateTimeList := make([]time.Time, 0)
+//	{
+//		sortDateList := dateList
+//		if tableDataConfig.Sort == 1 {
+//			baseDateList := utils.StrArr{}
+//			baseDateList = append(baseDateList, sortDateList...)
+//			sort.Sort(baseDateList)
+//			sortDateList = append([]string{}, baseDateList...)
+//		} else {
+//			sort.Strings(sortDateList)
+//		}
+//		for _, v := range sortDateList {
+//			tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, v, time.Local)
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			sortDateTimeList = append(sortDateTimeList, tmpDateTime)
+//		}
+//	}
+//
+//	// 数据处理,处理成表格的数据格式
+//	tableDataMap, textRowListDataResp := handleTable(tagEdbInfoIdMap, lastRealDateTime, sortDateTimeList, edbInfoIdDateDataMap, tableDataConfig.Data, tableDataConfig.TextRowData)
+//
+//	data := make([]request.EdbInfoData, 0)
+//	for _, tableEdbInfo := range tableDataConfig.TableEdbInfoList {
+//		tagEdbInfoIdMap[tableEdbInfo.Tag] = tableEdbInfo.EdbInfoId
+//
+//		manualDataReqList := make([]request.ManualDataReq, 0)
+//		tmpEdbInfoData := request.EdbInfoData{
+//			EdbInfoId:    tableEdbInfo.EdbInfoId,
+//			Tag:          tableEdbInfo.Tag,
+//			EdbName:      tableEdbInfo.EdbName,
+//			EdbAliasName: tableEdbInfo.EdbAliasName,
+//			Frequency:    tableEdbInfo.Frequency,
+//			Unit:         tableEdbInfo.Unit,
+//			Data:         manualDataReqList,
+//		}
+//
+//		edbInfo, ok := edbInfoMap[tableEdbInfo.EdbInfoId]
+//		if ok {
+//			tmpEdbInfoData.EdbName = edbInfo.EdbName
+//			tmpEdbInfoData.Frequency = edbInfo.Frequency
+//			tmpEdbInfoData.Unit = edbInfo.Unit
+//		}
+//
+//		for index, dateTime := range sortDateTimeList {
+//			dataTimeType := 1
+//			if dateTime.After(lastRealDateTime) {
+//				dataTimeType = 2
+//			}
+//			tmpDateTimeStr := dateTime.Format(utils.FormatDate)
+//
+//			rowData, ok := tableDataMap[index+1]
+//			if !ok {
+//				manualDataReqList = append(manualDataReqList, request.ManualDataReq{
+//					DataType:            3,
+//					DataTime:            tmpDateTimeStr,
+//					DataTimeType:        dataTimeType,
+//					ShowValue:           "",
+//					Value:               "",
+//					RelationEdbInfoList: nil,
+//				})
+//				continue
+//			}
+//
+//			tmpData, ok := rowData[tableEdbInfo.Tag]
+//			if !ok {
+//				manualDataReqList = append(manualDataReqList, request.ManualDataReq{
+//					DataType:            3,
+//					DataTime:            tmpDateTimeStr,
+//					DataTimeType:        dataTimeType,
+//					ShowValue:           "",
+//					Value:               "",
+//					RelationEdbInfoList: nil,
+//				})
+//				continue
+//			}
+//
+//			tmpData.DataTimeType = dataTimeType
+//			manualDataReqList = append(manualDataReqList, tmpData)
+//		}
+//
+//		tmpEdbInfoData.Data = manualDataReqList
+//
+//		data = append(data, tmpEdbInfoData)
+//	}
+//
+//	resultResp = request.TableDataReq{
+//		EdbInfoIdList: edbInfoIdList,
+//		Sort:          tableDataConfig.Sort,
+//		TextRowData:   textRowListDataResp,
+//		Data:          data,
+//	}
+//
+//	return
+//}
+//
+//func handleTable(tagEdbInfoIdMap map[string]int, lastRealDateTime time.Time, sortDateTimeList []time.Time, edbInfoIdDateDataMap map[int]map[string]request.ManualDataReq, manualDataList []ManualData, textRowData [][]request.ManualDataReq) (tableDataMap map[int]map[string]request.ManualDataReq, textRowListDataResp [][]request.ManualDataReq) {
+//	tagList := make([]string, 0)
+//	for tag := range tagEdbInfoIdMap {
+//		tagList = append(tagList, tag)
+//	}
+//	sort.Strings(tagList)
+//
+//	tableDataMap = make(map[int]map[string]request.ManualDataReq) //行、列数据
+//
+//	// 日期与行的关系
+//	dateIndexMap := make(map[string]int)
+//
+//	for k, dateTime := range sortDateTimeList {
+//		rowDataMap := make(map[string]request.ManualDataReq)
+//
+//		dataTimeType := 1
+//		if dateTime.After(lastRealDateTime) {
+//			dataTimeType = 2
+//		}
+//
+//		tmpDateTimeStr := dateTime.Format(utils.FormatDate)
+//		dateIndexMap[tmpDateTimeStr] = k + 1
+//
+//		for _, tag := range tagList {
+//			edbInfoId, ok := tagEdbInfoIdMap[tag]
+//			if !ok { // 没有找到该指标的映射关系,那么就用空串填补
+//				rowDataMap[tag] = request.ManualDataReq{
+//					DataType:            3,
+//					DataTime:            tmpDateTimeStr,
+//					DataTimeType:        dataTimeType,
+//					ShowValue:           "",
+//					Value:               "",
+//					RelationEdbInfoList: nil,
+//				}
+//				continue
+//			}
+//
+//			// 获取指标的数据map
+//			dateDataMap, ok := edbInfoIdDateDataMap[edbInfoId]
+//			if !ok { // 没有找到该指标的数据,那么就用空串填补
+//				rowDataMap[tag] = request.ManualDataReq{
+//					DataType:            3,
+//					DataTime:            tmpDateTimeStr,
+//					DataTimeType:        dataTimeType,
+//					ShowValue:           "",
+//					Value:               "",
+//					RelationEdbInfoList: nil,
+//				}
+//				continue
+//			}
+//
+//			// 获取指标该日期的数据
+//			tmpData, ok := dateDataMap[tmpDateTimeStr]
+//			if !ok { // 该指标没有找到对应日期的数据,那么就用空串填补
+//				rowDataMap[tag] = request.ManualDataReq{
+//					DataType:            3,
+//					DataTime:            tmpDateTimeStr,
+//					DataTimeType:        dataTimeType,
+//					ShowValue:           "",
+//					Value:               "",
+//					RelationEdbInfoList: nil,
+//				}
+//				continue
+//			}
+//			tmpData.DataTimeType = dataTimeType
+//			rowDataMap[tag] = tmpData
+//		}
+//		tableDataMap[k+1] = rowDataMap
+//	}
+//
+//	// 替换手工设置的数据
+//	for _, manualData := range manualDataList {
+//		// 找不到该日期,说明这日期过期了,不处理
+//		index, ok := dateIndexMap[manualData.DataTime]
+//		if !ok {
+//			continue
+//		}
+//
+//		// 获取对应行的数据
+//		rowDataMap, ok := tableDataMap[index]
+//		if !ok {
+//			continue
+//		}
+//
+//		// 找到对应的单元格
+//		tmpData, ok := rowDataMap[manualData.Tag]
+//		if !ok {
+//			continue
+//		}
+//
+//		// 如果该单元格实际有数据(包含预测值),或者插值法补充了数据的话,那么就不用手动填入的数据
+//		if utils.InArrayByInt([]int{1, 2, 5}, tmpData.DataType) {
+//			continue
+//		}
+//
+//		// 手工填写的数字
+//		if tmpData.DataType == 3 {
+//			tmpData.ShowValue = manualData.ShowValue
+//			tmpData.Value = manualData.Value
+//			tableDataMap[index][manualData.Tag] = tmpData
+//
+//			//edbInfoIdDateDataMap[manualData.EdbInfoId][manualData.DataTime] = tmpData
+//			continue
+//		}
+//
+//		// 公式
+//		tmpData.DataType = manualData.DataType
+//		tmpData.ShowValue = ``
+//		tmpData.Value = manualData.Value
+//		tmpData.RelationEdbInfoList = manualData.RelationEdbInfoList
+//		tableDataMap[index][manualData.Tag] = tmpData
+//
+//	}
+//
+//	// 文本行的列表插入
+//	lenTableData := len(tableDataMap)
+//
+//	// 文本行第一列的数据列表(可能多行)
+//	firstColTextRowList := make([]request.ManualDataReq, 0)
+//	// 参与计算的文本行列表数据
+//	tmpTextRowList := make([][]request.ManualDataReq, 0)
+//	for k, textRowList := range textRowData {
+//		// 判断列数是否匹配,不匹配的话那么过滤
+//		if len(tagList)+1 != len(textRowList) {
+//			continue
+//		}
+//		rowDataMap := make(map[string]request.ManualDataReq)
+//		tmpTextRow := make([]request.ManualDataReq, 0)
+//		for index, textRow := range textRowList {
+//			// 移除第一列,因为第一列是日期列
+//			if index == 0 {
+//				firstColTextRowList = append(firstColTextRowList, textRow)
+//				continue
+//			}
+//			rowDataMap[tagList[index-1]] = textRow
+//			tmpTextRow = append(tmpTextRow, textRow)
+//		}
+//
+//		tableDataMap[lenTableData+k+1] = rowDataMap
+//		tmpTextRowList = append(tmpTextRowList, tmpTextRow)
+//	}
+//
+//	// 参与计算的单元格
+//	calculateCellMap := make(map[string]string)
+//
+//	// 计算手工填写的单元格
+//	for _, manualData := range manualDataList {
+//		// 找不到该日期,说明这日期过期了,不处理
+//		index, ok := dateIndexMap[manualData.DataTime]
+//		if !ok {
+//			continue
+//		}
+//
+//		// 获取对应行的数据
+//		rowDataMap, ok := tableDataMap[index]
+//		if !ok {
+//			continue
+//		}
+//
+//		// 找到对应的单元格
+//		colData, ok := rowDataMap[manualData.Tag]
+//		if !ok {
+//			continue
+//		}
+//
+//		// 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
+//		if colData.DataType != 4 {
+//			continue
+//		}
+//
+//		tagMap := make(map[string]float64)
+//		lenRelation := len(colData.RelationEdbInfoList)
+//		replaceNum := 0
+//		for _, relation := range colData.RelationEdbInfoList {
+//			relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
+//			valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
+//			if tmpErr != nil {
+//				continue
+//			}
+//			tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
+//			if tmpErr != nil {
+//				continue
+//			}
+//			tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
+//			replaceNum++
+//		}
+//
+//		// 如果替换的数据与关联的不一致,那么就退出当前循环
+//		if lenRelation != replaceNum {
+//			continue
+//		}
+//
+//		// 计算
+//		val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
+//		// 计算失败,退出循环
+//		if err != nil {
+//			continue
+//		}
+//		// 重新赋值
+//		colData.ShowValue = val
+//		tableDataMap[index][manualData.Tag] = colData
+//
+//	}
+//
+//	// 计算文本行的单元格
+//	for k, textRow := range tmpTextRowList {
+//		// 获取对应行的数据
+//		index := lenTableData + k + 1
+//		rowDataMap, ok := tableDataMap[index]
+//		if !ok {
+//			continue
+//		}
+//
+//		for colIndex := range textRow {
+//			currTag := tagList[colIndex]
+//			// 找到对应的单元格
+//			colData, ok := rowDataMap[currTag]
+//			if !ok {
+//				continue
+//			}
+//
+//			// 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
+//			if colData.DataType != 4 {
+//				continue
+//			}
+//
+//			tagMap := make(map[string]float64)
+//			lenRelation := len(colData.RelationEdbInfoList)
+//			replaceNum := 0
+//			for _, relation := range colData.RelationEdbInfoList {
+//				relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
+//				valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
+//				if tmpErr != nil {
+//					continue
+//				}
+//				tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
+//				if tmpErr != nil {
+//					continue
+//				}
+//				tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
+//				replaceNum++
+//			}
+//
+//			// 如果替换的数据与关联的不一致,那么就退出当前循环
+//			if lenRelation != replaceNum {
+//				continue
+//			}
+//
+//			// 计算
+//			val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
+//			// 计算失败,退出循环
+//			if err != nil {
+//				continue
+//			}
+//			// 重新赋值
+//			colData.ShowValue = val
+//			tableDataMap[index][currTag] = colData
+//		}
+//
+//	}
+//
+//	// 计算文本行第一列的数据值(多行)
+//	for k, colData := range firstColTextRowList {
+//		// 如果该单元格不是计算公式的单元格,那么直接退出当前循环即可
+//		if colData.DataType != 4 {
+//			continue
+//		}
+//
+//		tagMap := make(map[string]float64)
+//		lenRelation := len(colData.RelationEdbInfoList)
+//		replaceNum := 0
+//		for _, relation := range colData.RelationEdbInfoList {
+//			relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
+//			valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
+//			if tmpErr != nil {
+//				continue
+//			}
+//			tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
+//			if tmpErr != nil {
+//				continue
+//			}
+//			tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
+//			replaceNum++
+//		}
+//
+//		// 如果替换的数据与关联的不一致,那么就退出当前循环
+//		if lenRelation != replaceNum {
+//			continue
+//		}
+//
+//		// 计算
+//		val, _, err := calculate(strings.ToUpper(colData.Value), tagMap)
+//		// 计算失败,退出循环
+//		if err != nil {
+//			continue
+//		}
+//		// 重新赋值
+//		colData.ShowValue = val
+//		firstColTextRowList[k] = colData
+//	}
+//
+//	{
+//		// 文本行的数据处理返回
+//		textRowListDataResp = make([][]request.ManualDataReq, 0)
+//		newLenTableDataMap := len(tableDataMap)
+//		// 文本行的第一行所在的位置
+//		firstTextRow := lenTableData + 1
+//		for i := firstTextRow; i <= newLenTableDataMap; i++ {
+//			textRowDataResp := make([]request.ManualDataReq, 0)
+//
+//			textRowDataResp = append(textRowDataResp, firstColTextRowList[i-firstTextRow])
+//			for _, tmpTag := range tagList {
+//				textRowDataResp = append(textRowDataResp, tableDataMap[i][tmpTag])
+//			}
+//			textRowListDataResp = append(textRowListDataResp, textRowDataResp)
+//		}
+//
+//	}
+//
+//	return
+//}
+//
+//// getCalculateValue 获取公式计算的结果
+//func getCalculateValue(tableDataMap map[int]map[string]request.ManualDataReq, tag, row string, calculateCellMap map[string]string) (val string, err error) {
+//	rowInt, err := strconv.Atoi(row)
+//	if err != nil {
+//		return
+//	}
+//
+//	// 单元格的标签名
+//	cellTagName := strings.ToUpper(tag) + row
+//	val, ok := calculateCellMap[cellTagName]
+//	if ok {
+//		return
+//	}
+//
+//	// 查找行数据
+//	rowData, ok := tableDataMap[rowInt]
+//	if !ok {
+//		err = errors.New("查找" + row + "行的数据失败")
+//		return
+//	}
+//
+//	// 查找单元格数据
+//	colData, ok := rowData[tag]
+//	if !ok {
+//		err = errors.New("查找单元格" + tag + row + "的数据失败")
+//		return
+//	}
+//
+//	// 如果不是计算单元格
+//	if colData.DataType != 4 {
+//		val = colData.ShowValue
+//		return
+//	}
+//
+//	// 如果是计算单元格
+//	calculateCellMap[cellTagName] = ``
+//
+//	tagMap := make(map[string]float64)
+//	for _, relation := range colData.RelationEdbInfoList {
+//		relationCellTagName := strings.ToUpper(relation.Tag) + relation.Row
+//		valStr, tmpErr := getCalculateValue(tableDataMap, relation.Tag, relation.Row, calculateCellMap)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//		tmpValDecimal, tmpErr := decimal.NewFromString(valStr)
+//		if tmpErr != nil {
+//			err = tmpErr
+//			return
+//		}
+//		tagMap[relationCellTagName], _ = tmpValDecimal.Float64()
+//	}
+//
+//	// 计算
+//	val, _, err = calculate(strings.ToUpper(colData.Value), tagMap)
+//	if err != nil {
+//		return
+//	}
+//	// 重新赋值
+//	colData.ShowValue = val
+//	tableDataMap[rowInt][tag] = colData
+//	calculateCellMap[cellTagName] = val
+//
+//	return
+//}
+//
+//// calculate 公式计算
+//func calculate(calculateFormula string, TagMap map[string]float64) (calVal, errMsg string, err error) {
+//	if calculateFormula == "" {
+//		errMsg = "公式异常"
+//		err = errors.New(errMsg)
+//		return
+//	}
+//	calculateFormula = strings.TrimPrefix(calculateFormula, "=")
+//	calculateFormula = strings.Replace(calculateFormula, "(", "(", -1)
+//	calculateFormula = strings.Replace(calculateFormula, ")", ")", -1)
+//	calculateFormula = strings.Replace(calculateFormula, ",", ",", -1)
+//	calculateFormula = strings.Replace(calculateFormula, "。", ".", -1)
+//	calculateFormula = strings.Replace(calculateFormula, "%", "*0.01", -1)
+//
+//	formulaFormStr := utils.ReplaceFormula(TagMap, calculateFormula)
+//	//计算公式异常,那么就移除该指标
+//	if formulaFormStr == `` {
+//		errMsg = "公式异常"
+//		err = errors.New(errMsg)
+//		return
+//	}
+//
+//	expression := formula.NewExpression(formulaFormStr)
+//	calResult, err := expression.Evaluate()
+//	if err != nil {
+//		errMsg = "计算失败"
+//		err = errors.New("计算失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+//		// 分母为0的报错
+//		if strings.Contains(err.Error(), "divide by zero") {
+//			errMsg = "分母不能为0"
+//			err = errors.New("分母不能为空,计算公式:" + formulaFormStr)
+//		}
+//		return
+//	}
+//	// 如果计算结果是NAN,那么就提示报错
+//	if calResult.IsNan() {
+//		errMsg = "计算失败"
+//		err = errors.New("计算失败:计算结果是:NAN;formulaStr:" + formulaFormStr)
+//		return
+//	}
+//	calVal = calResult.String()
+//
+//	// 转Decimal然后四舍五入
+//	valDecimal, err := decimal.NewFromString(calVal)
+//	if err != nil {
+//		errMsg = "计算失败"
+//		err = errors.New("计算失败,结果转 Decimal 失败:Err:" + err.Error() + ";formulaStr:" + formulaFormStr)
+//		return
+//	}
+//	calVal = valDecimal.Round(4).String()
+//
+//	return
+//}

+ 1 - 1
services/data/table/mixed_table.go → services/data/excel/mixed_table.go

@@ -1,4 +1,4 @@
-package table
+package excel
 
 import (
 	"encoding/json"

+ 202 - 389
services/data/excel_info.go → services/data/excel/time_table.go

@@ -1,10 +1,11 @@
-package data
+package excel
 
 import (
 	"errors"
 	"eta/eta_chart_lib/models"
 	"eta/eta_chart_lib/models/data_manage"
 	"eta/eta_chart_lib/models/request"
+	"eta/eta_chart_lib/services/data"
 	"eta/eta_chart_lib/utils"
 	"fmt"
 	"github.com/shopspring/decimal"
@@ -15,250 +16,8 @@ import (
 	"time"
 )
 
-// GetFirstEdbDataList 获取第一列的数据
-func GetFirstEdbDataList(edbInfo *data_manage.EdbInfo, num int, manualDateList []string) (resultDataList []request.ManualDataReq, err error) {
-	var dataList []*models.EdbDataList
-	switch edbInfo.EdbInfoType {
-	case 0:
-		dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
-	case 1:
-		_, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
-	default:
-		err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
-
-		return
-	}
-
-	// 获取需要的期数
-	lenData := len(dataList)
-	if lenData <= 0 {
-		return
-	}
-
-	tmpManualDateNum := 0 // 手工数据的期数
-	lenManualDate := len(manualDateList)
-	if lenManualDate > 0 {
-		sortDateList := manualDateList
-		baseDateList := utils.StrArr{}
-		baseDateList = append(baseDateList, sortDateList...)
-		sort.Sort(baseDateList)
-		sortDateList = append([]string{}, baseDateList...)
-
-		lastData := dataList[lenData-1]
-		lastDataDate, tmpErr := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-
-		// 遍历倒序后的日期,然后匹配在实际数据之后日期的个数
-		for _, tmpDateStr := range sortDateList {
-			tmpDate, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDateStr, time.Local)
-			if tmpErr != nil {
-				err = tmpErr
-				return
-			}
-			if tmpDate.After(lastDataDate) {
-				tmpManualDateNum++
-				continue
-			}
-
-			break
-		}
-
-	}
-
-	// 需要的期数减去手工数据的期数,这才是A列指标需要的数据
-	num = num - tmpManualDateNum
-	if num > lenData {
-		num = lenData
-	}
-
-	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
-	for i := 1; i <= num; i++ {
-		dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
-		dataType := 1
-		// 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
-		if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
-			dataType = 5
-		}
-
-		resultDataList = append(resultDataList, request.ManualDataReq{
-			DataType:     dataType,
-			DataTime:     dataList[lenData-i].DataTime,
-			ShowValue:    fmt.Sprint(dataList[lenData-i].Value),
-			Value:        fmt.Sprint(dataList[lenData-i].Value),
-			DataTimeType: 1,
-		})
-	}
-
-	return
-}
-
-// GetOtherEdbDataList 获取其他列的数据
-func GetOtherEdbDataList(edbInfo *data_manage.EdbInfo, dateList []string) (resultDataList []request.ManualDataReq, err error) {
-	lenDate := len(dateList)
-	if lenDate <= 0 {
-		return
-	}
-	sortDateList := dateList
-	baseDateList := utils.StrArr{}
-	baseDateList = append(baseDateList, sortDateList...)
-	sort.Sort(baseDateList)
-	sortDateList = append([]string{}, baseDateList...)
-
-	endDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[0], time.Local)
-	if err != nil {
-		return
-	}
-
-	firstDateTime, err := time.ParseInLocation(utils.FormatDate, sortDateList[lenDate-1], time.Local)
-	if err != nil {
-		return
-	}
-
-	var dataList []*models.EdbDataList
-	switch edbInfo.EdbInfoType {
-	case 0:
-		dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
-	case 1:
-		_, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
-	default:
-		err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
-
-		return
-	}
-
-	// 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
-	baseDataList := make([]*models.EdbDataList, 0)
-	var lastData *models.EdbDataList
-	var isInsert bool
-	for _, data := range dataList {
-		tmpDate := data.DataTime
-		tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-		if tmpDateTime.Before(firstDateTime) {
-			lastData = data
-			continue
-		}
-
-		// 如果是第一次写入数据
-		if !isInsert && lastData != nil {
-			baseDataList = append(baseDataList, lastData)
-		}
-
-		if tmpDateTime.After(endDateTime) {
-			baseDataList = append(baseDataList, data)
-			break
-		}
-		baseDataList = append(baseDataList, data)
-		isInsert = true
-	}
-
-	// 实际数据的日期map
-	realValMap := make(map[string]string)
-	for _, v := range baseDataList {
-		realValMap[v.DataTime] = v.DataTime
-	}
-
-	// 插值法处理
-	handleDataMap := make(map[string]float64)
-	err = HandleDataByLinearRegression(baseDataList, handleDataMap)
-	if err != nil {
-		return
-	}
-
-	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
-	// 对于不存在的数据做补充
-	for _, date := range sortDateList {
-		dataType := 1
-		if _, ok := realValMap[date]; !ok {
-			dataType = 2
-		} else {
-			dataTime, _ := time.ParseInLocation(utils.FormatDate, date, time.Local)
-			// 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
-			if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
-				dataType = 5
-			}
-		}
-		var value, showValue string
-		if tmpVal, ok := handleDataMap[date]; ok {
-			value = fmt.Sprint(tmpVal)
-			showValue = value
-		} else {
-			dataType = 3
-		}
-		resultDataList = append(resultDataList, request.ManualDataReq{
-			DataType:  dataType,
-			DataTime:  date,
-			ShowValue: showValue,
-			Value:     value,
-		})
-	}
-
-	return
-}
-
-// GetFirstHistoryEdbDataList 获取指标的历史的数据
-func GetFirstHistoryEdbDataList(edbInfo *data_manage.EdbInfo, num int, endDate string) (resultDataList []request.ManualDataReq, err error) {
-	endDateTime, err := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
-	if err != nil {
-		return
-	}
-
-	var dataList []*models.EdbDataList
-	switch edbInfo.EdbInfoType {
-	case 0:
-		dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, endDate)
-	case 1:
-		_, dataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, endDate, true)
-	default:
-		err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
-
-		return
-	}
-
-	// 获取需要的期数
-	lenData := len(dataList)
-	if lenData <= 0 {
-		return
-	}
-	lastData := dataList[lenData-1]
-	lastDataDateTime, err := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
-	if err != nil {
-		return
-	}
-	if endDateTime.Equal(lastDataDateTime) || lastDataDateTime.After(endDateTime) {
-		dataList = dataList[:lenData-1]
-		lenData = len(dataList)
-	}
-	if num > lenData {
-		num = lenData
-	}
-
-	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.LatestDate, time.Local)
-	for i := 1; i <= num; i++ {
-		dataTime, _ := time.ParseInLocation(utils.FormatDate, dataList[lenData-i].DataTime, time.Local)
-		dataType := 1
-		// 如果是预测指标,且当前值的日期,晚于实际日期,那么是预测值
-		if edbInfo.EdbInfoType == 1 && dataTime.After(latestDateTime) {
-			dataType = 5
-		}
-
-		resultDataList = append(resultDataList, request.ManualDataReq{
-			DataType:  dataType,
-			DataTime:  dataList[lenData-i].DataTime,
-			ShowValue: fmt.Sprint(dataList[lenData-i].Value),
-			Value:     fmt.Sprint(dataList[lenData-i].Value),
-		})
-	}
-
-	return
-}
-
+// TableDataConfig
+// @Description: 表格配置
 type TableDataConfig struct {
 	EdbInfoIdList    []int                     `description:"指标id列表,从左至右,从上到下的顺序"`
 	Sort             int                       `description:"日期排序,0:倒序,1:正序"`
@@ -270,15 +29,21 @@ type TableDataConfig struct {
 	TextRowData      [][]request.ManualDataReq `description:"文本列表"`
 }
 
+// TableEdbInfo
+// @Description: 表格指标信息
 type TableEdbInfo struct {
 	EdbInfoId    int    `description:"指标ID"`
 	Tag          string `description:"标签"`
 	EdbName      string `description:"指标名称"`
+	EdbNameEn    string `description:"英文指标名称"`
 	EdbAliasName string `description:"指标别名"`
 	Frequency    string `description:"频度"`
 	Unit         string `description:"单位"`
+	UnitEn       string `description:"英文单位"`
 }
 
+// ManualData
+// @Description: 手工文本配置
 type ManualData struct {
 	DataType            int                       `description:"数据类型,1:普通的,2:插值法,3:手动输入,4:公式计算"`
 	DataTime            string                    `description:"所属日期"`
@@ -290,147 +55,7 @@ type ManualData struct {
 	RelationEdbInfoList []request.RelationEdbInfo `description:"关联指标(计算公式中关联的指标,用于计算的时候去匹配)"`
 }
 
-func GetTableDataConfig(reqData request.TableDataReq) (tableDataConfig TableDataConfig, err error) {
-	// 指标数据
-	tableDataConfig.EdbInfoIdList = reqData.EdbInfoIdList
-	tableDataConfig.Sort = reqData.Sort
-
-	// 开始日期
-	var startDate string
-	// A列的指标id
-	var firstEdbInfoId int
-	// 手工操作的数据列
-	manualDataList := make([]ManualData, 0)
-	// 指标配置列表
-	tableEdbInfoList := make([]TableEdbInfo, 0)
-
-	// 第一列的日期map
-	firstDateMap := make(map[string]string)
-	manualDateMap := make(map[string]string)
-
-	for _, v := range reqData.Data {
-		// 指标信息
-		tmpTableEdbInfo := TableEdbInfo{
-			EdbInfoId:    v.EdbInfoId,
-			Tag:          v.Tag,
-			EdbName:      v.EdbName,
-			EdbAliasName: v.EdbAliasName,
-			Frequency:    v.Frequency,
-			Unit:         v.Unit,
-		}
-		tableEdbInfoList = append(tableEdbInfoList, tmpTableEdbInfo)
-
-		// 确定数据A列
-		if v.Tag == "A" {
-			firstEdbInfoId = v.EdbInfoId
-			lenData := len(v.Data)
-			if lenData <= 0 {
-				err = errors.New("A列不能为空")
-				return
-			}
-			index := 0
-			if reqData.Sort == 1 {
-				// 倒序
-				index = lenData - 1
-			}
-
-			startDate = v.Data[index].DataTime
-
-			// 存在的日期列表
-			for _, data := range v.Data {
-				firstDateMap[data.DataTime] = data.DataTime
-
-				if data.DataTimeType == 2 {
-					manualDateMap[data.DataTime] = data.DataTime
-				}
-			}
-		}
-
-		for _, data := range v.Data {
-			if data.DataType == 3 || data.DataType == 4 {
-				tmpManualData := ManualData{
-					DataType:            data.DataType,
-					DataTime:            data.DataTime,
-					DataTimeType:        data.DataTimeType,
-					ShowValue:           data.ShowValue,
-					Value:               data.Value,
-					EdbInfoId:           v.EdbInfoId,
-					Tag:                 v.Tag,
-					RelationEdbInfoList: data.RelationEdbInfoList,
-				}
-				if data.DataType == 4 {
-					tmpManualData.ShowValue = ``
-				}
-				manualDataList = append(manualDataList, tmpManualData)
-			}
-		}
-	}
-
-	// 实际期数
-	var num int
-	removeDate := make([]string, 0)
-
-	// 获取期数
-	{
-		firstDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-
-		edbInfo, tmpErr := data_manage.GetEdbInfoById(firstEdbInfoId)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-
-		var firstDataList []*models.EdbDataList
-		switch edbInfo.EdbInfoType {
-		case 0:
-			firstDataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
-		case 1:
-			_, firstDataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
-		default:
-			err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
-			return
-		}
-
-		// 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
-		baseDataList := make([]*models.EdbDataList, 0)
-		for _, data := range firstDataList {
-			tmpDate := data.DataTime
-			tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
-			if tmpErr != nil {
-				err = tmpErr
-				return
-			}
-			if tmpDateTime.Before(firstDateTime) {
-				continue
-			}
-			baseDataList = append(baseDataList, data)
-		}
-
-		// 开始日期到现在的实际期数
-		num = len(baseDataList)
-
-		// 筛选出需要删除的日期
-		for _, tmpData := range baseDataList {
-			//firstDateMap{}
-			if _, ok := firstDateMap[tmpData.DataTime]; !ok {
-				removeDate = append(removeDate, tmpData.DataTime)
-			}
-		}
-	}
-
-	tableDataConfig.Num = num
-	tableDataConfig.RemoveDate = removeDate
-	tableDataConfig.Data = manualDataList
-	tableDataConfig.TableEdbInfoList = tableEdbInfoList
-	tableDataConfig.TextRowData = reqData.TextRowData
-
-	return
-}
-
+// GetDataByTableDataConfig 根据数据配置获取表格数据
 func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp request.TableDataReq, err error) {
 	// 没有选择指标的情况下,直接返回吧
 	if len(tableDataConfig.EdbInfoIdList) <= 0 {
@@ -567,13 +192,23 @@ func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp reque
 		}
 
 		// 判断是否存在该日期的数据(不存在,那么插入数据吧,存在就不管了)
-		if _, ok = edbInfoIdDateData[tmpDate]; !ok {
+		tmpManualData, ok := edbInfoIdDateData[tmpDate]
+		if !ok {
 			edbInfoIdDateData[tmpDate] = request.ManualDataReq{
 				DataType:  v.DataType,
 				DataTime:  v.DataTime,
 				ShowValue: v.ShowValue,
 				Value:     v.Value,
 			}
+		} else {
+			if (tmpManualData.DataType == 3 || tmpManualData.DataType == 4) && tmpManualData.ShowValue == `` {
+				tmpManualData.DataType = v.DataType
+				tmpManualData.ShowValue = v.ShowValue
+				tmpManualData.Value = v.Value
+				tmpManualData.RelationEdbInfoList = v.RelationEdbInfoList
+
+				edbInfoIdDateData[tmpDate] = tmpManualData
+			}
 		}
 		edbInfoIdDateDataMap[v.EdbInfoId] = edbInfoIdDateData
 	}
@@ -612,17 +247,23 @@ func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp reque
 			EdbInfoId:    tableEdbInfo.EdbInfoId,
 			Tag:          tableEdbInfo.Tag,
 			EdbName:      tableEdbInfo.EdbName,
+			EdbNameEn:    tableEdbInfo.EdbNameEn,
 			EdbAliasName: tableEdbInfo.EdbAliasName,
 			Frequency:    tableEdbInfo.Frequency,
 			Unit:         tableEdbInfo.Unit,
+			UnitEn:       tableEdbInfo.UnitEn,
 			Data:         manualDataReqList,
 		}
 
 		edbInfo, ok := edbInfoMap[tableEdbInfo.EdbInfoId]
 		if ok {
 			tmpEdbInfoData.EdbName = edbInfo.EdbName
+			tmpEdbInfoData.EdbNameEn = edbInfo.EdbNameEn
 			tmpEdbInfoData.Frequency = edbInfo.Frequency
 			tmpEdbInfoData.Unit = edbInfo.Unit
+			tmpEdbInfoData.UnitEn = edbInfo.UnitEn
+			//tmpEdbInfoData.ClassifyId = edbInfo.ClassifyId
+			//tmpEdbInfoData.IsJoinPermission = edbInfo.IsJoinPermission
 		}
 
 		for index, dateTime := range sortDateTimeList {
@@ -667,6 +308,28 @@ func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp reque
 		data = append(data, tmpEdbInfoData)
 	}
 
+	// 处理一下数据格式
+	for _, d := range data {
+		for k2, d2 := range d.Data {
+			// 可能有ShowValue非数值, 转换一下报错则continue
+			vf, e := strconv.ParseFloat(d2.ShowValue, 64)
+			if e != nil {
+				continue
+			}
+			d.Data[k2].ShowValue = utils.FormatTableDataShowValue(vf)
+		}
+	}
+	for _, d := range textRowListDataResp {
+		for k2, d2 := range d {
+			// 可能有ShowValue非数值, 转换一下报错则continue
+			vf, e := strconv.ParseFloat(d2.ShowValue, 64)
+			if e != nil {
+				continue
+			}
+			d[k2].ShowValue = utils.FormatTableDataShowValue(vf)
+		}
+	}
+
 	resultResp = request.TableDataReq{
 		EdbInfoIdList: edbInfoIdList,
 		Sort:          tableDataConfig.Sort,
@@ -677,9 +340,159 @@ func GetDataByTableDataConfig(tableDataConfig TableDataConfig) (resultResp reque
 	return
 }
 
+// GetTableDataConfig 根据TableDataReq配置获取相关数据配置
+func GetTableDataConfig(reqData request.TableDataReq) (tableDataConfig TableDataConfig, err error) {
+	// 指标数据
+	tableDataConfig.EdbInfoIdList = reqData.EdbInfoIdList
+	tableDataConfig.Sort = reqData.Sort
+
+	if len(reqData.Data) <= 0 {
+		err = errors.New("数据不能为空")
+		return
+	}
+
+	// 开始日期
+	var startDate string
+	// A列的指标id
+	var firstEdbInfoId int
+	// 手工操作的数据列
+	manualDataList := make([]ManualData, 0)
+	// 指标配置列表
+	tableEdbInfoList := make([]TableEdbInfo, 0)
+
+	// 第一列的日期map
+	firstDateMap := make(map[string]string)
+	manualDateMap := make(map[string]string)
+
+	for _, v := range reqData.Data {
+		// 指标信息
+		tmpTableEdbInfo := TableEdbInfo{
+			EdbInfoId:    v.EdbInfoId,
+			Tag:          v.Tag,
+			EdbName:      v.EdbName,
+			EdbNameEn:    v.EdbNameEn,
+			EdbAliasName: v.EdbAliasName,
+			Frequency:    v.Frequency,
+			Unit:         v.Unit,
+			UnitEn:       v.UnitEn,
+		}
+		tableEdbInfoList = append(tableEdbInfoList, tmpTableEdbInfo)
+
+		// 确定数据A列
+		if v.Tag == "A" {
+			firstEdbInfoId = v.EdbInfoId
+			lenData := len(v.Data)
+			if lenData <= 0 {
+				err = errors.New("A列不能为空")
+				return
+			}
+			index := 0
+			if reqData.Sort == 1 {
+				// 倒序
+				index = lenData - 1
+			}
+
+			startDate = v.Data[index].DataTime
+
+			// 存在的日期列表
+			for _, data := range v.Data {
+				firstDateMap[data.DataTime] = data.DataTime
+
+				if data.DataTimeType == 2 {
+					manualDateMap[data.DataTime] = data.DataTime
+				}
+			}
+		}
+
+		for _, data := range v.Data {
+			if data.DataType == 3 || data.DataType == 4 {
+				tmpManualData := ManualData{
+					DataType:            data.DataType,
+					DataTime:            data.DataTime,
+					DataTimeType:        data.DataTimeType,
+					ShowValue:           data.ShowValue,
+					Value:               data.Value,
+					EdbInfoId:           v.EdbInfoId,
+					Tag:                 v.Tag,
+					RelationEdbInfoList: data.RelationEdbInfoList,
+				}
+				if data.DataType == 4 {
+					tmpManualData.ShowValue = ``
+				}
+				manualDataList = append(manualDataList, tmpManualData)
+			}
+		}
+	}
+
+	// 总共需要的期数
+	num := len(reqData.Data[0].Data)
+
+	removeDate := make([]string, 0)
+
+	// 获取期数
+	{
+		firstDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		edbInfo, tmpErr := data_manage.GetEdbInfoById(firstEdbInfoId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		var firstDataList []*models.EdbDataList
+		switch edbInfo.EdbInfoType {
+		case 0:
+			firstDataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
+		case 1:
+			_, firstDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
+		default:
+			err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
+		}
+		if err != nil {
+			return
+		}
+
+		// 获取日期内的数据(包含开始日期前一个日期,以及 结束日期后一个日期,目的为了做空日期时的 插值法兼容)
+		baseDataList := make([]*models.EdbDataList, 0)
+		for _, data := range firstDataList {
+			tmpDate := data.DataTime
+			tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			if tmpDateTime.Before(firstDateTime) {
+				continue
+			}
+			baseDataList = append(baseDataList, data)
+		}
+
+		// 筛选出需要删除的日期
+		for _, tmpData := range baseDataList {
+			//firstDateMap{}
+			if _, ok := firstDateMap[tmpData.DataTime]; !ok {
+				removeDate = append(removeDate, tmpData.DataTime)
+			}
+		}
+	}
+
+	tableDataConfig.Num = num
+	tableDataConfig.RemoveDate = removeDate
+	tableDataConfig.Data = manualDataList
+	tableDataConfig.TableEdbInfoList = tableEdbInfoList
+	tableDataConfig.TextRowData = reqData.TextRowData
+
+	return
+}
+
+// handleTable 表格数据处理
 func handleTable(tagEdbInfoIdMap map[string]int, lastRealDateTime time.Time, sortDateTimeList []time.Time, edbInfoIdDateDataMap map[int]map[string]request.ManualDataReq, manualDataList []ManualData, textRowData [][]request.ManualDataReq) (tableDataMap map[int]map[string]request.ManualDataReq, textRowListDataResp [][]request.ManualDataReq) {
 	tagList := make([]string, 0)
-	for tag := range tagEdbInfoIdMap {
+	for tag, _ := range tagEdbInfoIdMap {
 		tagList = append(tagList, tag)
 	}
 	sort.Strings(tagList)
@@ -890,7 +703,7 @@ func handleTable(tagEdbInfoIdMap map[string]int, lastRealDateTime time.Time, sor
 			continue
 		}
 
-		for colIndex := range textRow {
+		for colIndex, _ := range textRow {
 			currTag := tagList[colIndex]
 			// 找到对应的单元格
 			colData, ok := rowDataMap[currTag]

+ 57 - 41
services/excel/lucky_sheet.go

@@ -929,7 +929,7 @@ func (item *LuckySheetData) GetTableDataByLuckySheetDataStrBak() (selfTableData
 }
 
 // GetTableDataByCustomData 通过自定义表格数据获取表格数据
-func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTableData TableData, err error) {
+func GetTableDataByCustomData(excelType int, data request.TableDataReq, lang string) (selfTableData TableData, err error) {
 	tableDataList := make([][]LuckySheetDataValue, 0)
 	mergeList := make([]TableDataMerge, 0)
 
@@ -955,11 +955,14 @@ func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTab
 		// 第一行
 		{
 			firstCol := make([]LuckySheetDataValue, 0)
+			dateStr := "日期"
+			switch lang {
+			case utils.EnLangVersion:
+				dateStr = "Date"
+			}
 			firstCol = append(firstCol, LuckySheetDataValue{
-				Value:      "日期",
-				Monitor:    "日期",
-				Background: "#505b78",
-				FontColor:  "#FFFFFF",
+				Value:   dateStr,
+				Monitor: dateStr,
 				MergeCell: LuckySheetDataConfigMerge{
 					Row:    0, //行数
 					Column: 0, //列数
@@ -972,13 +975,16 @@ func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTab
 				edbName := v.EdbName
 				if v.EdbAliasName != `` {
 					edbName = v.EdbAliasName
+				} else {
+					switch lang {
+					case utils.EnLangVersion:
+						edbName = v.EdbNameEn
+					}
 				}
 				firstCol = append(firstCol, LuckySheetDataValue{
-					Value:      edbName,
-					Monitor:    edbName,
-					Background: "#505b78",
-					FontColor:  "#FFFFFF",
-					MergeCell:  LuckySheetDataConfigMerge{},
+					Value:     edbName,
+					Monitor:   edbName,
+					MergeCell: LuckySheetDataConfigMerge{},
 				})
 			}
 
@@ -991,13 +997,17 @@ func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTab
 			secondCol = append(secondCol, LuckySheetDataValue{})
 
 			for _, v := range data.Data {
-				name := v.Unit + " / " + v.Frequency
+				var name string
+				switch lang {
+				case utils.EnLangVersion:
+					name = v.UnitEn + " / " + utils.GetFrequencyEn(v.Frequency)
+				default:
+					name = v.Unit + " / " + v.Frequency
+				}
 				secondCol = append(secondCol, LuckySheetDataValue{
-					Value:      name,
-					Monitor:    name,
-					Background: "#505b78",
-					FontColor:  "#FFFFFF",
-					MergeCell:  LuckySheetDataConfigMerge{},
+					Value:     name,
+					Monitor:   name,
+					MergeCell: LuckySheetDataConfigMerge{},
 				})
 			}
 
@@ -1061,11 +1071,14 @@ func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTab
 		// 第一行
 		{
 			firstCol := make([]LuckySheetDataValue, 0)
+			dateStr := "日期"
+			switch lang {
+			case utils.EnLangVersion:
+				dateStr = "Date"
+			}
 			firstCol = append(firstCol, LuckySheetDataValue{
-				Value:      "日期",
-				Monitor:    "日期",
-				Background: "#505b78",
-				FontColor:  "#FFFFFF",
+				Value:   dateStr,
+				Monitor: dateStr,
 				MergeCell: LuckySheetDataConfigMerge{
 					Row:    0, //行数
 					Column: 0, //列数
@@ -1078,22 +1091,18 @@ func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTab
 			// 日期列
 			for _, v := range data.Data[0].Data {
 				firstCol = append(firstCol, LuckySheetDataValue{
-					Value:      v.DataTime,
-					Monitor:    v.DataTime,
-					Background: "#efeef1",
-					FontColor:  "#666666",
-					MergeCell:  LuckySheetDataConfigMerge{},
+					Value:     v.DataTime,
+					Monitor:   v.DataTime,
+					MergeCell: LuckySheetDataConfigMerge{},
 				})
 			}
 
 			// 文本列
 			for _, textColList := range data.TextRowData {
 				firstCol = append(firstCol, LuckySheetDataValue{
-					Value:      textColList[0].Value,
-					Monitor:    textColList[0].ShowValue,
-					Background: "#efeef1",
-					FontColor:  "#666666",
-					MergeCell:  LuckySheetDataConfigMerge{},
+					Value:     textColList[0].Value,
+					Monitor:   textColList[0].ShowValue,
+					MergeCell: LuckySheetDataConfigMerge{},
 				})
 			}
 
@@ -1113,25 +1122,32 @@ func GetTableDataByCustomData(excelType int, data request.TableDataReq) (selfTab
 				edbName := tmpEdbInfo.EdbName
 				if tmpEdbInfo.EdbAliasName != `` {
 					edbName = tmpEdbInfo.EdbAliasName
+				} else {
+					switch lang {
+					case utils.EnLangVersion:
+						edbName = tmpEdbInfo.EdbNameEn
+					}
 				}
 				dataCol = append(dataCol, LuckySheetDataValue{
-					Value:      edbName,
-					Monitor:    edbName,
-					Background: "#505b78",
-					FontColor:  "#FFFFFF",
-					MergeCell:  LuckySheetDataConfigMerge{},
+					Value:     edbName,
+					Monitor:   edbName,
+					MergeCell: LuckySheetDataConfigMerge{},
 				})
 			}
 
 			// 指标单位、频度
 			{
-				name := tmpEdbInfo.Unit + " / " + tmpEdbInfo.Frequency
+				var name string
+				switch lang {
+				case utils.EnLangVersion:
+					name = tmpEdbInfo.UnitEn + " / " + utils.GetFrequencyEn(tmpEdbInfo.Frequency)
+				default:
+					name = tmpEdbInfo.Unit + " / " + tmpEdbInfo.Frequency
+				}
 				dataCol = append(dataCol, LuckySheetDataValue{
-					Value:      name,
-					Monitor:    name,
-					Background: "#505b78",
-					FontColor:  "#FFFFFF",
-					MergeCell:  LuckySheetDataConfigMerge{},
+					Value:     name,
+					Monitor:   name,
+					MergeCell: LuckySheetDataConfigMerge{},
 				})
 			}
 

+ 25 - 0
utils/common.go

@@ -1117,3 +1117,28 @@ func ReplaceFormulaByTagMap(valTagMap map[string]int, formulaStr string) string
 	}
 	return formulaStr
 }
+
+// GetFrequencyEn 获取频度的英文版
+func GetFrequencyEn(frequency string) (frequencyEn string) {
+	switch frequency {
+	case "日度":
+		frequencyEn = "day"
+		return
+	case "周度":
+		frequencyEn = "week"
+		return
+	case "旬度":
+		frequencyEn = "ten days"
+		return
+	case "月度":
+		frequencyEn = "month"
+		return
+	case "季度":
+		frequencyEn = "quarter"
+		return
+	case "年度":
+		frequencyEn = "year"
+		return
+	}
+	return
+}

+ 6 - 0
utils/constants.go

@@ -207,3 +207,9 @@ const (
 	PercentCalculateTypeRange = 0 // 百分位算法类型-数据区间
 	PercentCalculateTypeNum   = 1 // 百分位算法类型-数据个数
 )
+
+// 语言版本
+const (
+	ZhLangVersion = "zh" // 中文语言版本
+	EnLangVersion = "en" // 英文语言版本
+)