Selaa lähdekoodia

Merge remote-tracking branch 'origin/debug' into debug

zwxi 7 kuukautta sitten
vanhempi
commit
1c3f60af0d

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

@@ -1646,7 +1646,10 @@ func (c *ExcelInfoController) GetExcelTableData() {
 	}
 
 	tableData = excel.HandleTableCell(tableData)
-
+	tableData, err = excel.HandleRuleToTableCell(excelInfo.ExcelInfoId, tableData)
+	if err != nil {
+		utils.FileLog.Info("表格管理规则处理失败,HandleRuleToTableCell err:", err.Error())
+	}
 	config := response.ExcelTableDetailConfigResp{
 		FontSize: 9,
 	}
@@ -3104,3 +3107,238 @@ func (c *ExcelInfoController) GetEdbSource() {
 	br.Ret = 200
 	br.Success = true
 }
+
+// ExcelRule
+// @Title 添加表格规则
+// @Description 添加表格规则
+// @Param	request	body excel3.BatchRefreshExcelReq true "type json string"
+// @Success Ret=200 刷新成功
+// @router /excel_info/rule/add [post]
+func (c *ExcelInfoController) AddExcelRule() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req *request.ExcelRuleMappingReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.LeftValue == "" {
+		br.Msg = "条件值不能为空"
+		return
+	}
+	if req.Scope == "" {
+		br.Msg = "应用选区不能为空"
+		return
+	}
+	if req.FontColor == "" {
+		br.Msg = "字体颜色不能为空"
+		return
+	}
+	if req.BackgroundColor == "" {
+		br.Msg = "背景颜色不能为空"
+		return
+	}
+	if req.RuleType == 3 && req.RightValue == "" {
+		br.Msg = "条件值不能为空"
+		return
+	}
+	err = excel2.AddExcelRule(req, c.Lang)
+	if err != nil {
+		br.Msg = "规则添加失败"
+		br.ErrMsg = "规则添加失败,Err:" + err.Error()
+		return
+	}
+	br.Msg = "添加成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// EditExcelRule
+// @Title 编辑表格规则
+// @Description 编辑表格规则
+// @Param	request	body request.ExcelRuleMappingReq true "type json string"
+// @Success Ret=200 刷新成功
+// @router /excel_info/rule/edit [post]
+func (c *ExcelInfoController) EditExcelRule() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req *request.ExcelRuleMappingReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.LeftValue == "" {
+		br.Msg = "条件值不能为空"
+		return
+	}
+	if req.Scope == "" {
+		br.Msg = "应用选区不能为空"
+		return
+	}
+	if req.FontColor == "" {
+		br.Msg = "字体颜色不能为空"
+		return
+	}
+	if req.BackgroundColor == "" {
+		br.Msg = "背景颜色不能为空"
+		return
+	}
+	if req.RuleType == 3 && req.RightValue == "" {
+		br.Msg = "条件值不能为空"
+		return
+	}
+	if req.ExcelRuleMappingId <= 0 {
+		br.Msg = "非法的管理规则ID"
+		return
+	}
+	err = excel2.ModifyExcelRule(req, c.Lang)
+	if err != nil {
+		br.Msg = "规则编辑失败"
+		br.ErrMsg = "规则编辑失败,Err:" + err.Error()
+		return
+	}
+	br.Msg = "编辑成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// DeleteExcelRule
+// @Title 删除表格规则
+// @Description 删除表格规则
+// @Param	request	body request.ExcelRuleMappingReq true "type json string"
+// @Success Ret=200 刷新成功
+// @router /excel_info/rule/delete [post]
+func (c *ExcelInfoController) DeleteExcelRule() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.DeleteExcelRuleMappingReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ExcelRuleMappingId <= 0 {
+		br.Msg = "非法的管理规则ID"
+		return
+	}
+	err = excel3.DeleteExcelRuleMappingById(req.ExcelRuleMappingId)
+	if err != nil {
+		br.Msg = "规则删除失败"
+		br.ErrMsg = "规则删除失败,Err:" + err.Error()
+		return
+	}
+	br.Msg = "删除成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// GetExcelRuleList
+// @Title 表格规则列表
+// @Description 表格规则列表
+// @Param   ExcelInfoId   query   int  true       "id"
+// @Success Ret=200 获取成功
+// @router /excel_info/rule/list [get]
+func (c *ExcelInfoController) GetExcelRuleList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	ExcelInfoId, _ := c.GetInt("ExcelInfoId")
+
+	if ExcelInfoId <= 0 {
+		br.Msg = "请选择表格"
+		return
+	}
+
+	items, err := excel2.GetExcelRuleList(ExcelInfoId)
+	if err != nil {
+		br.Msg = "管理规则编辑失败"
+		br.ErrMsg = "管理规则添加失败,Err:" + err.Error()
+		return
+	}
+	if items.List == nil {
+		items.List = []*excel3.ExcelInfoRuleMappingView{}
+	}
+
+	br.Data = items
+	br.Msg = "获取成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// GetExcelRuleDetail
+// @Title 表格规则详情
+// @Description 表格规则详情
+// @Param   ExcelInfoRuleMappingId   query   int  true       "id"
+// @Success Ret=200 获取成功
+// @router /excel_info/rule/detail [get]
+func (c *ExcelInfoController) GetExcelRuleDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	excelInfoRuleMappingId, _ := c.GetInt("ExcelInfoRuleMappingId")
+
+	items, err := excel2.GetExcelRuleDetail(excelInfoRuleMappingId)
+	if err != nil {
+		br.Msg = "管理规则编辑失败"
+		br.ErrMsg = "管理规则添加失败,Err:" + err.Error()
+		return
+	}
+
+	br.Data = items
+	br.Msg = "获取成功"
+	br.Ret = 200
+	br.Success = true
+}

+ 534 - 0
controllers/data_manage/fenwei_data.go

@@ -1,14 +1,19 @@
 package data_manage
 
 import (
+	"encoding/json"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"github.com/tealeg/xlsx"
 	"os"
 	"path/filepath"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -73,6 +78,7 @@ func (this *EdbInfoController) FenweiClassify() {
 // @Param   PageSize   query   int  true       "每页数据条数"
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ClassifyId   query   string  true       "分类id"
+// @Param   Frequency   query   string  true       "频率"
 // @Success 200 {object} data_manage.LzFrequency
 // @router /fenwei/index/data [get]
 func (this *EdbInfoController) FenweiIndexData() {
@@ -110,6 +116,7 @@ func (this *EdbInfoController) FenweiIndexData() {
 		br.ErrMsg = "请选择分类"
 		return
 	}
+	frequency := this.GetString("Frequency")
 
 	// 获取指标
 	var condition string
@@ -119,6 +126,11 @@ func (this *EdbInfoController) FenweiIndexData() {
 		pars = append(pars, classifyId)
 	}
 
+	if frequency != "" {
+		condition += ` AND frequency=? `
+		pars = append(pars, frequency)
+	}
+
 	indexes, err := data_manage.GetFenweiIndex(condition, pars)
 	if err != nil {
 		br.Msg = "获取数据失败"
@@ -141,6 +153,16 @@ func (this *EdbInfoController) FenweiIndexData() {
 		countMap[v.IndexCode] = v.Count
 	}
 
+	// 判断是否存在于指标库
+	edbCodeList, err := data_manage.GetEdbInfoByEdbCodeList(utils.DATA_SOURCE_FENWEI, indexCodes)
+	if err != nil {
+		return
+	}
+	edbCodeMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range edbCodeList {
+		edbCodeMap[v.EdbCode] = v
+	}
+
 	resultList := make([]*data_manage.BaseFromFenweiIndexList, 0)
 	for _, v := range indexes {
 		product := new(data_manage.BaseFromFenweiIndexList)
@@ -153,6 +175,13 @@ func (this *EdbInfoController) FenweiIndexData() {
 		product.CreateTime = v.CreateTime
 		product.ModifyTime = v.ModifyTime
 
+		_, ok := edbCodeMap[v.IndexCode]
+		if ok {
+			product.EdbExist = true
+		} else {
+			product.EdbExist = false
+		}
+
 		total := countMap[v.IndexCode]
 		page := paging.GetPaging(currentIndex, pageSize, total)
 		dataList, e := data_manage.GetFenweiIndexData(v.IndexCode, startSize, pageSize)
@@ -267,6 +296,12 @@ func (this *EdbInfoController) FenweiSingleData() {
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
+	indexCodeList := []string{indexCode}
+	edbCodeList, err := data_manage.GetEdbInfoByEdbCodeList(utils.DATA_SOURCE_FENWEI, indexCodeList)
+	if err != nil {
+		return
+	}
+
 	var ret data_manage.FenweiSingleDataResp
 	var dataList []*data_manage.FenweiSingleData
 
@@ -286,6 +321,11 @@ func (this *EdbInfoController) FenweiSingleData() {
 		dataList = append(dataList, tmp)
 	}
 	ret.Data = dataList
+	if len(edbCodeList) > 0 {
+		ret.EdbExist = true
+	} else {
+		ret.EdbExist = false
+	}
 
 	br.Ret = 200
 	br.Success = true
@@ -490,3 +530,497 @@ func (this *EdbInfoController) ExportFenweiList() {
 	br.Msg = "success"
 
 }
+
+// GetFenWeiFrequencyList
+// @Title 查询频率列表
+// @Description 查询频率列表
+// @Param   classifyId   query  int  false   "指标唯一编码"
+// @Success 200 {object} []string
+// @router /fenwei/frequency/list [get]
+func (this *EdbInfoController) GetFenWeiFrequencyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	classifyId, _ := this.GetInt("ClassifyId")
+
+	frequencyList, err := data_manage.GetFenWeiIndexFrequency(classifyId)
+	if err != nil {
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = frequencyList
+}
+
+// FenWeiIndexAddValidate
+// @Title 新增加入到指标库校验
+// @Description 新增加入到指标库校验
+// @Param   req    body   data_manage.BaseFromFenWeiIndexBatchAddCheckReq     true        "请求参数"
+// @Success 200 {object} []data_manage.IndexCheckData
+// @router /fenwei/index/add/validate [post]
+func (this *EdbInfoController) FenWeiIndexAddValidate() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	var req *data_manage.BaseFromFenWeiIndexBatchAddCheckReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+
+	codeLen := len(req.IndexCodes)
+	var codeMax = 30
+	if codeLen > codeMax {
+		br.Msg = "批量添加指标数量不得超过" + strconv.Itoa(codeMax) + "个"
+		br.ErrMsg = "批量添加指标数量不得超过" + strconv.Itoa(codeMax) + "个"
+		return
+	}
+
+	// 校验指标编码是否存在
+	addValidate, err := data.FenWeiIndexAddValidate(req.IndexCodes)
+	if err != nil {
+		return
+	}
+	br.Data = addValidate
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// FenWeiIndexAdd
+// @Title 指标添加到指标库
+// @Description 指标添加到指标库
+// @Param   req    body   []data_manage.AddEdbInfoReq     true        "请求参数"
+// @Success 200 string "操作成功"
+// @router /fenwei/index/add [post]
+func (this *EdbInfoController) FenWeiIndexAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	deleteCache := true
+	cacheKey := "CACHE_EDB_INFO_BATCH_ADD_FENWEI_" + strconv.Itoa(sysUser.AdminId)
+	defer func() {
+		if deleteCache {
+			_ = utils.Rc.Delete(cacheKey)
+		}
+	}()
+	if !utils.Rc.SetNX(cacheKey, 1, 30*time.Second) {
+		deleteCache = false
+		br.Msg = "系统处理中,请稍后重试!"
+		br.ErrMsg = "系统处理中,请稍后重试!" + sysUser.RealName + ";data:" + string(this.Ctx.Input.RequestBody)
+		return
+	}
+
+	var req []*data_manage.AddEdbInfoReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	codeMax := 30
+	if len(req) > codeMax {
+		br.Msg = "批量添加指标数量不得超过" + strconv.Itoa(codeMax) + "个"
+		return
+	}
+
+	indexNames := make([]string, 0)
+	resp := make([]*data_manage.FenWeiNameCheckResult, 0)
+	for _, index := range req {
+		index.EdbCode = strings.TrimSpace(index.EdbCode)
+		if index.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		index.EdbName = strings.TrimSpace(index.EdbName)
+		if index.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		index.Frequency = strings.TrimSpace(index.Frequency)
+		if index.Frequency == "" {
+			br.Msg = "请选择频度"
+			return
+		}
+		index.Unit = strings.TrimSpace(index.Unit)
+		if index.Unit == "" {
+			br.Msg = "请输入单位"
+			return
+		}
+		if index.ClassifyId <= 0 {
+			br.Msg = "请选择分类"
+			return
+		}
+		indexNames = append(indexNames, index.EdbName)
+		resp = append(resp, &data_manage.FenWeiNameCheckResult{
+			IndexCode: index.EdbCode,
+			IndexName: index.EdbName,
+			Exist:     false,
+		})
+	}
+
+	// 指标名称重复校验
+	nameCheck, err := data.FenWeiIndexNameCheck(indexNames, resp)
+	if err != nil {
+		br.Msg = err.Error()
+		br.ErrMsg = err.Error()
+		return
+	}
+	for _, v := range nameCheck {
+		if v.Exist {
+			br.Msg = "指标名称重复"
+			br.Data = nameCheck
+			br.Ret = 200
+			br.Success = true
+			return
+		}
+	}
+
+	for _, v := range req {
+		var fenWeiIndexAddReq data_manage.FenWeiIndexAddReq
+		fenWeiIndexAddReq.EdbCode = v.EdbCode
+		fenWeiIndexAddReq.EdbName = v.EdbName
+		fenWeiIndexAddReq.Frequency = v.Frequency
+		fenWeiIndexAddReq.Unit = v.Unit
+		fenWeiIndexAddReq.ClassifyId = v.ClassifyId
+		fenWeiIndexAddReq.AdminId = sysUser.AdminId
+		fenWeiIndexAddReq.AdminRealName = sysUser.RealName
+
+		// 新增指标到指标库
+		edbInfo, e, errMsg, skip := data.FenWeiIndexAdd(fenWeiIndexAddReq, this.Lang)
+		if e != nil {
+			br.Msg = "操作失败"
+			if errMsg != "" {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = e.Error()
+			return
+		}
+		if skip {
+			continue
+		}
+
+		// todo 下面两段代码能否抽离出来???
+		// 试用平台更新用户累计新增指标数
+		if utils.BusinessCode == utils.BusinessCodeSandbox {
+			go func() {
+				adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+				if e != nil {
+					tips := fmt.Sprintf("试用平台更新用户累计新增指标数-获取用户失败, Err: " + e.Error())
+					utils.FileLog.Info(tips)
+					return
+				}
+				if adminItem.DepartmentName != "ETA试用客户" {
+					return
+				}
+				var ur etaTrialService.EtaTrialUserReq
+				ur.Mobile = adminItem.Mobile
+				_, _ = etaTrialService.UpdateUserIndexNum(ur)
+			}()
+		}
+
+		// 新增操作日志
+		{
+			edbLog := new(data_manage.EdbInfoLog)
+			edbLog.EdbInfoId = edbInfo.EdbInfoId
+			edbLog.SourceName = edbInfo.SourceName
+			edbLog.Source = edbInfo.Source
+			edbLog.EdbCode = edbInfo.EdbCode
+			edbLog.EdbName = edbInfo.EdbName
+			edbLog.ClassifyId = edbInfo.ClassifyId
+			edbLog.SysUserId = sysUser.AdminId
+			edbLog.SysUserRealName = sysUser.RealName
+			edbLog.CreateTime = time.Now()
+			edbLog.Content = string(this.Ctx.Input.RequestBody)
+			edbLog.Status = "新增指标"
+			edbLog.Method = this.Ctx.Input.URI()
+			go data_manage.AddEdbInfoLog(edbLog)
+		}
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// FenWeiIndexDataExport
+// @Title 导出指标数据
+// @Description 导出指标数据
+// @Param  IndexCode     query   string     false        "指标编码"
+// @Param  ClassifyId     query   int     false        "分类ID"
+// @Success 200 string "操作成功"
+// @router /fenwei/index/data/export [get]
+func (this *EdbInfoController) FenWeiIndexDataExport() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+
+	classifyId, _ := this.GetInt("ClassifyId") //分类
+	indexCode := this.GetString("IndexCode")   //指标唯一编码
+
+	//userId := sysUser.AdminId
+	//超管账号可以查看分类下的所有频度数据
+	/*if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
+		userId = 0
+	}*/
+	//获取账户所拥有权限的分类id集合
+	/*classifyIdStrList, err := data.GetEdbClassifyListByAdminId(int64(userId))
+	if err != nil {
+		br.Msg = "获取分类数据失败"
+		return
+	}*/
+
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+
+	downLoadFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+	frequencies, err := data_manage.GetFenWeiIndexFrequency(classifyId)
+	if err != nil {
+		br.Msg = "查询频度失败"
+		br.ErrMsg = "查询频度失败"
+		return
+	}
+
+	fileName := `粮油商务网`
+	if classifyId > 0 && indexCode == "" {
+		fenWeiClassify, err := data_manage.GetFenweiClassifyItemByClassifyId(classifyId)
+		if err != nil {
+			return
+		}
+		fileName = fenWeiClassify.ClassifyName
+	}
+	if frequencies == nil {
+		sheet, err := xlsxFile.AddSheet("无数据")
+		if err != nil {
+			br.Msg = "新增Sheet失败"
+			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
+			return
+		}
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("")
+	}
+
+	for _, frequency := range frequencies {
+		fenWeiIndices, err := data_manage.GetFenWeiIndexByCodeAndClassify(indexCode, classifyId, frequency)
+		if err != nil {
+			return
+		}
+		var sheet *xlsx.Sheet
+		if len(fenWeiIndices) > 0 {
+			sheet, err = xlsxFile.AddSheet(*frequency)
+			if err != nil {
+				br.Msg = "新增Sheet失败"
+				br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
+				return
+			}
+		} else {
+			continue
+		}
+
+		if indexCode != "" {
+			fileName = fenWeiIndices[0].IndexName
+		}
+
+		//获取指标数据
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("指标名称")
+		rowFrequency := sheet.AddRow()
+		celFrequency := rowFrequency.AddCell()
+		celFrequency.SetValue("频率")
+		rowUnit := sheet.AddRow()
+		celUnit := rowUnit.AddCell()
+		celUnit.SetValue("单位")
+		rowModifyDate := sheet.AddRow()
+		rowModifyCell := rowModifyDate.AddCell()
+		rowModifyCell.SetValue("更新时间")
+
+		dataMap := make(map[string]map[string]*data_manage.BaseFromFenweiData)
+		var tradeCodeList []string
+		for _, v := range fenWeiIndices {
+			cellSenName := rowSecName.AddCell()
+			cellSenName.SetValue(v.IndexName)
+			celFrequency := rowFrequency.AddCell()
+			celFrequency.SetValue(v.Frequency)
+			celUnit := rowUnit.AddCell()
+			celUnit.SetValue(v.Unit)
+			rowModifyCell := rowModifyDate.AddCell()
+			rowModifyCell.SetValue(v.ModifyTime)
+			tradeCodeList = append(tradeCodeList, v.IndexCode)
+
+			var dataList []*data_manage.BaseFromFenweiData
+			dataList, err = data_manage.GetBaseFromFenWeiDataByIndexCode(v.IndexCode)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.ErrMsg = "GetBaseFromFenWeiDataByIndexCode,Err:" + err.Error()
+				br.Msg = "获取数据失败"
+				return
+			}
+			for _, item := range dataList {
+				if dataMap[item.IndexCode] == nil {
+					dataMap[item.IndexCode] = make(map[string]*data_manage.BaseFromFenweiData)
+				}
+				dataMap[item.IndexCode][item.DataTime] = item
+			}
+		}
+
+		tradeCodeStr := strings.Join(tradeCodeList, "','")
+		tradeCodeStr = "'" + tradeCodeStr + "'"
+		dataTimeList, err := data_manage.GetFenWeiDataListByIndexCodes(tradeCodeStr)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
+			return
+		}
+		for _, dataTime := range dataTimeList {
+			rowData := sheet.AddRow()
+			celDate := rowData.AddCell()
+			celDate.SetValue(dataTime)
+
+			for _, m := range fenWeiIndices {
+				celData := rowData.AddCell()
+				if dataMap[m.IndexCode][dataTime] != nil {
+					celData.SetValue(dataMap[m.IndexCode][dataTime].Value)
+				}
+			}
+		}
+	}
+
+	err = xlsxFile.Save(downLoadFilePath)
+	if err != nil {
+		//有指标无数据时先导出一遍空表
+		sheet, err := xlsxFile.AddSheet("无数据")
+		if err != nil {
+			br.Msg = "新增Sheet失败"
+			br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
+			return
+		}
+		rowSecName := sheet.AddRow()
+		celSecName := rowSecName.AddCell()
+		celSecName.SetValue("")
+		err = xlsxFile.Save(downLoadFilePath)
+		if err != nil {
+			br.Msg = "保存文件失败"
+			br.ErrMsg = "保存文件失败"
+			return
+		}
+	}
+
+	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
+	this.Ctx.Output.Download(downLoadFilePath, fileName)
+	defer func() {
+		os.Remove(downLoadFilePath)
+	}()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+}
+
+// GetFenWeiIndexInfo
+// @Title 添加指标-根据条件获取指标信息
+// @Description 添加指标-根据条件获取指标信息
+// @Param   KeyWord   query   string  false       "关键字"
+// @Param   ClassifyIds   query   string  false       "分类id"
+// @Param   Frequencies   query   string  false       "频率"
+// @Param   PageSize   query   int  false       "每页数据条数"
+// @Param   CurrentIndex   query   int  false       "当前页页码,从1开始"
+// @Success 200 {object} data_manage.BaseFromFenWeiIndexPage
+// @router /fenwei/get/index/info [get]
+func (this *EdbInfoController) GetFenWeiIndexInfo() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	keyWord := this.GetString("KeyWord")
+	classifyIds := this.GetString("ClassifyIds")
+	frequencies := this.GetString("Frequencies")
+
+	classifyIdList := strings.Split(classifyIds, ",")
+	frequencyList := strings.Split(frequencies, ",")
+
+	indexInfoPage, err := data.GetFenWeiIndexInfo(keyWord, classifyIdList, frequencyList, currentIndex, pageSize)
+	if err != nil {
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = indexInfoPage
+}

+ 15 - 0
controllers/data_manage/range_analysis/chart_classify.go

@@ -516,6 +516,21 @@ func (this *RangeChartClassifyController) DeleteChartClassify() {
 			//go data.EsDeleteMyChartInfoByChartInfoId(chartInfo.ChartInfoId)
 			go data.EsDeleteMyChartInfoByMyChartIds(myIds)
 		}
+		// 删除配置关联指标数据
+		multiConfig, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfo.ChartInfoId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			br.Msg = "删除失败"
+			br.ErrMsg = "获取图表关联配置失败, Err: " + e.Error()
+			return
+		}
+		if multiConfig != nil { // 删除配置关联指标数据
+			e = data_manage.DeleteMultipleGraphConfigByChartInfoId(chartInfo.ChartInfoId, multiConfig.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
+			if e != nil {
+				br.Msg = "删除失败"
+				br.ErrMsg = "删除图表关联配置失败, Err: " + e.Error()
+				return
+			}
+		}
 
 		var condition string
 		var pars []interface{}

+ 15 - 7
controllers/data_manage/range_analysis/chart_info.go

@@ -1306,27 +1306,37 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 		_ = utils.Rc.Delete(cacheKey)
 	}()
 	fromEdbInfoIds := make([]int, 0)
+	edbInfoIds := make([]int, 0)
 	for _, v := range req.EdbInfoList {
+		if v.EdbInfoId > 0 {
+			edbInfoIds = append(edbInfoIds, v.EdbInfoId)
+		}
 		fromEdbInfoIds = append(fromEdbInfoIds, v.FromEdbInfoId)
+		edbInfoIds = append(edbInfoIds, v.FromEdbInfoId)
 	}
-	fromEdbInfoMappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList(fromEdbInfoIds)
+	edbInfoMappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList(edbInfoIds)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取图表,指标信息失败,Err:" + err.Error()
 		return
 	}
-	fromEdbInfoMap := make(map[int]*data_manage.ChartEdbInfoMapping, 0)
-	for _, v := range fromEdbInfoMappingList {
-		fromEdbInfoMap[v.EdbInfoId] = v
+	edbInfoMap := make(map[int]*data_manage.ChartEdbInfoMapping, 0)
+	for _, v := range edbInfoMappingList {
+		edbInfoMap[v.EdbInfoId] = v
 	}
 
 	for _, v := range req.EdbInfoList {
-		if _, ok := fromEdbInfoMap[v.FromEdbInfoId]; !ok {
+		if _, ok := edbInfoMap[v.FromEdbInfoId]; !ok {
 			br.Msg = "指标信息不存在"
 			br.ErrMsg = "指标信息不存在,EdbInfoId:" + strconv.Itoa(v.FromEdbInfoId)
 			br.IsSendEmail = false
 			return
 		}
+		if v.EdbInfoId > 0 {
+			if _, ok := edbInfoMap[v.EdbInfoId]; !ok {
+				v.EdbInfoId = 0
+			}
+		}
 	}
 	// 区间计算图表配置校验
 	extraConfig := req.ExtraConfig
@@ -1358,7 +1368,6 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 		return
 	}
 	deleteEdbInfoIds := make([]int, 0) // 需要解除绑定的指标ID
-	fromEdbMap := make(map[int]int)
 	configMapping := make(map[int]*data_manage.MultipleGraphConfigEdbMapping, 0)
 	if len(multipleGraphConfigEdbMappingList) == 0 || req.IsSaveAs {
 		// 需要新增的指标
@@ -1380,7 +1389,6 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 
 		// 说明指标还在,没有被删除
 		for _, v := range oldEdbCalculateMappingList {
-			fromEdbMap[v.FromEdbInfoId] = v.EdbInfoId
 			if !utils.InArrayByInt(fromEdbInfoIds, v.FromEdbInfoId) && (config.EdbInfoMode == 1 || req.EdbInfoType != v.FromEdbInfoType) {
 				deleteEdbInfoIds = append(deleteEdbInfoIds, v.EdbInfoId)
 			}

+ 141 - 0
models/data_manage/base_from_fenwei.go

@@ -31,6 +31,7 @@ type BaseFromFenweiIndexList struct {
 	ModifyTime    string
 	DataList      []*BaseFromFenweiData
 	Paging        *paging.PagingItem `description:"分页数据"`
+	EdbExist      bool               `description:"是否存在于指标库"`
 }
 
 type FenweiSingleDataResp struct {
@@ -43,6 +44,7 @@ type FenweiSingleDataResp struct {
 	CreateTime    string
 	ModifyTime    string
 	Data          []*FenweiSingleData
+	EdbExist      bool `description:"是否存在于指标库"`
 }
 
 type FenweiSingleData struct {
@@ -50,6 +52,45 @@ type FenweiSingleData struct {
 	DataTime string `orm:"column(data_time)" description:"值"`
 }
 
+// BaseFromFenWeiIndexBatchAddCheckReq 校验编码是否存在请求参数
+type BaseFromFenWeiIndexBatchAddCheckReq struct {
+	IndexCodes []string `form:"IndexCodes" description:"指标编码列表"`
+}
+
+// IndexCheckData 校验编码是否存在
+type FenWeiIndexCheckData struct {
+	IndexCode  string `orm:"column(index_code)" description:"指标编码"`
+	IndexName  string `orm:"column(index_name)" description:"指标名称"`
+	Frequency  string `orm:"column(frequency)" description:"频度"`
+	Unit       string `orm:"column(unit)" description:"单位"`
+	EdbInfoId  int    `json:"edb_info_id" description:"指标库主键id"`
+	UniqueCode string `json:"unique_code" description:"指标库唯一编码"`
+	ClassifyId int    `json:"classify_id" description:"分类id"`
+}
+
+// NameCheckResult 校验名称是否存在
+type FenWeiNameCheckResult struct {
+	IndexCode string `from:"EdbCode" description:"edb编码"`
+	IndexName string `from:"EdbName" description:"edb名称"`
+	Exist     bool
+}
+
+// FenWeiIndexAddReq 指标添加vo
+type FenWeiIndexAddReq struct {
+	EdbCode       string `description:"指标编码"`
+	EdbName       string `description:"指标名称"`
+	Frequency     string `description:"频度"`
+	Unit          string `description:"单位"`
+	ClassifyId    int    `description:"分类ID"`
+	AdminId       int    `description:"管理员ID"`
+	AdminRealName string `description:"管理员名称"`
+}
+
+type BaseFromFenWeiIndexPage struct {
+	List   []*BaseFromFenweiIndex `description:"指标列表"`
+	Paging *paging.PagingItem     `description:"分页数据"`
+}
+
 func GetFenweiIndex(condition string, pars interface{}) (items []*BaseFromFenweiIndexList, err error) {
 	o := orm.NewOrmUsingDB("data")
 	sql := ` SELECT * FROM base_from_fenwei_index WHERE 1=1  `
@@ -142,3 +183,103 @@ func GetBaseFromFenweiIndexByIndexCode(indexCode string) (list *BaseFromFenweiIn
 	err = o.Raw(sql, indexCode).QueryRow(&list)
 	return
 }
+
+// GetFenWeiIndexFrequency 获取指标频度
+func GetFenWeiIndexFrequency(classifyId int) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency 
+        FROM base_from_fenwei_index 
+        WHERE frequency IS NOT NULL`
+
+	// 如果 classifyId > 0,则添加该条件
+	if classifyId > 0 {
+		sql += ` AND base_from_ly_classify_id = ?`
+	}
+
+	sql += ` ORDER BY FIELD(frequency, '日度', '周度', '月度', '季度', '半年度', '年度')`
+
+	o := orm.NewOrmUsingDB("data")
+	if classifyId > 0 {
+		_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	} else {
+		_, err = o.Raw(sql).QueryRows(&items)
+	}
+
+	return items, err
+}
+
+// GetFenWeiIndexByCodeAndClassify 根据指标编码和分类查询 indexCode非必传
+func GetFenWeiIndexByCodeAndClassify(indexCode string, classifyId int, frequency *string) (items []*BaseFromFenweiIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+
+	// SQL 查询语句
+	sql := `SELECT a.index_code, a.index_name, a.frequency, a.unit, MAX(b.modify_time) AS modify_time
+			FROM base_from_ly_index AS a
+			INNER JOIN base_from_ly_data AS b ON a.base_from_ly_index_id = b.base_from_ly_index_id
+			WHERE 1=1`
+
+	var params []interface{}
+
+	if classifyId != 0 {
+		sql += ` AND a.classify_id = ?`
+		params = append(params, classifyId)
+	}
+
+	// 如果 indexCode 不为空,增加过滤条件
+	if indexCode != "" {
+		sql += ` AND a.index_code = ?`
+		params = append(params, indexCode)
+	}
+
+	if frequency != nil {
+		sql += ` AND a.frequency = ?`
+		params = append(params, *frequency)
+	}
+
+	sql += ` GROUP BY a.index_code, a.index_name, a.frequency, a.unit`
+
+	_, err = o.Raw(sql, params...).QueryRows(&items)
+	if err != nil {
+		return nil, err
+	}
+	return
+}
+
+// GetBaseFromFenWeiDataByIndexCode 根据指标编码查询
+func GetBaseFromFenWeiDataByIndexCode(indexCode string) (items []*BaseFromFenweiData, err error) {
+	sql := `SELECT * FROM base_from_ly_data WHERE index_code=? ORDER BY data_time desc`
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, indexCode).QueryRows(&items)
+	return
+}
+
+// GetFenWeiDataListByIndexCodes 根据指标编码查询
+func GetFenWeiDataListByIndexCodes(IndexCodes string) (items []string, err error) {
+	sql := ` SELECT data_time FROM base_from_ly_data WHERE index_code IN(` + IndexCodes + `)  GROUP BY data_time DESC `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// GetFenWeiIndexInfoPage 分页查询指标信息
+func GetFenWeiIndexInfoPage(condition string, pars []interface{}, size int, pageSize int) (items []*BaseFromFenweiIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_fenwei_index WHERE 1=1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY fenwei_index_id asc LIMIT ?,?`
+	_, err = o.Raw(sql, pars, size, pageSize).QueryRows(&items)
+	return
+
+}
+
+// GetFenWeiIndexInfoCount 查询指标信息总数
+func GetFenWeiIndexInfoCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count FROM base_from_fenwei_index WHERE 1=1  `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}

+ 13 - 0
models/data_manage/base_from_fenwei_classify.go

@@ -53,3 +53,16 @@ func (y *BaseFromFenweiClassify) Format2Item(origin *BaseFromFenweiClassify) (it
 	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
 	return
 }
+
+// GetFenweiClassifyItemByClassifyId 根据分类id查询分类信息
+func GetFenweiClassifyItemByClassifyId(classifyId int) (item *BaseFromFenweiClassifyItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_fenwei_classify WHERE classify_id = ?`
+	var origin BaseFromFenweiClassify
+	err = o.Raw(sql, classifyId).QueryRow(&origin)
+	if err != nil {
+		return
+	}
+	item = origin.Format2Item(&origin)
+	return
+}

+ 1 - 1
models/data_manage/chart_info_range_analysis.go

@@ -280,7 +280,7 @@ func EditRangeChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr, lang stri
 			mapItem.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp + "_" + strconv.Itoa(v.EdbInfoId))
 			//mapItem.MaxData = v.MaxData
 			//mapItem.MinData = v.MinData
-			mapItem.IsOrder = true
+			//mapItem.IsOrder = true
 			mapItem.EdbInfoType = 1
 			//mapItem.LeadValue = v.LeadValue
 			//mapItem.LeadUnit = v.LeadUnit

+ 21 - 20
models/data_manage/edb_info.go

@@ -11,9 +11,10 @@ import (
 	"strings"
 	"time"
 
+	"go.mongodb.org/mongo-driver/bson"
+
 	"github.com/beego/beego/v2/client/orm"
 	"github.com/rdlucklib/rdluck_tools/paging"
-	"go.mongodb.org/mongo-driver/bson"
 )
 
 type EdbInfo struct {
@@ -1846,25 +1847,6 @@ func GetEdbInfoByCodeArr(codes []string, edbInfoType int) (items []*EdbInfo, err
 	return
 }
 
-type EdbInfoEditRecord struct {
-	EdbInfoId           int    `description:"指标ID"`
-	EdbName             string `description:"指标名称"`
-	Frequency           string `description:"频率"`
-	Unit                string `description:"单位"`
-	ClassifyId          int    `description:"分类id"`
-	CalculateFormula    string `description:"计算公式"`
-	OperateUserId       int    `description:"操作人id"`
-	OperateUserRealName string `description:"操作人姓名"`
-}
-
-func ModifyEdbInfoBaseTimeById(edbInfoId int, cTime time.Time) (err error) {
-	o := orm.NewOrmUsingDB("data")
-	// 更新修改时间
-	sql := ` UPDATE edb_info SET base_modify_time = ? WHERE edb_info_id = ? `
-	_, err = o.Raw(sql, cTime, edbInfoId).Exec()
-	return
-}
-
 // GetEdbCodesBySource 根据来源获取指标编码
 func GetEdbCodesBySource(source int) (items []*EdbInfo, err error) {
 	o := orm.NewOrmUsingDB("data")
@@ -2010,6 +1992,25 @@ func GetEdbInfoListByCond(condition string, pars []interface{}) (list []*EdbInfo
 	return
 }
 
+type EdbInfoEditRecord struct {
+	EdbInfoId           int    `description:"指标ID"`
+	EdbName             string `description:"指标名称"`
+	Frequency           string `description:"频率"`
+	Unit                string `description:"单位"`
+	ClassifyId          int    `description:"分类id"`
+	CalculateFormula    string `description:"计算公式"`
+	OperateUserId       int    `description:"操作人id"`
+	OperateUserRealName string `description:"操作人姓名"`
+}
+
+func ModifyEdbInfoBaseTimeById(edbInfoId int, cTime time.Time) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	// 更新修改时间
+	sql := ` UPDATE edb_info SET base_modify_time = ? WHERE edb_info_id = ? `
+	_, err = o.Raw(sql, cTime, edbInfoId).Exec()
+	return
+}
+
 func GetEdbInfoFieldList(cond string, pars []interface{}, fields []string) (items []*EdbInfo, err error) {
 	field := " * "
 	if len(fields) > 0 {

+ 4 - 2
models/data_manage/edb_info_calculate.go

@@ -2,10 +2,12 @@ package data_manage
 
 import (
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
-	"github.com/rdlucklib/rdluck_tools/paging"
+
 	"strings"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 type EdbInfoCalculateSaveReq struct {

+ 82 - 0
models/data_manage/excel/excel_info_rule_mapping.go

@@ -0,0 +1,82 @@
+package excel
+
+import (
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type ExcelInfoRuleMapping struct {
+	ExcelInfoRuleMappingId int       `orm:"pk" description:"主键"`
+	ExcelInfoId            int       `description:"Excel信息ID"`
+	RuleType               int       `description:"规则类型"`
+	LeftValue              string    `description:"左值"`
+	LeftValueShow          string    `description:"左值前端显示"`
+	LeftValueType          int       `description:"左值类型"`
+	RightValue             string    `description:"右值"`
+	RightValueShow         string    `description:"右值前端显示"`
+	RightValueType         int       `description:"右值类型"`
+	FontColor              string    `description:"字体颜色"`
+	BackgroundColor        string    `description:"背景颜色"`
+	Remark                 string    `description:"预设颜色说明"`
+	RemarkEn               string    `description:"预设颜色英文说明"`
+	Scope                  string    `description:"作用范围"`
+	ScopeCoord             string    `description:"作用范围坐标"`
+	ScopeShow              string    `description:"作用范围坐标前端显示"`
+	CreateTime             time.Time `description:"创建时间"`
+}
+
+type ExcelInfoRuleMappingView struct {
+	ExcelInfoRuleMappingId int    `orm:"pk" description:"主键"`
+	ExcelInfoId            int    `description:"Excel信息ID"`
+	RuleType               int    `description:"规则类型"`
+	LeftValue              string `description:"左值"`
+	LeftValueShow          string `description:"左值前端显示"`
+	LeftValueType          int    `description:"左值类型"`
+	RightValue             string `description:"右值"`
+	RightValueShow         string `description:"右值前端显示"`
+	RightValueType         int    `description:"右值类型"`
+	FontColor              string `description:"字体颜色"`
+	BackgroundColor        string `description:"背景颜色"`
+	Remark                 string `description:"预设颜色说明"`
+	RemarkEn               string `description:"预设颜色英文说明"`
+	Scope                  string `description:"作用范围"`
+	ScopeCoord             string `description:"作用范围坐标"`
+	ScopeShow              string `description:"作用范围坐标前端显示"`
+	CreateTime             string `description:"创建时间"`
+}
+
+func (e *ExcelInfoRuleMapping) Insert() (insertId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	insertId, err = o.Insert(e)
+	return
+}
+
+func (e *ExcelInfoRuleMapping) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(e, cols...)
+	return
+}
+
+// GetExcelRuleMappingByExcelInfoId 根据excelInfoId获取规则映射信息
+func GetExcelRuleMappingByExcelInfoId(id int) (items []*ExcelInfoRuleMappingView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_info_rule_mapping WHERE excel_info_id = ? ORDER BY create_time ASC`
+	_, err = o.Raw(sql, id).QueryRows(&items)
+	return
+}
+
+// GetExcelRuleMappingById 根据主键Id获取规则映射信息
+func GetExcelRuleMappingById(id int) (item *ExcelInfoRuleMappingView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_info_rule_mapping WHERE excel_info_rule_mapping_id = ?`
+	err = o.Raw(sql, id).QueryRow(&item)
+	return
+}
+
+func DeleteExcelRuleMappingById(id int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `DELETE FROM excel_info_rule_mapping WHERE excel_info_rule_mapping_id = ?`
+	_, err = o.Raw(sql, id).Exec()
+	return
+}

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

@@ -177,3 +177,21 @@ type ShareExcelInfoReq struct {
 	ViewUserIds []int `description:"查看权限用户IDs"`
 	EditUserIds []int `description:"编辑权限用户IDs"`
 }
+
+type ExcelRuleMappingReq struct {
+	ExcelRuleMappingId int    `description:"规则映射ID"`
+	ExcelInfoId        int    `description:"ETA表格ID"`
+	RuleType           int    `description:"规则类型:1-大于,2-小于,3-介于,4-等于,5-发生日期"`
+	LeftValue          string `description:"条件值"`
+	LeftValueType      int    `description:"条件值的类型,1:数值,2:坐标"`
+	RightValue         string `description:"条件值, 用于介于的条件"`
+	RightValueType     int    `description:"条件值的类型,1:数值,2:坐标"`
+	FontColor          string `description:"字体颜色"`
+	BackgroundColor    string `description:"背景颜色"`
+	Remark             string `description:"预设的单元格样式名称"`
+	Scope              string `description:"应用选区"`
+}
+
+type DeleteExcelRuleMappingReq struct {
+	ExcelRuleMappingId int `description:"规则映射ID"`
+}

+ 5 - 2
models/data_manage/excel/request/mixed_table.go

@@ -133,8 +133,11 @@ type MixDateCalculateTagReq struct {
 
 // MixCellShowStyle 混合表格 单元格样式展示计算
 type MixCellShowStyle struct {
-	Pn int    `description:"小数点位数增加或减少,正数表述增加,负数表示减少" json:"pn"`
-	Nt string `description:"变换类型:number 小数点位数改变,percent百分比," json:"nt"`
+	Pn              int         `description:"小数点位数增加或减少,正数表述增加,负数表示减少" json:"pn"`
+	Nt              string      `description:"变换类型:number 小数点位数改变,percent百分比," json:"nt"`
+	GlObj           interface{} `description:"公式对象:1:数值,2:百分比,3:文本" json:"glObj"`
+	Color           string      `description:"颜色值,#RRG" json:"color"`
+	BackgroundColor string      `description:"背景颜色值,#RRG" json:"background-color"`
 }
 
 type DateDataBeforeAfterReq struct {

+ 6 - 1
models/data_manage/excel/response/excel_info.go

@@ -4,8 +4,9 @@ import (
 	excel2 "eta/eta_api/models/data_manage/excel"
 	"eta/eta_api/models/data_manage/excel/request"
 	"eta/eta_api/services/excel"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // AddExcelInfoResp 添加excel表格的返回
@@ -118,3 +119,7 @@ type ShareExcelInfoDetail struct {
 	ViewUserIds []int `description:"查看权限用户IDs"`
 	EditUserIds []int `description:"编辑权限用户IDs"`
 }
+
+type ExcelRuleListResp struct {
+	List []*excel2.ExcelInfoRuleMappingView
+}

+ 28 - 0
models/data_manage/multiple_graph_config_edb_mapping.go

@@ -74,3 +74,31 @@ func DeleteMultipleGraphConfigEdbMappingByEdbIds(configId, source int, edbIds []
 	_, err = o.Raw(sql, configId, source, edbIds).Exec()
 	return
 }
+
+func DeleteMultipleGraphConfigByChartInfoId(chartInfoId, configId, source int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+	sql := ` DELETE FROM multiple_graph_config WHERE multiple_graph_config_id = ?`
+	_, err = to.Raw(sql, configId).Exec()
+	if err != nil {
+		return
+	}
+	sql = ` DELETE FROM multiple_graph_config_chart_mapping WHERE chart_info_id=? and multiple_graph_config_id = ? and	source=?`
+	_, err = to.Raw(sql, chartInfoId, configId, source).Exec()
+	if err != nil {
+		return
+	}
+	sql = ` DELETE FROM  multiple_graph_config_edb_mapping WHERE multiple_graph_config_id = ? and	source=? `
+	_, err = to.Raw(sql, configId, source).Exec()
+	return
+}

+ 10 - 9
models/db.go

@@ -507,15 +507,16 @@ func initChartFramework() {
 // initExcel 初始化EXCEL
 func initExcel() {
 	orm.RegisterModel(
-		new(excel.ExcelClassify),   //ETA excel表格分类
-		new(excel.ExcelInfo),       //ETA excel表格
-		new(excel.ExcelDraft),      //ETA excel表格草稿
-		new(excel.ExcelSheet),      //ETA excel sheet
-		new(excel.ExcelSheetData),  //ETA excel sheet data
-		new(excel.ExcelEdbMapping), //ETA excel 与 指标 的关系表
-		new(excel.ExcelWorker),     // 平衡表协作人表格
-		new(excel.ExcelChartEdb),   // 平衡表做图指标
-		new(excel.ExcelChartData),  // 平衡表作图数据
+		new(excel.ExcelClassify),        //ETA excel表格分类
+		new(excel.ExcelInfo),            //ETA excel表格
+		new(excel.ExcelDraft),           //ETA excel表格草稿
+		new(excel.ExcelSheet),           //ETA excel sheet
+		new(excel.ExcelSheetData),       //ETA excel sheet data
+		new(excel.ExcelEdbMapping),      //ETA excel 与 指标 的关系表
+		new(excel.ExcelWorker),          // 平衡表协作人表格
+		new(excel.ExcelChartEdb),        // 平衡表做图指标
+		new(excel.ExcelChartData),       // 平衡表作图数据
+		new(excel.ExcelInfoRuleMapping), //表格的管理规则
 	)
 }
 

+ 90 - 0
routers/commentsRouter.go

@@ -1276,6 +1276,51 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "AddExcelRule",
+            Router: `/excel_info/rule/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "DeleteExcelRule",
+            Router: `/excel_info/rule/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "GetExcelRuleDetail",
+            Router: `/excel_info/rule/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "EditExcelRule",
+            Router: `/excel_info/rule/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "GetExcelRuleList",
+            Router: `/excel_info/rule/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:ExcelInfoController"],
         beego.ControllerComments{
             Method: "GetBatchEdbData",
@@ -4615,6 +4660,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "GetFenWeiFrequencyList",
+            Router: `/fenwei/frequency/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "GetFenWeiIndexInfo",
+            Router: `/fenwei/get/index/info`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "FenWeiIndexAdd",
+            Router: `/fenwei/index/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "FenWeiIndexAddValidate",
+            Router: `/fenwei/index/add/validate`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "FenweiIndexData",
@@ -4624,6 +4705,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "FenWeiIndexDataExport",
+            Router: `/fenwei/index/data/export`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "FenweiSearchList",

+ 180 - 0
services/data/base_from_fenwei_index_service.go

@@ -0,0 +1,180 @@
+// Package data
+// @Author gmy 2024/8/22 9:44:00
+package data
+
+import (
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// FenWeiIndexAddValidate 指标添加校验
+func FenWeiIndexAddValidate(indexCodes []string) (*[]data_manage.FenWeiIndexCheckData, error) {
+	// 根据指标编码获取指标库 指标信息
+	edbInfos, err := data_manage.GetEdbInfoByEdbCodeList(utils.DATA_SOURCE_FENWEI, indexCodes)
+	if err != nil {
+		return nil, err
+	}
+	var respList []data_manage.FenWeiIndexCheckData
+	if len(edbInfos) > 0 {
+		for _, ebdInfo := range edbInfos {
+			respList = append(respList, data_manage.FenWeiIndexCheckData{
+				IndexCode:  ebdInfo.EdbCode,
+				IndexName:  ebdInfo.EdbName,
+				Unit:       ebdInfo.Unit,
+				Frequency:  ebdInfo.Frequency,
+				EdbInfoId:  ebdInfo.EdbInfoId,
+				ClassifyId: ebdInfo.ClassifyId,
+				UniqueCode: ebdInfo.UniqueCode,
+			})
+		}
+	}
+	return &respList, nil
+}
+
+// FenWeiIndexNameCheck 指标名称校验
+func FenWeiIndexNameCheck(indexNames []string, resp []*data_manage.FenWeiNameCheckResult) ([]*data_manage.FenWeiNameCheckResult, error) {
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
+	if e != nil {
+		return nil, e
+	}
+	nameExists := make(map[string]bool)
+	for _, edbInfo := range edbList {
+		nameExists[edbInfo.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.IndexName]
+		}
+	}
+	return resp, nil
+}
+
+// FenWeiIndexAdd 批量添加指标
+func FenWeiIndexAdd(req data_manage.FenWeiIndexAddReq, lang string) (edb *data_manage.EdbInfo, err error, errMsg string, skip bool) {
+	if req.EdbCode == "" {
+		err = fmt.Errorf("指标ID为空")
+		return
+	}
+	defer func() {
+		if err != nil {
+			tips := fmt.Sprintf("BloombergIndexSource2Edb新增失败, Err: %s", err.Error())
+			utils.FileLog.Info(tips)
+		}
+	}()
+	source := utils.DATA_SOURCE_FENWEI
+
+	// 是否已有指标数据
+	dataList, e := data_manage.GetEdbDataAllByEdbCode(req.EdbCode, source, utils.DATA_SUB_SOURCE_EDB, utils.EDB_DATA_LIMIT)
+	if e != nil {
+		err = fmt.Errorf("获取指标数据失败, Err: %s", e.Error())
+		return
+	}
+
+	// 新增指标数据
+	if len(dataList) == 0 {
+		res, e := AddEdbData(source, req.EdbCode, req.Frequency)
+		if e != nil {
+			err = fmt.Errorf("index_lib: 新增指标数据失败, Err: %s", e.Error())
+			return
+		}
+		if res == nil {
+			err = fmt.Errorf("index_lib: 新增指标数据失败, res nil")
+			return
+		}
+		if res.Ret != 200 {
+			err = fmt.Errorf("index_lib: 新增指标数据失败, Ret: %d", res.Ret)
+			return
+		}
+	}
+
+	// 是否新增过指标
+	exist, e := data_manage.GetEdbInfoByEdbCode(source, req.EdbCode)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("获取指标是否存在失败, err: %s", e.Error())
+		return
+	}
+	if exist != nil {
+		skip = true
+		return
+	}
+
+	// 开始结束时间
+	var startDate, endDate string
+	minMax, e := data_manage.GetEdbInfoMaxAndMinInfo(source, utils.DATA_SUB_SOURCE_EDB, req.EdbCode)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = fmt.Errorf("MinMax: 获取指标极值失败, err: %s", e.Error())
+		return
+	}
+	if minMax != nil {
+		startDate = minMax.MinDate
+		endDate = minMax.MaxDate
+	}
+
+	// 新增指标到指标库
+	edbInfo, e, msg, _ := EdbInfoAdd(source, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, startDate, endDate, req.AdminId, req.AdminRealName, lang)
+	if e != nil {
+		errMsg = msg
+		err = fmt.Errorf("EdbInfo: 新增指标失败, err: %s", e.Error())
+		return
+	}
+	edb = edbInfo
+
+	// todo EdbInfoAdd方法已经新增es,这里不需要再新增???
+	// 新增es
+	// go AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+	return
+}
+
+// GetFenWeiIndexInfo 获取指标信息-分页
+func GetFenWeiIndexInfo(keyWord string, classifyIdList []string, frequencyList []string, currentIndex int, pageSize int) (baseFromFenWeiIndexPage *data_manage.BaseFromFenWeiIndexPage, err error) {
+
+	// 获取指标
+	var condition string
+	var pars []interface{}
+	if keyWord != "" {
+		condition += ` AND CONCAT(index_name,index_code) LIKE '%` + keyWord + `%'`
+	}
+	if len(classifyIdList) > 0 {
+		condition += ` AND classify_id IN (`
+		for _, v := range classifyIdList {
+			condition += `?,`
+			pars = append(pars, v)
+		}
+		condition = condition[:len(condition)-1] + `)`
+	}
+	if len(frequencyList) > 0 {
+		condition += ` AND frequency IN (`
+		for _, v := range frequencyList {
+			condition += `?,`
+			pars = append(pars, v)
+		}
+		condition = condition[:len(condition)-1] + `)`
+	}
+
+	count, err := data_manage.GetFenWeiIndexInfoCount(condition, pars)
+	if err != nil {
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, count)
+	if count <= 0 {
+		baseFromFenWeiIndexPage = &data_manage.BaseFromFenWeiIndexPage{
+			List:   []*data_manage.BaseFromFenweiIndex{},
+			Paging: page,
+		}
+		return
+	}
+
+	startSize := utils.StartIndex(currentIndex, pageSize)
+	fenWeiIndexInfoList, err := data_manage.GetFenWeiIndexInfoPage(condition, pars, startSize, pageSize)
+	if err != nil {
+		return
+	}
+	baseFromFenWeiIndexPage = &data_manage.BaseFromFenWeiIndexPage{
+		List:   fenWeiIndexInfoList,
+		Paging: page,
+	}
+	return
+}

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

@@ -14,7 +14,10 @@ import (
 	"eta/eta_api/utils"
 	"fmt"
 	"sort"
+	"strings"
 	"time"
+
+	"github.com/xuri/excelize/v2"
 )
 
 // GetExcelDetailInfoByExcelInfoId 根据表格id获取表格详情
@@ -649,3 +652,206 @@ func GetCustomAnalysisOpButton(sysUser *system.Admin, belongUserId int, permissi
 	}
 	return
 }
+
+func parseExcelScopeCoord(scopeList []string) (scopeCoord string, err error) {
+	if len(scopeList) == 2 {
+		x1, y1, er := excelize.CellNameToCoordinates(scopeList[0])
+		if er != nil {
+			return "", er
+		}
+		x2, y2, er := excelize.CellNameToCoordinates(scopeList[1])
+		if er != nil {
+			return "", er
+		}
+		scopeCoord = fmt.Sprintf("%d,%d,%d,%d", x1, y1, x2, y2)
+	}
+	if len(scopeList) == 1 {
+		x1, y1, er := excelize.CellNameToCoordinates(scopeList[0])
+		if er != nil {
+			return "", er
+		}
+		scopeCoord = fmt.Sprintf("%d,%d", x1, y1)
+	}
+	return
+}
+
+func ExcelRuleFormat(req *request.ExcelRuleMappingReq, lang string) (res *excel.ExcelInfoRuleMapping, err error) {
+	res = new(excel.ExcelInfoRuleMapping)
+	if req.RuleType == 5 {
+		switch req.LeftValue {
+		// 今天
+		case "today":
+			res.LeftValueShow = "今天"
+		// 明天
+		case "tomorrow":
+			res.LeftValueShow = "明天"
+		// 最近7天
+		case "last7days":
+			res.LeftValueShow = "最近7天"
+		// 上周
+		case "lastweek":
+			res.LeftValueShow = "上周"
+		// 本周
+		case "thisweek":
+			res.LeftValueShow = "本周"
+		// 下周
+		case "nextweek":
+			res.LeftValueShow = "下周"
+		// 上月
+		case "lastmonth":
+			res.LeftValueShow = "上月"
+		// 本月
+		case "thismonth":
+			res.LeftValueShow = "本月"
+		// 下月
+		case "nextmonth":
+			res.LeftValueShow = "下月"
+		default:
+			err = errors.New("发生日期规则错误")
+			return
+		}
+	}
+	// 格式化条件值
+	switch req.LeftValueType {
+	// 坐标
+	case 2:
+		x, y, err := excelize.CellNameToCoordinates(req.LeftValue)
+		if err != nil {
+			return nil, err
+		}
+		res.LeftValue = fmt.Sprintf("%d,%d", x, y)
+	default:
+		res.LeftValue = req.LeftValue
+	}
+	switch req.RightValueType {
+	// 坐标
+	case 2:
+		x, y, err := excelize.CellNameToCoordinates(req.RightValue)
+		if err != nil {
+			return nil, err
+		}
+		res.RightValue = fmt.Sprintf("%d,%d", x, y)
+		res.RightValueShow = req.RightValue
+	default:
+		res.RightValue = req.RightValue
+		res.RightValueShow = req.RightValue
+	}
+	if res.LeftValueShow == "" {
+		res.LeftValueShow = req.LeftValue
+	}
+	if res.RightValueShow == "" {
+		res.RightValueShow = req.RightValue
+	}
+	res.RuleType = req.RuleType
+	res.ExcelInfoId = req.ExcelInfoId
+	res.ExcelInfoRuleMappingId = req.ExcelRuleMappingId
+	res.LeftValueType = req.LeftValueType
+	res.RightValueType = req.RightValueType
+	res.FontColor = req.FontColor
+	res.BackgroundColor = req.BackgroundColor
+	res.Remark = req.Remark
+	res.RemarkEn = req.Remark
+	res.ScopeShow = req.Scope
+	scopeList := strings.Split(req.Scope, ":")
+	res.ScopeCoord, err = parseExcelScopeCoord(scopeList)
+	return
+}
+
+func AddExcelRule(req *request.ExcelRuleMappingReq, lang string) (err error) {
+	excelRule, err := ExcelRuleFormat(req, lang)
+	if err != nil {
+		return
+	}
+	if excelRule.ExcelInfoRuleMappingId != 0 {
+		return errors.New("规则已存在")
+	}
+	excelRule.CreateTime = time.Now()
+	_, err = excelRule.Insert()
+	return
+}
+
+func ModifyExcelRule(req *request.ExcelRuleMappingReq, lang string) (err error) {
+	excelInfo, err := excel.GetExcelRuleMappingById(req.ExcelRuleMappingId)
+	if err != nil {
+		return
+	}
+	editExcelInfo, err := ExcelRuleFormat(req, lang)
+	if err != nil {
+		return
+	}
+	var updateCols []string
+	if excelInfo.LeftValue != editExcelInfo.LeftValue {
+		updateCols = append(updateCols, "LeftValue")
+		updateCols = append(updateCols, "LeftValueShow")
+	}
+	if excelInfo.LeftValueType != editExcelInfo.LeftValueType {
+		updateCols = append(updateCols, "LeftValueType")
+	}
+	if excelInfo.RightValue != editExcelInfo.RightValue {
+		updateCols = append(updateCols, "RightValue")
+		updateCols = append(updateCols, "RightValueShow")
+	}
+	if excelInfo.RightValueType != editExcelInfo.RightValueType {
+		updateCols = append(updateCols, "RightValueType")
+	}
+	if excelInfo.FontColor != editExcelInfo.FontColor {
+		updateCols = append(updateCols, "FontColor")
+	}
+	if excelInfo.BackgroundColor != editExcelInfo.BackgroundColor {
+		updateCols = append(updateCols, "BackgroundColor")
+	}
+	if excelInfo.Remark != editExcelInfo.Remark {
+		updateCols = append(updateCols, "Remark")
+	}
+	if excelInfo.RemarkEn != editExcelInfo.RemarkEn {
+		updateCols = append(updateCols, "RemarkEn")
+	}
+	if excelInfo.ScopeShow != editExcelInfo.ScopeShow {
+		updateCols = append(updateCols, "ScopeCoord")
+		updateCols = append(updateCols, "ScopeShow")
+	}
+	if len(updateCols) > 0 {
+		err = editExcelInfo.Update(updateCols)
+	}
+
+	return
+}
+
+// GetExcelRuleList 获取规则列表
+func GetExcelRuleList(excelInfoId int) (resp *response.ExcelRuleListResp, err error) {
+	resp = new(response.ExcelRuleListResp)
+	excelInfoList, err := excel.GetExcelRuleMappingByExcelInfoId(excelInfoId)
+	if err != nil {
+		return
+	}
+	for _, v := range excelInfoList {
+		switch v.RuleType {
+		// 大于
+		case 1:
+			v.LeftValueShow = "大于" + v.LeftValueShow
+		// 小于
+		case 2:
+			v.LeftValueShow = "小于" + v.LeftValueShow
+		// 介于
+		case 3:
+			v.LeftValueShow = "介于" + v.LeftValueShow + "到" + v.RightValueShow
+		// 等于
+		case 4:
+			v.LeftValueShow = "等于" + v.LeftValueShow
+		}
+	}
+
+	resp.List = excelInfoList
+	return
+}
+
+// GetExcelRuleDetail 获取规则列表
+func GetExcelRuleDetail(excelInfoMappingId int) (resp *excel.ExcelInfoRuleMappingView, err error) {
+	resp = new(excel.ExcelInfoRuleMappingView)
+	excelInfoDetail, err := excel.GetExcelRuleMappingById(excelInfoMappingId)
+	if err != nil {
+		return
+	}
+	resp = excelInfoDetail
+	return
+}

+ 8 - 0
services/data/excel/mixed_table.go

@@ -1221,6 +1221,14 @@ func handleMixCellShowStyle(showStyleList []string, calculateCellMap map[string]
 			} else {
 				cell.ShowFormatValue = cell.ShowValue
 			}
+			// 前端传过来的json中有可能有glObj,需要去掉
+			if styleConf.GlObj != nil {
+				styleConf.GlObj = nil
+				tmpStyleConf, err := json.Marshal(styleConf)
+				if err == nil {
+					cell.ShowStyle = string(tmpStyleConf)
+				}
+			}
 			config[cellPosition.Column][cellPosition.Row] = cell
 		}
 	}

+ 79 - 29
services/data/range_analysis/chart_info.go

@@ -173,8 +173,8 @@ func HandleDataByCalculateType(originList []*data_manage.ChartRangeAnalysisDateD
 					if len(calDataList) == 0 {
 						continue
 					}
-					baseVal = calDataList[len(calDataList)-1].Value
-					baseDate := calDataList[len(calDataList)-1].DataTime
+					baseVal = calDataList[0].Value
+					baseDate := calDataList[0].DataTime
 					if baseVal == 0 {
 						continue
 					}
@@ -196,8 +196,8 @@ func HandleDataByCalculateType(originList []*data_manage.ChartRangeAnalysisDateD
 				if len(item.DataList) == 0 {
 					break
 				}
-				baseVal := item.DataList[len(item.DataList)-1].Value
-				baseDate := item.DataList[len(item.DataList)-1].DataTime
+				baseVal := item.DataList[0].Value
+				baseDate := item.DataList[0].DataTime
 				if baseVal == 0 {
 					break
 				}
@@ -229,8 +229,8 @@ func HandleDataByCalculateType(originList []*data_manage.ChartRangeAnalysisDateD
 					if len(calDataList) == 0 {
 						continue
 					}
-					baseVal = calDataList[len(calDataList)-1].Value
-					baseDate = calDataList[len(calDataList)-1].DataTime
+					baseVal = calDataList[0].Value
+					baseDate = calDataList[0].DataTime
 					if v.DataTime == baseDate {
 						continue
 					}
@@ -261,8 +261,8 @@ func HandleDataByCalculateType(originList []*data_manage.ChartRangeAnalysisDateD
 				if len(item.DataList) == 0 {
 					break
 				}
-				baseVal := item.DataList[len(item.DataList)-1].Value
-				baseDate := item.DataList[len(item.DataList)-1].DataTime
+				baseVal := item.DataList[0].Value
+				baseDate := item.DataList[0].DataTime
 				if baseVal == 0 {
 					break
 				}
@@ -503,13 +503,32 @@ func GetChartDataByEdbInfoList(chartInfoId int, dateType, startYear int, startDa
 	}
 	dataResp = data_manage.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req}
 	if req.MultipleGraphConfigId > 0 {
+		//判断MultipleGraphConfigId和图表关系是否正确
 		multipleGraphConfigEdbMappingList, e := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
 		if e != nil && e.Error() != utils.ErrNoRow() {
 			err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
 			return
 		}
-		// 查询是否已经生成指标
-		dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
+		if len(multipleGraphConfigEdbMappingList) > 0 {
+			// 查询指标是否已存在,如果已经被删除了,则返回0值
+			edbIds := make([]int, 0)
+			for _, v := range multipleGraphConfigEdbMappingList {
+				edbIds = append(edbIds, v.EdbInfoId)
+			}
+			var condition string
+			var pars []interface{}
+			condition = " AND edb_info_id in (" + utils.GetOrmInReplace(len(edbIds)) + ") "
+			pars = append(pars, edbIds)
+			count, e := data_manage.GetEdbInfoCountByCondition(condition, pars)
+			if e != nil {
+				err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
+				return
+			}
+			if count > 0 {
+				// 查询是否已经生成指标
+				dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
+			}
+		}
 	}
 	edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
 	if err != nil {
@@ -633,8 +652,26 @@ func GetChartDataByEdbInfoListBySeries(chartInfoId int, dateType, startYear int,
 			err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
 			return
 		}
-		// 查询是否已经生成指标
-		dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
+		if len(multipleGraphConfigEdbMappingList) > 0 {
+			// 查询指标是否已存在,如果已经被删除了,则返回0值
+			edbIds := make([]int, 0)
+			for _, v := range multipleGraphConfigEdbMappingList {
+				edbIds = append(edbIds, v.EdbInfoId)
+			}
+			var condition string
+			var pars []interface{}
+			condition = " edb_info_id in (" + utils.GetOrmInReplace(len(edbIds)) + ") "
+			pars = append(pars, edbIds)
+			count, e := data_manage.GetEdbInfoCountByCondition(condition, pars)
+			if e != nil {
+				err = fmt.Errorf("获取区间计算图表, 指标信息失败, Err:" + e.Error())
+				return
+			}
+			if count > 0 {
+				// 查询是否已经生成指标
+				dataResp.ConfigEdbNum = len(multipleGraphConfigEdbMappingList)
+			}
+		}
 	}
 
 	edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
@@ -655,19 +692,20 @@ func getChartDataByEdbInfo(edbInfoMapping *data_manage.ChartEdbInfoMapping, req
 	edbEndDate := edbEndDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
 
 	// 获取时间基准指标在时间区间内的值
-	dataListTmp := make([]*data_manage.EdbDataList, 0)
+	dataList := make([]*data_manage.EdbDataList, 0)
 	switch edbInfoMapping.EdbInfoCategoryType {
 	case 0:
-		dataListTmp, err = data_manage.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, "", "")
+		dataList, err = data_manage.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, "", "")
 	case 1:
-		_, dataListTmp, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfoMapping.EdbInfoId, "", "", false)
+		_, dataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(edbInfoMapping.EdbInfoId, "", "", false)
 	default:
 		err = errors.New("指标base类型异常")
 		return
 	}
-	var dataList data_manage.SortEdbDataList
+	/*var dataList data_manage.SortEdbDataList
 	dataList = dataListTmp
-	sort.Sort(dataList)
+	ascDataList := dataListTmp
+	sort.Sort(dataList)*/
 	dateList := make([]*data_manage.ChartRangeAnalysisDateDataItem, 0)
 	switch req.DateRangeType {
 	case 0:
@@ -1409,6 +1447,21 @@ func EditChartInfo(req data_manage.EditChartInfoReq, sysUser *system.Admin, lang
 func CopyChartInfo(classifyId int, chartName string, oldChartInfo *data_manage.ChartInfo, sysUser *system.Admin, lang string) (chartInfo *data_manage.ChartInfo, err error, errMsg string, isSendEmail bool) {
 	isSendEmail = true
 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	var extraConfig data_manage.ChartRangeAnalysisExtraConf
+	err = json.Unmarshal([]byte(oldChartInfo.ExtraConfig), &extraConfig)
+	if err != nil {
+		errMsg = "配置信息错误"
+		err = errors.New(errMsg + ", Err: " + err.Error())
+		return
+	}
+	extraConfig.MultipleGraphConfigId = 0
+	newExtraConfigBytes, err := json.Marshal(extraConfig)
+	if err != nil {
+		errMsg = "配置信息错误"
+		err = errors.New(errMsg + ", Err: " + err.Error())
+		return
+	}
+	newExtraConfig := string(newExtraConfigBytes)
 	chartInfo = &data_manage.ChartInfo{
 		ChartInfoId:     0,
 		ChartName:       chartName,
@@ -1438,7 +1491,7 @@ func CopyChartInfo(classifyId int, chartName string, oldChartInfo *data_manage.C
 		Right2Max:         oldChartInfo.Right2Max,
 		Disabled:          oldChartInfo.Disabled,
 		Source:            oldChartInfo.Source,
-		ExtraConfig:       oldChartInfo.ExtraConfig,
+		ExtraConfig:       newExtraConfig,
 		SeasonExtraConfig: oldChartInfo.SeasonExtraConfig,
 		StartYear:         oldChartInfo.StartYear,
 		Unit:              oldChartInfo.Unit,
@@ -1455,7 +1508,7 @@ func CopyChartInfo(classifyId int, chartName string, oldChartInfo *data_manage.C
 		return
 	}
 	chartInfo.ChartInfoId = int(newId)
-	edbInfoMappingList, err := data_manage.GetChartEdbMappingList(oldChartInfo.ChartInfoId)
+	edbInfoMappingList, err := data_manage.GetChartMappingList(oldChartInfo.ChartInfoId)
 	if err != nil {
 		err = fmt.Errorf("获取图表,指标信息失败,Err:" + err.Error())
 		return
@@ -1513,13 +1566,7 @@ func CopyChartInfo(classifyId int, chartName string, oldChartInfo *data_manage.C
 	} else {
 		// 新增指标系列
 		// 区间计算图表配置校验
-		var extraConfig data_manage.ChartRangeAnalysisExtraConf
-		err = json.Unmarshal([]byte(chartInfo.ExtraConfig), &extraConfig)
-		if err != nil {
-			errMsg = "配置信息错误"
-			err = errors.New(errMsg + ", Err: " + err.Error())
-			return
-		}
+
 		err = AddSeries(edbInfoIdArr, chartInfo.ChartInfoId, utils.CHART_SOURCE_RANGE_ANALYSIS, extraConfig, chartInfo.ExtraConfig)
 		if err != nil {
 			errMsg = "操作失败"
@@ -1827,17 +1874,20 @@ func FormatChartEdbInfoMappings(chartInfoId int, mappings []*data_manage.ChartEd
 func GetEdbDateByMoveForward(startDate string, moveForward int, edbDataList []*data_manage.EdbDataList) (date string) {
 	// 根据日期进行排序
 	index := 0
-	for _, v := range edbDataList {
-		if v.DataTime == startDate {
+	length := len(edbDataList)
+	for i := length - 1; i >= 0; i-- {
+		item := edbDataList[i]
+		if item.DataTime == startDate {
 			index += 1
 			continue
 		}
 		if index >= moveForward {
-			date = v.DataTime
+			date = item.DataTime
 			break
 		}
 		if index > 0 {
 			index += 1
+			date = item.DataTime
 		}
 	}
 	return

+ 13 - 2
services/excel/lucky_sheet.go

@@ -6,13 +6,14 @@ import (
 	"eta/eta_api/models/data_manage/excel/request"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/tealeg/xlsx"
-	"github.com/xuri/excelize/v2"
 	"os"
 	"reflect"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/tealeg/xlsx"
+	"github.com/xuri/excelize/v2"
 )
 
 type LuckySheetDataBak struct {
@@ -1739,8 +1740,18 @@ func GetTableDataByMixedTableData(config [][]request.MixedTableCellDataReq, hide
 					tmp.MergeCell.Column = cell.MerData.Mer.Col
 				}
 				if cell.ShowStyle != "" {
+					var styleConfig request.MixCellShowStyle
+					if err := json.Unmarshal([]byte(cell.ShowStyle), &styleConfig); err != nil {
+						utils.FileLog.Info("表格样式showStyle解析失败", err.Error())
+					}
 					showFormatValue := fmt.Sprintf("%v", cell.ShowFormatValue)
 					tmp.Monitor = showFormatValue
+					if styleConfig.BackgroundColor != "" {
+						tmp.Background = styleConfig.BackgroundColor
+					}
+					if styleConfig.Color != "" {
+						tmp.FontColor = styleConfig.Color
+					}
 				}
 				dataCol = append(dataCol, tmp)
 			}

+ 222 - 0
services/excel/lucky_sheet_table.go

@@ -1,8 +1,13 @@
 package excel
 
 import (
+	"eta/eta_api/models/data_manage/excel"
+	"eta/eta_api/utils"
 	"fmt"
 	"sort"
+	"strconv"
+	"strings"
+	"time"
 )
 
 // HandleTableCell 前端d毛需要我根据合并单元格处理掉多余的单元格
@@ -99,3 +104,220 @@ func handleCellVal(tmpTableColData LuckySheetDataValue) (valueStr string) {
 	}
 	return
 }
+
+// HandleRuleToTableCell 根据管理规则渲染单元格数据
+func HandleRuleToTableCell(excelInfoId int, oldTableData TableData) (newTableData TableData, err error) {
+	newTableData = oldTableData
+	excelRuleMappingList, err := excel.GetExcelRuleMappingByExcelInfoId(excelInfoId)
+	if err != nil {
+		return
+	}
+	if len(excelRuleMappingList) == 0 {
+		return
+	}
+	tableDataList := oldTableData.TableDataList
+	excelRuleMap := make(map[int]*excel.ExcelInfoRuleMappingView)
+	for _, v := range excelRuleMappingList {
+		excelRuleMap[v.ExcelInfoRuleMappingId] = v
+	}
+	ruleScopeMap := generateRuleScopeIndexMap(excelRuleMappingList)
+	for row, scopeValues := range ruleScopeMap {
+		for col, ruleId := range scopeValues {
+			if v, ok := excelRuleMap[ruleId]; ok {
+				if len(tableDataList) > row && len(tableDataList[row]) > col {
+					// 符合管理规则要求,则进行字体和背景颜色的渲染
+					if checkCellRule(v, tableDataList[row][col].Monitor, tableDataList) {
+						tableDataList[row][col].Background = v.BackgroundColor
+						tableDataList[row][col].FontColor = v.FontColor
+					}
+				} else {
+					continue
+				}
+			} else {
+				continue
+			}
+		}
+	}
+	return
+}
+
+func getCellValueByType(value string, valueType int, tableDataList [][]LuckySheetDataValue) (float64, bool) {
+	if valueType == 2 {
+		coords := strings.Split(value, ",")
+		var coordIntArr []int
+		for _, v := range coords {
+			t, _ := strconv.Atoi(v)
+			coordIntArr = append(coordIntArr, t)
+		}
+		if len(coordIntArr) == 2 {
+			x, y := coordIntArr[0]-1, coordIntArr[1]-1
+			conditionValue, err := strconv.ParseFloat(tableDataList[x][y].Monitor, 64)
+			if err == nil {
+				return 0, false
+			}
+			return conditionValue, true
+		}
+	} else {
+		conditionValue, err := strconv.ParseFloat(value, 64)
+		if err != nil {
+			return 0, false
+		}
+		return conditionValue, true
+	}
+	return 0, false
+}
+
+func checkCellRule(ruleInfo *excel.ExcelInfoRuleMappingView, value string, tableDataList [][]LuckySheetDataValue) bool {
+	var tableValue float64
+	var tableTime time.Time
+	var err error
+
+	if ruleInfo.RuleType == 5 {
+		tableTime, err = time.Parse(utils.FormatDate, value)
+		if err != nil {
+			return false
+		}
+	} else {
+		tableValue, err = strconv.ParseFloat(value, 64)
+		if err != nil {
+			return false
+		}
+	}
+	switch ruleInfo.RuleType {
+	// 大于
+	case 1:
+		conditionValue, ok := getCellValueByType(ruleInfo.LeftValue, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if tableValue > conditionValue {
+			return true
+		}
+	// 小于
+	case 2:
+		conditionValue, ok := getCellValueByType(ruleInfo.LeftValue, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if tableValue < conditionValue {
+			return true
+		}
+	// 介于
+	case 3:
+		leftcondValue, ok := getCellValueByType(ruleInfo.LeftValue, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		rightcondValue, ok := getCellValueByType(ruleInfo.RightValue, ruleInfo.RightValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if leftcondValue <= tableValue && tableValue <= rightcondValue {
+			return true
+		}
+	// 等于
+	case 4:
+		conditionValue, ok := getCellValueByType(ruleInfo.LeftValue, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if tableValue == conditionValue {
+			return true
+		}
+	// 发生日期
+	case 5:
+		// 发生日期
+		var dateStart, dataEnd time.Time
+		switch value {
+		// 今天
+		case "today":
+			// 获得今天的零点零分零秒
+			dateStart = utils.Today()
+			if tableTime == dateStart {
+				return true
+			}
+		// 明天
+		case "tomorrow":
+			dateStart = utils.Tomorrow()
+			if tableTime == dateStart {
+				return true
+			}
+		// 最近7天
+		case "last7days":
+			dateStart, dataEnd = utils.Last7Days()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 上周
+		case "lastweek":
+			dateStart, dataEnd = utils.LastWeek()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 本周
+		case "thisweek":
+			dateStart, dataEnd = utils.ThisWeek()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 下周
+		case "nextweek":
+			dateStart, dataEnd = utils.NextWeek()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 上月
+		case "lastmonth":
+			dateStart, dataEnd = utils.LastMonth()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 本月
+		case "thismonth":
+			dateStart, dataEnd = utils.ThisMonth()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 下月
+		case "nextmonth":
+			dateStart, dataEnd = utils.NextMonth()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		default:
+			return false
+		}
+
+	}
+	return false
+}
+
+func generateRuleScopeIndexMap(items []*excel.ExcelInfoRuleMappingView) (ruleScopeMap map[int]map[int]int) {
+	ruleScopeMap = make(map[int]map[int]int)
+	for _, item := range items {
+		coords := strings.Split(item.ScopeCoord, ",")
+		var coordIntArr []int
+		for _, v := range coords {
+			t, _ := strconv.Atoi(v)
+			coordIntArr = append(coordIntArr, t)
+		}
+
+		if len(coords) == 4 {
+			xmin, ymin, xmax, ymax := coordIntArr[0]-1, coordIntArr[1]-1, coordIntArr[2]-1, coordIntArr[3]-1
+			for i := ymin; i <= ymax; i++ {
+				for j := xmin; j <= xmax; j++ {
+					if _, ok := ruleScopeMap[i]; !ok {
+						ruleScopeMap[i] = make(map[int]int)
+					}
+					ruleScopeMap[i][j] = item.ExcelInfoRuleMappingId
+				}
+			}
+		}
+		if len(coords) == 2 {
+			x, y := coordIntArr[0]-1, coordIntArr[1]-1
+			ruleScopeMap[y] = make(map[int]int)
+			ruleScopeMap[y][x] = item.ExcelInfoRuleMappingId
+		}
+	}
+	return
+}

+ 0 - 1
services/smart_report.go

@@ -141,7 +141,6 @@ func ReportToPdf(width int, reportUrl, filePath string) (err error) {
 import asyncio
 from pyppeteer import launch
 
-@asyncio.coroutine
 async def main():
     # 异步代码
     browser = await launch({

+ 3 - 1
utils/constants.go

@@ -179,6 +179,7 @@ const (
 	DATA_SOURCE_CALCULATE_RANGEANLYSIS               = 87       //区间计算->87
 	DATA_SOURCE_PREDICT_CALCULATE_RANGEANLYSIS       = 90       // 预测指标区间计算->90
 	DATA_SOURCE_LY                                   = 91       // 粮油商务网
+	DATA_SOURCE_FENWEI                               = 77       // 汾渭数据->92
 )
 
 // 数据刷新频率
@@ -241,7 +242,7 @@ const (
 	CACHE_CREATE_REPORT_IMGPDF_QUEUE = "eta_report:report_img_pdf_queue" // 生成报告长图PDF队列
 	CACHE_EDB_TERMINAL_CODE_URL      = "edb:terminal_code:edb_code:"     // 指标与终端关系的缓存
 
-	CACHE_KEY_REPLACE_EDB = "eta:replace_edb1" //系统用户操作日志队列
+	CACHE_KEY_REPLACE_EDB = "eta:replace_edb" //系统用户操作日志队列
 )
 
 // 模板消息推送类型
@@ -479,6 +480,7 @@ const (
 	EdbBaseCalculateLjzNczj              = 14 // 累计值年初至今->14
 	EdbBaseCalculateExponentialSmoothing = 15 // 指数修匀->15
 	EdbBaseCalculateRjz                  = 16 // 日均值->16
+
 )
 
 // MultiAddNum 批量插入的数据量

+ 65 - 0
utils/time.go

@@ -0,0 +1,65 @@
+package utils
+
+import "time"
+
+// 获取今天的日期(零点零分零秒)
+func Today() time.Time {
+	return time.Now().Round(0).UTC().Local()
+}
+
+// 获取明天的日期(零点零分零秒)
+func Tomorrow() time.Time {
+	return Today().AddDate(0, 0, 1)
+}
+
+// 获取最近7天的日期范围
+func Last7Days() (time.Time, time.Time) {
+	today := Today()
+	return today.AddDate(0, 0, -6), today
+}
+
+// 获取上周的日期范围
+func LastWeek() (time.Time, time.Time) {
+	start := Today().AddDate(0, 0, -7)
+	end := start.AddDate(0, 0, 6)
+	return start, end
+}
+
+// 获取本周的日期范围
+func ThisWeek() (time.Time, time.Time) {
+	start := time.Now().Round(0).Local().AddDate(0, 0, 0-int(time.Now().Weekday())+1) // 0是本周的第一天,+1是因为AddDate是相对于当前时间的
+	end := start.AddDate(0, 0, 6)
+	return start, end
+}
+
+// 获取下周的日期范围
+func NextWeek() (time.Time, time.Time) {
+	_, thisEnd := ThisWeek()
+	start := thisEnd.AddDate(0, 0, 1)
+	end := start.AddDate(0, 0, 6)
+	return start, end
+}
+
+// 获取上月的日期范围
+func LastMonth() (time.Time, time.Time) {
+	today := time.Now()
+	year, month, _ := today.Date()
+	start := time.Date(year, month-1, 1, 0, 0, 0, 0, today.Location())
+	end := time.Date(year, month, 0, 23, 59, 59, 999999999, today.Location())
+	return start, end
+}
+
+// 获取本月的日期范围
+func ThisMonth() (time.Time, time.Time) {
+	today := time.Now()
+	year, month, _ := today.Date()
+	start := time.Date(year, month, 1, 0, 0, 0, 0, today.Location())
+	end := time.Date(year, month+1, 0, 23, 59, 59, 999999999, today.Location())
+	return start, end
+}
+
+// 获取下月的日期范围
+func NextMonth() (time.Time, time.Time) {
+	start, end := ThisMonth()
+	return end.AddDate(0, 0, 1), start.AddDate(0, 1, 0)
+}