Browse Source

Merge branch 'master' of http://8.136.199.33:3000/eta_server/eta_api into bzq1/excel_rule_master

zqbao 7 months ago
parent
commit
dc208e839b

+ 68 - 63
controllers/data_manage/chart_info.go

@@ -1435,42 +1435,44 @@ func (this *ChartInfoController) PreviewChartInfoDetail() {
 			return
 		}
 		for i := range markerLines {
-			if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 {
+			if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 && markerLines[i].Axis != 3 {
 				// 图上第一个指标且时间区间跟随图表
-				if edbList[0].IsAxis == 1 {
-					value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
-					if err != nil {
-						br.Msg = "标识线配置异常"
-						br.ErrMsg = "标识线配置异常" + err.Error()
-						return
-					}
-					markerLines[i].Value = value
-				} else {
-					// 其他的都走指标计算
-					edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
-					if err != nil {
-						br.Msg = "指标计算标识线获取指标信息异常"
-						br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
-						return
-					}
-					// 判断时间区间不为跟随图表的情况
-					if markerLines[i].TimeIntervalType != 0 {
-						startDate = markerLines[i].StartDate.Date
-						endDate = markerLines[i].EndDate.Date
-					}
-					dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
-					if err != nil {
-						br.Msg = "指标计算标识线获取指标数据异常"
-						br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
-						return
-					}
-					value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
-					if err != nil {
-						br.Msg = "标识线配置异常"
-						br.ErrMsg = "标识线配置异常" + err.Error()
-						return
+				if markerLines[i].MarkLineType == 2 {
+					if edbList[0].IsAxis == 1 {
+						value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
+						if err != nil {
+							br.Msg = "标识线配置异常"
+							br.ErrMsg = "标识线配置异常" + err.Error()
+							return
+						}
+						markerLines[i].Value = value
+					} else {
+						// 其他的都走指标计算
+						edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
+						if err != nil {
+							br.Msg = "指标计算标识线获取指标信息异常"
+							br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
+							return
+						}
+						// 判断时间区间不为跟随图表的情况
+						if markerLines[i].TimeIntervalType != 0 {
+							startDate = markerLines[i].StartDate.Date
+							endDate = markerLines[i].EndDate.Date
+						}
+						dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
+						if err != nil {
+							br.Msg = "指标计算标识线获取指标数据异常"
+							br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
+							return
+						}
+						value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
+						if err != nil {
+							br.Msg = "标识线配置异常"
+							br.ErrMsg = "标识线配置异常" + err.Error()
+							return
+						}
+						markerLines[i].Value = value
 					}
-					markerLines[i].Value = value
 				}
 			}
 		}
@@ -3416,37 +3418,40 @@ func (this *ChartInfoController) PreviewBarChartInfo() {
 			return
 		}
 		for i := range markerLines {
-			if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 {
+			if markerLines[i].EdbType == 0 && markerLines[i].TimeIntervalType == 0 && markerLines[i].Axis != 3 {
 				// 图上第一个指标且时间区间跟随图表
-				if edbList[0].IsAxis == 1 {
-					value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
-					if err != nil {
-						br.Msg = "标识线配置异常"
-						br.ErrMsg = "标识线配置异常" + err.Error()
-						return
-					}
-					markerLines[i].Value = value
-				} else {
-					// 其他的都走指标计算
-					edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
-					if err != nil {
-						br.Msg = "指标计算标识线获取指标信息异常"
-						br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
-						return
-					}
-					dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, "", "")
-					if err != nil {
-						br.Msg = "指标计算标识线获取指标数据异常"
-						br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
-						return
-					}
-					value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
-					if err != nil {
-						br.Msg = "标识线配置异常"
-						br.ErrMsg = "标识线配置异常" + err.Error()
-						return
+				if markerLines[i].MarkLineType == 2 {
+					// 图上第一个指标且时间区间跟随图表
+					if edbList[0].IsAxis == 1 {
+						value, err := data.MarkerLineCalculate(markerLines[i], edbList[0].DataList, chartInfo)
+						if err != nil {
+							br.Msg = "标识线配置异常"
+							br.ErrMsg = "标识线配置异常" + err.Error()
+							return
+						}
+						markerLines[i].Value = value
+					} else {
+						// 其他的都走指标计算
+						edbInfo, err := data_manage.GetEdbInfoById(markerLines[i].EdbInfoId)
+						if err != nil {
+							br.Msg = "指标计算标识线获取指标信息异常"
+							br.ErrMsg = "指标计算标识线获取指标信息异常" + err.Error()
+							return
+						}
+						dataList, err := data_manage.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, "", "")
+						if err != nil {
+							br.Msg = "指标计算标识线获取指标数据异常"
+							br.ErrMsg = "指标计算标识线获取指标数据异常" + err.Error()
+							return
+						}
+						value, err := data.MarkerLineCalculate(markerLines[i], dataList, chartInfo)
+						if err != nil {
+							br.Msg = "标识线配置异常"
+							br.ErrMsg = "标识线配置异常" + err.Error()
+							return
+						}
+						markerLines[i].Value = value
 					}
-					markerLines[i].Value = value
 				}
 			}
 		}

+ 67 - 1
controllers/data_manage/edb_info.go

@@ -21,11 +21,12 @@ import (
 	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"strconv"
 	"strings"
 	"sync"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // EdbInfoController 数据管理
@@ -1803,6 +1804,52 @@ func (this *EdbInfoController) EdbInfoSearch() {
 				searchItem.Unit = "元/吨"
 				searchItem.EdbName = indexInfo.IndexName
 			}
+		} else if source == utils.DATA_SOURCE_SCI_HQ {
+			dataItems, err := data_manage.GetEdbDataAllByEdbCode(edbCode, source, subSource, utils.EDB_DATA_LIMIT)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取SCIHQ已存在信息失败,Err:" + err.Error()
+				return
+			}
+
+			fmt.Println("dataItems:", len(dataItems))
+			if len(dataItems) > 0 {
+				searchItem.EdbCode = edbCode
+				minDate, maxDate, err := data_manage.GetEdbDataSciHqMaxAndMinDate(edbCode)
+				if err != nil {
+					br.Msg = "获取失败"
+					br.ErrMsg = "获取SCIHQ日期信息失败,Err:" + err.Error()
+					return
+				}
+				searchItem.DataList = dataItems
+				searchItem.StartDate = minDate
+				searchItem.EndDate = maxDate
+			} else {
+				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
+				}
+				isAdd = true
+			}
+			//获取指标信息
+			sciHqInfo, err := data_manage.GetSciHqIndexByIndexCode(edbCode)
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取SciHq指标详情失败,Err:" + err.Error()
+				return
+			}
+			if sciHqInfo != nil {
+				searchItem.Frequency = sciHqInfo.Frequency
+				searchItem.Unit = sciHqInfo.Unit
+				searchItem.EdbName = sciHqInfo.IndexName
+			}
 		} else {
 			// 代码中没有的来源那么从edb_source中找是否有对应的
 			sourceItem := data_manage.EdbSourceIdMap[source]
@@ -2433,6 +2480,11 @@ func (this *EdbInfoController) EdbInfoEdit() {
 		return
 	}
 
+	// 记录旧的指标基本信息
+	oldEdbName := edbInfo.EdbName
+	oldFrequency := edbInfo.Frequency
+	oldUnit := edbInfo.Unit
+
 	var haveOperaAuth bool
 	// 权限校验
 	{
@@ -2526,6 +2578,20 @@ func (this *EdbInfoController) EdbInfoEdit() {
 	//	}
 	//}
 
+	// 新增保存记录日志
+	oldEdbInfo := new(data_manage.EdbInfo)
+	oldEdbInfo.EdbInfoId = edbInfo.EdbInfoId
+	oldEdbInfo.EdbName = oldEdbName
+	oldEdbInfo.Frequency = oldFrequency
+	oldEdbInfo.Unit = oldUnit
+	newEdbInfoRecord := new(data_manage.EdbInfoEditRecord)
+	newEdbInfoRecord.EdbName = req.EdbName
+	newEdbInfoRecord.Frequency = req.Frequency
+	newEdbInfoRecord.Unit = req.Unit
+	newEdbInfoRecord.OperateUserId = sysUser.AdminId
+	newEdbInfoRecord.OperateUserRealName = sysUser.RealName
+	go data.AddEditEdbInfoRcord(oldEdbInfo, newEdbInfoRecord)
+
 	//新增操作日志
 	{
 		edbLog := new(data_manage.EdbInfoLog)

+ 8 - 1
controllers/data_manage/edb_info_calculate.go

@@ -9,11 +9,12 @@ import (
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
 	"net/url"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 // 计算指标
@@ -849,6 +850,8 @@ func (this *ChartInfoController) CalculateBatchEdit() {
 		Frequency:     req.Frequency,
 		Unit:          req.Unit,
 		ClassifyId:    req.ClassifyId,
+		AdminId:       this.SysUser.AdminId,
+		AdminName:     this.SysUser.RealName,
 		Formula:       req.Formula, //N数值移动平均计算、环比值、环差值
 		FromEdbInfoId: req.FromEdbInfoId,
 		Source:        req.Source,
@@ -1950,6 +1953,10 @@ func (this *ChartInfoController) BatchCalculateBatchEdit() {
 		}
 		return
 	}
+
+	req.AdminId = sysUser.AdminId
+	req.AdminName = sysUser.RealName
+
 	req.EdbList = reqEdbList
 	// 调用指标库去更新
 	reqJson, err := json.Marshal(req)

+ 6 - 1
controllers/data_manage/manual_edb.go

@@ -330,6 +330,9 @@ func (c *ManualEdbController) EdbList() {
 	var condition string
 	var pars []interface{}
 
+	// 权限用户id
+	permissionUserId := sysUser.AdminId
+
 	//超管账号可以查看分类下的所有频度数据
 	if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_ADMIN {
 		classifyIdList, err := data.GetUserManualClassifyIdList(sysUser.AdminId)
@@ -344,6 +347,8 @@ func (c *ManualEdbController) EdbList() {
 			pars = append(pars, classifyIdList)
 		}
 
+	} else {
+		permissionUserId = 0
 	}
 
 	// 关键词
@@ -359,7 +364,7 @@ func (c *ManualEdbController) EdbList() {
 	// 所属分类
 	if classifyId > 0 {
 		// 获取有用权限的分类
-		classifyList, err := models.GetEdbdataClassify(int64(userId))
+		classifyList, err := models.GetEdbdataClassify(int64(permissionUserId))
 		if err != nil {
 			return
 		}

+ 13 - 2
controllers/data_manage/predict_edb_info.go

@@ -13,12 +13,13 @@ import (
 	"eta/eta_api/services/elastic"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
-	"github.com/shopspring/decimal"
 	"sort"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"github.com/shopspring/decimal"
 )
 
 // PredictEdbInfoController 预测指标
@@ -771,6 +772,16 @@ func (this *PredictEdbInfoController) Edit() {
 	//修改es
 	data.AddOrEditEdbInfoToEs(resp.EdbInfoId)
 
+	// 添加操作日志
+	newEdbRecord := new(data_manage.EdbInfoEditRecord)
+	newEdbRecord.EdbName = req.EdbName
+	// 频度和单位在此接口不处理
+	newEdbRecord.Frequency = edbInfo.Frequency
+	newEdbRecord.Unit = edbInfo.Unit
+	newEdbRecord.OperateUserId = sysUser.AdminId
+	newEdbRecord.OperateUserRealName = sysUser.RealName
+	go data.AddEditEdbInfoRcord(edbInfo, newEdbRecord)
+
 	// 刷新关联指标
 	go data.EdbInfoRefreshAllFromBaseV2(resp.EdbInfoId, true, false)
 

+ 1584 - 0
controllers/data_manage/sci_hq_data.go

@@ -0,0 +1,1584 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/request"
+	"eta/eta_api/models/data_manage/response"
+	"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"
+)
+
+type SciHqDataController struct {
+	controllers.BaseAuthController
+}
+
+// @Title 卓创红期数据分类
+// @Description 卓创红期数据分类接口
+// @Success 200 {object} data_manage.SciClassify
+// @router /sci_hq/classify [get]
+func (this *SciHqDataController) Classify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyList, err := data_manage.GetSciHqClassifyAll()
+	if err != nil {
+		br.Msg = "查询失败"
+		br.ErrMsg = "查询失败, Err:" + err.Error()
+		return
+	}
+
+	initClassify := &data_manage.BaseFromSciHqClassifyItem{
+		ClassifyId:     0,
+		ClassifyName:   "未分类",
+		ClassifyNameEn: "Unclassified",
+		UniqueCode:     "0",
+		ParentId:       0,
+		Level:          1,
+		Sort:           0,
+		Children:       nil,
+	}
+	finalList := make([]*data_manage.BaseFromSciHqClassifyItem, 0)
+	classifyTree := getSciHqClassifyTree(classifyList, 0)
+	finalList = append(finalList, initClassify)
+	finalList = append(finalList, classifyTree...)
+
+	br.Msg = "查询成功"
+	br.Data = finalList
+	br.Success = true
+	br.Ret = 200
+}
+
+// AddSciClassify
+// @Title 新增分类
+// @Description 新增分类接口
+// @Param	request	body data_manage.AddBaseFromSciClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /sci_hq/classify/add [post]
+func (this *SciHqDataController) AddClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.AddBaseFromSciHqClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	if req.ParentId < 0 {
+		br.Msg = "操作异常"
+		return
+	}
+	ok, msg, err := data.AddSciHqClassify(req.ClassifyName, this.Lang, req.ParentId)
+	if err != nil {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+	if !ok {
+		if msg != "" {
+			br.Msg = msg
+			return
+		}
+		br.Msg = "添加失败"
+		return
+	}
+	br.Msg = "添加成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// DelClassify
+// @Title 新增分类
+// @Description 新增分类接口
+// @Param	request	body data_manage.AddBaseFromSciClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /sci_hq/classify/del [post]
+func (this *SciHqDataController) DelClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.DelBaseFromSciHqClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err = data.DelSciHqClassify(req.ClassifyId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// EditClassify
+// @Title 修改分类
+// @Description 修改分类接口
+// @Param	request	body data_manage.EditBaseFromMysteelChemicalClassifyReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /sci_hq/classify/edit [post]
+func (this *SciHqDataController) EditClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.EditBaseFromSciHqClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	classify, err := data_manage.GetSciHqClassifyById(req.ClassifyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "分类不存在"
+			return
+		}
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类失败,Err:" + err.Error()
+		return
+	}
+	switch this.Lang {
+	case utils.EnLangVersion:
+		if classify.ClassifyNameEn != req.ClassifyName {
+			count, err := data_manage.GetSciHqClassifyCountByName(req.ClassifyName, this.Lang)
+			if err != nil {
+				br.Msg = "编辑失败"
+				br.ErrMsg = "获取分类失败,Err:" + err.Error()
+				return
+			}
+			if count > 0 {
+				br.Msg = "分类名称已存在"
+				return
+			}
+			classify.ClassifyNameEn = req.ClassifyName
+			classify.ModifyTime = time.Now()
+			err = classify.Update([]string{"classify_name_en", "modify_time"})
+			if err != nil {
+				br.Msg = "编辑失败"
+				br.ErrMsg = "编辑失败,Err:" + err.Error()
+				return
+			}
+		}
+	default:
+		if classify.ClassifyName != req.ClassifyName {
+			count, err := data_manage.GetSciHqClassifyCountByName(req.ClassifyName, this.Lang)
+			if err != nil {
+				br.Msg = "编辑失败"
+				br.ErrMsg = "获取分类失败,Err:" + err.Error()
+				return
+			}
+			if count > 0 {
+				br.Msg = "分类名称已存在"
+				return
+			}
+			classify.ClassifyName = req.ClassifyName
+			classify.ModifyTime = time.Now()
+			err = classify.Update([]string{"classify_name", "modify_time"})
+			if err != nil {
+				br.Msg = "编辑失败"
+				br.ErrMsg = "编辑失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+
+	br.Msg = "编辑成功"
+	br.Success = true
+	br.Ret = 200
+	br.IsAddLog = true
+}
+
+// MoveClassify
+// @Title 分类移动接口
+// @Description 分类移动接口
+// @Success 200 {object} data_manage.MoveBaseFromMysteelChemicalClassifyReq
+// @router /sci_hq/classify/move [post]
+func (this *SciHqDataController) MoveClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.MoveBaseFromSciHqClassifyReq
+	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "分类id小于等于0"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.MoveSciHqClassify(req.ClassifyId, req.ParentId, req.PrevClassifyId, req.NextClassifyId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "移动成功"
+}
+
+// IndexList
+// @Title 卓创红期指标列表
+// @Description 卓创红期数据指标列表接口
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Success 200 {object} data_manage.BaseFromMysteelChemicalIndexResp
+// @router /sci_hq/index/list [get]
+func (this *SciHqDataController) IndexList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("ClassifyId", 0)
+	indexList, err := data_manage.GetSciHqIndexBaseInfoByClassifyId(classifyId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = indexList
+}
+
+// BatchIndexList
+// @Title 卓创红期批量操作指标列表
+// @Description 卓创红期批量操作指标列表
+// @Param   request	body   request.SciHqDataBatchListReq true "type json string"
+// @Success 200 {object} data_manage.BaseFromMysteelChemicalIndexResp
+// @router /sci_hq/index/batch_list [post]
+func (this *SciHqDataController) BatchIndexList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.SciHqDataBatchListReq
+	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	var condition string
+	var pars []interface{}
+	if req.KeyWord != "" {
+		condition += `AND (index_code=? OR index_name=?)`
+		pars = utils.GetLikeKeywordPars(pars, req.KeyWord, 2)
+	}
+	if req.IsSelectAll {
+		if len(req.SelectedId) > 0 {
+			condition += ` AND base_from_sci_hq_index_id NOT IN (` + utils.GetOrmInReplace(len(req.SelectedId)) + `)`
+			pars = append(pars, req.SelectedId)
+		}
+	} else {
+		if len(req.SelectedId) > 0 {
+			condition += ` AND base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(req.SelectedId)) + `)`
+			pars = append(pars, req.SelectedId)
+		}
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "分类选择错误"
+		return
+	}
+	if req.ClassifyId > 0 {
+		childClassify, err := data_manage.GetChildSciHqClassifyListById(req.ClassifyId)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+		if len(childClassify) > 0 {
+			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
+			for _, child := range childClassify {
+				pars = append(pars, child.ClassifyId)
+			}
+		} else {
+			condition += ` AND classify_id=?`
+			pars = append(pars, req.ClassifyId)
+		}
+	} else {
+		condition += ` AND classify_id=?`
+		pars = append(pars, req.ClassifyId)
+	}
+
+	count, err := data_manage.GetSciHqIndexCountByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+	MaxLen := 30
+	if count > MaxLen {
+		br.Msg = "批量操作数量不能超过" + strconv.Itoa(MaxLen)
+		return
+	}
+	indexList, err := data_manage.GetSciHqIndexByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = indexList
+}
+
+// IndexPageList
+// @Title 卓创红期指标列表
+// @Description 卓创红期数据指标列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyId   query   int  true       "分类id"
+// @Param   IsListAll   query   int  true       "是否展示全部"
+// @Success 200 {object} data_manage.BaseFromMysteelChemicalIndexResp
+// @router /sci_hq/index/page/list [get]
+func (this *SciHqDataController) IndexPageList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("ClassifyId", 0)
+	pageSize, _ := this.GetInt("PageSize")
+	currrentIndex, _ := this.GetInt("CurrentIndex")
+	isListAll, _ := this.GetBool("IsListAll")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currrentIndex <= 0 {
+		currrentIndex = 1
+	}
+	startSize = utils.StartIndex(currrentIndex, pageSize)
+	var total int
+	var indexList []*data_manage.BaseFromSciHqIndexView
+	if isListAll {
+		tmpTotal, err := data_manage.GetSciHqIndexCount()
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		tmpIndexList, err := data_manage.GetSciHqIndexByPage(startSize, pageSize)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		indexList = tmpIndexList
+	} else {
+		var classifyIds []int
+		if classifyId > 0 {
+			tmpClassifyIds, err := data_manage.GetSciHqChildClassifyIdsById(classifyId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取分类信息失败,Err:" + err.Error()
+				return
+			}
+			if len(tmpClassifyIds) > 0 {
+				classifyIds = append(classifyIds, tmpClassifyIds...)
+			}
+		}
+		classifyIds = append(classifyIds, classifyId)
+		tmpTotal, err := data_manage.GetSciHqIndexCountByClassifyId(classifyIds)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		tmpIndexList, err := data_manage.GetSciHqIndexByClassifyId(classifyIds, startSize, pageSize)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		indexList = tmpIndexList
+	}
+
+	page := paging.GetPaging(currrentIndex, pageSize, total)
+	resp := new(response.SciHqIndexPageListResp)
+	resp.List = indexList
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// SearchList
+// @Title 卓创红期模糊搜索
+// @Description 卓创红期模糊搜索
+// @Param   Keyword   query   string  true       "关键字搜索"
+// @Success 200 {object} models.BaseResponse
+// @router /sci_hq/search_list [get]
+func (this *SciHqDataController) SearchList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	//关键字
+	keyword := this.GetString("Keyword")
+	var condition string
+	var pars []interface{}
+	if keyword != "" {
+		condition += ` AND (index_code LIKE ? OR index_name LIKE ?)`
+		pars = utils.GetLikeKeywordPars(pars, keyword, 2)
+	} else {
+		br.Msg = "请输入指标ID/指标名称"
+		return
+	}
+
+	list, err := data_manage.GetSciHqIndexBaseInfoByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = list
+}
+
+// SingleData
+// @Title 获取卓创红期据
+// @Description 获取卓创红期单条数据接口
+// @Param   BaseFromSciHqIndexId   query   string  true       "指标唯一编码"
+// @Success 200 {object} models.BaseResponse
+// @router /sci_hq/single_data [get]
+func (this *SciHqDataController) SingleData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	baseFromSciHqIndexId, _ := this.GetInt("BaseFromSciHqIndexId")
+	indexInfo, err := data_manage.GetSciHqIndexByIndexId(baseFromSciHqIndexId)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_SCI_HQ, indexInfo.IndexCode)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取指标数据失败"
+		br.ErrMsg = "获取指标库数据失败,Err:" + err.Error()
+		return
+	}
+	var edbInfoId int
+	if edbInfo != nil {
+		edbInfoId = edbInfo.EdbInfoId
+	}
+	dataList, err := data_manage.GetSciHqDataByIndexId(baseFromSciHqIndexId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	var ret response.SciHqSingleDataResp
+	ret.ClassifyId = indexInfo.ClassifyId
+	ret.BaseFromSciHqIndexId = indexInfo.BaseFromSciHqIndexId
+	ret.IndexCode = indexInfo.IndexCode
+	ret.EdbInfoId = edbInfoId
+	ret.IndexName = indexInfo.IndexName
+	ret.Frequency = indexInfo.Frequency
+	ret.CreateTime = indexInfo.CreateTime.Format(utils.FormatDateTime)
+	ret.ModifyTime = indexInfo.ModifyTime.Format(utils.FormatDateTime)
+	ret.Unit = indexInfo.Unit
+	ret.Data = dataList
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = ret
+}
+
+// MoveSciHqData
+// @Title 卓创红期指标移动接口
+// @Description 卓创红期指标移动接口
+// @Success 200 {object} request.MoveBaseFromSciHqReq
+// @router /sci_hq/move [post]
+func (this *SciHqDataController) MoveSciHqData() {
+	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 request.MoveBaseFromSciHqReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromSciHqIndexId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "指标id小于等于0"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.MoveSciHqData(req.BaseFromSciHqIndexId, req.ClassifyId, req.PrevBaseFromSciHqIndexId, req.NextBaseFromSciHqIndexId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "移动成功"
+}
+
+// ResetSciHqIndex
+// @Title 指标数据清除分类
+// @Description 指标数据清除分类
+// @Param	request	body data_manage.DelBaseFromSciReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /sci_hq/reset [post]
+func (this *SciHqDataController) ResetSciHqIndex() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.ResetBaseFromSciHqReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromSciHqIndexId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err = data.ResetSciHqIndex(req.BaseFromSciHqIndexId)
+	if err != nil {
+		br.Msg = "移动失败"
+		br.ErrMsg = "移动失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "操作成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// AddEdbInfo
+// @Title 新增指标接口
+// @Description 新增指标接口
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success Ret=200 保存成功
+// @router /sci_hq/edb_info/add [post]
+func (this *SciHqDataController) AddEdbInfo() {
+	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
+	}
+
+	_, err = data_manage.GetSciHqIndexByIndexCode(req.EdbCode)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "指标不存在"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	source := utils.DATA_SOURCE_SCI_HQ
+	// 指标入库
+	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
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+	br.Data = resp
+	br.IsAddLog = true
+}
+
+// AddCheck
+// @Title 新增校验
+// @Description 新增校验
+// @Param	request	body request.BusinessDataBatchAddCheckReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /sci_hq/edb_info/add_check [post]
+func (this *SciHqDataController) AddCheck() {
+	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 *request.SciHqDataBatchAddCheckReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	codeMax := 30
+	codeLen := len(req.IndexCodes)
+	if len(req.IndexCodes) == 0 {
+		br.Msg = "请选择指标"
+		return
+	}
+
+	if codeLen > codeMax {
+		br.Msg = fmt.Sprintf("最多只能选择%d个指标", codeMax)
+		return
+	}
+	// 获取指标库已有指标
+	existsEdb, e := data_manage.GetEdbCodesBySource(utils.DATA_SOURCE_SCI_HQ)
+	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(codeLen))
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.IndexCodes)
+	list, err := data_manage.GetSciHqIndexAndEdbInfoByCondition(cond, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取卓创红期原始指标列表失败, Err: " + err.Error()
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromSciHqIndexView, 0)
+	for _, v := range list {
+		if v.EdbInfoId > 0 {
+			v.EdbExist = 1
+		}
+		resp = append(resp, v)
+	}
+
+	br.Data = resp
+	br.Msg = "校验成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// NameCheck
+// @Title 重名校验
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /sci_hq/edb_info/name_check [post]
+func (c *SciHqDataController) NameCheck() {
+	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 err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.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_SCI_HQ, 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_SCI_HQ, 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
+}
+
+// BatchAdd
+// @Title 批量新增
+// @Description 批量新增
+// @Param	request	body data_manage.AddEdbInfoReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /sci_hq/edb_info/batch_add [post]
+func (this *SciHqDataController) BatchAdd() {
+	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_SCI_HQ_" + 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.SciHqIndexSource2EdbReq
+		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, errMsg, skip, e := data.SciHqIndexSource2Edb(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
+}
+
+// BatchDelete
+// @Title 批量删除
+// @Description 批量删除
+// @Param	request	body []*request.DelBaseFromSciHqReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /sci_hq/edb_info/batch_delete [post]
+func (this *SciHqDataController) BatchDelete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req []*request.DelBaseFromSciHqReq
+	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
+	}
+	var deleteIds []int
+	for _, v := range req {
+		if v.BaseFromSciHqIndexId <= 0 {
+			continue
+		}
+		deleteIds = append(deleteIds, v.BaseFromSciHqIndexId)
+	}
+	existList, err := data.BatchDelSciHqData(deleteIds)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Data = existList
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// BatchEdit
+// @Title 批量编辑
+// @Description 批量编辑
+// @Param	request	body []*request.DelBaseFromSciHqReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /sci_hq/edb_info/batch_edit [post]
+func (this *SciHqDataController) BatchEdit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req []*request.EditBaseFromSciHqReq
+	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
+	}
+
+	indexIds := make([]int, 0)
+	classifyIds := make([]int, 0)
+	indexIdToclassifyId := make(map[int]int)
+	for _, v := range req {
+		if v.BaseFromSciHqIndexId <= 0 {
+			continue
+		}
+		if v.ClassifyId <= 0 {
+			continue
+		}
+		indexIds = append(indexIds, v.BaseFromSciHqIndexId)
+		classifyIds = append(classifyIds, v.ClassifyId)
+		indexIdToclassifyId[v.BaseFromSciHqIndexId] = v.ClassifyId
+	}
+	if len(indexIds) == 0 {
+		br.Msg = "请选择指标或指定正确的分类"
+		return
+	}
+	indexList, err := data_manage.GetSciHqIndexListByIndexIds(indexIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取指标失败,Err:" + err.Error()
+		return
+	}
+	classifySort, err := data_manage.GetSciHqClassifyMaxSortByClassifyIds(classifyIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类最大排序失败,Err:" + err.Error()
+		return
+	}
+	classifySortMap := make(map[int]int)
+	for _, v := range classifySort {
+		classifySortMap[v.ClassifyId] = v.MaxSort
+	}
+	classifyList, err := data_manage.GetSciHqClassifyListByIds(classifyIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类失败,Err:" + err.Error()
+		return
+	}
+	existClassifyList := make(map[int]struct{})
+	for _, v := range classifyList {
+		existClassifyList[v.ClassifyId] = struct{}{}
+	}
+	//编辑指标
+	updateIndexList := make([]*data_manage.BaseFromSciHqIndex, 0)
+	for _, v := range indexList {
+		tmpClassifyId := indexIdToclassifyId[v.BaseFromSciHqIndexId]
+		if _, ok := existClassifyList[tmpClassifyId]; ok {
+			v.ClassifyId = tmpClassifyId
+			v.Sort = classifySortMap[tmpClassifyId] + 1
+			classifySortMap[tmpClassifyId] += 1
+			updateIndexList = append(updateIndexList, v)
+		}
+	}
+	err = data_manage.BatchModifySciHqIndexClassify(updateIndexList)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑指标失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+
+}
+
+// EditSciHq
+// @Title 编辑卓创红期指标
+// @Description 编辑卓创红期指标接口
+// @Param	request	body data_manage.AddEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /sci_hq/edit [post]
+func (this *SciHqDataController) EditSciHq() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.EditBaseFromSciHqReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromSciHqIndexId <= 0 {
+		br.Msg = "请选择指标"
+		br.IsSendEmail = false
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	//编辑指标
+	sciIndexInfo, errMsg, err := data.EditSciHqIndex(req.BaseFromSciHqIndexId, req.ClassifyId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		return
+	}
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑指标失败,Err:" + err.Error()
+		return
+	}
+
+	resp := response.EditSciHqIndexInfoResp{
+		BaseFromSciHqIndexId: sciIndexInfo.BaseFromSciHqIndexId,
+		IndexCode:            sciIndexInfo.IndexCode,
+	}
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "保存成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// DeleteSciHqData
+// @Title 删除指标
+// @Description 删除指标接口
+// @Param	request	body data_manage.DelBaseFromSciReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /sci_hq/del [post]
+func (this *SciHqDataController) DeleteSciHqData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.DelBaseFromSciHqReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromSciHqIndexId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.DelSciHqData(req.BaseFromSciHqIndexId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = errMsg + ";Err:" + err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// ExportSciHqList
+// @Title 导出Sci数据
+// @Description 导出Sci数据
+// @Param   ClassifyId   query   int  true       "关键字搜索"
+// @Param   IndexCode   query   string  true       "指标编码"
+// @Success 200  导出成功
+// @router /export/sciHqList [get]
+func (this *SciHqDataController) ExportSciHqList() {
+	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")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+	secNameList := make([]*data_manage.BaseFromSciHqIndex, 0)
+	dir, _ := os.Executable()
+	exPath := filepath.Dir(dir)
+	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	xlsxFile := xlsx.NewFile()
+
+	var condition string
+	var pars []interface{}
+	if classifyId > 0 {
+		childClassify, err := data_manage.GetChildSciHqClassifyListById(classifyId)
+		if err != nil {
+			br.Msg = "下载失败"
+			br.ErrMsg = "获取分类失败,Err:" + err.Error()
+			return
+		}
+		if len(childClassify) > 0 {
+			condition += `AND classify_id IN (` + utils.GetOrmInReplace(len(childClassify)) + `)`
+			for _, child := range childClassify {
+				pars = append(pars, child.ClassifyId)
+			}
+		} else {
+			condition += ` AND classify_id=?`
+			pars = append(pars, classifyId)
+		}
+	} else {
+		condition += ` AND classify_id=?`
+		pars = append(pars, classifyId)
+	}
+	if indexCode != "" {
+		condition += ` AND index_code=? `
+		pars = append(pars, indexCode)
+	}
+	frequencies, err := data_manage.GetSciHqFrequencyByCondition(condition, pars)
+	if err != nil {
+		fmt.Println("GetSciFrequency err:", err.Error())
+		utils.FileLog.Info("GetSciFrequency err:" + err.Error())
+		return
+	}
+	for _, frequency := range frequencies {
+		//获取指标
+		secNameList, err = data_manage.GetSciHqIndexByConditionAndFrequency(condition, *frequency, pars)
+		if err != nil {
+			fmt.Println("获取数据失败,Err:" + err.Error())
+			return
+		}
+		if len(secNameList) <= 0 {
+			fmt.Println("secNameList长度为0")
+			return
+		}
+		sheetNew, err := xlsxFile.AddSheet(*frequency)
+		if err != nil {
+			fmt.Println("新增Sheet失败", err.Error())
+			return
+		}
+		secNameRow := sheetNew.AddRow()
+		frequencyRow := sheetNew.AddRow()
+		unitRow := sheetNew.AddRow()
+		lastModifyDateRow := sheetNew.AddRow()
+
+		var indexIdList []int
+		for _, sv := range secNameList {
+			indexIdList = append(indexIdList, sv.BaseFromSciHqIndexId)
+		}
+		dataTimeList, err := data_manage.GetSciHqDataDataTimeByIndexId(indexIdList)
+		if err != nil {
+			fmt.Println("获取数据时间失败", err.Error())
+			return
+		}
+
+		// 添加excel左侧指标日期
+		setRowIndex := 4
+		for rk, dv := range dataTimeList {
+			rowIndex := setRowIndex + rk
+			row := sheetNew.Row(rowIndex)
+			displayDate, _ := time.Parse(utils.FormatDate, dv)
+			displayDateCell := row.AddCell()
+			style := new(xlsx.Style)
+			style.ApplyAlignment = true
+			style.Alignment.WrapText = true
+			displayDateCell.SetStyle(style)
+			displayDateCell.SetDate(displayDate)
+
+		}
+		for k, sv := range secNameList {
+			//获取数据
+			dataList, err := data_manage.GetSciHqIndexDataByCode(sv.IndexCode)
+			if err != nil {
+				br.Msg = "获取数据失败"
+				br.ErrMsg = "获取数据失败,Err:" + err.Error()
+				return
+			}
+			if k == 0 {
+				secNameRow.AddCell().SetValue("指标名称")
+				frequencyRow.AddCell().SetValue("频率")
+				unitRow.AddCell().SetValue("单位")
+				lastModifyDateRow.AddCell().SetValue("更新时间")
+				min := k * 3
+				sheetNew.SetColWidth(min, min, 15)
+			}
+			if len(dataList) == 0 {
+				continue
+			}
+			secNameRow.AddCell().SetValue(sv.IndexName)
+			frequencyRow.AddCell().SetValue(sv.Frequency)
+			unitRow.AddCell().SetValue(sv.Unit)
+
+			lastModifyDateRow.AddCell().SetValue(sv.ModifyTime.Format(utils.FormatDate))
+			dataInfoMap := make(map[string]*data_manage.BaseFromSciHqData)
+			for _, v := range dataList {
+				dataInfoMap[v.DataTime] = v
+			}
+
+			for rk, dtv := range dataTimeList {
+				rowIndex := setRowIndex + rk
+				row := sheetNew.Row(rowIndex)
+				displayDateCell := row.AddCell()
+				tmpData, ok := dataInfoMap[dtv]
+				if ok {
+					displayDateCell.SetValue(tmpData.Value)
+				}
+			}
+		}
+	}
+
+	err = xlsxFile.Save(downLoadnFilePath)
+	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(downLoadnFilePath)
+		if err != nil {
+			br.Msg = "保存文件失败"
+			br.ErrMsg = "保存文件失败"
+			return
+		}
+	}
+	fileName := `卓创红期`
+	if indexCode != "" && len(secNameList) == 1 {
+		fileName = secNameList[0].IndexName
+	}
+	fileName += time.Now().Format("2006.01.02") + `.xlsx` //文件名称
+	this.Ctx.Output.Download(downLoadnFilePath, fileName)
+	defer func() {
+		os.Remove(downLoadnFilePath)
+	}()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+}
+
+// getSciHqClassifyTree 返回卓创红旗的树形结构
+func getSciHqClassifyTree(items []*data_manage.BaseFromSciHqClassifyItem, parentId int) []*data_manage.BaseFromSciHqClassifyItem {
+	res := make([]*data_manage.BaseFromSciHqClassifyItem, 0)
+	for _, item := range items {
+		if item.ParentId == parentId {
+			t := new(data_manage.BaseFromSciHqClassifyItem)
+			t.ClassifyId = item.ClassifyId
+			t.ClassifyName = item.ClassifyName
+			t.ParentId = item.ParentId
+			t.Level = item.Level
+			t.Sort = item.Sort
+			t.ModifyTime = item.ModifyTime
+			t.CreateTime = item.CreateTime
+			t.ClassifyNameEn = item.ClassifyNameEn
+			if item.UniqueCode == "" {
+				t.UniqueCode = strconv.Itoa(item.ClassifyId)
+			}
+			t.Children = getSciHqClassifyTree(items, item.ClassifyId)
+			res = append(res, t)
+		}
+	}
+	return res
+}

+ 83 - 43
controllers/target.go

@@ -953,7 +953,7 @@ func (this *TargetController) ExportDataList() {
 
 	var condition string
 	var pars []interface{}
-	//分类ID
+	// 指标名称
 	if keyWord != "" {
 		condition += ` AND  a.SEC_NAME LIKE '%` + keyWord + `%'`
 	}
@@ -975,10 +975,45 @@ func (this *TargetController) ExportDataList() {
 	//	condition += ` AND a.frequency = ? `
 	//	pars = append(pars, frequency)
 	//}
+	permissionUserId := sysUser.AdminId
+	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
+		permissionUserId = 0
+	}
+
+	childClassifyIdList := make([]int, 0)
+	// 所属分类
 	if classifyId > 0 {
-		condition += ` AND a.classify_id = ? `
-		pars = append(pars, classifyId)
+		// 获取有用权限的分类
+		classifyList, err := models.GetEdbdataClassify(int64(permissionUserId))
+		if err != nil {
+			return
+		}
+
+		var isParent bool
+		for _, v := range classifyList {
+			if v.ClassifyId == classifyId {
+				isParent = true
+				childClassifyIdList = append(childClassifyIdList, v.ClassifyId)
+				if v.Child != nil && len(v.Child) > 0 {
+					for _, vv := range v.Child {
+						childClassifyIdList = append(childClassifyIdList, vv.ClassifyId)
+					}
+				}
+				break
+			}
+		}
+
+		// 如果是最小级,那么就把自己放进去
+		if !isParent {
+			childClassifyIdList = append(childClassifyIdList, classifyId)
+		}
 	}
+
+	// 如果所选分类是一级时,那么是一级下的所有分类;如果是二级时,那么是二级自己本身
+	num := len(childClassifyIdList)
+	condition += ` AND a.classify_id in (` + utils.GetOrmInReplace(num) + `) `
+	pars = append(pars, childClassifyIdList)
+
 	if mobile != "" {
 		condition += ` AND d.mobile=? `
 		pars = append(pars, mobile)
@@ -999,28 +1034,39 @@ func (this *TargetController) ExportDataList() {
 	dir, _ := os.Executable()
 	exPath := filepath.Dir(dir)
 
-	downLoadnFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
+	downloadFilePath := exPath + "/" + time.Now().Format(utils.FormatDateTimeUnSpace) + ".xlsx"
 	xlsxFile := xlsx.NewFile()
 	if err != nil {
 		br.Msg = "生成文件失败"
 		br.ErrMsg = "生成文件失败"
 		return
 	}
-	var frequencies []*string
-	if keyWord == "" {
-		frequencies, err = models.GetEdbDataFrequency(classifyId)
+	var frequencies []string
+	if len(childClassifyIdList) > 0 {
+		frequencies, err = models.GetEdbDataFrequencyByClassifyIdList(childClassifyIdList)
 		if err != nil {
 			br.Msg = "查询频度失败"
 			br.ErrMsg = "查询频度失败"
 			return
 		}
-	} else {
+	} else if tradeCode != `` {
+		manualEdb, err := models.GetEdbinfoByTradeCode(tradeCode)
+		if err != nil {
+			br.Msg = "查询指标信息失败"
+			br.ErrMsg = "查询指标信息失败,err:" + err.Error()
+			return
+		}
+		frequencies = append(frequencies, manualEdb.Frequency)
+	} else if keyWord != `` {
 		frequencies, err = models.GetEdbDataFrequencyByKeyord(keyWord)
 		if err != nil {
 			br.Msg = "查询频度失败"
 			br.ErrMsg = "查询频度失败"
 			return
 		}
+	} else {
+		// 啥也没选的情况下
+		frequencies = append(frequencies, `日度`, `周度`, `月度`, `季度`, `半年度`, `年度`)
 	}
 
 	fileName := `手工数据`
@@ -1052,7 +1098,7 @@ func (this *TargetController) ExportDataList() {
 		}
 		var sheet *xlsx.Sheet
 		if len(secNameList) > 0 {
-			sheet, err = xlsxFile.AddSheet(*frequency)
+			sheet, err = xlsxFile.AddSheet(frequency)
 			if err != nil {
 				br.Msg = "新增Sheet失败"
 				br.ErrMsg = "新增Sheet失败,Err:" + err.Error()
@@ -1129,7 +1175,7 @@ func (this *TargetController) ExportDataList() {
 
 	}
 
-	err = xlsxFile.Save(downLoadnFilePath)
+	err = xlsxFile.Save(downloadFilePath)
 	if err != nil {
 		//有指标无数据时先导出一遍空表
 		sheet, err := xlsxFile.AddSheet("无数据")
@@ -1141,19 +1187,20 @@ func (this *TargetController) ExportDataList() {
 		rowSecName := sheet.AddRow()
 		celSecName := rowSecName.AddCell()
 		celSecName.SetValue("")
-		err = xlsxFile.Save(downLoadnFilePath)
+		err = xlsxFile.Save(downloadFilePath)
 		if err != nil {
 			br.Msg = "保存文件失败"
 			br.ErrMsg = "保存文件失败"
 			return
 		}
 	}
-
-	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
-	this.Ctx.Output.Download(downLoadnFilePath, fileName)
 	defer func() {
-		os.Remove(downLoadnFilePath)
+		os.Remove(downloadFilePath)
 	}()
+
+	fileName += time.Now().Format("06.01.02") + `.xlsx` //文件名称
+	this.Ctx.Output.Download(downloadFilePath, fileName)
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "success"
@@ -3302,22 +3349,8 @@ func (this *TargetController) ExcelDataAdd() {
 	userId := sysUser.AdminId
 	if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN {
 		userId = 0
-
-		// 校验下当前用户是否有该指标的权限
-		count, err := models.GetCountManualUserClassify(sysUser.AdminId, req.ClassifyId)
-		if err != nil {
-			br.Msg = "获取分类数据失败"
-			br.ErrMsg = "获取分类数据失败,err:" + err.Error()
-			return
-		}
-
-		if count <= 0 {
-			br.Msg = "无权访问"
-			br.ErrMsg = "无权访问"
-			br.IsSendEmail = false
-			return
-		}
 	}
+
 	//获取账户所拥有权限的分类id集合
 	classifyIdList, err := data.GetUserManualClassifyIdList(userId)
 	if err != nil {
@@ -3325,6 +3358,12 @@ func (this *TargetController) ExcelDataAdd() {
 		br.Msg = "获取拥有的分类数据失败,Err:" + err.Error()
 		return
 	}
+	if !utils.InArrayByInt(classifyIdList, req.ClassifyId) {
+		br.Msg = "无权访问"
+		br.ErrMsg = "无权访问"
+		br.IsSendEmail = false
+		return
+	}
 
 	//操作指标,新增指标及数据等
 	{
@@ -3413,6 +3452,20 @@ func (this *TargetController) ExcelDataAdd() {
 						continue
 					}
 
+					// 指标信息变更,需要更新
+					if frequency != target.Frequency || unit != target.Unit || req.ClassifyId != target.ClassifyId {
+						fmt.Println("更新指标频度或单位")
+						err = models.ModifyEdbinfo(target.TradeCode, unit, frequency, req.ClassifyId)
+						if err != nil {
+							fmt.Println("EditEdbinfo err:", err.Error())
+							return
+						}
+						// 指标信息变更
+						if _, isAdd := addEdbTradeMap[target.TradeCode]; !isAdd {
+							updateEdbTradeMap[target.TradeCode] = true
+						}
+					}
+
 					//判断指标数据是否已经存在
 					tmpDataMap, ok2 := edbCodeDataMap[target.TradeCode]
 					if !ok2 {
@@ -3468,19 +3521,6 @@ func (this *TargetController) ExcelDataAdd() {
 							// 指标数据变更
 							updateDataTradeMap[target.TradeCode] = true
 						}
-
-						if frequency != target.Frequency || unit != target.Unit || req.ClassifyId != target.ClassifyId {
-							fmt.Println("更新指标频度或单位")
-							err = models.ModifyEdbinfo(target.TradeCode, unit, frequency, req.ClassifyId)
-							if err != nil {
-								fmt.Println("EditEdbinfo err:", err.Error())
-								return
-							}
-							// 指标信息变更
-							if _, isAdd := addEdbTradeMap[target.TradeCode]; !isAdd {
-								updateEdbTradeMap[target.TradeCode] = true
-							}
-						}
 					} else { //数据不存在,进行新增操作
 						if target.TradeCode != "" && createDate != "" && closeVal != "" {
 							fmt.Println("新增")

+ 3 - 2
models/data_manage/base_from_sci.go

@@ -1,10 +1,11 @@
 package data_manage
 
 import (
-	"fmt"
-	"github.com/beego/beego/v2/client/orm"
 	"eta/eta_api/utils"
+	"fmt"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
 )
 
 type BaseFromSci struct {

+ 217 - 0
models/data_manage/base_from_sci_hq_classify.go

@@ -0,0 +1,217 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+// BaseFromSciHqClassify 卓创红期原始数据分类表
+type BaseFromSciHqClassify struct {
+	ClassifyId     int       `orm:"column(classify_id);pk"`
+	ClassifyName   string    `description:"分类名称"`
+	ParentId       int       `description:"父级id"`
+	Level          int       `description:"层级"`
+	Sort           int       `description:"排序字段"`
+	ModifyTime     time.Time `description:"修改时间"`
+	CreateTime     time.Time `description:"创建时间"`
+	ClassifyNameEn string    `description:"英文分类名称"`
+}
+
+type BaseFromSciHqClassifyItem struct {
+	ClassifyId     int                          `orm:"column(classify_id);pk"`
+	ClassifyName   string                       `description:"分类名称"`
+	ParentId       int                          `description:"父级id"`
+	Level          int                          `description:"层级"`
+	Sort           int                          `description:"排序字段"`
+	UniqueCode     string                       `description:"唯一code"`
+	ModifyTime     time.Time                    `description:"修改时间"`
+	CreateTime     time.Time                    `description:"创建时间"`
+	ClassifyNameEn string                       `description:"英文分类名称"`
+	Children       []*BaseFromSciHqClassifyItem `description:"子分类"`
+}
+
+type BaseFromSciHqClassifyMaxSort struct {
+	ClassifyId int `description:"分类id"`
+	MaxSort    int `description:"最大排序"`
+}
+
+func (t *BaseFromSciHqClassify) Add() (insertId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	insertId, err = o.Insert(t)
+	return
+}
+
+func (t *BaseFromSciHqClassify) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(t, cols...)
+	return
+}
+
+func BatchAddSciHqClassify(items []*BaseFromSciHqClassify) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+// 获取所有分类
+func GetSciHqClassifyAll() (items []*BaseFromSciHqClassifyItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_classify ORDER BY sort ASC, classify_id ASC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// GetChildSciHqClassifyListById 获取子分类列表
+func GetChildSciHqClassifyListById(classifyId int) (items []*BaseFromSciHqClassifyItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_classify WHERE parent_id=? `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetChildSciHqClassifyIdsById 获取子分类的id集合
+func GetChildSciHqClassifyIdsById(classifyId int) (items []int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT classify_id FROM base_from_sci_hq_classify WHERE parent_id=? `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetChildSciHqClassifyMaxSortById 获取子分类最大排序
+func GetChildSciHqClassifyMaxSortById(classifyId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT MAX(sort) AS sort FROM base_from_sci_hq_classify WHERE parent_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	return
+}
+
+// GetSciHqClassifyCountById 获取分类数量
+func GetSciHqClassifyCountById(classifyId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_sci_hq_classify WHERE classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&count)
+	return
+}
+
+// GetSciHqClassifyById 通过分类id获取分类
+func GetSciHqClassifyById(classifyId int) (item *BaseFromSciHqClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_classify WHERE classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+// GetSciHqChildClassifyById 通过分类id获取子分类
+func GetSciHqChildClassifyIdsById(classifyId int) (items []int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT classify_id FROM base_from_sci_hq_classify WHERE parent_id=? `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetSciHqClassifyListByIds 通过分类id获取分类列表
+func GetSciHqClassifyListByIds(classifyIds []int) (items []*BaseFromSciHqClassify, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_classify WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)`
+	_, err = o.Raw(sql, classifyIds).QueryRows(&items)
+	return
+}
+
+// GetSciHqClassifyCountByName 通过分类名称获取分类
+func GetSciHqClassifyCountByName(classifyName string, lang string) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_sci_hq_classify WHERE 1=1`
+	if lang == utils.EnLangVersion {
+		sql += ` AND classify_name_en=? `
+	} else {
+		sql += ` AND classify_name=? `
+	}
+	err = o.Raw(sql, classifyName).QueryRow(&count)
+	return
+}
+
+func GetBaseFromSciHqClassifyEnCount(classifyNameEn string, parentId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT COUNT(1) AS count FROM base_from_sci_hq_classify WHERE classify_name_en=? AND parent_id=? `
+	err = o.Raw(sql, classifyNameEn, parentId).QueryRow(&count)
+	return
+}
+
+func GetBaseFromSciHqClassifyCount(classifyName string, parentId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT COUNT(1) AS count FROM base_from_sci_hq_classify WHERE classify_name=? AND parent_id=? `
+	err = o.Raw(sql, classifyName, parentId).QueryRow(&count)
+	return
+}
+
+func DeleteSciHqClassifyById(classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` DELETE FROM base_from_sci_hq_classify WHERE classify_id=? `
+	_, err = o.Raw(sql, classifyId).Exec()
+	return
+}
+
+// BatchDeleteSciHqClassifyById 批量删除分类
+func BatchDeleteSciHqClassifyById(classifyId []int) (err error) {
+	if len(classifyId) == 0 {
+		return
+	}
+	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 base_from_sci_hq_classify WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyId)) + `) `
+	_, err = o.Raw(sql, classifyId).Exec()
+
+	return
+}
+
+// DeleteSciHqClassifyByClassifyId 根据分类id删除对应的指标分类
+func DeleteSciHqClassifyByClassifyId(classifyIdList []int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	//删除分类
+	sql := `DELETE FROM base_from_sci_hq_classify WHERE classify_id IN (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, classifyIdList).Exec()
+	return
+}
+
+// GetSciHqIndexClassifyMinSort 获取最小不等于0的排序
+func GetSciHqIndexClassifyMinSort(parentId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT MIN(sort) FROM base_from_sci_hq_classify WHERE parent_id=? AND sort <> 0 `
+	err = o.Raw(sql, parentId).QueryRow(&sort)
+	return
+}
+
+// MoveUpSciHqIndexClassifyBySort 往上移动
+func MoveUpSciHqIndexClassifyBySort(parentId, nextSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_sci_hq_classify set sort = sort + 1 where parent_id=? and sort >= ? and sort< ?`
+	_, err = o.Raw(sql, parentId, nextSort, currentSort).Exec()
+	return
+}
+
+// MoveDownSciHqIndexClassifyBySort 往下移动
+func MoveDownSciHqIndexClassifyBySort(parentId, prevSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_sci_hq_classify set sort = sort - 1 where parent_id=? and sort <= ? and sort> ? `
+	_, err = o.Raw(sql, parentId, prevSort, currentSort).Exec()
+	return
+}

+ 52 - 0
models/data_manage/base_from_sci_hq_data.go

@@ -0,0 +1,52 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type BaseFromSciHqData struct {
+	SciHqDataId          int       `orm:"column(sci_hq_data_id);pk"`
+	BaseFromSciHqIndexId int       `description:"指标id"`
+	IndexCode            string    `description:"指标编码"`
+	DataTime             string    `description:"数据日期"`
+	Value                float64   `description:"数据值"`
+	CreateTime           time.Time `description:"创建时间"`
+	ModifyTime           time.Time `description:"修改时间"`
+	DataTimestamp        int64     `description:"数据时间戳"`
+}
+
+// GetSciHqDataByIndexId 根据指标id获取指标数据
+func GetSciHqDataByIndexId(indexId int) (items []*BaseFromSciHqData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_data WHERE base_from_sci_hq_index_id=? ORDER BY data_time DESC`
+	_, err = o.Raw(sql, indexId).QueryRows(&items)
+	return
+}
+
+// GetSciHqDataDataTimeByIndexId 根据指标id获取指标数据的日期列表
+func GetSciHqDataDataTimeByIndexId(indexIdList []int) (items []string, err error) {
+	if len(indexIdList) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT DISTINCT data_time FROM base_from_sci_hq_data WHERE base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(indexIdList)) + `) ORDER BY data_time DESC`
+	_, err = o.Raw(sql, indexIdList).QueryRows(&items)
+	return
+}
+
+func GetSciHqIndexDataByCode(indexCode string) (items []*BaseFromSciHqData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *  FROM base_from_sci_hq_data WHERE index_code=? ORDER BY data_time DESC  `
+	_, err = o.Raw(sql, indexCode).QueryRows(&items)
+	return
+}
+
+func GetSciHqIndexDataCount(indexCode string) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count  FROM base_from_sci_hq_data WHERE index_code=? `
+	err = o.Raw(sql, indexCode).QueryRow(&count)
+	return
+}

+ 374 - 0
models/data_manage/base_from_sci_hq_index.go

@@ -0,0 +1,374 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type BaseFromSciHqIndex struct {
+	BaseFromSciHqIndexId int       `orm:"pk"`
+	ClassifyId           int       `description:"指标分类id"`
+	IndexCode            string    `description:"指标编码"`
+	IndexName            string    `description:"指标名称"`
+	Unit                 string    `description:"单位"`
+	Frequency            string    `description:"频度"`
+	StartDate            string    `description:"开始日期"`
+	EndDate              string    `description:"结束日期"`
+	Sort                 int       `description:"排序"`
+	LatestValue          float64   `description:"最新值"`
+	LatestDate           time.Time `description:"最后更新时间"`
+	TerminalCode         string
+	FilePath             string `json:"-"`
+	CreateTime           time.Time
+	ModifyTime           time.Time
+}
+
+type BaseFromSciHqIndexView struct {
+	BaseFromSciHqIndexId int     `orm:"pk"`
+	EdbInfoId            int     `description:"指标库id"`
+	ClassifyId           int     `description:"指标分类id"`
+	IndexCode            string  `description:"指标编码"`
+	IndexName            string  `description:"指标名称"`
+	UniqueCode           string  `description:"唯一code"`
+	Frequency            string  `description:"频度"`
+	Unit                 string  `description:"单位"`
+	StartDate            string  `description:"开始日期"`
+	EndDate              string  `description:"结束日期"`
+	Sort                 int     `description:"排序"`
+	LatestValue          float64 `description:"最新值"`
+	LatestDate           string  `description:"最后更新时间"`
+	EdbExist             int     `description:"edb是否存在"`
+	ModifyTime           string
+}
+
+func (b *BaseFromSciHqIndex) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(b, cols...)
+	return
+}
+
+// GetSciHqIndexByCondition 根据条件获取卓创红期指标列表
+func GetSciHqIndexByCondition(condition string, pars []interface{}) (items []*BaseFromSciHqIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC, base_from_sci_hq_index_id ASC`
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// GetSciHqIndexByCondition 根据条件获取卓创红期指标列表
+func GetSciHqIndexByConditionAndFrequency(condition, frequency string, pars []interface{}) (items []*BaseFromSciHqIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` AND frequency=?`
+	sql += ` ORDER BY sort ASC, base_from_sci_hq_index_id ASC`
+	_, err = o.Raw(sql, pars, frequency).QueryRows(&items)
+	return
+}
+
+func GetSciHqIndexCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_sci_hq_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC, base_from_sci_hq_index_id ASC`
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+// GetSciHqIndexAndEdbInfoByCondition 根据条件获取卓创红期index和指标库的信息
+func GetSciHqIndexAndEdbInfoByCondition(condition string, pars []interface{}) (items []*BaseFromSciHqIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT b.*, e.edb_info_id FROM base_from_sci_hq_index AS b LEFT JOIN edb_info AS e ON b.index_code=e.edb_code AND e.source=? WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC `
+	_, err = o.Raw(sql, utils.DATA_SOURCE_SCI_HQ, pars).QueryRows(&items)
+	return
+}
+
+// GetSciHqIndexByIndexCode 根据指标编码获取指标信息
+func GetSciHqIndexByIndexCode(indexCode string) (item *BaseFromSciHqIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_index WHERE index_code=? `
+	err = o.Raw(sql, indexCode).QueryRow(&item)
+	return
+}
+
+// GetSciHqIndexByIndexId 根据指标id获取指标信息
+func GetSciHqIndexByIndexId(indexId int) (item *BaseFromSciHqIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_index WHERE base_from_sci_hq_index_id=? `
+	err = o.Raw(sql, indexId).QueryRow(&item)
+	return
+}
+
+// GetSciHqIndexListByIndexIds 根据指标id获取指标信息
+func GetSciHqIndexListByIndexIds(indexIds []int) (items []*BaseFromSciHqIndex, err error) {
+	if len(indexIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_sci_hq_index WHERE base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(indexIds)) + `) `
+	_, err = o.Raw(sql, indexIds).QueryRows(&items)
+	return
+}
+
+// GetSciHqIndexCountByClassifyIds 获取分类下指标的个数
+func GetSciHqIndexCountByClassifyIds(classifyIds []int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	num := len(classifyIds)
+	if num <= 0 {
+		return
+	}
+	sql := `SELECT COUNT(1) AS count FROM base_from_sci_hq_index WHERE classify_id IN (` + utils.GetOrmInReplace(num) + `) `
+	err = o.Raw(sql, classifyIds).QueryRow(&count)
+	return
+}
+
+// GetSciHqIndexByClassifyId 根据分类id获取卓创红期指标列表
+func GetSciHqIndexByClassifyId(classifyIds []int, startSize, pageSize int) (items []*BaseFromSciHqIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT b.*, e.edb_info_id,
+	CASE WHEN e.edb_info_id IS NULL THEN 0 ELSE 1 END AS edb_exist
+	FROM base_from_sci_hq_index AS b
+	LEFT JOIN edb_info AS e ON b.index_code=e.edb_code AND e.source=88
+	WHERE b.classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) ORDER BY b.sort ASC LIMIT ?,? `
+	_, err = o.Raw(sql, classifyIds, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// GetSciHqIndexCountByClassifyId 根据分类id获取卓创红期指标数量
+func GetSciHqIndexCountByClassifyId(classifyIds []int) (count int, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_sci_hq_index WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) `
+	err = o.Raw(sql, classifyIds).QueryRow(&count)
+	return
+}
+
+// GetSciHqIndexCount 获取卓创红期指标数量
+func GetSciHqIndexCount() (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_sci_hq_index `
+	err = o.Raw(sql).QueryRow(&count)
+	return
+}
+
+func GetSciHqIndexByPage(startSize, pageSize int) (items []*BaseFromSciHqIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT b.*, e.edb_info_id,
+	CASE WHEN e.edb_info_id IS NULL THEN 0 ELSE 1 END AS edb_exist
+	FROM base_from_sci_hq_index AS b
+	LEFT JOIN edb_info AS e ON b.index_code=e.edb_code AND e.source=88
+	ORDER BY b.modify_time DESC LIMIT ?,?`
+	_, err = o.Raw(sql, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// GetSciHqIndexBaseInfoByClassifyId 根据分类id获取卓创红期指标列表
+func GetSciHqIndexBaseInfoByClassifyId(classifyId int) (items []*BaseFromSciHqIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT base_from_sci_hq_index_id, classify_id, index_code, index_name, CONCAT(classify_id, '_', base_from_sci_hq_index_id) AS unique_code  FROM base_from_sci_hq_index WHERE classify_id = ? ORDER BY sort ASC `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetSciHqIndexBaseInfoByClassifyId 根据分类id获取卓创红期指标列表
+func GetSciHqIndexBaseInfoByCondition(condition string, pars []interface{}) (items []*BaseFromSciHqIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT base_from_sci_hq_index_id, index_code, index_name  FROM base_from_sci_hq_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC `
+	_, err = o.Raw(sql, pars...).QueryRows(&items)
+	return
+}
+
+func GetSciHqDataMaxCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT MAX(t.num) AS count FROM ( SELECT COUNT(1) AS num  FROM base_from_sci_hq_index AS a INNER JOIN base_from_sci_hq_data AS b ON a.index_code=b.index_code WHERE 1=1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY a.base_from_sci_hq_index_id) AS t `
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+// GetSciHqIndexMaxSortByClassifyId 根据分类id获取指标最大排序
+func GetSciHqIndexMaxSortByClassifyId(classifyId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT MAX(sort) FROM base_from_sci_index WHERE classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	return
+}
+
+func GetSciHqFrequency(classifyId int) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_sci_hq_index WHERE classify_id=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+func GetSciHqFrequencyByCondition(condition string, pars []interface{}) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_sci_hq_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, pars...).QueryRows(&items)
+	return
+}
+
+func GetSciHqFrequencyByCode(code string) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_sci_hq_index WHERE index_code=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, code).QueryRows(&items)
+	return
+}
+
+// GetSciHqClassifyMaxSortByClassifyIds 通过分类id获取对应分类的最大sort
+func GetSciHqClassifyMaxSortByClassifyIds(classifyIds []int) (items []*BaseFromSciHqClassifyMaxSort, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT bc.classify_id, COALESCE(MAX(bi.sort), 0) AS max_sort FROM base_from_sci_hq_classify  AS bc
+	LEFT JOIN base_from_sci_hq_index AS bi
+	ON bc.classify_id=bi.classify_id  
+	WHERE bc.classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)
+	GROUP BY bc.classify_id
+	`
+	// sql = ` SELECT classify_id, MAX(sort) AS max_sort FROM base_from_sci_hq_index WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) GROUP BY classify_id `
+	_, err = o.Raw(sql, classifyIds).QueryRows(&items)
+	return
+}
+
+func BatchModifySciHqIndexClassify(items []*BaseFromSciHqIndex) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE base_from_sci_hq_index SET classify_id=?, sort=? WHERE base_from_sci_hq_index_id=? `
+	p, err := o.Raw(sql).Prepare()
+	if err != nil {
+		return
+	}
+	defer func() {
+		p.Close()
+	}()
+	for _, v := range items {
+		_, err = p.Exec(v.ClassifyId, v.Sort, v.BaseFromSciHqIndexId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// MoveDownSciHqIndexBySort 往下移动
+func MoveDownSciHqIndexBySort(classifyId, prevSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_sci_hq_index set sort = sort - 1 where classify_id=? and sort <= ? and sort> ? `
+	_, err = o.Raw(sql, classifyId, prevSort, currentSort).Exec()
+	return
+}
+
+// MoveUpSciHqIndexBySort 往上移动
+func MoveUpSciHqIndexBySort(classifyId, nextSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_sci_hq_index set sort = sort + 1 where classify_id=? and sort >= ? and sort< ?`
+	_, err = o.Raw(sql, classifyId, nextSort, currentSort).Exec()
+	return
+}
+
+func DeleteSciHqIndexById(indexId 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 base_from_sci_hq_index WHERE base_from_sci_hq_index_id=? `
+	_, err = to.Raw(sql, indexId).Exec()
+	if err != nil {
+		return
+	}
+	sql = `DELETE FROM base_from_sci_hq_data WHERE base_from_sci_hq_index_id=? `
+	_, err = to.Raw(sql, indexId).Exec()
+	if err != nil {
+		return
+	}
+	return
+}
+
+func DeleteSciHqIndexByIds(indexIds []int) (err error) {
+	if len(indexIds) == 0 {
+		return
+	}
+	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 base_from_sci_hq_index WHERE base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(indexIds)) + `) `
+	_, err = o.Raw(sql, indexIds).Exec()
+	if err != nil {
+		return
+	}
+	sql = `DELETE FROM base_from_sci_hq_data WHERE base_from_sci_hq_index_id IN (` + utils.GetOrmInReplace(len(indexIds)) + `) `
+	_, err = o.Raw(sql, indexIds).Exec()
+	if err != nil {
+		return
+	}
+	return
+}
+
+// MoveSciHqIndex 移动指标分类
+func MoveSciHqIndex(indexId, classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` UPDATE base_from_sci_hq_index
+			SET
+			  classify_id = ?, modify_time=NOW() 
+			WHERE base_from_sci_hq_index_id = ?`
+	_, err = o.Raw(sql, classifyId, indexId).Exec()
+	return
+}
+
+// GetSciHqIndexMinSortByClassifyId 获取最小不等于0的排序
+func GetSciHqIndexMinSortByClassifyId(classifyId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT min(sort) FROM base_from_sci_hq_index WHERE classify_id=? and sort <> 0 `
+	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	return
+}

+ 16 - 0
models/data_manage/chart_info.go

@@ -58,6 +58,7 @@ type ChartInfo struct {
 	UnitEn            string `description:"英文单位名称"`
 	IsJoinPermission  int    `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	ForumChartInfoId  int    `description:"社区的图表ID"`
+	ChartAlias        string `description:"图表别名"`
 }
 
 type ChartInfoMore struct {
@@ -261,6 +262,7 @@ type EditChartInfoReq struct {
 	MarkersAreas         string                  `description:"标识区"`
 	Unit                 string                  `description:"中文单位名称"`
 	UnitEn               string                  `description:"英文单位名称"`
+	ChartAlias           string                  `description:"图表别名"`
 }
 
 type EditFutureGoodChartInfoReq struct {
@@ -321,6 +323,7 @@ type EditChartEnInfoReq struct {
 	ChartNameEn      string                    `description:"英文图表名称"`
 	ChartEdbInfoList []*EditChartEnInfoEdbItem `description:"指标及配置信息"`
 	ExtraConfig      string                    `description:"图表额外配置信息,json字符串"`
+	ChartAlias       string                    `description:"图表别名"`
 }
 type EditChartEnInfoEdbItem struct {
 	EdbInfoId int    `description:"指标ID"`
@@ -335,6 +338,7 @@ type EditChartInfoBaseReq struct {
 	ChartName        string                      `description:"图表名称(根据语言版本区分)"`
 	ChartEdbInfoList []*EditChartInfoEdbBaseItem `description:"指标及配置信息"`
 	ExtraConfig      string                      `description:"图表额外配置信息,json字符串"`
+	ChartAlias       string                      `description:"图表别名"`
 }
 type EditChartInfoEdbBaseItem struct {
 	EdbInfoId int    `description:"指标ID"`
@@ -375,6 +379,7 @@ type ChartInfoList struct {
 	CreateTime           time.Time
 	ModifyTime           time.Time
 	EdbInfoList          []*EdbInfoList
+	ChartAlias           string `description:"图表别名"`
 }
 
 type ChartInfoListResp struct {
@@ -1058,6 +1063,9 @@ func EditChartInfoAndMapping(req *EditChartInfoReq, edbInfoIdStr string, calenda
 	sql += `,min_max_save = ? `
 	pars = append(pars, req.MinMaxSave)
 
+	sql += `,chart_alias = ? `
+	pars = append(pars, req.ChartAlias)
+
 	sql += `WHERE chart_info_id = ?`
 
 	pars = append(pars, req.ChartInfoId)
@@ -1332,6 +1340,9 @@ func EditChartEnInfoAndEdbEnInfo(req *EditChartEnInfoReq) (err error) {
 		pars = append(pars, req.ExtraConfig)
 	}
 
+	updateField += ` chart_alias =?, `
+	pars = append(pars, req.ChartAlias)
+
 	sql := ` UPDATE  chart_info
 			SET ` + updateField + ` modify_time = NOW()
 			WHERE chart_info_id = ?`
@@ -1405,6 +1416,9 @@ func EditChartBaseInfoAndEdbEnInfo(req *EditChartInfoBaseReq, chartItem *ChartIn
 		chartItem.ExtraConfig = req.ExtraConfig
 		updateChartCols = append(updateChartCols, "ExtraConfig")
 	}
+
+
+
 	chartItem.ModifyTime = time.Now()
 	updateChartCols = append(updateChartCols, "ModifyTime")
 	_, err = to.Update(chartItem, updateChartCols...)
@@ -1487,6 +1501,7 @@ type AddChartInfoReq struct {
 	MarkersAreas         string                  `description:"标识区"`
 	Unit                 string                  `description:"中文单位名称"`
 	UnitEn               string                  `description:"英文单位名称"`
+	ChartAlias           string                  `description:"图表别名"`
 }
 
 type AddFutureGoodChartInfoReq struct {
@@ -1942,6 +1957,7 @@ type ChartInfoView struct {
 	IsJoinPermission  int             `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	HaveOperaAuth     bool            `description:"是否有数据权限,默认:false"`
 	ForumChartInfoId  int             `description:"社区的图表ID"`
+	ChartAlias        string          `description:"图表别名"`
 }
 
 type ChartViewButton struct {

+ 5 - 2
models/data_manage/edb_data_base.go

@@ -4,10 +4,11 @@ import (
 	"eta/eta_api/models/mgo"
 	"eta/eta_api/utils"
 	"fmt"
-	"github.com/beego/beego/v2/client/orm"
-	"go.mongodb.org/mongo-driver/bson"
 	"strconv"
 	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+	"go.mongodb.org/mongo-driver/bson"
 )
 
 // GetEdbDataTableName 指标数据->存储表
@@ -176,6 +177,8 @@ func GetEdbDataTableName(source, subSource int) (tableName string) {
 		tableName = "edb_data_icpi"
 	case utils.DATA_SOURCE_SCI99: //ICPI消费价格指数->85
 		tableName = "edb_data_sci99"
+	case utils.DATA_SOURCE_SCI_HQ:
+		tableName = "edb_data_sci_hq"
 	default:
 		edbSource := EdbSourceIdMap[source]
 		if edbSource != nil {

+ 10 - 0
models/data_manage/edb_data_sci_hq.go

@@ -0,0 +1,10 @@
+package data_manage
+
+import "github.com/beego/beego/v2/client/orm"
+
+func GetEdbDataSciHqMaxAndMinDate(edbCode string) (min_date, max_date string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT MIN(data_time) AS min_date,MAX(data_time) AS max_date FROM edb_data_sci_hq WHERE edb_code=? `
+	err = o.Raw(sql, edbCode).QueryRow(&min_date, &max_date)
+	return
+}

+ 32 - 1
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 {
@@ -36,6 +37,7 @@ type EdbInfo struct {
 	UniqueCode       string `description:"指标唯一编码"`
 	CreateTime       time.Time
 	ModifyTime       time.Time
+	BaseModifyTime   time.Time
 	MinValue         float64 `description:"指标最小值"`
 	MaxValue         float64 `description:"指标最大值"`
 	CalculateFormula string  `description:"计算公式"`
@@ -168,6 +170,16 @@ func GetEdbInfoByEdbCode(source int, edbCode string) (item *EdbInfo, err error)
 	return
 }
 
+func GetEdbInfoListByEdbCodes(source int, edbCodes []string) (items []*EdbInfo, err error) {
+	if len(edbCodes) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM edb_info WHERE source=? AND edb_code IN (` + utils.GetOrmInReplace(len(edbCodes)) + `) `
+	_, err = o.Raw(sql, source, edbCodes).QueryRows(&items)
+	return
+}
+
 func GetEdbInfoById(edbInfoId int) (item *EdbInfo, err error) {
 	o := orm.NewOrmUsingDB("data")
 	sql := ` SELECT * FROM edb_info WHERE edb_info_id=? `
@@ -1965,6 +1977,25 @@ type ReplaceEdbInfoItem struct {
 	NewEdbInfo *EdbInfo
 }
 
+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 {

+ 6 - 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 {
@@ -257,6 +259,8 @@ type EdbInfoCalculateBatchEditReqByEdbLib struct {
 	Frequency     string `description:"频度"`
 	Unit          string `description:"单位"`
 	ClassifyId    int    `description:"分类id"`
+	AdminId       int    `description:"操作人id"`
+	AdminName     string `description:"操作人姓名"`
 	Formula       string `description:"N值"`
 	EdbInfoId     int    `description:"编辑指标id"`
 	FromEdbInfoId int    `description:"计算来源指标id"`

+ 28 - 0
models/data_manage/edb_info_record.go

@@ -0,0 +1,28 @@
+package data_manage
+
+import (
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type EdbInfoRecord struct {
+	EdbInfoRecordId     int       `orm:"column(edb_info_record_id);pk"`
+	EdbInfoId           int       `orm:"column(edb_info_id)"`
+	OldEdbName          string    `description:"旧的指标名称"`
+	OldFrequency        string    `description:"旧的频率"`
+	OldUnit             string    `description:"旧的单位"`
+	NewEdbName          string    `description:"新的指标名称"`
+	NewFrequency        string    `description:"新的频率"`
+	NewUnit             string    `description:"新的单位"`
+	OperateUserId       int       `description:"执行人id"`
+	OperateUserRealName string    `description:"执行人名称"`
+	CreateTime          time.Time `description:"记录的生成时间"`
+	Timestamp           int64     `description:"时间戳"`
+}
+
+func AddEditEdbInfoRcord(edbRecord *EdbInfoRecord) (e error) {
+	o := orm.NewOrmUsingDB("data")
+	_, e = o.Insert(edbRecord)
+	return
+}

+ 3 - 3
models/data_manage/excel/excel_edb_mapping.go

@@ -141,12 +141,12 @@ func GetExcelEdbMappingByEdbInfoIdAndSource(edbInfoId int, sources []int) (items
 // @Description: 根据指标id删除与自定义分析表格的关系
 // @author: Roc
 // @datetime 2023-11-02 13:20:02
-// @param excelInfoId int
+// @param edbInfoId int
 // @return err error
-func DeleteCustomAnalysisExcelEdbMappingByEdbInfoId(excelInfoId int) (err error) {
+func DeleteCustomAnalysisExcelEdbMappingByEdbInfoId(edbInfoId int) (err error) {
 	o := orm.NewOrmUsingDB("data")
 	sql := `DELETE FROM excel_edb_mapping WHERE source = ? AND edb_info_id = ? LIMIT 1`
-	_, err = o.Raw(sql, utils.CUSTOM_ANALYSIS_TABLE, excelInfoId).Exec()
+	_, err = o.Raw(sql, utils.CUSTOM_ANALYSIS_TABLE, edbInfoId).Exec()
 
 	return
 }

+ 71 - 0
models/data_manage/request/sci_hq_data.go

@@ -0,0 +1,71 @@
+package request
+
+type AddBaseFromSciHqClassifyReq struct {
+	ParentId     int    `description:"上级id"`
+	ClassifyName string `description:"分类名称"`
+}
+
+// DelBaseFromSciHqReq 删除卓创红期分类
+type DelBaseFromSciHqClassifyReq struct {
+	ClassifyId int `description:"分类id"`
+}
+
+// EditBaseFromSciClassifyReq 编辑卓创红期分类
+type EditBaseFromSciHqClassifyReq struct {
+	ClassifyName string `description:"分类名称"`
+	ClassifyId   int    `description:"分类id"`
+}
+
+// EditBaseFromSciHqReq 编辑卓创红期指标所属分类
+type EditBaseFromSciHqReq struct {
+	BaseFromSciHqIndexId int `description:"指标id"`
+	ClassifyId           int `description:"分类id"`
+}
+
+// DelBaseFromSciHqReq 删除卓创红期指标
+type DelBaseFromSciHqReq struct {
+	BaseFromSciHqIndexId int `description:"指标id"`
+}
+
+// ResetBaseFromSciHqReq 重置指标所属分类
+type ResetBaseFromSciHqReq struct {
+	BaseFromSciHqIndexId int `description:"指标id"`
+}
+
+// SciHqDataBatchAddCheckReq 卓创红期指标批量添加校验
+type SciHqDataBatchAddCheckReq struct {
+	// MysteelChemicalDataListReq
+	IndexCodes []string `description:"指标编码"`
+}
+
+// SciHqDataBatchListReq 卓创红期指标批量列表
+type SciHqDataBatchListReq struct {
+	ClassifyId  int    `description:"分类id"`
+	KeyWord     string `description:"关键字"`
+	SelectedId  []int  `description:"已选指标id, 为true时表示反选"`
+	IsSelectAll bool   `description:"是否查询全部, 默认false, true:全选, false:查询已选"`
+}
+
+// MoveBaseFromSciHqClassifyReq 移动分类请求参数
+type MoveBaseFromSciHqClassifyReq struct {
+	ClassifyId     int `description:"分类id"`
+	ParentId       int `description:"父级分类id"`
+	PrevClassifyId int `description:"上一个兄弟节点分类id"`
+	NextClassifyId int `description:"下一个兄弟节点分类id"`
+}
+
+// MoveBaseFromSciHqReq 移动指标请求参数
+type MoveBaseFromSciHqReq struct {
+	ClassifyId               int `description:"分类id"`
+	BaseFromSciHqIndexId     int `description:"指标id"`
+	PrevBaseFromSciHqIndexId int `description:"上一个兄弟节点id"`
+	NextBaseFromSciHqIndexId int `description:"下一个兄弟节点id"`
+}
+
+// ExportSciHqExcelReq导出卓创红期excel指标
+type ExportSciHqExcelReq struct {
+	KeyWord       string   `description:"关键字, 指标编码或指标ID"`
+	IndexCode     []string `description:"指标编码,全选时,表示反选"`
+	IsSelectedAll bool     `description:"是否全选:true:全选|false: 无"`
+	ClassifyId    int      `description:"指标id"`
+}

+ 35 - 0
models/data_manage/response/sci_hq_data.go

@@ -0,0 +1,35 @@
+package response
+
+import (
+	"eta/eta_api/models/data_manage"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type SciHqIndexPageListResp struct {
+	List   []*data_manage.BaseFromSciHqIndexView
+	Paging *paging.PagingItem
+}
+
+type EditSciHqIndexInfoResp struct {
+	BaseFromSciHqIndexId int
+	IndexCode            string
+}
+
+type SciHqSingleDataResp struct {
+	BaseFromSciHqIndexId int
+	ClassifyId           int
+	EdbInfoId            int
+	Name                 string
+	IndexCode            string
+	IndexName            string
+	Frequency            string
+	Unit                 string
+	ApiStartTime         string
+	ApiUpdateTime        string
+	StartTime            string
+	FinishTime           string
+	CreateTime           string
+	ModifyTime           string
+	Data                 []*data_manage.BaseFromSciHqData
+}

+ 4 - 0
models/db.go

@@ -321,6 +321,7 @@ func initEdbData() {
 		new(data_manage.BaseFromSmmData),
 		new(data_manage.BaseFromSmmClassify),
 		new(data_manage.EdbInfoLog),
+		new(data_manage.EdbInfoRecord),
 		new(data_manage.EdbInfoCalculateMapping),
 		new(data_manage.PredictEdbConf),                  //预测指标配置
 		new(data_manage.BaseFromMysteelChemicalClassify), //预测指标配置
@@ -351,6 +352,9 @@ func initEdbData() {
 		new(data_manage.BaseFromThsHfClassify),
 		new(data_manage.BaseFromEdbMapping),
 		new(data_manage.EdbInfoRelation), //指标关系表
+		new(data_manage.BaseFromSciHqClassify),
+		new(data_manage.BaseFromSciHqIndex),
+		new(data_manage.BaseFromSciHqData),
 	)
 }
 

+ 3 - 3
models/manual_edb.go

@@ -104,7 +104,7 @@ type EdbListResp struct {
 // @return err error
 func GetEdbInfoList(condition string, pars []interface{}, startSize, pageSize int) (items []*EdbInfoListItem, err error) {
 	o := orm.NewOrmUsingDB("edb")
-	sql := `SELECT DISTINCT a.* FROM edbinfo AS a  WHERE a.REMARK='手动' `
+	sql := `SELECT DISTINCT a.* FROM edbinfo AS a  WHERE a.classify_id > 0 `
 	if condition != "" {
 		sql += condition
 	}
@@ -130,7 +130,7 @@ func GetEdbInfoList(condition string, pars []interface{}, startSize, pageSize in
 // @return err error
 func GetCountEdbInfoList(condition string, pars []interface{}) (total int, err error) {
 	o := orm.NewOrmUsingDB("edb")
-	sql := `SELECT COUNT(1) ct FROM edbinfo AS a  WHERE a.REMARK='手动' `
+	sql := `SELECT COUNT(1) ct FROM edbinfo AS a  WHERE a.classify_id > 0 `
 	if condition != "" {
 		sql += condition
 	}
@@ -167,7 +167,7 @@ func DelEdbdataByCodeAndDateList(tradeCode string, dateList []string) (err error
 	}
 
 	o := orm.NewOrmUsingDB("edb")
-	sql := `delete from  edbdata AS a  WHERE a.TRADE_CODE=? and DT in (` + utils.GetOrmInReplace(num) + `) `
+	sql := `delete from edbdata  WHERE TRADE_CODE=? AND DT in (` + utils.GetOrmInReplace(num) + `) `
 	_, err = o.Raw(sql, tradeCode, dateList).Exec()
 
 	return

+ 1 - 1
models/report_v2.go

@@ -369,7 +369,7 @@ func GetReportListCountByAuthorized(condition string, pars []interface{}) (count
 func GetReportListByAuthorized(condition string, pars []interface{}, startSize, pageSize int) (items []*ReportList, err error) {
 	o := orm.NewOrmUsingDB("rddp")
 
-	sql := `SELECT id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter FROM report as a WHERE 1=1  `
+	sql := `SELECT id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time FROM report as a WHERE 1=1  `
 	if condition != "" {
 		sql += condition
 	}

+ 40 - 22
models/target.go

@@ -36,7 +36,7 @@ func GetDataList(condition string, pars []interface{}, startSize, pageSize int)
 	sql := `select a.TRADE_CODE,a.SEC_NAME,a.UNIT,a.frequency,a.classify_id,b.classify_name,c.DT,c.CLOSE,c.modify_time FROM edbdata AS c
                 inner join edbinfo AS a ON a.TRADE_CODE=c.TRADE_CODE
                 left join edbdata_classify AS b ON a.classify_id=b.classify_id
-                where left(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+                where a.classify_id>0`
 	if condition != "" {
 		sql += condition
 	}
@@ -50,7 +50,7 @@ func GetDataListCount(condition string, pars []interface{}) (count int, err erro
 	sql := ` select count(1) as count FROM edbdata AS c
                     inner join edbinfo AS a ON a.TRADE_CODE=c.TRADE_CODE    
                     left join edbdata_classify AS b ON a.classify_id=b.classify_id
-                    where left(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0 `
+                    where a.classify_id>0 `
 	if condition != "" {
 		sql += condition
 	}
@@ -191,14 +191,14 @@ func GetEdbinfoListCount(condition string, pars []interface{}, mobile string, ro
 	if mobile != "" && roleType == 1 {
 		sql = `SELECT COUNT(1) AS count FROM edbinfo AS a 
              INNER JOIN edbinfo_user AS c ON a.TRADE_CODE=c.TRADE_CODE AND c.mobile=?
-             WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+             WHERE a.classify_id>0`
 
 		if condition != "" {
 			sql += condition
 		}
 		err = o.Raw(sql, mobile, pars).QueryRow(&count)
 	} else {
-		sql := `SELECT COUNT(1) AS count FROM edbinfo AS a WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+		sql := `SELECT COUNT(1) AS count FROM edbinfo AS a WHERE a.classify_id>0`
 
 		if condition != "" {
 			sql += condition
@@ -234,7 +234,7 @@ func GetEdbinfoItemList(condition string, pars []interface{}, startSize, pageSiz
 		sql = ` SELECT DISTINCT a.*,b.classify_name FROM edbinfo AS a
                     LEFT JOIN edbdata_classify AS b ON a.classify_id=b.classify_id
                     INNER JOIN edbinfo_user AS c ON a.TRADE_CODE=c.TRADE_CODE AND c.mobile=?
-                    WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+                    WHERE a.classify_id>0`
 		if condition != "" {
 			sql += condition
 		}
@@ -243,7 +243,7 @@ func GetEdbinfoItemList(condition string, pars []interface{}, startSize, pageSiz
 	} else {
 		sql = `SELECT DISTINCT a.*,b.classify_name FROM edbinfo AS a
                      LEFT JOIN edbdata_classify AS b on a.classify_id=b.classify_id
-                     WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+                     WHERE a.classify_id>0`
 		if condition != "" {
 			sql += condition
 		}
@@ -296,7 +296,7 @@ type EdbinfoAddReq struct {
 
 // GetMaxTradeCode 获取指标最大trade_code
 func GetMaxTradeCode() (max_trade_code string, err error) {
-	sql := " SELECT MAX(TRADE_CODE) AS max_trade_code FROM edbinfo WHERE LEFT(TRADE_CODE,1)='W' AND TRADE_CODE not like '%index%' and TRADE_CODE NOT LIKE 'WDC%'"
+	sql := " SELECT MAX(TRADE_CODE) AS max_trade_code FROM edbinfo WHERE LEFT(TRADE_CODE,1)='W' "
 	o := orm.NewOrmUsingDB("edb")
 	err = o.Raw(sql).QueryRow(&max_trade_code)
 	if (err != nil && err.Error() == utils.ErrNoRow()) || max_trade_code == `` {
@@ -306,7 +306,7 @@ func GetMaxTradeCode() (max_trade_code string, err error) {
 }
 
 func GetEdbinfoBySecName(secName string) (item *Edbinfo, err error) {
-	sql := `SELECT * FROM edbinfo WHERE SEC_NAME=? AND left(TRADE_CODE,1)='W' AND REMARK='手动' `
+	sql := `SELECT * FROM edbinfo WHERE SEC_NAME=? `
 	o := orm.NewOrmUsingDB("edb")
 	err = o.Raw(sql, secName).QueryRow(&item)
 	return
@@ -367,7 +367,7 @@ func EditEdbinfo(tradeCode, secName, unit, frequency, noticeTime string, classif
 func SearchTargetEntry(classifyId int, keyWord string) (items []*Edbinfo, err error) {
 	where := ""
 	pars := make([]interface{}, 0)
-	sql := `SELECT * FROM edbinfo WHERE LEFT(TRADE_CODE,1)='W' AND REMARK='手动' AND classify_id>0 AND classify_id=? `
+	sql := `SELECT * FROM edbinfo WHERE classify_id>0 AND classify_id=? `
 	pars = append(pars, classifyId)
 	if keyWord != "" {
 		sql += `AND SEC_NAME LIKE ? `
@@ -471,7 +471,7 @@ type EdbdataClassifyResp struct {
 }
 
 func GetTargetBySecName(secName string) (item *Edbinfo, err error) {
-	sql := `SELECT * FROM edbinfo WHERE SEC_NAME=? AND left(TRADE_CODE,1)='W' AND REMARK='手动' `
+	sql := `SELECT * FROM edbinfo WHERE SEC_NAME=? `
 	o := orm.NewOrmUsingDB("edb")
 	err = o.Raw(sql, secName).QueryRow(&item)
 	return
@@ -580,7 +580,7 @@ func GetDataListForExport(startDate, endDate, frequency, keyWord string, classif
 	sql := ` SELECT a.TRADE_CODE,a.SEC_NAME,a.UNIT,a.frequency,a.classify_id,b.classify_name,c.DT,c.CLOSE FROM edbdata AS c
                 INNER JOIN edbinfo AS a ON a.TRADE_CODE=c.TRADE_CODE
                 LEFT JOIN edbdata_classify AS b ON a.classify_id=b.classify_id
-                WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0 `
+                WHERE a.classify_id>0 `
 	if where != "" {
 		sql += where
 	}
@@ -676,7 +676,7 @@ func GetResearcherEntry() (items []*Researcher, err error) {
 		mobile := items[i].Mobile
 		sqlCount := ` SELECT COUNT(DISTINCT a.TRADE_CODE) AS count FROM  edbinfo_user AS a
             INNER JOIN edbinfo AS b ON a.TRADE_CODE=b.TRADE_CODE
-            WHERE a.mobile=? AND LEFT(b.TRADE_CODE,1)='W' AND b.REMARK='手动' AND b.classify_id>0 `
+            WHERE a.mobile=? AND b.classify_id>0 `
 		err = edbO.Raw(sqlCount, mobile).QueryRow(&count)
 		items[i].TargetCount = count
 	}
@@ -697,7 +697,7 @@ func GetResearcherEntryByMobile(mobile string) (items []*Researcher, err error)
 		mobile := items[i].Mobile
 		sqlCount := ` SELECT COUNT(DISTINCT a.TRADE_CODE) AS count FROM  edbinfo_user AS a
             INNER JOIN edbinfo AS b ON a.TRADE_CODE=b.TRADE_CODE
-            WHERE a.mobile=? AND LEFT(b.TRADE_CODE,1)='W' AND b.REMARK='手动' AND b.classify_id>0 `
+            WHERE a.mobile=? AND b.classify_id>0 `
 		err = edbO.Raw(sqlCount, mobile).QueryRow(&count)
 		items[i].TargetCount = count
 	}
@@ -729,10 +729,10 @@ type SortEdbInfo []EdbinfoItems
 func GetTargetItems(mobile string, classifyId int) (lastItems SortEdbInfo, err error) {
 	var items []*EdbinfoItems
 	o := orm.NewOrmUsingDB("edb")
-	//sql := ` SELECT *,'' modify_date,'' status FROM edbinfo AS a WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0 `
+	//sql := ` SELECT *,'' modify_date,'' status FROM edbinfo AS a WHERE a.classify_id>0 `
 
 	sql := ` SELECT *,'' modify_date,'' STATUS FROM edbinfo AS a 
-            WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0
+            WHERE a.classify_id>0
              `
 	if classifyId > 0 {
 		sql += ` AND a.classify_id=` + strconv.Itoa(classifyId) + ``
@@ -741,7 +741,7 @@ func GetTargetItems(mobile string, classifyId int) (lastItems SortEdbInfo, err e
 
 	//if classifyId > 0 {
 	//	sql = ` SELECT *,'' modify_date,'' status FROM edbinfo AS a
-	//        WHERE a.classify_id=` + strconv.Itoa(classifyId) + ` AND LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0
+	//        WHERE a.classify_id=` + strconv.Itoa(classifyId) + ` AND a.classify_id>0
 	//         GROUP BY a.TRADE_CODE `
 	//}
 
@@ -1035,12 +1035,12 @@ func GetEdbdataSecName(condition string, pars []interface{}) (items []*EdbdataEx
 	//	        INNER JOIN edbinfo AS a ON a.TRADE_CODE=c.TRADE_CODE
 	//	        INNER JOIN edbinfo_user AS d ON a.TRADE_CODE=d.TRADE_CODE
 	//	        LEFT JOIN edbdata_classify AS b ON a.classify_id=b.classify_id
-	//	        WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+	//	        WHERE a.classify_id>0`
 	sql := `SELECT a.TRADE_CODE,a.SEC_NAME,a.frequency,a.UNIT,MAX(c.DT) AS Dt,b.classify_name
 		        FROM edbdata AS c
 		        INNER JOIN edbinfo AS a ON a.TRADE_CODE=c.TRADE_CODE
 		        LEFT JOIN edbdata_classify AS b ON a.classify_id=b.classify_id
-		        WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0`
+		        WHERE a.classify_id>0`
 	if condition != "" {
 		sql += condition
 	}
@@ -1057,7 +1057,25 @@ func GetEdbDataFrequency(classifyId int) (items []*string, err error) {
 	return
 }
 
-func GetEdbDataFrequencyByKeyord(keyword string) (items []*string, err error) {
+// GetEdbDataFrequencyByClassifyIdList
+// @Description: 根据分类列表获取所有的频度
+// @author: Roc
+// @datetime 2024-08-15 17:51:13
+// @param classifyIdList []int
+// @return items []*string
+// @return err error
+func GetEdbDataFrequencyByClassifyIdList(classifyIdList []int) (items []string, err error) {
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	sql := `SELECT DISTINCT frequency FROM edbinfo where classify_id in (` + utils.GetOrmInReplace(num) + `) AND frequency IS NOT NULL ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年度','年度') `
+	o := orm.NewOrmUsingDB("edb")
+	_, err = o.Raw(sql, classifyIdList).QueryRows(&items)
+	return
+}
+
+func GetEdbDataFrequencyByKeyord(keyword string) (items []string, err error) {
 	sql := `SELECT DISTINCT frequency FROM edbinfo where SEC_NAME=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年度','年度') `
 	o := orm.NewOrmUsingDB("edb")
 	_, err = o.Raw(sql, keyword).QueryRows(&items)
@@ -1279,7 +1297,7 @@ func GetTargetItemList(classifyId, edbShowType int, frequency, keyword, tradeCod
 		sql = ` SELECT a.*,b.DT,'' modify_date,'' STATUS FROM edbinfo AS a 
 left join edbdata b on a.TRADE_CODE=b.TRADE_CODE `
 	}
-	sql += ` WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id>0 `
+	sql += ` WHERE a.classify_id>0 `
 
 	//如果没有分类id集合列表,那么就没有数据了,不用往下执行了,直接返回好了
 	if len(classifyIdStrList) <= 0 {
@@ -1432,7 +1450,7 @@ func GetEdbInfoCountByClassifyId(classifyId int) (count int, err error) {
 	o := orm.NewOrmUsingDB("edb")
 	sql := `SELECT COUNT(1) AS count FROM ( SELECT a.*,b.CLOSE FROM edbinfo AS a 
              INNER JOIN edbdata AS b ON a.TRADE_CODE=b.TRADE_CODE
-             WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' AND a.classify_id=? group by a.TRADE_CODE) d `
+             WHERE a.classify_id=? group by a.TRADE_CODE) d `
 	err = o.Raw(sql, classifyId).QueryRow(&count)
 	return
 }
@@ -1448,7 +1466,7 @@ func GetEdbInfoGroupCountByClassifyIds(classifyIds string) (list []*EdbInfoGroup
 	o := orm.NewOrmUsingDB("edb")
 	sql := `SELECT COUNT(1) AS count,classify_id FROM ( SELECT a.*,b.CLOSE FROM edbinfo AS a 
              INNER JOIN edbdata AS b ON a.TRADE_CODE=b.TRADE_CODE
-             WHERE LEFT(a.TRADE_CODE,1)='W' AND a.REMARK='手动' and a.classify_id in (` + classifyIds + `) group by a.TRADE_CODE) d 
+             WHERE a.classify_id in (` + classifyIds + `) group by a.TRADE_CODE) d 
 						 GROUP BY classify_id `
 	_, err = o.Raw(sql).QueryRows(&list)
 	return

+ 189 - 0
routers/commentsRouter.go

@@ -5650,6 +5650,195 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "ExportSciHqList",
+            Router: `/export/sciHqList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "Classify",
+            Router: `/sci_hq/classify`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "AddClassify",
+            Router: `/sci_hq/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "DelClassify",
+            Router: `/sci_hq/classify/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "EditClassify",
+            Router: `/sci_hq/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "MoveClassify",
+            Router: `/sci_hq/classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "DeleteSciHqData",
+            Router: `/sci_hq/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "AddEdbInfo",
+            Router: `/sci_hq/edb_info/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "AddCheck",
+            Router: `/sci_hq/edb_info/add_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "BatchAdd",
+            Router: `/sci_hq/edb_info/batch_add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "BatchDelete",
+            Router: `/sci_hq/edb_info/batch_delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "BatchEdit",
+            Router: `/sci_hq/edb_info/batch_edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "NameCheck",
+            Router: `/sci_hq/edb_info/name_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "EditSciHq",
+            Router: `/sci_hq/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "BatchIndexList",
+            Router: `/sci_hq/index/batch_list`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "IndexList",
+            Router: `/sci_hq/index/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "IndexPageList",
+            Router: `/sci_hq/index/page/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "MoveSciHqData",
+            Router: `/sci_hq/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "ResetSciHqIndex",
+            Router: `/sci_hq/reset`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "SearchList",
+            Router: `/sci_hq/search_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:SciHqDataController"],
+        beego.ControllerComments{
+            Method: "SingleData",
+            Router: `/sci_hq/single_data`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_source:DataSourceController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_source:DataSourceController"],
         beego.ControllerComments{
             Method: "GfexClassifyList",

+ 2 - 0
routers/router.go

@@ -31,6 +31,7 @@ import (
 	"eta/eta_api/controllers/smart_report"
 	"eta/eta_api/controllers/speech_recognition"
 	"eta/eta_api/controllers/trade_analysis"
+
 	"github.com/beego/beego/v2/server/web"
 	"github.com/beego/beego/v2/server/web/filter/cors"
 )
@@ -174,6 +175,7 @@ func init() {
 				&data_manage.BaseFromThsHfController{},
 				&data_manage.EdbInfoRelationController{},
 				&data_manage.FactorEdbSeriesController{},
+				&data_manage.SciHqDataController{},
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 4 - 0
services/data/base_edb_lib.go

@@ -74,6 +74,8 @@ func AddEdbData(source int, edbCode, frequency string) (resp *models.BaseRespons
 		urlStr = "icpi/add"
 	case utils.DATA_SOURCE_SCI99:
 		urlStr = "sci99/add"
+	case utils.DATA_SOURCE_SCI_HQ:
+		urlStr = "sci_hq/add"
 	default:
 		edbSource := data_manage.EdbSourceIdMap[source]
 		if edbSource != nil {
@@ -270,6 +272,8 @@ func RefreshEdbData(edbInfoId, source, subSource int, edbCode, startDate string)
 		urlStr = "icpi/refresh"
 	case utils.DATA_SOURCE_SCI99:
 		urlStr = "sci99/refresh"
+	case utils.DATA_SOURCE_SCI_HQ:
+		urlStr = "sci_hq/refresh"
 	default:
 		edbSource := data_manage.EdbSourceIdMap[source]
 		if edbSource != nil {

+ 583 - 0
services/data/base_from_sci_hq.go

@@ -0,0 +1,583 @@
+package data
+
+import (
+	"errors"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+func AddSciHqClassify(classifyName, lang string, parentId int) (ok bool, msg string, err error) {
+	var count int
+	switch lang {
+	case utils.EnLangVersion:
+		count, err = data_manage.GetBaseFromSciHqClassifyEnCount(classifyName, parentId)
+	default:
+		count, err = data_manage.GetBaseFromSciHqClassifyCount(classifyName, parentId)
+	}
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		return false, "分类已存在", nil
+	}
+
+	sort, err := data_manage.GetChildSciHqClassifyMaxSortById(parentId)
+	if err != nil {
+		return false, "", err
+	}
+	if parentId > 0 {
+		count, err = data_manage.GetSciHqClassifyCountById(parentId)
+		if err != nil {
+			return false, "", err
+		}
+		if count == 0 {
+			return false, "", errors.New("父分类不存在")
+		}
+		sciHqClassify := &data_manage.BaseFromSciHqClassify{
+			ClassifyName:   classifyName,
+			ClassifyNameEn: classifyName,
+			ParentId:       parentId,
+			Level:          2,
+			Sort:           sort + 1,
+			ModifyTime:     time.Now(),
+			CreateTime:     time.Now(),
+		}
+		_, err = sciHqClassify.Add()
+		if err != nil {
+			return
+		}
+	} else {
+		sciHqClassify := &data_manage.BaseFromSciHqClassify{
+			ClassifyName:   classifyName,
+			ClassifyNameEn: classifyName,
+			ParentId:       0,
+			Level:          1,
+			Sort:           sort + 1,
+			ModifyTime:     time.Now(),
+			CreateTime:     time.Now(),
+		}
+		insertId, er := sciHqClassify.Add()
+		if er != nil {
+			return false, "", er
+		}
+		sciHqClassifyList := []*data_manage.BaseFromSciHqClassify{
+			{
+				ClassifyName:   "价格",
+				ClassifyNameEn: "价格",
+				ParentId:       int(insertId),
+				Level:          2,
+				Sort:           1,
+				ModifyTime:     time.Now(),
+				CreateTime:     time.Now(),
+			},
+			{
+				ClassifyName:   "供应",
+				ClassifyNameEn: "供应",
+				ParentId:       int(insertId),
+				Level:          2,
+				Sort:           2,
+				ModifyTime:     time.Now(),
+				CreateTime:     time.Now(),
+			},
+			{
+				ClassifyName:   "需求",
+				ClassifyNameEn: "需求",
+				ParentId:       int(insertId),
+				Level:          2,
+				Sort:           3,
+				ModifyTime:     time.Now(),
+				CreateTime:     time.Now(),
+			},
+			{
+				ClassifyName:   "库存",
+				ClassifyNameEn: "库存",
+				ParentId:       int(insertId),
+				Level:          2,
+				Sort:           4,
+				ModifyTime:     time.Now(),
+				CreateTime:     time.Now(),
+			},
+		}
+		err = data_manage.BatchAddSciHqClassify(sciHqClassifyList)
+		if err != nil {
+			return
+		}
+	}
+	return true, "", nil
+}
+
+func DelSciHqClassify(classifyId int) (err error) {
+	classify, err := data_manage.GetSciHqClassifyById(classifyId)
+	if err != nil {
+		return
+	}
+	var classifyIds []int
+	classifyIds = append(classifyIds, classify.ClassifyId)
+	if classify.ParentId == 0 {
+		tmpClassifyIds, er := data_manage.GetChildSciHqClassifyIdsById(classify.ClassifyId)
+		if er != nil {
+			err = er
+			return
+		}
+		classifyIds = append(classifyIds, tmpClassifyIds...)
+	}
+	// 获取分类下的所有指标
+	count, err := data_manage.GetSciHqIndexCountByClassifyIds(classifyIds)
+	if err != nil {
+		err = errors.New("获取分类下的指标信息失败,Err:" + err.Error())
+		return
+	}
+	if count > 0 {
+		err = errors.New("该分类下有指标,不可删除")
+		return
+	}
+	// 删除对应的分类
+	err = data_manage.DeleteSciHqClassifyByClassifyId(classifyIds)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// ResetSciHqIndex 指标数据清除分类接口
+func ResetSciHqIndex(indexId int) (err error) {
+	sciHqIndex, err := data_manage.GetSciHqIndexByIndexId(indexId)
+	if err != nil {
+		return
+	}
+
+	// 更新指标在未分类下的排序,永远排在未分类的最后一个
+	//移动排序
+	classifyId := 0
+	updateCol := make([]string, 0)
+	var currentSort, prevSort int
+	currentSort = sciHqIndex.Sort
+	//未分类的最大的sort值
+	prevSort, err = data_manage.GetSciHqIndexMaxSortByClassifyId(classifyId)
+	if err != nil {
+		err = errors.New("获取上一个兄弟节点指标信息失败,Err:" + err.Error())
+		return
+	}
+
+	//如果前面一个节点的sort值比当前大,则当前节点往下移动
+	if prevSort >= currentSort {
+		//往下移动
+		err = data_manage.MoveDownSciIndexBySort(classifyId, prevSort, currentSort)
+		if err != nil {
+			err = errors.New("向下移动出错:" + err.Error())
+			return
+		}
+		sciHqIndex.Sort = prevSort
+	}
+
+	//更新
+	sciHqIndex.ModifyTime = time.Now()
+	sciHqIndex.ClassifyId = classifyId
+	updateCol = append(updateCol, "Sort", "ModifyTime", "ClassifyId")
+	err = sciHqIndex.Update(updateCol)
+	if err != nil {
+		err = errors.New("移动失败,Err:" + err.Error())
+		return
+	}
+	return
+}
+
+// 批量删除卓创红期指标
+func BatchDelSciHqData(indexIds []int) (existIndex []*data_manage.BaseFromSciHqIndex, err error) {
+	sciHqIndexList, err := data_manage.GetSciHqIndexListByIndexIds(indexIds)
+	if err != nil {
+		return
+	}
+
+	indexCodes := make([]string, 0)
+	codeToIndex := make(map[string]*data_manage.BaseFromSciHqIndex)
+	for _, v := range sciHqIndexList {
+		indexCodes = append(indexCodes, v.IndexCode)
+		codeToIndex[v.IndexCode] = v
+	}
+
+	edbInfoList, err := data_manage.GetEdbInfoListByEdbCodes(utils.DATA_SOURCE_SCI_HQ, indexCodes)
+	if err != nil {
+		return
+	}
+	deleteIndexIds := make([]int, 0)
+	for _, v := range edbInfoList {
+		if index, ok := codeToIndex[v.EdbCode]; ok {
+			existIndex = append(existIndex, index)
+			delete(codeToIndex, v.EdbCode)
+		}
+	}
+	for _, v := range codeToIndex {
+		deleteIndexIds = append(deleteIndexIds, v.BaseFromSciHqIndexId)
+	}
+
+	// 删除对应的指标
+	err = data_manage.DeleteSciHqIndexByIds(deleteIndexIds)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// DelSciHqData 删除卓创红期指标
+func DelSciHqData(indexId int) (err error, errMsg string) {
+	baseFromSciHqIndex, err := data_manage.GetSciHqIndexByIndexId(indexId)
+	if err != nil {
+		errMsg = `获取数据失败`
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该指标未入库`
+			err = nil
+		}
+		return
+	}
+
+	// 获取已经加入到EDB指标库的Sci指标
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_SCI_HQ, baseFromSciHqIndex.IndexCode)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		errMsg = "删除失败"
+		err = errors.New("获取分类下的指标信息失败,Err:" + err.Error())
+		return
+	}
+	if edbInfo != nil {
+		errMsg = "当前指标已被引用,不可删除"
+		err = nil
+		return
+	}
+
+	// 删除对应的指标
+	err = data_manage.DeleteSciHqIndexById(indexId)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// EditSciHqIndex 编辑卓创红期指标
+func EditSciHqIndex(indexId, classifyId int) (baseFromSciHqIndex *data_manage.BaseFromSciHqIndex, errMsg string, err error) {
+	baseFromSciHqIndex, err = data_manage.GetSciHqIndexByIndexId(indexId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该指标未入库`
+			err = nil
+		}
+		return
+	}
+	classify, err := data_manage.GetSciHqClassifyById(classifyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该分类不存在或已删除`
+			err = nil
+		}
+		return
+	}
+	if classify.Level == 1 { // 顶级分类
+		errMsg = `不合法的编辑`
+		err = nil
+		return
+	}
+	maxSort, err := data_manage.GetChildSciHqClassifyMaxSortById(classifyId)
+	if err != nil {
+		return
+	}
+
+	baseFromSciHqIndex.ClassifyId = classifyId
+	baseFromSciHqIndex.Sort = maxSort + 1
+	baseFromSciHqIndex.ModifyTime = time.Now()
+	err = baseFromSciHqIndex.Update([]string{"classify_id", "sort", "modify_time"})
+	return
+}
+
+type SciHqIndexSource2EdbReq struct {
+	EdbCode       string
+	EdbName       string
+	Frequency     string
+	Unit          string
+	ClassifyId    int
+	AdminId       int
+	AdminRealName string
+}
+
+// SciHqIndexSource2Edb 新增卓创红期数据从数据源到指标库
+func SciHqIndexSource2Edb(req SciHqIndexSource2EdbReq, lang string) (edb *data_manage.EdbInfo, errMsg string, skip bool, err error) {
+	if req.EdbCode == "" {
+		err = fmt.Errorf("指标ID为空")
+		return
+	}
+	defer func() {
+		if err != nil {
+			tips := fmt.Sprintf("SciHqIndexSource2Edb新增失败, Err: %s", err.Error())
+			fmt.Println(tips)
+			utils.FileLog.Info(tips)
+		}
+	}()
+	source := utils.DATA_SOURCE_SCI_HQ
+
+	// 是否新增过指标
+	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
+}
+
+// MoveSciHqClassify 移动卓创红期分类
+func MoveSciHqClassify(classifyId, parentClassifyId, prevClassifyId, nextClassifyId int) (err error, errMsg string) {
+	//判断分类是否存在
+	classifyInfo, err := data_manage.GetSciHqClassifyById(classifyId)
+	if err != nil {
+		errMsg = "移动失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+
+	updateCol := make([]string, 0)
+
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if classifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		parentClassifyInfo, tmpErr := data_manage.GetSciHqClassifyById(parentClassifyId)
+		if tmpErr != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上级分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+		classifyInfo.ParentId = parentClassifyInfo.ClassifyId
+		classifyInfo.Level = parentClassifyInfo.Level + 1
+		updateCol = append(updateCol, "ParentId", "Level")
+	}
+	var currentSort, prevSort, nextSort int
+	currentSort = classifyInfo.Sort
+
+	var prevClassify *data_manage.BaseFromSciHqClassify
+	var nextClassify *data_manage.BaseFromSciHqClassify
+	//如果有传入 上一个兄弟节点分类id
+	if prevClassifyId > 0 {
+		prevClassify, err = data_manage.GetSciHqClassifyById(prevClassifyId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "移动失败"
+				err = errors.New("上一个兄弟节点分类信息不存在" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		prevSort = prevClassify.Sort
+	}
+	if nextClassifyId > 0 {
+		//下一个兄弟节点
+		nextClassify, err = data_manage.GetSciHqClassifyById(nextClassifyId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "移动失败"
+				err = errors.New("下一个兄弟节点分类信息不存在" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		nextSort = nextClassify.Sort
+	}
+	// 修改历史数据中的排序为0的情况
+	if prevSort == 0 && nextSort == 0 { //目标是让当前分类处于目录的最顶部
+		//更新为0排序的数据为当前最小排序
+		if nextClassify != nil {
+			minSort, e := data_manage.GetSciHqIndexClassifyMinSort(parentClassifyId)
+			if e != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + e.Error())
+				return
+			}
+			if minSort > 1 {
+				minSort -= 1
+			}
+			nextClassify.Sort = minSort
+			err = nextClassify.Update([]string{"sort"})
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("更新下一个兄弟节点分类信息失败,Err:" + err.Error())
+				return
+			}
+			nextSort = minSort
+		}
+	}
+	//移到两个排序值中间操作
+	if prevSort >= currentSort {
+		//往下移动
+		err = data_manage.MoveDownSciHqIndexClassifyBySort(parentClassifyId, prevSort, currentSort)
+		if err != nil {
+			err = errors.New("向下移动出错:" + err.Error())
+			return
+		}
+		classifyInfo.Sort = prevSort
+	} else if nextSort <= currentSort && nextSort != 0 {
+		//往上移动
+		err = data_manage.MoveUpSciHqIndexClassifyBySort(parentClassifyId, nextSort, currentSort)
+		if err != nil {
+			err = errors.New("向上移动出错:" + err.Error())
+			return
+		}
+		classifyInfo.Sort = nextSort
+	}
+	classifyInfo.ModifyTime = time.Now()
+	updateCol = append(updateCol, "Sort", "ModifyTime")
+	err = classifyInfo.Update(updateCol)
+	if err != nil {
+		errMsg = "移动失败"
+		err = errors.New("修改失败,Err:" + err.Error())
+		return
+	}
+	return
+}
+
+// MoveSciHqData 移动卓创红期指标
+func MoveSciHqData(indexId, classifyId, prevIndexId, nextIndexId int) (err error, errMsg string) {
+	//分类信息
+	sciHqIndex, err := data_manage.GetSciHqIndexByIndexId(indexId)
+	if err != nil {
+		errMsg = `获取数据失败`
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该指标未入库`
+			err = nil
+		}
+		return
+	}
+
+	//判断分类是否存在
+	if classifyId > 0 {
+		_, err = data_manage.GetSciHqClassifyById(classifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取分类信息失败,Err:" + err.Error())
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "找不到该分类"
+				err = nil
+			}
+			return
+		}
+	}
+
+	//如果改变了分类,那么移动该图表数据
+	if sciHqIndex.ClassifyId != classifyId {
+		tmpErr := data_manage.MoveSciHqIndex(indexId, classifyId)
+		if tmpErr != nil {
+			errMsg = "移动失败"
+			err = errors.New("移动失败,Err:" + tmpErr.Error())
+			return
+		}
+	}
+
+	//移动排序
+	updateCol := make([]string, 0)
+	var currentSort, prevSort, nextSort int
+	currentSort = sciHqIndex.Sort
+	//如果有传入 上一个兄弟节点分类id
+	var prevIndex *data_manage.BaseFromSciHqIndex
+	var nextIndex *data_manage.BaseFromSciHqIndex
+	if prevIndexId > 0 {
+		prevIndex, err = data_manage.GetSciHqIndexByIndexId(prevIndexId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "移动失败"
+				err = errors.New("上一个兄弟节点指标信息不存在" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点指标信息失败,Err:" + err.Error())
+			return
+		}
+		prevSort = prevIndex.Sort
+	}
+
+	if nextIndexId > 0 {
+		//下一个兄弟节点
+		nextIndex, err = data_manage.GetSciHqIndexByIndexId(nextIndexId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "移动失败"
+				err = errors.New("下一个兄弟节点指标信息不存在" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取下一个兄弟节点指标信息失败,Err:" + err.Error())
+			return
+		}
+		nextSort = nextIndex.Sort
+	}
+
+	// 修改历史数据中的排序为0的情况
+	if prevSort == 0 && nextSort == 0 { //目标是让当前分类处于目录的最顶部, 但是历史数据里下个节点的sort为0的情况
+		//更新为0排序的数据为当前最小排序
+		if nextIndex != nil {
+			minSort, e := data_manage.GetSciHqIndexMinSortByClassifyId(classifyId)
+			if e != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + e.Error())
+				return
+			}
+			if minSort > 1 {
+				minSort -= 1
+			}
+			nextIndex.Sort = minSort
+			err = nextIndex.Update([]string{"Sort"})
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("更新下一个兄弟节点分类信息失败,Err:" + err.Error())
+				return
+			}
+			nextSort = minSort
+		}
+	}
+	//移到两个排序值中间操作
+	if prevSort >= currentSort {
+		//往下移动
+		err = data_manage.MoveDownSciHqIndexBySort(classifyId, prevSort, currentSort)
+		if err != nil {
+			err = errors.New("向下移动出错:" + err.Error())
+			return
+		}
+		sciHqIndex.Sort = prevSort
+	} else if nextSort <= currentSort && nextSort != 0 {
+		//往上移动
+		err = data_manage.MoveUpSciHqIndexBySort(classifyId, nextSort, currentSort)
+		if err != nil {
+			err = errors.New("向上移动出错:" + err.Error())
+			return
+		}
+		sciHqIndex.Sort = nextSort
+	}
+
+	//更新
+	sciHqIndex.ModifyTime = time.Now()
+	updateCol = append(updateCol, "Sort", "ModifyTime")
+	err = sciHqIndex.Update(updateCol)
+	if err != nil {
+		errMsg = "移动失败"
+		err = errors.New("修改失败,Err:" + err.Error())
+		return
+	}
+	return
+}

+ 1 - 0
services/data/chart_info.go

@@ -2573,6 +2573,7 @@ func AddChartInfo(req data_manage.AddChartInfoReq, sysUserId int, sysUserRealNam
 	chartInfo.MarkersAreas = req.MarkersAreas
 	chartInfo.Unit = req.Unit
 	chartInfo.UnitEn = req.UnitEn
+	chartInfo.ChartAlias = req.ChartAlias
 	newId, err := data_manage.AddChartInfo(chartInfo)
 	if err != nil {
 		errMsg = `保存失败`

+ 1 - 0
services/data/edb_info.go

@@ -1832,6 +1832,7 @@ func EdbInfoAdd(source, subSource, classifyId int, edbCode, edbName, frequency,
 		utils.DATA_SOURCE_NATIONAL_STATISTICS: "国家统计局",
 		utils.DATA_SOURCE_FUBAO:               "富宝数据",
 		utils.DATA_SOURCE_GFEX:                "广期所",
+		utils.DATA_SOURCE_SCI_HQ:              "卓创红期",
 	}
 
 	sourceName, ok := sourceNameMap[source]

+ 30 - 0
services/data/edb_info_record.go

@@ -0,0 +1,30 @@
+package data
+
+import (
+	"eta/eta_api/models/data_manage"
+	"time"
+)
+
+func AddEditEdbInfoRcord(oldEdbInfo *data_manage.EdbInfo, newEdbInfo *data_manage.EdbInfoEditRecord) (err error) {
+	if oldEdbInfo.EdbName != newEdbInfo.EdbName || oldEdbInfo.Frequency != newEdbInfo.Frequency || oldEdbInfo.Unit != newEdbInfo.Unit {
+		ctime := time.Now()
+		edbRecord := new(data_manage.EdbInfoRecord)
+		edbRecord.EdbInfoId = oldEdbInfo.EdbInfoId
+		edbRecord.OldEdbName = oldEdbInfo.EdbName
+		edbRecord.OldFrequency = oldEdbInfo.Frequency
+		edbRecord.OldUnit = oldEdbInfo.Unit
+		edbRecord.NewEdbName = newEdbInfo.EdbName
+		edbRecord.NewFrequency = newEdbInfo.Frequency
+		edbRecord.NewUnit = newEdbInfo.Unit
+		edbRecord.OperateUserId = newEdbInfo.OperateUserId
+		edbRecord.OperateUserRealName = newEdbInfo.OperateUserRealName
+		edbRecord.CreateTime = ctime
+		edbRecord.Timestamp = ctime.Unix()
+		err = data_manage.AddEditEdbInfoRcord(edbRecord)
+		if err != nil {
+			return
+		}
+		err = data_manage.ModifyEdbInfoBaseTimeById(edbRecord.EdbInfoId, ctime)
+	}
+	return
+}

+ 28 - 5
services/data/manual.go

@@ -285,16 +285,29 @@ func ImportManualData(path string, sysUser *system.Admin) (successCount, failCou
 			err = errors.New(errMsg)
 			return
 		}
+
+		templateType := 1 // 模板类型
+		minCellNum := 6   // 模板最小列数
 		headerCell := rowList[0].Cells
-		if len(headerCell) < 7 {
+
+		// 确定模板
+		for _, v := range headerCell {
+			if v.String() == "导入模板2/Import Template 2" {
+				templateType = 2
+				minCellNum = 2
+				break
+			}
+		}
+
+		// 如果小于最少列数,则报错
+		if len(headerCell) < minCellNum {
 			errMsg = sheet.Name + "页模板异常"
 			err = errors.New(errMsg)
 			return
 		}
 
-		templateName := headerCell[6].String()
-		switch templateName {
-		case "导入模板2/Import Template 2":
+		switch templateType {
+		case 2:
 			// 模板2需要走对应的取数逻辑
 			tmpIndexDataList, tmpFailDataList, err, errMsg = getDataByTemplate2(sheet, sysUser.AdminId)
 		default:
@@ -695,7 +708,17 @@ func getDataByTemplate1(sheet *xlsx.Sheet, sysUserId int) (indexDataList []Impor
 	for i := 2; i < maxRow; i++ {
 		row := sheet.Row(i)
 		cells := row.Cells
-		if len(cells) < 6 {
+		lenCell := len(cells)
+
+		// 过滤空白行
+		if lenCell <= 0 {
+			continue
+		}
+
+		if lenCell < 6 {
+			if cells[0].Value == `` {
+				continue
+			}
 			errMsg = "导入文件异常,请下载最新导入模板文件"
 			err = errors.New(errMsg)
 			return

BIN
static/template/导入模板1.xlsx


+ 2 - 0
utils/constants.go

@@ -173,6 +173,7 @@ const (
 	DATA_SOURCE_BLOOMBERG                            = 83       // bloomberg彭博数据
 	DATA_SOURCE_BUSINESS                             = 84       // 来源于自有数据
 	DATA_SOURCE_SCI99                                = 85       // 卓创资讯 -> 85
+	DATA_SOURCE_SCI_HQ                               = 88       // 卓创红期->88
 )
 
 // 数据刷新频率
@@ -417,6 +418,7 @@ var DataSourceEnMap = map[int]string{
 	DATA_SOURCE_BAIINFO:          "BAIINFO",
 	DATA_SOURCE_MYSTEEL_CHEMICAL: "Horizon Insights",
 	DATA_SOURCE_FUBAO:            "FuBao",
+	DATA_SOURCE_SCI_HQ:           "SCI(hongqi)",
 }
 
 const (