Browse Source

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

zwxi 8 months ago
parent
commit
cb101bada2

+ 586 - 8
controllers/data_manage/eia_steo.go

@@ -1,14 +1,23 @@
 package data_manage
 
 import (
-	"github.com/rdlucklib/rdluck_tools/paging"
-	"github.com/tealeg/xlsx"
+	"encoding/json"
 	"eta/eta_api/models"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/system"
+	"eta/eta_api/services/data"
+	"eta/eta_api/services/data_stat"
+	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
+	"fmt"
 	"os"
 	"path/filepath"
+	"strconv"
+	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/tealeg/xlsx"
 )
 
 // EiaSteoClassify
@@ -35,16 +44,24 @@ func (this *EdbInfoController) EiaSteoClassify() {
 		br.ErrMsg = "获取分类失败,Err:" + err.Error()
 		return
 	}
+	childClassifyMap := make(map[int][]*data_manage.BaseFromEiaSteoClassifyView)
+	rootList := make([]*data_manage.BaseFromEiaSteoClassifyView, 0)
 	for _, v := range classifyList {
-		if v.ClassifyName == `` {
-			v.ClassifyName = v.ClassifyNameOriginal
+		if v.Level == 1 {
+			rootList = append(rootList, v)
+		} else {
+			childClassifyMap[v.ParentId] = append(childClassifyMap[v.ParentId], v)
+		}
+	}
+	for _, v := range rootList {
+		if existItems, ok := childClassifyMap[v.BaseFromEiaSteoClassifyId]; ok {
+			v.Child = existItems
 		}
 	}
-
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"
-	br.Data = classifyList
+	br.Data = rootList
 }
 
 // EiaSteoData
@@ -98,8 +115,18 @@ func (this *EdbInfoController) EiaSteoData() {
 	}
 	classifyId, _ := this.GetInt("BaseFromEiaSteoClassifyId")
 	if classifyId > 0 {
-		condition += ` AND base_from_eia_steo_classify_id = ? `
-		pars = append(pars, classifyId)
+		classifyList, err := data.GetClassifyALLById(classifyId)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取分类数据失败,Err:" + err.Error()
+			return
+		}
+		var classifyIds []int
+		for _, v := range classifyList {
+			classifyIds = append(classifyIds, v.BaseFromEiaSteoClassifyId)
+		}
+		condition += ` AND base_from_eia_steo_classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) `
+		pars = append(pars, classifyIds)
 	}
 
 	//获取指标
@@ -289,3 +316,554 @@ func EiaSteoDataExport(this *EdbInfoController, list []data_manage.EiaSteoIndexL
 	br.Success = true
 	br.Msg = "success"
 }
+
+// EiaSteoBatchSearch
+// @Title EiaSteo批量操作查询接口
+// @Description EiaSteo批量操作查询接口
+// @Param   BaseFromEiaSteoClassifyIds   query   string  true       "分类id"
+// @Param   Keyword   query   string  true       "名称关键词"
+// @Success 200 {object} data_manage.LzFrequency
+// @router /eia_steo/batch_search [get]
+func (this *EdbInfoController) EiaSteoBatchSearch() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	classifyIdStr := this.GetString("BaseFromEiaSteoClassifyIds")
+
+	var condition string
+	var pars []interface{}
+	classifyIds := strings.Split(classifyIdStr, ",")
+	if len(classifyIds) > 0 && classifyIds[0] != `` {
+		condition += " AND base_from_eia_steo_classify_id IN (" + utils.GetOrmInReplace(len(classifyIds)) + " ) "
+		pars = append(pars, classifyIds)
+	}
+	keyword := this.GetString("Keyword")
+	if keyword != `` {
+		condition += " AND (index_name like ? OR index_code like ?) "
+		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
+	}
+
+	if classifyIdStr == `` && keyword == `` {
+		var list = make([]*data_manage.BaseFromEiaSteoIndex, 0)
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = list
+		return
+	}
+
+	list, err := data_manage.GetEiaSteoIndexList(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// AddCheck
+// @Title 新增校验
+// @Description 新增校验
+// @Param	request	body request.BusinessDataBatchAddCheckReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /eia_steo/edb_info/add_check [post]
+func (c *EdbInfoController) EiaSteoAddCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 data_manage.EiaSteoDataBatchAddCheckReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	codeMax := 30
+	codeLen := len(req.IndexCodes)
+	if codeLen == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	if codeLen > codeMax {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+		return
+	}
+
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_EIA_STEO)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取自有数据已添加的指标失败, Err: " + e.Error()
+		return
+	}
+	existMap := make(map[string]*data_manage.EdbInfo)
+	for _, v := range existsEdb {
+		existMap[v.EdbCode] = v
+	}
+
+	// 查询选中的指标
+	cond := fmt.Sprintf(` AND index_code IN (%s) `, utils.GetOrmInReplace(len(req.IndexCodes)))
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.IndexCodes)
+	list, err := data_manage.GetEiaSteoIndexList(cond, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取eiaSteo原始指标列表失败, Err: " + err.Error()
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromEiaSteoIndexItem, 0)
+	for _, v := range list {
+		if edbInfo, ok := existMap[v.IndexCode]; ok {
+			resp = append(resp, &data_manage.BaseFromEiaSteoIndexItem{
+				BaseFromEiaSteoIndexId:    v.BaseFromEiaSteoIndexId,
+				BaseFromEiaSteoClassifyId: v.BaseFromEiaSteoClassifyId,
+				IndexCode:                 v.IndexCode,
+				IndexName:                 v.IndexName,
+				EdbInfoId:                 edbInfo.EdbInfoId,
+				EdbUniqueCode:             edbInfo.UniqueCode,
+				EdbClassifyId:             edbInfo.ClassifyId,
+				EdbExist:                  1,
+			})
+		} else {
+			resp = append(resp, &data_manage.BaseFromEiaSteoIndexItem{
+				BaseFromEiaSteoIndexId:    v.BaseFromEiaSteoIndexId,
+				BaseFromEiaSteoClassifyId: v.BaseFromEiaSteoClassifyId,
+				IndexCode:                 v.IndexCode,
+				IndexName:                 v.IndexName,
+				EdbInfoId:                 0,
+				EdbUniqueCode:             "",
+				EdbClassifyId:             0,
+				EdbExist:                  0,
+			})
+		}
+	}
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// EiaSteoNameCheck
+// @Title 重名校验
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /eia_steo/name_check [post]
+func (c *EdbInfoController) EiaSteoNameCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		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 []*data_manage.NameCheckEdbInfoReq
+	if e := json.Unmarshal(c.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	if len(req) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+	codeMax := 30
+	codeLen := len(req)
+	if codeLen > codeMax {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+		return
+	}
+
+	type NameCheckResult struct {
+		EdbCode string
+		EdbName string
+		Exist   bool
+	}
+	indexNames := make([]string, 0)
+	resp := make([]*NameCheckResult, 0)
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		indexNames = append(indexNames, v.EdbName)
+		resp = append(resp, &NameCheckResult{
+			EdbCode: v.EdbCode,
+			EdbName: v.EdbName,
+		})
+		dataItems, err := data_manage.GetEdbDataAllByEdbCode(v.EdbCode, utils.DATA_SOURCE_EIA_STEO, 0, utils.EDB_DATA_LIMIT)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
+			return
+		}
+		if len(dataItems) <= 0 {
+			respItem, err := data.AddEdbData(utils.DATA_SOURCE_EIA_STEO, v.EdbCode, v.Frequency)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			if respItem.Ret != 200 {
+				br.Msg = "未搜索到该指标"
+				br.ErrMsg = respItem.ErrMsg + ";EdbCode:" + v.EdbCode
+				return
+			}
+		}
+	}
+
+	// 重名校验
+	edbList, e := data_manage.GetEdbInfoByNameArr(indexNames, utils.EDB_INFO_TYPE)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取重名指标失败, Err: " + e.Error()
+		return
+	}
+	nameExists := make(map[string]bool)
+	for _, v := range edbList {
+		nameExists[v.EdbName] = true
+	}
+	if len(nameExists) > 0 {
+		for _, v := range resp {
+			v.Exist = nameExists[v.EdbName]
+		}
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// EiaSteoBatchAdd
+// @Title eiaSteo批量新增
+// @Description eiaSteo批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /eia_steo/batch_add [post]
+func (this *EdbInfoController) EiaSteoBatchAdd() {
+	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_EIA_STEO_" + 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
+	}
+	if len(req) > 30 {
+		br.Msg = "批量添加指标数量不得超过30个"
+		return
+	}
+	for _, v := range req {
+		v.EdbCode = strings.TrimSpace(v.EdbCode)
+		if v.EdbCode == "" {
+			br.Msg = "指标ID不可为空"
+			return
+		}
+		v.EdbName = strings.TrimSpace(v.EdbName)
+		if v.EdbName == "" {
+			br.Msg = "请输入指标名称"
+			return
+		}
+		v.Frequency = strings.TrimSpace(v.Frequency)
+		if v.Frequency == "" {
+			br.Msg = "请选择频度"
+			return
+		}
+		v.Unit = strings.TrimSpace(v.Unit)
+		if v.Unit == "" {
+			br.Msg = "请输入单位"
+			return
+		}
+		if v.ClassifyId <= 0 {
+			br.Msg = "请选择分类"
+			return
+		}
+	}
+
+	// 限定同一时间最多批量新增30个指标
+	for _, v := range req {
+		var r data.EiaSteoIndexSource2EdbReq
+		r.EdbCode = v.EdbCode
+		r.EdbName = v.EdbName
+		r.Frequency = v.Frequency
+		r.Unit = v.Unit
+		r.ClassifyId = v.ClassifyId
+		r.AdminId = sysUser.AdminId
+		r.AdminRealName = sysUser.RealName
+
+		edbInfo, e, errMsg, skip := data.EiaSteoIndexSource2Edb(r, this.Lang)
+		if e != nil {
+			br.Msg = "操作失败"
+			if errMsg != "" {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = e.Error()
+			return
+		}
+		if skip {
+			continue
+		}
+
+		// 试用平台更新用户累计新增指标数
+		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
+}
+
+// EiaSteoAdd
+// @Title 新增eiaSteo指标接口
+// @Description 新增eiaSteo指标接口
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /eia_steo/edb_info/add [post]
+func (this *EdbInfoController) EiaSteoAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		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_ADD_" + 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
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	req.EdbName = strings.Trim(req.EdbName, " ")
+	req.EdbCode = strings.Trim(req.EdbCode, " ")
+
+	if req.EdbCode == "" {
+		br.Msg = "指标ID不能为空"
+		return
+	}
+
+	if req.EdbName == "" {
+		br.Msg = "指标名称不能为空"
+		return
+	}
+
+	if req.Frequency == "" {
+		br.Msg = "频率不能为空"
+		return
+	}
+
+	if req.Unit == "" {
+		br.Msg = "单位不能为空"
+		return
+	}
+
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+
+	tmpInfo, err := data_manage.GetBaseFromEiaSteoIndexByCode(req.EdbCode)
+	if err != nil {
+		if err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + err.Error()
+			return
+		}
+	}
+	var source int
+	if tmpInfo != nil {
+		source = utils.DATA_SOURCE_EIA_STEO
+	} else {
+		br.Msg = "指标不存在"
+		return
+	}
+
+	// 指标入库
+	edbInfo, err, errMsg, isSendEmail := data.EdbInfoAdd(source, utils.DATA_SUB_SOURCE_EDB, req.ClassifyId, req.EdbCode, req.EdbName, req.Frequency, req.Unit, req.StartDate, req.EndDate, sysUser.AdminId, sysUser.RealName, this.Lang)
+	if err != nil {
+		br.Msg = "保存失败"
+		if errMsg != `` {
+			br.Msg = errMsg
+		}
+		br.ErrMsg = err.Error()
+		br.IsSendEmail = isSendEmail
+		return
+	}
+
+	// 试用平台更新用户累计新增指标数
+	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取系统用户数据失败,Err:" + e.Error()
+		return
+	}
+	if utils.BusinessCode == utils.BusinessCodeSandbox && adminItem.DepartmentName == "ETA试用客户" {
+		go func() {
+			var r etaTrialService.EtaTrialUserReq
+			r.Mobile = adminItem.Mobile
+			_, _ = etaTrialService.UpdateUserIndexNum(r)
+		}()
+	}
+
+	//新增操作日志
+	{
+		// 添加钢联指标更新日志
+		if edbInfo.Source == utils.DATA_SOURCE_MYSTEEL_CHEMICAL {
+			go data_stat.AddEdbInfoUpdateLog(edbInfo.EdbInfoId, 1, "", sysUser, 2)
+		}
+
+		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)
+	}
+
+	// 更新es
+	go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+
+	resp := new(data_manage.AddEdbInfoResp)
+	resp.EdbInfoId = edbInfo.EdbInfoId
+	resp.UniqueCode = edbInfo.UniqueCode
+	resp.ClassifyId = edbInfo.ClassifyId
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+	br.IsAddLog = true
+}

+ 0 - 271
controllers/data_manage/excel/custom_analysis.go

@@ -1152,274 +1152,3 @@ func (c *CustomAnalysisController) ShareDetail() {
 	br.Success = true
 	br.Msg = "获取成功"
 }
-
-// CustomAnalysisCommonController 修复数据用的
-type CustomAnalysisCommonController struct {
-	controllers.BaseCommonController
-}
-
-//var OnceCustomAnalysisFixed = false
-
-// FixClassify
-// @Title 修复表格分类(一次性-后续版本可删掉)
-// @Description 修复表格分类
-// @Param   ExcelInfoId  query  int  true  "表格ID"
-// @Success 200 string "操作成功"
-// @router /excel/fix_classify [get]
-func (c *CustomAnalysisCommonController) FixClassify() {
-	br := new(models.BaseResponse).Init()
-	defer func() {
-		if br.ErrMsg != "" {
-			br.IsSendEmail = false
-		}
-		if br.Ret == 200 {
-			//OnceCustomAnalysisFixed = true
-		}
-		c.Data["json"] = br
-		c.ServeJSON()
-	}()
-	//if OnceCustomAnalysisFixed {
-	//	br.Ret = 200
-	//	br.Success = true
-	//	br.Msg = "请勿重复修复"
-	//	return
-	//}
-	source := utils.CUSTOM_ANALYSIS_TABLE
-
-	// 获取所有分类
-	classifies, e := excelModel.GetExcelClassifyModelBySource(source)
-	if e != nil {
-		br.Msg = "操作失败"
-		br.ErrMsg = fmt.Sprintf("获取分类列表失败, %v", e)
-		return
-	}
-	classifyMap := make(map[int]*excelModel.ExcelClassify)
-	for _, v := range classifies {
-		classifyMap[v.ExcelClassifyId] = v
-	}
-
-	// 查询所有excel
-	excels, e := excelModel.GetAllExcelInfoBySource(source)
-	if e != nil {
-		br.Msg = "操作失败"
-		br.ErrMsg = fmt.Sprintf("获取excel列表失败, %v", e)
-		return
-	}
-	if len(excels) == 0 {
-		br.Ret = 200
-		br.Success = true
-		br.Msg = "无分类需要修复"
-		return
-	}
-
-	// 先按照用户ID分组
-	groupExcels := make(map[int][]*excelModel.ExcelInfo)
-	for _, v := range excels {
-		//if v.SysUserId != 198 {
-		//	continue
-		//}
-		if groupExcels[v.SysUserId] == nil {
-			groupExcels[v.SysUserId] = make([]*excelModel.ExcelInfo, 0)
-		}
-		groupExcels[v.SysUserId] = append(groupExcels[v.SysUserId], v)
-	}
-
-	// 递归函数
-	findAndReplace := func(replaceId map[int]*excelModel.ExcelClassify, userId int, excelItem *excelModel.ExcelInfo, classifyItem *excelModel.ExcelClassify, firstStep bool) (hasParent, updateChild bool, currentClassify *excelModel.ExcelClassify, err error) {
-		// 分类创建人与表格不一致
-		currentClassify = classifyItem
-		if classifyItem.SysUserId != userId {
-			// 是否已存在替换分类
-			_, ok := replaceId[classifyItem.ExcelClassifyId]
-			if !ok {
-				classifyNew := &excelModel.ExcelClassify{
-					ExcelClassifyName: fmt.Sprintf("%d%s", userId, classifyItem.ExcelClassifyName),
-					ParentId:          classifyItem.ParentId, // 根据updateChild递归外更新
-					Source:            source,
-					SysUserId:         excelItem.SysUserId,
-					SysUserRealName:   excelItem.SysUserRealName,
-					Level:             classifyItem.Level,
-					UniqueCode:        utils.MD5(utils.EXCEL_DATA_PREFIX + "_" + strconv.FormatInt(time.Now().UnixNano(), 10)),
-					Sort:              classifyItem.Sort,
-					CreateTime:        time.Now(),
-					ModifyTime:        time.Now(),
-				}
-				_, e = excelModel.AddExcelClassify(classifyNew)
-				if e != nil {
-					err = fmt.Errorf("AddExcelClassify, %v", e)
-					return
-				}
-				replaceId[classifyItem.ExcelClassifyId] = classifyNew
-				excelItem.ExcelClassifyId = classifyNew.ExcelClassifyId
-				currentClassify = classifyNew
-				classifyMap[classifyNew.ExcelClassifyId] = classifyNew
-			} else {
-				excelItem.ExcelClassifyId = replaceId[classifyItem.ExcelClassifyId].ExcelClassifyId
-				currentClassify = replaceId[classifyItem.ExcelClassifyId]
-			}
-			// 仅第一次递归时修改
-			if firstStep {
-				//fmt.Printf("修改ExcelClassifyId: %d\n", excelItem.ExcelClassifyId)
-				excelItem.ModifyTime = time.Now().Local()
-				if e = excelItem.Update([]string{"ExcelClassifyId", "ModifyTime"}); e != nil {
-					err = fmt.Errorf("UpdateExcelInfo, %v", e)
-					return
-				}
-			}
-		}
-
-		// 查上级
-		if classifyItem.ParentId <= 0 {
-			//fmt.Printf("终止递归, ClassifyId: %d", classifyItem.ExcelClassifyId)
-			return
-		}
-		hasParent = true
-		parent := classifyMap[classifyItem.ParentId]
-		if parent == nil {
-			err = fmt.Errorf("未找到上级分类, ClassifyId: %d, ParentId: %d", classifyItem.ExcelClassifyId, classifyItem.ParentId)
-			return
-		}
-		if parent.SysUserId != userId {
-			updateChild = true
-		}
-		return
-	}
-
-	for uid, gv := range groupExcels {
-
-		replaceId := make(map[int]*excelModel.ExcelClassify)
-		for _, v := range gv {
-			classifyItem, e := excelModel.GetExcelClassifyById(v.ExcelClassifyId)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("获取表格分类失败, ExcelClassifyId: %d, %v", v.ExcelClassifyId, e)
-				return
-			}
-			// 首次递归
-			hasParent, updateChild, currentClassify, e := findAndReplace(replaceId, uid, v, classifyItem, true)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("findAndReplace1, %v", e)
-				return
-			}
-			if !hasParent {
-				continue
-			}
-
-			// 二次递归
-			//fmt.Printf("二次递归: %d\n", currentClassify.ParentId)
-			parentClassify, e := excelModel.GetExcelClassifyById(currentClassify.ParentId)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("2-parent-GetExcelClassifyById, %v", e)
-				return
-			}
-			hasParent2, updateChild2, currentClassify2, e := findAndReplace(replaceId, uid, v, parentClassify, false)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("findAndReplace2, %v", e)
-				return
-			}
-			// 更新上次递归的parent_id
-			if updateChild {
-				currentClassify.ParentId = currentClassify2.ExcelClassifyId
-				currentClassify.ModifyTime = time.Now().Local()
-				if e = currentClassify.Update([]string{"ParentId", "ModifyTime"}); e != nil {
-					br.Msg = "操作失败"
-					br.ErrMsg = fmt.Sprintf("2-更新父级分类ID失败, %v", e)
-					return
-				}
-			}
-			if !hasParent2 {
-				continue
-			}
-
-			// 三次递归
-			//fmt.Printf("三次递归: %d\n", currentClassify2.ParentId)
-			parentClassify2, e := excelModel.GetExcelClassifyById(currentClassify2.ParentId)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("3-parent-GetExcelClassifyById, %v", e)
-				return
-			}
-			hasParent3, updateChild3, currentClassify3, e := findAndReplace(replaceId, uid, v, parentClassify2, false)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("findAndReplace3, %v", e)
-				return
-			}
-			if updateChild2 {
-				currentClassify2.ParentId = currentClassify3.ExcelClassifyId
-				currentClassify2.ModifyTime = time.Now().Local()
-				if e = currentClassify2.Update([]string{"ParentId", "ModifyTime"}); e != nil {
-					br.Msg = "操作失败"
-					br.ErrMsg = fmt.Sprintf("3-更新父级分类ID失败, %v", e)
-					return
-				}
-			}
-			if !hasParent3 {
-				continue
-			}
-
-			// 四次递归
-			//fmt.Printf("四次递归: %d\n", currentClassify3.ParentId)
-			parentClassify3, e := excelModel.GetExcelClassifyById(currentClassify3.ParentId)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("4-parent-GetExcelClassifyById, %v", e)
-				return
-			}
-			hasParent4, updateChild4, currentClassify4, e := findAndReplace(replaceId, uid, v, parentClassify3, false)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("findAndReplace4, %v", e)
-				return
-			}
-			if updateChild3 {
-				currentClassify3.ParentId = currentClassify4.ExcelClassifyId
-				currentClassify3.ModifyTime = time.Now().Local()
-				if e = currentClassify3.Update([]string{"ParentId", "ModifyTime"}); e != nil {
-					br.Msg = "操作失败"
-					br.ErrMsg = fmt.Sprintf("4-更新父级分类ID失败, %v", e)
-					return
-				}
-			}
-			if !hasParent4 {
-				continue
-			}
-
-			// 五次递归-理论上没了(自定义分析最多三级目录+最底层的表格)
-			//fmt.Printf("五次递归: %d\n", currentClassify4.ParentId)
-			parentClassify4, e := excelModel.GetExcelClassifyById(currentClassify4.ParentId)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("5-parent-GetExcelClassifyById, %v", e)
-				return
-			}
-			hasParent5, _, currentClassify5, e := findAndReplace(replaceId, uid, v, parentClassify4, false)
-			if e != nil {
-				br.Msg = "操作失败"
-				br.ErrMsg = fmt.Sprintf("findAndReplace5, %v", e)
-				return
-			}
-			if updateChild4 {
-				currentClassify4.ParentId = currentClassify5.ExcelClassifyId
-				currentClassify4.ModifyTime = time.Now().Local()
-				if e = currentClassify4.Update([]string{"ParentId", "ModifyTime"}); e != nil {
-					br.Msg = "操作失败"
-					br.ErrMsg = fmt.Sprintf("5-更新父级分类ID失败, %v", e)
-					return
-				}
-			}
-			if !hasParent5 {
-				continue
-			}
-		}
-
-		//fmt.Println("replaceId: ", replaceId)
-	}
-
-	br.Ret = 200
-	br.Success = true
-	br.Msg = "操作成功"
-}

+ 1 - 101
controllers/data_manage/mysteel_chemical_data.go

@@ -1630,7 +1630,7 @@ func (this *EdbInfoController) Add() {
 	adminItem, e := system.GetSysAdminById(sysUser.AdminId)
 	if e != nil {
 		br.Msg = "操作失败"
-		br.ErrMsg = "获取系统用户数据失败,Err:" + err.Error()
+		br.ErrMsg = "获取系统用户数据失败,Err:" + e.Error()
 		return
 	}
 	if utils.BusinessCode == utils.BusinessCodeSandbox && adminItem.DepartmentName == "ETA试用客户" {
@@ -1677,106 +1677,6 @@ func (this *EdbInfoController) Add() {
 	br.IsAddLog = true
 }
 
-// AddCheck
-// @Title 新增指标检测接口
-// @Description 新增指标检测接口
-// @Param   EdbCode   query   string  true      "指标编码/指标代码"
-// @Success Ret=200 保存成功
-// @router /mysteel_chemical/edb_info/add_check [get]
-// func (this *EdbInfoController) AddCheck() {
-// 	br := new(models.BaseResponse).Init()
-// 	defer func() {
-// 		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.AddCheckEdbInfoReq
-// 	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
-// 		br.Msg = "参数解析异常!"
-// 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-// 		return
-// 	}
-
-// 	source := utils.DATA_SOURCE_MYSTEEL_CHEMICAL
-// 	indexNameMap := make(map[string]string)
-// 	indexNames := make([]string, 0)
-// 	for _, v := range req {
-// 		v.EdbCode = strings.Trim(v.EdbCode, "\t")
-// 		v.EdbCode = strings.Trim(v.EdbCode, " ")
-// 		v.EdbCode = strings.Replace(v.EdbCode, "\t", "", -1)
-// 		if v.EdbCode == "" {
-// 			br.Msg = "请输入指标ID"
-// 			return
-// 		}
-// 		v.EdbName = strings.Trim(v.EdbName, "\t")
-// 		v.EdbName = strings.Trim(v.EdbName, " ")
-// 		v.EdbName = strings.Replace(v.EdbName, "\t", "", -1)
-// 		if v.EdbName == "" {
-// 			br.Msg = "请输入指标名称"
-// 			return
-// 		}
-// 		indexNames = append(indexNames, v.EdbName)
-
-// 		item, err := data_manage.GetEdbInfoByEdbCode(source, edbCode)
-// 		if err != nil && err.Error() != utils.ErrNoRow() {
-// 			br.Msg = "获取失败"
-// 			br.ErrMsg = "获取失败,Err:" + err.Error()
-// 			return
-// 		}
-
-// 		resp := new(data_manage.EdbInfoMySteelChemicalCheckResp)
-// 		if item != nil && item.EdbInfoId > 0 {
-// 			resp.Status = 1
-// 			// 查询该指标是否有权限
-// 			obj := data_manage.EdbInfoNoPermissionAdmin{}
-// 			conf, err := obj.GetByEdbInfoIdAndAdminId(this.SysUser.AdminId, item.EdbInfoId)
-// 			if err != nil && err.Error() != utils.ErrNoRow() {
-// 				br.Msg = "获取失败"
-// 				br.ErrMsg = "获取当前账号的不可见指标配置失败,err:" + err.Error()
-// 				return
-// 			}
-// 			if conf != nil {
-// 				resp.Status = 3
-// 			}
-// 		} else {
-// 			resp.Status = 2
-// 			dataItems, err := data_manage.GetEdbDataAllByEdbCode(edbCode, source, 0, utils.EDB_DATA_LIMIT)
-// 			if err != nil && err.Error() != utils.ErrNoRow() {
-// 				br.Msg = "获取失败"
-// 				br.ErrMsg = "获取钢联已存在信息失败,Err:" + err.Error()
-// 				return
-// 			}
-
-// 			if len(dataItems) <= 0 {
-// 				respItem, err := data.AddEdbData(source, edbCode, frequency)
-// 				if err != nil {
-// 					br.Msg = "获取失败"
-// 					br.ErrMsg = "获取失败,Err:" + err.Error()
-// 					return
-// 				}
-// 				if respItem.Ret != 200 {
-// 					br.Msg = "未搜索到该指标"
-// 					br.ErrMsg = respItem.ErrMsg + ";EdbCode:" + edbCode
-// 					return
-// 				}
-// 			}
-// 		}
-// 	}
-
-// 	br.Ret = 200
-// 	br.Success = true
-// 	br.Msg = "保存成功"
-// 	br.Data = resp
-// 	br.IsAddLog = true
-// }
-
 // AddCheck
 // @Title 新增校验
 // @Description 新增校验

+ 153 - 116
controllers/data_manage/range_analysis/chart_info.go

@@ -1241,7 +1241,7 @@ func (this *RangeChartChartInfoController) Refresh() {
 // @Success Ret=200 返回指标id
 // @router /edb/save [post]
 func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
-	/*br := new(models.BaseResponse).Init()
+	br := new(models.BaseResponse).Init()
 	defer func() {
 		this.Data["json"] = br
 		this.ServeJSON()
@@ -1273,7 +1273,7 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 	}()
 	edbInfoIds := make([]int, 0)
 	for _, v := range req.EdbInfoList {
-		edbInfoIds = append(edbInfoIds, v.EdbInfoId)
+		edbInfoIds = append(edbInfoIds, v.FromEdbInfoId)
 	}
 	mappingList, err := data_manage.GetChartEdbMappingListByEdbInfoIdList(edbInfoIds)
 	if err != nil {
@@ -1287,32 +1287,40 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 	}
 
 	for _, v := range req.EdbInfoList {
-		if _, ok := edbInfoMap[v.EdbInfoId]; !ok {
+		if _, ok := edbInfoMap[v.FromEdbInfoId]; !ok {
 			br.Msg = "指标信息不存在"
-			br.ErrMsg = "指标信息不存在,EdbInfoId:" + strconv.Itoa(v.EdbInfoId)
+			br.ErrMsg = "指标信息不存在,EdbInfoId:" + strconv.Itoa(v.FromEdbInfoId)
 			br.IsSendEmail = false
 			return
 		}
 	}
-
+	// 区间计算图表配置校验
+	/*var extraConfig string
+	extraConfigByte, err := json.Marshal(req.ExtraConfig)
+	if err != nil {
+		br.Msg = "配置信息错误"
+		br.ErrMsg = "配置信息错误, Err: " + err.Error()
+		return
+	}*/
+	extraConfig := req.ExtraConfig
 	// todo 校验配置合法性
-	multipleGraphConfigEdbMappingList, err := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, 10)
+	multipleGraphConfigEdbMappingList, err := data_manage.GetMultipleGraphConfigEdbMappingListByIdAndSource(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS)
 	if err != nil {
 		br.Msg = `保存失败`
 		br.ErrMsg = "查询配置与图表的关联关系失败,ERR:" + err.Error()
 		return
 	}
-	var edbInfoId int
-	addEdbInfoIds := make([]int, 0)
-	updateEdbInfoIds := make([]int, 0)
-	deleteEdbInfoIds := make([]int, 0)
-	if len(multipleGraphConfigEdbMappingList) == 0 {
+	deleteEdbInfoIds := make([]int, 0) // 需要解除绑定的指标ID
+	fromEdbMap := make(map[int]int)
+	configMapping := make(map[int]*data_manage.MultipleGraphConfigEdbMapping, 0)
+	if len(multipleGraphConfigEdbMappingList) == 0 || req.IsSaveAs {
 		// 需要新增的指标
 	} else {
 		// 需要更新的指标
 		// 查询原先所有指标的来源指标,进一步筛选出需要新增,或者更新 或者删除的指标
 		oldEdbInfoIds := make([]int, 0)
 		for _, v := range multipleGraphConfigEdbMappingList {
+			configMapping[v.EdbInfoId] = v
 			oldEdbInfoIds = append(oldEdbInfoIds, v.EdbInfoId)
 		}
 
@@ -1324,140 +1332,170 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 		}
 
 		// 说明指标还在,没有被删除
-		oldFromEdbInfoIds := make([]int, 0)
 		for _, v := range oldEdbCalculateMappingList {
+			fromEdbMap[v.FromEdbInfoId] = v.EdbInfoId
 			if !utils.InArrayByInt(edbInfoIds, v.FromEdbInfoId) {
 				deleteEdbInfoIds = append(deleteEdbInfoIds, v.EdbInfoId)
 			}
-			oldFromEdbInfoIds = append(oldFromEdbInfoIds, v.FromEdbInfoId)
 		}
 	}
-
-	// 关联指标
-	edbInfoIdArr := []data_manage.EdbInfoFromTag{
-		{
-			EdbInfoId: edbInfoMappingA.EdbInfoId,
-			FromTag:   "A",
-			MoveValue: 0,
-		}, {
-			EdbInfoId: edbInfoMappingB.EdbInfoId,
-			FromTag:   "B",
-			MoveValue: 0,
-		},
-	}
-
-	calculateFormula := request.EdbCalculateFormula{
-		BaseCalculateValue: correlationConf.CalculateValue,
-		BaseCalculateUnit:  correlationConf.CalculateUnit,
-		LeadValue:          rollingCorrelation.LeadValue,
-		LeadUnit:           rollingCorrelation.LeadUnit,
-		CalculateValue:     rollingCorrelation.CalculateValue,
-		CalculateUnit:      rollingCorrelation.CalculateUnit,
-	}
-	calculateFormulaByte, err := json.Marshal(calculateFormula)
-	if err != nil {
-		br.Msg = "参数解析异常!"
-		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-		return
+	resp := data_manage.BatchEdbInfoCalculateBatchSaveResp{
+		Fail:    make([]data_manage.BatchEdbInfoCalculateBatchSaveFailResp, 0),
+		Success: make([]data_manage.BatchEdbInfoCalculateBatchSaveSuccessResp, 0),
 	}
+	// 普通指标批量新增\批量编辑
+	var saveReq data_manage.BatchEdbInfoCalculateBatchSaveReq
+	calculateEdbList := make([]data_manage.BatchEdbInfoCalculateBatchSaveSuccessResp, 0)
+	reqEdbList := make([]*data_manage.CalculateEdbInfoItem, 0)
+	for _, v := range req.EdbInfoList {
+		if edbInfoId, ok := fromEdbMap[v.EdbInfoId]; ok {
+			v.EdbInfoId = edbInfoId
+		}
+		v.CalculateId = strconv.Itoa(v.FromEdbInfoId)
+		v.EdbName = strings.Trim(v.EdbName, " ")
+		if v.EdbName == "" {
+			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
+				CalculateId: v.CalculateId,
+				Msg:         "指标名称不能为空",
+			})
+			continue
+		}
 
-	var respItem *data.AddPredictEdbDataResponse
-	if edbInfoId <= 0 || req.IsSaveAs {
-		req2 := &data_manage.EdbInfoCalculateBatchSaveReqByEdbLib{
-			AdminId:      sysUser.AdminId,
-			AdminName:    sysUser.RealName,
-			EdbName:      req.EdbName,
-			Frequency:    req.Frequency,
-			Unit:         req.Unit,
-			ClassifyId:   req.ClassifyId,
-			Formula:      string(calculateFormulaByte),
-			Source:       utils.DATA_SOURCE_CALCULATE_CORRELATION,
-			EdbInfoIdArr: edbInfoIdArr,
-			Calendar:     `公历`,
+		if v.Frequency == "" {
+			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
+				CalculateId: v.CalculateId,
+				Msg:         "频率不能为空",
+			})
+			continue
 		}
 
-		// 调用指标库去添加
-		reqJson, err := json.Marshal(req2)
-		if err != nil {
-			br.Msg = "参数解析异常!"
-			br.ErrMsg = "参数解析失败,Err:" + err.Error()
-			return
+		if v.Unit == "" {
+			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
+				CalculateId: v.CalculateId,
+				Msg:         "单位不能为空",
+			})
+			continue
 		}
-		respItem, err = data.BatchSaveEdbCalculateData(string(reqJson), this.Lang)
-		if err != nil {
-			br.Msg = "新增失败"
-			br.ErrMsg = "新增失败,Err:" + err.Error()
-			return
+
+		if v.ClassifyId <= 0 {
+			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
+				CalculateId: v.CalculateId,
+				Msg:         "请选择分类",
+			})
+			continue
 		}
-	} else {
-		req2 := &data_manage.EdbInfoCalculateBatchEditReqByEdbLib{
-			EdbInfoId:    edbInfoId,
-			EdbName:      req.EdbName,
-			Frequency:    req.Frequency,
-			Unit:         req.Unit,
-			ClassifyId:   req.ClassifyId,
-			Formula:      string(calculateFormulaByte),
-			Source:       utils.DATA_SOURCE_CALCULATE_CORRELATION,
-			EdbInfoIdArr: edbInfoIdArr,
-			Calendar:     `公历`,
+
+		//加入缓存机制,避免创建同一个名称的指标 start
+		redisKey := fmt.Sprint("edb_info:calculate:batch:save:", utils.DATA_SOURCE_CALCULATE_RANGEANLYSIS, ":", v.EdbName)
+		//加入缓存机制,避免创建同一个名称的指标 start
+		if req.EdbInfoType == 1 {
+			redisKey = fmt.Sprint("predict_edb_info:calculate:batch:save:", sysUser.AdminId, ":", utils.DATA_SOURCE_CALCULATE_RANGEANLYSIS, ":", v.CalculateId)
 		}
+		isExist := utils.Rc.IsExist(redisKey)
+		if isExist {
+			resp.Fail = append(resp.Fail, data_manage.BatchEdbInfoCalculateBatchSaveFailResp{
+				CalculateId: strconv.Itoa(v.FromEdbInfoId),
+				Msg:         "指标正在处理,请勿重复提交",
+			})
+			continue
+		} else {
+		}
+		reqEdbList = append(reqEdbList, v)
+	}
 
+	if req.EdbInfoType == 0 { //普通指标
+		if len(reqEdbList) <= 0 {
+			br.Msg = "新增失败!"
+			if len(resp.Fail) > 0 {
+				br.ErrMsg = resp.Fail[0].Msg
+			} else {
+				br.Msg = "请选择指标"
+			}
+			return
+		}
+		saveReq.Source = utils.DATA_SOURCE_CALCULATE_RANGEANLYSIS
+		saveReq.CalculateFormula = extraConfig
+		saveReq.AdminId = sysUser.AdminId
+		saveReq.AdminName = sysUser.RealName
+		saveReq.EdbList = reqEdbList
 		// 调用指标库去更新
-		reqJson, err := json.Marshal(req2)
+		reqJson, err := json.Marshal(saveReq)
 		if err != nil {
 			br.Msg = "参数解析异常!"
 			br.ErrMsg = "参数解析失败,Err:" + err.Error()
 			return
 		}
-		respItem, err = data.BatchEditEdbCalculateData(string(reqJson), this.Lang)
+		respItem, err := data.BatchSaveEdbCalculateMultiData(string(reqJson), this.Lang)
 		if err != nil {
-			br.Msg = "编辑失败"
-			br.ErrMsg = "编辑失败,Err:" + err.Error()
+			br.Msg = "新增失败!"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
 			return
 		}
-	}
-	if respItem == nil {
-		br.Msg = "保存失败"
-		br.ErrMsg = "保存失败"
-		return
-	}
-	if respItem.Ret != 200 {
-		br.Msg = respItem.Msg
-		br.ErrMsg = respItem.ErrMsg
-		return
+		if respItem.Ret != 200 {
+			br.Msg = respItem.Msg
+			br.ErrMsg = respItem.ErrMsg
+			return
+		}
+		calculateEdbList = respItem.Data.Success
+	} else if req.EdbInfoType == 1 {
+		// 预测指标
+		for _, v := range req.EdbInfoList {
+			predictReq := new(data_manage.PredictEdbInfoCalculateBatchSaveReq)
+			predictReq.EdbInfoId = v.EdbInfoId
+			predictReq.CalculateFormula = extraConfig
+			predictReq.EdbName = v.EdbName
+			predictReq.Frequency = v.Frequency
+			predictReq.Unit = v.Unit
+			predictReq.ClassifyId = v.ClassifyId
+			predictReq.FromEdbInfoId = v.FromEdbInfoId
+			predictReq.AdminId = sysUser.AdminId
+			predictReq.AdminName = sysUser.RealName
+			//todo 新增预测指标的区间计算指标
+		}
 	}
 
-	resp := respItem.Data
-
-	//添加es
-	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)
+	// 批量删除
+	if len(deleteEdbInfoIds) > 0 {
+		err = data_manage.DeleteMultipleGraphConfigEdbMappingByEdbIds(req.MultipleGraphConfigId, utils.CHART_SOURCE_RANGE_ANALYSIS, deleteEdbInfoIds)
+		if err != nil {
+			br.Msg = "更新失败!"
+			br.ErrMsg = "删除失败,Err:" + err.Error()
+			return
+		}
+	}
 
 	// 如果不是另存为的话,那么需要建立配置与指标的关系
 	if !req.IsSaveAs {
 		// 如果指标没有建立关联关系,那么就需要添加关系
-		if isAdd {
-			multipleGraphConfigEdbMapping = &data_manage.MultipleGraphConfigEdbMapping{
-				//Id:                    0,
-				MultipleGraphConfigId: req.MultipleGraphConfigId,
-				EdbInfoId:             resp.EdbInfoId,
-				Source:                req.Source,
-				ModifyTime:            time.Now(),
-				CreateTime:            time.Now(),
-			}
-			err = data_manage.AddMultipleGraphConfigEdbMapping(multipleGraphConfigEdbMapping)
-			if err != nil {
-				br.Msg = "保存失败"
-				br.ErrMsg = "保存配置与指标的关联关系失败,ERR:" + err.Error()
-				return
+		configEdbMappingList := make([]*data_manage.MultipleGraphConfigEdbMapping, 0)
+		for _, v := range calculateEdbList {
+			item, ok := configMapping[v.EdbInfoId]
+			if !ok {
+				multipleGraphConfigEdbMapping := &data_manage.MultipleGraphConfigEdbMapping{
+					//Id:                    0,
+					MultipleGraphConfigId: req.MultipleGraphConfigId,
+					EdbInfoId:             v.EdbInfoId,
+					Source:                utils.CHART_SOURCE_RANGE_ANALYSIS,
+					ModifyTime:            time.Now(),
+					CreateTime:            time.Now(),
+				}
+				configEdbMappingList = append(configEdbMappingList, multipleGraphConfigEdbMapping)
+			} else {
+				item.ModifyTime = time.Now()
+				err = item.Update([]string{"ModifyTime"})
+				if err != nil {
+					br.Msg = "保存失败"
+					br.ErrMsg = "保存配置与指标的关联关系失败,ERR:" + err.Error()
+					return
+				}
 			}
-		} else if multipleGraphConfigEdbMapping != nil {
-			multipleGraphConfigEdbMapping.EdbInfoId = resp.EdbInfoId
-			multipleGraphConfigEdbMapping.ModifyTime = time.Now()
-			err = multipleGraphConfigEdbMapping.Update([]string{"EdbInfoId", "ModifyTime"})
-			if err != nil {
-				br.Msg = "保存失败"
-				br.ErrMsg = "保存配置与指标的关联关系失败,ERR:" + err.Error()
-				return
+			if len(configEdbMappingList) > 0 {
+				err = data_manage.AddMultipleGraphConfigEdbMappingList(configEdbMappingList)
+				if err != nil {
+					br.Msg = "保存失败"
+					br.ErrMsg = "保存配置与指标的关联关系失败,ERR:" + err.Error()
+					return
+				}
 			}
 		}
 	}
@@ -1467,5 +1505,4 @@ func (this *RangeChartChartInfoController) MultipleGraphConfigSaveEdb() {
 	br.Msg = "保存成功"
 	br.Data = resp
 	br.IsAddLog = true
-	*/
 }

+ 23 - 0
controllers/report_v2.go

@@ -14,6 +14,8 @@ import (
 	"fmt"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"html"
+	"io"
+	"os"
 	"strconv"
 	"strings"
 	"time"
@@ -1954,3 +1956,24 @@ func fixSmartReport() {
 
 	fmt.Println("修复智能研报完成")
 }
+func initPdf() {
+	inFile := "anNNgk3Bbi4LRULwcJgNOPrREYh5.pdf"
+	f2, err := services.GeneralWaterMarkPdf(inFile, "颜鹏 - 18170239278")
+	//f2, err := services.GeneralWaterMarkPdf(inFile, "上周美国馏分油库存累库95万桶,馏分油表需环比下降(-25.6万桶/日)。本期馏分油产量继续抬升,在供增需减的环比变动下库存持续累库。馏分油供应的增加我们认为可能和进口的油种有关,今年以来美国进口的中重质原油占比不断走高,尤其是5")
+	if err != nil {
+		fmt.Println("生成失败,ERR:", err)
+		return
+	}
+
+	// 创建一个新的文件
+	newPdf, err := os.Create("new0555.pdf")
+	if err != nil {
+		fmt.Println("创建临时文件失败,Err:", err)
+		return
+	}
+	defer func() {
+		_ = newPdf.Close()
+	}()
+
+	_, _ = io.Copy(newPdf, f2)
+}

+ 7 - 1
go.mod

@@ -34,6 +34,7 @@ require (
 	github.com/mojocn/base64Captcha v1.3.6
 	github.com/nosixtools/solarlunar v0.0.0-20211112060703-1b6dea7b4a19
 	github.com/olivere/elastic/v7 v7.0.32
+	github.com/pdfcpu/pdfcpu v0.8.0
 	github.com/qiniu/qmgo v1.1.8
 	github.com/rdlucklib/rdluck_tools v1.0.3
 	github.com/shopspring/decimal v1.4.0
@@ -89,6 +90,8 @@ require (
 	github.com/gorilla/css v1.0.1 // indirect
 	github.com/hashicorp/golang-lru v0.5.4 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
+	github.com/hhrutter/lzw v1.0.0 // indirect
+	github.com/hhrutter/tiff v1.0.1 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
@@ -97,6 +100,7 @@ require (
 	github.com/leodido/go-urn v1.2.0 // indirect
 	github.com/magiconair/properties v1.8.7 // indirect
 	github.com/mailru/easyjson v0.7.7 // indirect
+	github.com/mattn/go-runewidth v0.0.15 // indirect
 	github.com/minio/md5-simd v1.1.2 // indirect
 	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -112,6 +116,7 @@ require (
 	github.com/prometheus/procfs v0.12.0 // indirect
 	github.com/richardlehane/mscfb v1.0.4 // indirect
 	github.com/richardlehane/msoleps v1.0.3 // indirect
+	github.com/rivo/uniseg v0.4.7 // indirect
 	github.com/rs/xid v1.5.0 // indirect
 	github.com/sagikazarmark/locafero v0.4.0 // indirect
 	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@@ -137,7 +142,7 @@ require (
 	go.uber.org/multierr v1.9.0 // indirect
 	golang.org/x/crypto v0.25.0 // indirect
 	golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
-	golang.org/x/image v0.14.0 // indirect
+	golang.org/x/image v0.15.0 // indirect
 	golang.org/x/sync v0.7.0 // indirect
 	golang.org/x/sys v0.22.0 // indirect
 	golang.org/x/text v0.16.0 // indirect
@@ -146,6 +151,7 @@ require (
 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
 	gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	xorm.io/builder v0.3.6 // indirect
 	xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb // indirect

+ 13 - 2
go.sum

@@ -270,6 +270,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hhrutter/lzw v1.0.0 h1:laL89Llp86W3rRs83LvKbwYRx6INE8gDn0XNb1oXtm0=
+github.com/hhrutter/lzw v1.0.0/go.mod h1:2HC6DJSn/n6iAZfgM3Pg+cP1KxeWc3ezG8bBqW5+WEo=
+github.com/hhrutter/tiff v1.0.1 h1:MIus8caHU5U6823gx7C6jrfoEvfSTGtEFRiM8/LOzC0=
+github.com/hhrutter/tiff v1.0.1/go.mod h1:zU/dNgDm0cMIa8y8YwcYBeuEEveI4B0owqHyiPpJPHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
@@ -321,6 +325,8 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v
 github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
 github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
@@ -374,6 +380,8 @@ github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5h
 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A=
 github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
 github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/pdfcpu/pdfcpu v0.8.0 h1:SuEB4uVsPFz1nb802r38YpFpj9TtZh/oB0bGG34IRZw=
+github.com/pdfcpu/pdfcpu v0.8.0/go.mod h1:jj03y/KKrwigt5xCi8t7px2mATcKuOzkIOoCX62yMho=
 github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
@@ -422,6 +430,9 @@ github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTK
 github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
 github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
 github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
 github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
 github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
@@ -571,8 +582,8 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
-golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
-golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
+golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
+golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

+ 35 - 16
models/data_manage/base_from_eia_stero.go

@@ -2,9 +2,10 @@ package data_manage
 
 import (
 	"eta/eta_api/utils"
+	"time"
+
 	"github.com/beego/beego/v2/client/orm"
 	"github.com/rdlucklib/rdluck_tools/paging"
-	"time"
 )
 
 // BaseFromEiaSteoIndex EiaSteo指标
@@ -33,20 +34,11 @@ type BaseFromEiaSteoIndexItem struct {
 	BaseFromEiaSteoIndexId    int    `orm:"column(base_from_eia_steo_index_id);pk"`
 	BaseFromEiaSteoClassifyId int    `description:"指标分类id"`
 	IndexCode                 string `description:"指标编码"`
-	IndexName                 string `description:"指标名称(中文名称)"`
-	IndexNameOriginal         string `description:"指标名称(原始名称)"`
-	Frequency                 string `description:"频度"`
-	Level                     int    `description:"指标层级(原始层级)"`
-	Unit                      string `description:"单位"`
-	Super                     string `description:"我也不知道是个啥,反正先存起来,万一用到了呢"`
-	Precision                 int    `description:"精度,我也不知道会不会用到,反正先存起来,万一用到了呢"`
-	LastHistorical            string `description:"最近的历史记录,我也不知道会不会用到,反正先存起来,万一用到了呢"`
-	Description               string `description:"备注信息,我也不知道会不会用到,反正先存起来,万一用到了呢"`
-	IsMappable                int    `description:"是否可映射,我也不知道会不会用到,反正先存起来,万一用到了呢"`
-	StartDate                 string `description:"开始日期"`
-	EndDate                   string `description:"结束日期"`
-	ModifyTime                string `description:"最新更新时间"`
-	CreateTime                string `description:"创建时间"`
+	IndexName                 string `description:"指标名称"`
+	EdbInfoId                 int    `description:"eta指标库的id"`
+	EdbUniqueCode             string `description:"指标库唯一编码"`
+	EdbClassifyId             int    `description:"指标库分类ID"`
+	EdbExist                  int    `description:"指标库是否已添加:0-否;1-是"`
 }
 
 // BaseFromEiaSteoClassify EiaSteo分类
@@ -54,10 +46,21 @@ type BaseFromEiaSteoClassify struct {
 	BaseFromEiaSteoClassifyId int       `orm:"column(base_from_eia_steo_classify_id);pk"`
 	ClassifyName              string    `description:"分类名称(中文名称)"`
 	ClassifyNameOriginal      string    `description:"分类名称(原始名称)"`
+	ParentId                  int       `description:"父级id"`
+	Level                     int       `description:"层级"`
 	ModifyTime                time.Time `description:"最新更新时间"`
 	CreateTime                time.Time `description:"创建时间"`
 }
 
+type BaseFromEiaSteoClassifyView struct {
+	BaseFromEiaSteoClassifyId int                            `orm:"column(base_from_eia_steo_classify_id);pk"`
+	ClassifyName              string                         `description:"分类名称(中文名称)"`
+	ClassifyNameOriginal      string                         `description:"分类名称(原始名称)"`
+	ParentId                  int                            `description:"父级id"`
+	Level                     int                            `description:"层级"`
+	Child                     []*BaseFromEiaSteoClassifyView `description:"子级分类列表"`
+}
+
 // BaseFromEiaSteoData EiaSteo数据表
 type BaseFromEiaSteoData struct {
 	BaseFromEiaSteoDataId  int       `orm:"column(base_from_eia_steo_data_id);pk"`
@@ -81,13 +84,29 @@ type BaseFromEiaSteoDataItem struct {
 }
 
 // GetEiaSteoClassifyList 获取分类列表
-func GetEiaSteoClassifyList() (items []*BaseFromEiaSteoClassify, err error) {
+func GetEiaSteoClassifyList() (items []*BaseFromEiaSteoClassifyView, err error) {
 	sql := ` SELECT * FROM base_from_eia_steo_classify  ORDER BY base_from_eia_steo_classify_id ASC `
 	o := orm.NewOrmUsingDB("data")
 	o.Raw(sql).QueryRows(&items)
 	return
 }
 
+// GetEiaSteoClassifyById 根据分类id获取分类
+func GetEiaSteoClassifyById(classifyId int) (item *BaseFromEiaSteoClassify, err error) {
+	sql := ` SELECT * FROM base_from_eia_steo_classify WHERE base_from_eia_steo_classify_id=? `
+	o := orm.NewOrmUsingDB("data")
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+// GetChildEiaSteoClassifyById 获取子分类列表
+func GetChildEiaSteoClassifyById(classifyId int) (items []*BaseFromEiaSteoClassify, err error) {
+	sql := ` SELECT * FROM base_from_eia_steo_classify WHERE parent_id=? `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
 type EiaSteoIndexListResp struct {
 	BaseFromEiaSteoIndexId    int                `orm:"column(base_from_eia_steo_index_id);pk"`
 	BaseFromEiaSteoClassifyId int                `description:"指标分类id"`

+ 5 - 3
models/data_manage/chart_info_range_analysis.go

@@ -81,7 +81,8 @@ func (a ChartRangeAnalysisManualDateConfList) Less(i, j int) bool {
 
 type ChartRangeAnalysisDataResp struct { //图表详情返回值
 	*ChartRangeAnalysisExtraConf
-	SeriesId int `description:"指标系列ID"`
+	SeriesId              int `description:"指标系列ID"`
+	MultipleGraphConfigId int `description:"配置ID"`
 }
 
 type ChartRangeAnalysisDateDataItem struct {
@@ -277,8 +278,9 @@ func EditRangeChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr, lang stri
 
 // SaveChartRangeAnalysisEdbReq 指标保存请求
 type SaveChartRangeAnalysisEdbReq struct {
-	EdbInfoList           []*EdbInfoBase `description:"指标列表"`
-	ExtraConfig           ChartRangeAnalysisExtraConf
+	EdbInfoList           []*CalculateEdbInfoItem `description:"指标列表"`
+	ExtraConfig           string
 	MultipleGraphConfigId int  `description:"配置id"`
 	IsSaveAs              bool `description:"是否另存为,true的话,就是另存为,不会建立与配置的关系"`
+	EdbInfoType           int  `description:"指标类型"`
 }

+ 4 - 0
models/data_manage/edb_info.go

@@ -226,6 +226,10 @@ type MysteelChemicalDataBatchAddCheckReq struct {
 	IndexCodes []string `form:"IndexCodes" description:"全选为false时, 该数组为选中; 全选为true时, 该数组为不选的指标"`
 }
 
+type EiaSteoDataBatchAddCheckReq struct {
+	IndexCodes []string `description:"指标编码"`
+}
+
 type AddEdbInfoReq struct {
 	Source     int    `description:"来源id"`
 	EdbCode    string `description:"指标编码"`

+ 15 - 0
models/data_manage/multiple_graph_config_edb_mapping.go

@@ -1,6 +1,7 @@
 package data_manage
 
 import (
+	"eta/eta_api/utils"
 	"github.com/beego/beego/v2/client/orm"
 	"time"
 )
@@ -59,3 +60,17 @@ func GetMultipleGraphConfigEdbMappingListByIdAndSource(configId, source int) (it
 
 	return
 }
+
+// AddMultipleGraphConfigEdbMappingList 新增多图配置
+func AddMultipleGraphConfigEdbMappingList(items []*MultipleGraphConfigEdbMapping) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+func DeleteMultipleGraphConfigEdbMappingByEdbIds(configId, source int, edbIds []int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `DELETE FROM multiple_graph_config_edb_mapping WHERE multiple_graph_config_id = ? AND source = ? AND edb_id IN (` + utils.GetOrmInReplace(len(edbIds)) + `) `
+	_, err = o.Raw(sql, configId, source, edbIds).Exec()
+	return
+}

+ 54 - 9
routers/commentsRouter.go

@@ -871,15 +871,6 @@ func init() {
             Filters: nil,
             Params: nil})
 
-    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:CustomAnalysisCommonController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:CustomAnalysisCommonController"],
-        beego.ControllerComments{
-            Method: "FixClassify",
-            Router: `/excel/fix_classify`,
-            AllowHTTPMethods: []string{"get"},
-            MethodParams: param.Make(),
-            Filters: nil,
-            Params: nil})
-
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:CustomAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:CustomAnalysisController"],
         beego.ControllerComments{
             Method: "Add",
@@ -2140,6 +2131,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/range_analysis:RangeChartChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/range_analysis:RangeChartChartInfoController"],
+        beego.ControllerComments{
+            Method: "MultipleGraphConfigSaveEdb",
+            Router: `/edb/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/range_analysis:RangeChartClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/range_analysis:RangeChartClassifyController"],
         beego.ControllerComments{
             Method: "AddChartClassify",
@@ -4381,6 +4381,24 @@ 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: "EiaSteoBatchAdd",
+            Router: `/eia_steo/batch_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: "EiaSteoBatchSearch",
+            Router: `/eia_steo/batch_search`,
+            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: "EiaSteoClassify",
@@ -4399,6 +4417,33 @@ 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: "EiaSteoAdd",
+            Router: `/eia_steo/edb_info/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: "EiaSteoAddCheck",
+            Router: `/eia_steo/edb_info/add_check`,
+            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: "EiaSteoNameCheck",
+            Router: `/eia_steo/name_check`,
+            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: "EiaSteoSearchList",

+ 0 - 1
routers/router.go

@@ -292,7 +292,6 @@ func init() {
 		web.NSNamespace("/custom_analysis",
 			web.NSInclude(
 				&excel.CustomAnalysisController{},
-				&excel.CustomAnalysisCommonController{},
 			),
 		),
 		web.NSNamespace("/out_link",

+ 77 - 0
services/data/base_from_eia_steo.go

@@ -0,0 +1,77 @@
+package data
+
+import (
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/utils"
+	"fmt"
+)
+
+func GetClassifyALLById(classifyId int) (items []*data_manage.BaseFromEiaSteoClassify, err error) {
+	classify, err := data_manage.GetEiaSteoClassifyById(classifyId)
+	if err != nil {
+		return
+	}
+	if classify.Level == 1 {
+		childClassify, er := data_manage.GetChildEiaSteoClassifyById(classifyId)
+		if er != nil {
+			err = er
+			return
+		}
+		items = append(items, childClassify...)
+	} else {
+		items = append(items, classify)
+	}
+	return
+}
+
+type EiaSteoIndexSource2EdbReq struct {
+	EdbCode       string
+	EdbName       string
+	Frequency     string
+	Unit          string
+	ClassifyId    int
+	AdminId       int
+	AdminRealName string
+}
+
+// EiaSteoIndexSource2Edb 新增eiaSteo数据源到指标库
+func EiaSteoIndexSource2Edb(req EiaSteoIndexSource2EdbReq, 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("EiaSteoIndexSource2Edb新增失败, Err: %s", err.Error())
+			fmt.Println(tips)
+			utils.FileLog.Info(tips)
+		}
+	}()
+	source := utils.DATA_SOURCE_EIA_STEO
+
+	// 是否新增过指标
+	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
+
+	// 新增指标库
+	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
+
+	return
+}

+ 48 - 7
services/data/range_analysis/chart_info.go

@@ -302,6 +302,15 @@ func GetChartDataByEdbInfoList(chartInfoId int, dateType, startYear int, startDa
 		}
 	}
 	dataResp = data_manage.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req}
+	// 查询配置关联关系
+	if chartInfoId > 0 {
+		multipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfoId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			err = fmt.Errorf("获取配置与图表的关联关系失败,ERR:" + e.Error())
+			return
+		}
+		dataResp.MultipleGraphConfigId = multipleGraphConfigChartMapping.MultipleGraphConfigId
+	}
 	edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
 	if err != nil {
 		err = fmt.Errorf("获取区间计算图表, 完善指标信息失败, Err:" + err.Error())
@@ -407,6 +416,16 @@ func GetChartDataByEdbInfoListBySeries(chartInfoId int, dateType, startYear int,
 		}
 	}
 	dataResp = data_manage.ChartRangeAnalysisDataResp{ChartRangeAnalysisExtraConf: req, SeriesId: seriesMappingItem.FactorEdbSeriesId}
+	// 查询配置关联关系
+	if chartInfoId > 0 {
+		multipleGraphConfigChartMapping, e := data_manage.GetMultipleGraphConfigChartMappingByChartId(chartInfoId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			err = fmt.Errorf("获取配置与图表的关联关系失败,ERR:" + e.Error())
+			return
+		}
+		dataResp.MultipleGraphConfigId = multipleGraphConfigChartMapping.MultipleGraphConfigId
+	}
+
 	edbList, err = GetChartEdbInfoFormat(chartInfoId, edbInfoMappingList)
 	if err != nil {
 		err = fmt.Errorf("获取区间计算图表, 完善指标信息失败, Err:" + err.Error())
@@ -478,12 +497,7 @@ func getChartDataByEdbInfo(edbInfoMapping *data_manage.ChartEdbInfoMapping, req
 			endDateTime, _ = time.ParseInLocation(utils.FormatDate, endDate, time.Local)
 		} else {
 			endConf := req.AutoDateConf.EndDateConf
-			endDate := ""
-			if endConf.BaseDateType == 0 { //
-				endDate = edbEndDate
-			} else if endConf.BaseDateType == 2 {
-				endDate = "2020-01-01"
-			}
+			endDate := edbEndDate
 			if endConf.MoveForward > 0 {
 				endDate = GetEdbDateByMoveForward(endConf.MoveForward, dataList)
 			}
@@ -916,7 +930,34 @@ func AddChartInfo(req data_manage.AddChartInfoReq, source int, sysUser *system.A
 		}
 		//todo 如果保存失败是否要删除
 	}
-
+	//添加配置信息
+	multipleGraphConfig := &data_manage.MultipleGraphConfig{
+		//MultipleGraphConfigId: 0,
+		SysUserId:       sysUser.AdminId,
+		SysUserRealName: sysUser.RealName,
+		ModifyTime:      time.Now(),
+		CreateTime:      time.Now(),
+	}
+	err = data_manage.AddMultipleGraphConfig(multipleGraphConfig)
+	if err != nil {
+		errMsg = "操作失败"
+		err = errors.New("新增区间计算图表配置失败, Err: " + err.Error())
+		return
+	}
+	multipleGraphConfigChartMapping := &data_manage.MultipleGraphConfigChartMapping{
+		//Id:                    0,
+		MultipleGraphConfigId: multipleGraphConfig.MultipleGraphConfigId,
+		ChartInfoId:           chartInfo.ChartInfoId,
+		Source:                utils.CHART_SOURCE_RANGE_ANALYSIS,
+		ModifyTime:            time.Now(),
+		CreateTime:            time.Now(),
+	}
+	err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping)
+	if err != nil {
+		errMsg = "操作失败"
+		err = errors.New("新增区间计算图表和配置关联关系失败, Err: " + err.Error())
+		return
+	}
 	// 添加指标引用记录
 	_ = data.SaveChartEdbInfoRelation(edbInfoIdArr, chartInfo)
 	//添加es数据

+ 88 - 0
services/file.go

@@ -1,14 +1,21 @@
 package services
 
 import (
+	"bytes"
 	"errors"
 	"eta/eta_api/models"
 	"eta/eta_api/utils"
 	"fmt"
+	"github.com/pdfcpu/pdfcpu/pkg/api"
+	"github.com/pdfcpu/pdfcpu/pkg/font"
+	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
+	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
+	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
 	"io"
 	"mime/multipart"
 	"os"
 	"os/exec"
+	"strings"
 	"time"
 )
 
@@ -179,3 +186,84 @@ func GetResourceUrlBySvgImg(imgData string) (resourceUrl string, err error, errM
 
 	return
 }
+
+func GeneralWaterMarkPdf(pdfPath, waterMarkStr string) (f2 *bytes.Buffer, err error) {
+	onTop := true
+	update := false
+	//fontDir := `C:\Users\123\go\src\eta\eta_api\static`
+	fontDir := `static`
+	font.UserFontDir = fontDir
+
+	ttfList := fontDir + `/SimHei.ttf`
+	err = api.InstallFonts([]string{ttfList})
+	if err != nil {
+		fmt.Println("InstallFonts err:", err)
+	}
+
+	api.DisableConfigDir()
+
+	f1, err := os.Open(pdfPath)
+	if err != nil {
+		fmt.Println("文件不存在")
+		return
+	}
+	defer func() {
+		_ = f1.Close()
+	}()
+
+	f2 = &bytes.Buffer{}
+
+	//strList := []string{waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr}
+	strList := []string{waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr}
+	//strList := []string{waterMarkStr}
+	newWaterMarkStr := strings.Join(strList, "  ")
+	wmList := make([]*model.Watermark, 0)
+	for i := types.TopLeft; i <= 9; i++ {
+		wm, tmpErr := api.TextWatermark(newWaterMarkStr, "fo:SimHei, points:48, col: 0.75 0.75 0.75, rot:45, scale:1 abs, opacity:0.3", onTop, update, types.POINTS)
+		if tmpErr != nil {
+			fmt.Println("TextWatermark err:", tmpErr)
+			return
+		}
+		//wm.Pos = types.Center
+		wm.Pos = i
+		wmList = append(wmList, wm)
+	}
+
+	err = AddWatermarks(f1, f2, nil, wmList, nil)
+
+	return
+}
+func AddWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, wmList []*model.Watermark, conf *model.Configuration) error {
+	if rs == nil {
+		return errors.New("pdfcpu: AddWatermarks: missing rs")
+	}
+
+	if conf == nil {
+		conf = model.NewDefaultConfiguration()
+	}
+	conf.Cmd = model.ADDWATERMARKS
+	conf.OptimizeDuplicateContentStreams = false
+
+	if len(wmList) <= 0 {
+		return errors.New("pdfcpu: missing watermark configuration")
+	}
+
+	ctx, err := api.ReadValidateAndOptimize(rs, conf)
+	if err != nil {
+		return err
+	}
+
+	var pages types.IntSet
+	pages, err = api.PagesForPageSelection(ctx.PageCount, selectedPages, true, true)
+	if err != nil {
+		return err
+	}
+
+	for _, wm := range wmList {
+		if err = pdfcpu.AddWatermarks(ctx, pages, wm); err != nil {
+			return err
+		}
+	}
+
+	return api.Write(ctx, w, conf)
+}

+ 16 - 0
services/report_v2.go

@@ -1451,3 +1451,19 @@ func GetGeneralPdfUrl(reportCode, classifyFirstName string, reportLayout int8) (
 
 	return
 }
+
+func GetReportWaterMarkPdf(reportInfo *models.Report, sysUser *system.Admin) {
+	dateDir := time.Now().Format("20060102")
+	uploadDir := utils.STATIC_DIR + "pdf/" + dateDir
+	filePath, err := utils.DownloadFile(reportInfo.DetailPdfUrl, uploadDir)
+	if err != nil {
+		return
+	}
+	// 移除临时Pdf文件
+	defer func() {
+		_ = os.Remove(filePath)
+	}()
+
+	waterMarkStr := fmt.Sprintf("%s - %s", sysUser.RealName, sysUser.Mobile)
+	GeneralWaterMarkPdf(filePath, waterMarkStr)
+}

+ 8 - 8
services/smart_report.go

@@ -136,7 +136,7 @@ func SmartReportElasticUpsert(smartReportId int, state int) (err error) {
 	return
 }
 
-func ReportToPdf(reportUrl, filePath string) (err error) {
+func ReportToPdf(width int, reportUrl, filePath string) (err error) {
 	pyCode := `
 import asyncio
 from pyppeteer import launch
@@ -151,7 +151,7 @@ async def main():
     })
     page = await browser.newPage()
     await page.setViewport({
-        'width': 1920,
+        'width': %d,
         'height': 1080,
     })
     await page.goto('%s', {
@@ -186,7 +186,7 @@ finally:
     loop.close()
 `
 
-	pyCode = fmt.Sprintf(pyCode, utils.ChromePath, reportUrl, filePath)
+	pyCode = fmt.Sprintf(pyCode, utils.ChromePath, width, reportUrl, filePath)
 	utils.FileLog.Info("pdf pyCode: \n" + pyCode)
 	cmd := exec.Command("python3", "-c", pyCode)
 	output, e := cmd.CombinedOutput()
@@ -329,7 +329,11 @@ func Report2pdfAndJpeg(reportUrl string, reportId, reportType int) {
 	pdfPath := `./static/` + reportCode + ".pdf"
 	jpegPath := `./static/` + reportCode + ".jpg"
 
-	err = ReportToPdf(reportUrl, pdfPath)
+	width := 1560
+	if reportType == 3 {
+		width = 800
+	}
+	err = ReportToPdf(width, reportUrl, pdfPath)
 	if err != nil {
 		utils.FileLog.Info("ReportToPdf failed: , error: \n" + err.Error())
 		go alarm_msg.SendAlarmMsg("ReportToPdf failed:"+err.Error(), 3)
@@ -389,10 +393,6 @@ func Report2pdfAndJpeg(reportUrl string, reportId, reportType int) {
 
 	time.Sleep(1 * time.Minute)
 
-	width := 1200
-	if reportType == 3 {
-		width = 800
-	}
 	err = ReportToJpeg(width, reportUrl, jpegPath)
 	if err != nil {
 		utils.FileLog.Info("ReportToJpeg failed: , error: \n" + err.Error())

BIN
static/SimHei.gob


+ 1 - 0
utils/constants.go

@@ -175,6 +175,7 @@ const (
 	DATA_SOURCE_SCI99                                = 85       // 卓创资讯 -> 85
 	DATA_SOURCE_SCI_HQ                               = 88       // 卓创红期->88
 	DATA_SOURCE_OILCHEM                              = 89       // 隆众资讯 -> 89
+	DATA_SOURCE_CALCULATE_RANGEANLYSIS               = 87       //区间计算->87
 )
 
 // 数据刷新频率