31 次代碼提交 399fe79a11 ... 210494affc

作者 SHA1 備註 提交日期
  xiziwen 210494affc Merge branch 'master' of http://8.136.199.33:3000/eta_server/eta_api 1 天之前
  xiziwen 81ff2aa221 Merge branch 'ETA_2.3.2' 1 天之前
  xiziwen 183a2a9975 Merge branch 'ETA_2.3.0' 1 天之前
  xiziwen f04fdc2460 fix 1 天之前
  xiziwen 7f41233f5f fix 1 天之前
  xiziwen 05069689a1 fix 1 天之前
  xiziwen 5404d34fb2 fix 4 天之前
  xiziwen 7ba6864eb6 fix 4 天之前
  xiziwen 8f59ddf5f6 fix 4 天之前
  xiziwen 950985ac79 fix 4 天之前
  xiziwen 809d44e509 fix 4 天之前
  xiziwen 702542ebde fix 4 天之前
  xiziwen 1759649e80 fix 3 周之前
  xiziwen 583fa9a99f fix 3 周之前
  xiziwen 034d64039a fix 3 周之前
  xiziwen c0aa43e694 fix 3 周之前
  xiziwen 5c5fe62a0b fix 3 周之前
  xiziwen ef21e512c2 fix 3 周之前
  xiziwen 6de41a83bd fix 3 周之前
  xiziwen 12e163fa69 first 4 周之前
  xiziwen 7c06b170bd 回显顺序按照传入id的顺序来 1 月之前
  xiziwen 97c4918e2d 分词 1 月之前
  xiziwen de99af3f5f fix 1 月之前
  xiziwen 1204f9bdd5 fix 1 月之前
  xiziwen b3b46513e0 fix 1 月之前
  xiziwen e3f06b504f fix 1 月之前
  xiziwen 3b72250533 fix 1 月之前
  xiziwen 0eb52018d6 fix 1 月之前
  xiziwen 252d7aaa83 fix 1 月之前
  xiziwen 2ba2ce3415 first 1 月之前
  xiziwen 268c2c793b first 1 月之前

+ 6 - 1
controllers/data_manage/chart_info.go

@@ -4677,7 +4677,12 @@ func (this *ChartInfoController) ChartList() {
 		}
 	}
 	if keyWord != "" {
-		condition += ` AND  ( chart_name LIKE '%` + keyWord + `%' OR chart_name_en LIKE '%` + keyWord + `%' )`
+		keyWordArr := strings.Split(keyWord, " ")
+		if len(keyWordArr) > 0 {
+			for _, v := range keyWordArr {
+				condition += ` AND CONCAT(chart_name,chart_name_en) LIKE '%` + v + `%'`
+			}
+		}
 	}
 	if sysUserIds != "" {
 		adminIds := strings.Split(sysUserIds, ",")

+ 1653 - 0
controllers/data_manage/clarksons_data.go

@@ -0,0 +1,1653 @@
+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"
+	etaTrialService "eta/eta_api/services/eta_trial"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"os"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/tealeg/xlsx"
+)
+
+type ClarksonsDataController struct {
+	controllers.BaseAuthController
+}
+
+// @Title 克拉克森数据分类
+// @Description 克拉克森数据分类接口
+// @Success 200 {object} data_manage.SciClassify
+// @router /clarksons/classify [get]
+func (this *ClarksonsDataController) Classify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	classifyList, err := data_manage.GetClarksonsClassifyAll()
+	if err != nil {
+		br.Msg = "查询失败"
+		br.ErrMsg = "查询失败, Err:" + err.Error()
+		return
+	}
+
+	initClassify := &data_manage.BaseFromClarksonsClassifyItem{
+		BaseFromClassifyId: 0,
+		ClassifyName:       "未分类",
+		ClassifyNameEn:     "Unclassified",
+		UniqueCode:         "0",
+		ParentId:           0,
+		Level:              1,
+		Sort:               0,
+		Children:           nil,
+	}
+	finalList := make([]*data_manage.BaseFromClarksonsClassifyItem, 0)
+	classifyTree := getClarksonsClassifyTree(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 /clarksons/classify/add [post]
+func (this *ClarksonsDataController) AddClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.AddBaseFromClarksonsClassifyReq
+	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.AddClarksonsClassify(req.ClassifyName, 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 /clarksons/classify/del [post]
+func (this *ClarksonsDataController) DelClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.DelBaseFromClarksonsClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromClassifyId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err = data.DelClarksonsClassify(req.BaseFromClassifyId)
+	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 /clarksons/classify/edit [post]
+func (this *ClarksonsDataController) EditClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.EditBaseFromClarksonsClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromClassifyId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "请输入分类名称"
+		return
+	}
+	classify, err := data_manage.GetClarksonsClassifyById(req.BaseFromClassifyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "分类不存在"
+			return
+		}
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类失败,Err:" + err.Error()
+		return
+	}
+
+	if classify.ClassifyName != req.ClassifyName {
+		count, err := data_manage.GetClarksonsClassifyCountByName(req.ClassifyName)
+		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 /clarksons/classify/move [post]
+func (this *ClarksonsDataController) MoveClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req request.MoveBaseFromClarksonsClassifyReq
+	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromClassifyId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "分类id小于等于0"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.MoveClarksonsClassify(req.BaseFromClassifyId, req.ParentClassifyId, 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   BaseFromClassifyId   query   int  true       "分类id"
+// @Success 200 {object} data_manage.BaseFromMysteelChemicalIndexResp
+// @router /clarksons/index/list [get]
+func (this *ClarksonsDataController) IndexList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	classifyId, _ := this.GetInt("BaseFromClassifyId", 0)
+	indexList, err := data_manage.GetClarksonsIndexBaseInfoByClassifyId(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
+}
+
+// GetClarksonsIndexInfo
+// @Title 添加指标-根据条件获取指标信息
+// @Description 添加指标-根据条件获取指标信息
+// @Param   KeyWord   query   string  false       "关键字"
+// @Param   ClassifyIds   query   string  false       "分类id"
+// @Param   Frequencies   query   string  false       "频率"
+// @Param   PageSize   query   int  false       "每页数据条数"
+// @Param   CurrentIndex   query   int  false       "当前页页码,从1开始"
+// @Success 200 {object} data_manage.BaseFromRzdIndexPage
+// @router /clarksons/get/index/info [post]
+func (this *ClarksonsDataController) GetClarksonsIndexInfo() {
+	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.ClarksonsDataBatchListReq
+	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	keyWord := req.KeyWord
+	classifyIds := req.ClassifyIds
+	frequencies := req.Frequencies
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+	var startSize int
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	var classifyIdList []string
+	var frequencyList []string
+	if classifyIds != "" {
+		classifyIdList = strings.Split(classifyIds, ",")
+	}
+	if frequencies != "" {
+		frequencyList = strings.Split(frequencies, ",")
+	}
+	indexInfoPage, err := data.GetClarksonsIndexInfo(keyWord, classifyIdList, frequencyList, currentIndex, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = indexInfoPage
+}
+
+// SearchList
+// @Title 克拉克森模糊搜索
+// @Description 克拉克森模糊搜索
+// @Param   Keyword   query   string  true       "关键字搜索"
+// @Success 200 {object} models.BaseResponse
+// @router /clarksons/search_list [get]
+func (this *ClarksonsDataController) 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.GetClarksonsIndexBaseInfoByCondition(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   BaseFromClarksonsIndexId   query   string  true       "指标唯一编码"
+// @Success 200 {object} models.BaseResponse
+// @router /clarksons/single_data [get]
+func (this *ClarksonsDataController) SingleData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	baseFromClarksonsIndexId, _ := this.GetInt("BaseFromClarksonsIndexId")
+	indexInfo, err := data_manage.GetClarksonsIndexByIndexId(baseFromClarksonsIndexId)
+	if err != nil {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+		return
+	}
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_CLARKSONS, 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.GetClarksonsDataByIndexId(baseFromClarksonsIndexId)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	var ret response.ClarksonsSingleDataResp
+	ret.ClassifyId = indexInfo.ClassifyId
+	ret.BaseFromClarksonsIndexId = indexInfo.BaseFromClarksonsIndexId
+	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
+}
+
+// MoveClarksonsData
+// @Title 克拉克森指标移动接口
+// @Description 克拉克森指标移动接口
+// @Success 200 {object} request.MoveBaseFromClarksonsReq
+// @router /clarksons/move [post]
+func (this *ClarksonsDataController) MoveClarksonsData() {
+	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.MoveBaseFromClarksonsReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromClarksonsIndexId <= 0 {
+		br.Msg = "参数错误"
+		br.ErrMsg = "指标id小于等于0"
+		br.IsSendEmail = false
+		return
+	}
+
+	if req.BaseFromClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.MoveClarksonsData(req.BaseFromClarksonsIndexId, req.BaseFromClassifyId, req.PrevBaseFromClarksonsIndexId, req.NextBaseFromClarksonsIndexId)
+	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 = "移动成功"
+}
+
+// ResetClarksonsIndex
+// @Title 指标数据清除分类
+// @Description 指标数据清除分类
+// @Param	request	body data_manage.DelBaseFromSciReq true "type json string"
+// @Success 200 Ret=200 操作成功
+// @router /clarksons/reset [post]
+//func (this *ClarksonsDataController) ResetClarksonsIndex() {
+//	br := new(models.BaseResponse).Init()
+//	defer func() {
+//		this.Data["json"] = br
+//		this.ServeJSON()
+//	}()
+//	var req request.ResetBaseFromClarksonsReq
+//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+//	if err != nil {
+//		br.Msg = "参数解析异常!"
+//		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+//		return
+//	}
+//
+//	if req.BaseFromClarksonsIndexId < 0 {
+//		br.Msg = "参数错误"
+//		br.IsSendEmail = false
+//		return
+//	}
+//
+//	err = data.ResetClarksonsIndex(req.BaseFromClarksonsIndexId)
+//	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 /clarksons/edb_info/add [post]
+//func (this *ClarksonsDataController) 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.GetClarksonsIndexByIndexCode(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_CLARKSONS
+//	// 指标入库
+//	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 /clarksons/edb_info/add_check [post]
+func (this *ClarksonsDataController) 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.ClarksonsDataBatchAddCheckReq
+	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_CLARKSONS)
+	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.GetClarksonsIndexAndEdbInfoByCondition(cond, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取克拉克森原始指标列表失败, Err: " + err.Error()
+		return
+	}
+
+	resp := make([]*data_manage.BaseFromClarksonsIndexView, 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 /clarksons/edb_info/name_check [post]
+func (c *ClarksonsDataController) 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_CLARKSONS, 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_CLARKSONS, 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 /clarksons/edb_info/batch_add [post]
+func (this *ClarksonsDataController) 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_CLARKSONS_" + 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.ClarksonsIndexSource2EdbReq
+		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.ClarksonsIndexSource2Edb(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)
+		}
+
+		// 更新es
+		go data.AddOrEditEdbInfoToEs(edbInfo.EdbInfoId)
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// BatchDelete
+// @Title 批量删除
+// @Description 批量删除
+// @Param	request	body []*request.DelBaseFromClarksonsReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/batch_delete [post]
+func (this *ClarksonsDataController) BatchDelete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req []*request.DelBaseFromClarksonsReq
+	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.BaseFromClarksonsIndexId <= 0 {
+			continue
+		}
+		deleteIds = append(deleteIds, v.BaseFromClarksonsIndexId)
+	}
+	existList, err := data.BatchDelClarksonsData(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.DelBaseFromClarksonsReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /clarksons/edb_info/batch_edit [post]
+func (this *ClarksonsDataController) BatchEdit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req []*request.EditBaseFromClarksonsReq
+	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.BaseFromClarksonsIndexId <= 0 {
+			continue
+		}
+		if v.BaseFromClassifyId <= 0 {
+			continue
+		}
+		indexIds = append(indexIds, v.BaseFromClarksonsIndexId)
+		classifyIds = append(classifyIds, v.BaseFromClassifyId)
+		indexIdToclassifyId[v.BaseFromClarksonsIndexId] = v.BaseFromClassifyId
+	}
+	if len(indexIds) == 0 {
+		br.Msg = "请选择指标或指定正确的分类"
+		return
+	}
+	indexList, err := data_manage.GetClarksonsIndexListByIndexIds(indexIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取指标失败,Err:" + err.Error()
+		return
+	}
+	classifySort, err := data_manage.GetClarksonsClassifyMaxSortByClassifyIds(classifyIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类最大排序失败,Err:" + err.Error()
+		return
+	}
+	classifySortMap := make(map[int]int)
+	for _, v := range classifySort {
+		classifySortMap[v.BaseFromClassifyId] = v.MaxSort
+	}
+	classifyList, err := data_manage.GetClarksonsClassifyListByIds(classifyIds)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "获取分类失败,Err:" + err.Error()
+		return
+	}
+	existClassifyList := make(map[int]struct{})
+	for _, v := range classifyList {
+		existClassifyList[v.BaseFromClassifyId] = struct{}{}
+	}
+	//编辑指标
+	updateIndexList := make([]*data_manage.BaseFromClarksonsIndex, 0)
+	for _, v := range indexList {
+		tmpClassifyId := indexIdToclassifyId[v.BaseFromClarksonsIndexId]
+		if _, ok := existClassifyList[tmpClassifyId]; ok {
+			v.ClassifyId = tmpClassifyId
+			v.Sort = classifySortMap[tmpClassifyId] + 1
+			classifySortMap[tmpClassifyId] += 1
+			updateIndexList = append(updateIndexList, v)
+		}
+	}
+	err = data_manage.BatchModifyClarksonsIndexClassify(updateIndexList)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑指标失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+
+}
+
+// EditClarksons
+// @Title 编辑克拉克森指标
+// @Description 编辑克拉克森指标接口
+// @Param	request	body data_manage.AddEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /clarksons/edit [post]
+func (this *ClarksonsDataController) EditClarksons() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.EditBaseFromClarksonsReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BaseFromClarksonsIndexId <= 0 {
+		br.Msg = "请选择指标"
+		br.IsSendEmail = false
+		return
+	}
+	if req.BaseFromClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.IsSendEmail = false
+		return
+	}
+
+	//编辑指标
+	sciIndexInfo, errMsg, err := data.EditClarksonsIndex(req.BaseFromClarksonsIndexId, req.BaseFromClassifyId)
+	if errMsg != `` {
+		br.Msg = errMsg
+		return
+	}
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑指标失败,Err:" + err.Error()
+		return
+	}
+
+	resp := response.EditClarksonsIndexInfoResp{
+		BaseFromClarksonsIndexId: sciIndexInfo.BaseFromClarksonsIndexId,
+		IndexCode:                sciIndexInfo.IndexCode,
+	}
+	br.Data = resp
+	br.Ret = 200
+	br.Msg = "保存成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// DeleteClarksonsData
+// @Title 删除指标
+// @Description 删除指标接口
+// @Param	request	body data_manage.DelBaseFromSciReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /clarksons/del [post]
+func (this *ClarksonsDataController) DeleteClarksonsData() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req request.DelBaseFromClarksonsReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BaseFromClarksonsIndexId < 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	err, errMsg := data.DelClarksonsData(req.BaseFromClarksonsIndexId)
+	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
+}
+
+// ExportClarksonsList
+// @Title 导出Sci数据
+// @Description 导出Sci数据
+// @Param   BaseFromClassifyId   query   int  true       "关键字搜索"
+// @Param   IndexCode   query   string  true       "指标编码"
+// @Success 200  导出成功
+// @router /export/clarksonsList [get]
+func (this *ClarksonsDataController) ExportClarksonsList() {
+	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("BaseFromClassifyId")
+	indexCode := this.GetString("IndexCode")
+	if classifyId < 0 {
+		br.Msg = "请选择分类"
+		return
+	}
+	secNameList := make([]*data_manage.BaseFromClarksonsIndex, 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.GetChildClarksonsClassifyListById(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.BaseFromClassifyId)
+			}
+		} 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.GetClarksonsFrequencyByCondition(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.GetClarksonsIndexByConditionAndFrequency(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.BaseFromClarksonsIndexId)
+		}
+		dataTimeList, err := data_manage.GetClarksonsDataDataTimeByIndexId(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.GetClarksonsIndexDataByCode(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.BaseFromClarksonsData)
+			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"
+}
+
+// getClarksonsClassifyTree 返回卓创红旗的树形结构
+func getClarksonsClassifyTree(items []*data_manage.BaseFromClarksonsClassifyItem, parentId int) []*data_manage.BaseFromClarksonsClassifyItem {
+	res := make([]*data_manage.BaseFromClarksonsClassifyItem, 0)
+	for _, item := range items {
+		if item.ParentId == parentId {
+			t := new(data_manage.BaseFromClarksonsClassifyItem)
+			t.BaseFromClassifyId = item.BaseFromClassifyId
+			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.BaseFromClassifyId)
+			}
+			t.Children = getClarksonsClassifyTree(items, item.BaseFromClassifyId)
+			res = append(res, t)
+		}
+	}
+	return res
+}
+
+// @Title 获取克拉克森数据
+// @Description 获取克拉克森数据接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   BaseFromSci99ClassifyId   query   int  true       "分类id"
+// @Param   KeyWord   query   string  true       "关键词"
+// @Success 200 {object} data_source.BaseFromSci99IndexView
+// @router /clarksons/index/data [get]
+func (this *ClarksonsDataController) ClarksonsData() {
+	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
+	}
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	var startSize int
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	baseFromClarksonsClassifyId, _ := this.GetInt("BaseFromClarksonsClassifyId")
+	if baseFromClarksonsClassifyId < 0 {
+		br.Msg = "请选择分类"
+		br.ErrMsg = "请选择分类"
+		return
+	}
+
+	keyword := this.GetString("KeyWord")
+
+	//获取指标
+	var condition string
+	var pars []interface{}
+
+	if baseFromClarksonsClassifyId > 0 {
+		condition += ` AND classify_id=? `
+		pars = append(pars, baseFromClarksonsClassifyId)
+	}
+
+	if keyword != "" {
+		condition += ` AND (index_code =? OR index_name LIKE ?)  `
+		pars = append(pars, keyword)
+		pars = append(pars, "%"+keyword+"%")
+	}
+
+	sci99List, err := data_manage.GetClarksonsIndex(condition, pars)
+	if err != nil {
+		br.Msg = "获取数据失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	resultList := make([]*data_manage.BaseFromClarksonsIndexList, 0)
+	for _, v := range sci99List {
+		product := new(data_manage.BaseFromClarksonsIndexList)
+		product.BaseFromClarksonsIndexId = v.BaseFromClarksonsIndexId
+		product.ClassifyId = v.ClassifyId
+		product.IndexCode = v.IndexCode
+		product.IndexName = v.IndexName
+		product.Frequency = v.Frequency
+		product.Unit = v.Unit
+		product.ModifyTime = v.ModifyTime
+
+		modifyTime, err := data_manage.GetClarksonsIndexLatestDate(v.IndexCode)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取更新时间失败"
+			br.ErrMsg = "获取更新时间失败,Err:" + err.Error()
+			return
+		}
+		product.ModifyTime = modifyTime
+
+		total, err := data_manage.GetClarksonsIndexDataCount(v.IndexCode)
+		page := paging.GetPaging(currentIndex, pageSize, total)
+		dataList, err := data_manage.GetClarksonsIndexData(v.IndexCode, startSize, pageSize)
+		if err != nil {
+			br.Msg = "获取数据失败"
+			br.ErrMsg = "获取指标数据失败,Err:" + err.Error()
+			return
+		}
+		if dataList == nil {
+			dataList = make([]*data_manage.BaseFromClarksonsData, 0)
+		}
+		product.DataList = dataList
+		product.Paging = page
+		resultList = append(resultList, product)
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resultList
+}
+
+// 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 /clarksons/index/page/list [get]
+func (this *ClarksonsDataController) 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.BaseFromClarksonsIndexView
+	if isListAll {
+		tmpTotal, err := data_manage.GetClarksonsIndexCount()
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		tmpIndexList, err := data_manage.GetClarksonsIndexByPage(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.GetClarksonsChildClassifyIdsById(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.GetClarksonsIndexCountByClassifyId(classifyIds)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取指标信息失败,Err:" + err.Error()
+			return
+		}
+		total = tmpTotal
+		tmpIndexList, err := data_manage.GetClarksonsIndexByClassifyId(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.ClarksonsIndexPageListResp)
+	resp.List = indexList
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 161 - 3
controllers/data_manage/edb_classify.go

@@ -9,7 +9,10 @@ import (
 	"eta/eta_api/services/data"
 	"eta/eta_api/services/data/data_manage_permission"
 	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
 	"sort"
+	"strconv"
+	"strings"
 )
 
 // EdbClassifyController 数据管理-分类模块
@@ -288,7 +291,7 @@ func (this *EdbClassifyController) EditEdbClassify() {
 		return
 	}
 
-	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ClassifyName, this.Lang, this.SysUser)
+	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ParentId, req.ClassifyName, this.Lang, this.SysUser)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -1109,7 +1112,7 @@ func (this *EdbClassifyController) ClassifyTree() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-
+	level, _ := this.GetInt(`Level`)
 	allList, err := data_manage.GetNormalEdbClassifyAll()
 	if err != nil && err.Error() != utils.ErrNoRow() {
 		br.Msg = "获取失败"
@@ -1135,7 +1138,7 @@ func (this *EdbClassifyController) ClassifyTree() {
 			button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
 			allList[k].Button = button
 		}
-		nodeAll = data.GetClassifyTreeRecursive(allList, 0)
+		nodeAll = data.GetClassifyTreeRecursive(allList, 0, level)
 		//根据sort值排序
 		sortList = nodeAll
 		sort.Sort(sortList)
@@ -1221,3 +1224,158 @@ func (this *EdbClassifyController) ClassifyTree() {
 //	br.Success = true
 //	br.Msg = "移动成功"
 //}
+
+// EdbInfoList
+// @Title 批量编辑指标列表接口
+// @Description 批量编辑指标列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   EdbInfoId   query   int  true       "指标id"
+// @Param   KeyWord   query   string  false       "搜索关键词:指标ID/指标名称"
+// @Success 200 {object} data_manage.EdbInfoListResp
+// @router /classify/edb/list [get]
+func (this *EdbInfoController) ClassifyEdbInfoList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	subClassify, _ := this.GetBool("SubClassify")
+	sources := this.GetString("Sources")
+	keyWord := this.GetString("KeyWord")
+	sysUserIds := this.GetString("SysUserIds")
+	classifyIdsStr := this.GetString("ClassifyIds")
+	classifyIds := strings.Split(classifyIdsStr, ",")
+
+	var condition string
+	var pars []interface{}
+
+	// 已授权分类id
+	//permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
+	//if err != nil {
+	//	br.Msg = "获取失败"
+	//	br.ErrMsg = "获取已授权分类id数据失败,Err:" + err.Error()
+	//	return
+	//}
+	classifyIdsArr := make([]int, 0)
+	for _, v := range classifyIds {
+		if v != `` {
+			id, _ := strconv.Atoi(v)
+			classifyIdsArr = append(classifyIdsArr, id)
+		}
+	}
+
+	//if len(permissionClassifyIdList) > 0 {
+	//	classifyIdsArr = utils.IntersectInt(permissionClassifyIdList, classifyIdsArr)
+	//}
+
+	condition += " AND edb_info_type = 0 "
+	if len(classifyIdsArr) > 0 {
+		if !subClassify {
+			condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(classifyIdsArr)) + ") "
+			pars = append(pars, classifyIdsArr)
+		} else {
+			classifyAll, err := data_manage.GetNormalEdbClassifyAll()
+			if err != nil && err.Error() != utils.ErrNoRow() {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取数据失败,Err:" + err.Error()
+				return
+			}
+			finalClassifyIds := make([]int, 0)
+			parents := data.GetEdbClassifyChildrenRecursiveByParentIds(classifyAll, classifyIds)
+			sort.Slice(parents, func(i, j int) bool {
+				return parents[i].Level < parents[i].Level
+			})
+			for _, v := range parents {
+				finalClassifyIds = append(finalClassifyIds, v.ClassifyId)
+			}
+
+			condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(finalClassifyIds)) + ") "
+			pars = append(pars, finalClassifyIds)
+		}
+	}
+
+	if keyWord != "" {
+		keyWordArr := strings.Split(keyWord, " ")
+		if len(keyWordArr) > 0 {
+			for _, v := range keyWordArr {
+				condition += ` AND edb_name LIKE '%` + v + `%' `
+			}
+		}
+	}
+	if sources != "" {
+		condition += " AND source IN(" + utils.GetOrmInReplace(len(strings.Split(sources, ","))) + ") "
+		pars = append(pars, strings.Split(sources, ","))
+	}
+	if sysUserIds != "" {
+		adminIds := strings.Split(sysUserIds, ",")
+		if len(adminIds) == 0 {
+			br.Msg = "请选择正确的创建人"
+			return
+		}
+		adminIdsSlice := make([]int, 0)
+		for _, adminId := range adminIds {
+			adminIdInt, e := strconv.Atoi(adminId)
+			if e != nil {
+				br.Msg = "请选择正确的创建人"
+				return
+			}
+			adminIdsSlice = append(adminIdsSlice, adminIdInt)
+		}
+		condition += "  AND sys_user_id in (" + utils.GetOrmInReplace(len(adminIds)) + ") "
+		pars = append(pars, adminIdsSlice)
+	}
+
+	// 获取当前账号的不可见指标
+	obj := data_manage.EdbInfoNoPermissionAdmin{}
+	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		return
+	}
+	noPermissionEdbInfoIds := make([]int, 0)
+	for _, v := range confList {
+		noPermissionEdbInfoIds = append(noPermissionEdbInfoIds, v.EdbInfoId)
+	}
+	if len(noPermissionEdbInfoIds) > 0 {
+		condition += " AND edb_info_id NOT IN(" + utils.GetOrmInReplace(len(noPermissionEdbInfoIds)) + ") "
+		pars = append(pars, noPermissionEdbInfoIds)
+	}
+
+	count, err := data_manage.GetEdbInfoByConditionCount(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, count)
+
+	list, err := data_manage.GetEdbInfoListByCondition(condition, pars, startSize, pageSize, "")
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	resp := new(data_manage.EdbInfoFilterDataResp)
+	resp.List = list
+	resp.Paging = page
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 187 - 0
controllers/data_manage/edb_info.go

@@ -21,6 +21,7 @@ import (
 	etaTrialService "eta/eta_api/services/eta_trial"
 	"eta/eta_api/utils"
 	"fmt"
+	"sort"
 	"strconv"
 	"strings"
 	"sync"
@@ -6719,3 +6720,189 @@ func (this *EdbInfoController) ChartImageSetBySvg() {
 	br.Success = true
 	br.Msg = "保存成功"
 }
+
+// ModifyChartList
+// @Title 批量修改图表
+// @Description 批量修改图表
+// @Param   SysUserIds   query   string  true       "根据创建人查询"
+// @Param   ChartClassifyIds   query   string  true       "图片分类id"
+// @Success 200 {object} models.ChartClassifyListResp
+// @router /modify/edbList [post]
+func (this *EdbInfoController) ModifyEdbList() {
+	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.ModifyEdbListReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	classifyIds := strings.Split(req.EdbClassifyIds, ",")
+
+
+	if !req.SelectAll && req.EdbInfoIds == "" {
+		br.Msg = "请选择图表"
+		return
+	}
+	if req.ClassifyId < 0 {
+		br.Msg = "请选择新分类"
+		return
+	}
+
+	var condition string
+	var pars []interface{}
+	edbInfoIds := make([]int, 0)
+
+	if req.SelectAll {
+		// 已授权分类id
+		permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取已授权分类id数据失败,Err:" + err.Error()
+			return
+		}
+		classifyIdsArr := make([]int, 0)
+		for _, v := range classifyIds {
+			if v != `` {
+				id, _ := strconv.Atoi(v)
+				classifyIdsArr = append(classifyIdsArr, id)
+			}
+		}
+
+		if len(permissionClassifyIdList) > 0 {
+			classifyIdsArr = utils.IntersectInt(permissionClassifyIdList, classifyIdsArr)
+		}
+
+		condition += " AND edb_info_type = 0 "
+		if len(classifyIdsArr) > 0 {
+			if !req.SubClassify {
+				condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(classifyIdsArr)) + ") "
+				pars = append(pars, classifyIdsArr)
+			} else {
+				classifyAll, err := data_manage.GetNormalEdbClassifyAll()
+				if err != nil && err.Error() != utils.ErrNoRow() {
+					br.Msg = "获取失败"
+					br.ErrMsg = "获取数据失败,Err:" + err.Error()
+					return
+				}
+				finalClassifyIds := make([]int, 0)
+				parents := data.GetEdbClassifyChildrenRecursiveByParentIds(classifyAll, classifyIds)
+				sort.Slice(parents, func(i, j int) bool {
+					return parents[i].Level < parents[i].Level
+				})
+				for _, v := range parents {
+					finalClassifyIds = append(finalClassifyIds, v.ClassifyId)
+				}
+
+				condition += " AND classify_id IN(" + utils.GetOrmInReplace(len(finalClassifyIds)) + ") "
+				pars = append(pars, finalClassifyIds)
+			}
+		}
+		if req.KeyWord != "" {
+			condition += ` AND edb_name LIKE '%` + req.KeyWord + `%' `
+		}
+		if req.Sources != "" {
+			condition += " AND source IN(" + utils.GetOrmInReplace(len(strings.Split(req.Sources, ","))) + ") "
+			pars = append(pars, strings.Split(req.Sources, ","))
+		}
+		if req.SysUserIds != "" {
+			adminIds := strings.Split(req.SysUserIds, ",")
+			if len(adminIds) == 0 {
+				br.Msg = "请选择正确的创建人"
+				return
+			}
+			adminIdsSlice := make([]int, 0)
+			for _, adminId := range adminIds {
+				adminIdInt, e := strconv.Atoi(adminId)
+				if e != nil {
+					br.Msg = "请选择正确的创建人"
+					return
+				}
+				adminIdsSlice = append(adminIdsSlice, adminIdInt)
+			}
+			condition += "  AND sys_user_id in (" + utils.GetOrmInReplace(len(adminIds)) + ") "
+			pars = append(pars, adminIdsSlice)
+		}
+		// 获取当前账号的不可见指标
+		obj := data_manage.EdbInfoNoPermissionAdmin{}
+		confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+			return
+		}
+		noPermissionEdbInfoIds := make([]int, 0)
+		for _, v := range confList {
+			noPermissionEdbInfoIds = append(noPermissionEdbInfoIds, v.EdbInfoId)
+		}
+		if len(noPermissionEdbInfoIds) > 0 {
+			condition += " AND edb_info_id NOT IN(" + utils.GetOrmInReplace(len(noPermissionEdbInfoIds)) + ") "
+			pars = append(pars, noPermissionEdbInfoIds)
+		}
+
+		count, err := data_manage.GetEdbInfoByConditionCount(condition, pars)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
+			return
+		}
+		if count > 100 {
+			br.Msg = "最多选择100个"
+			return
+		}
+
+		list, err := data_manage.GetEdbInfoListByCondition(condition, pars, 0, 0, "")
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
+			return
+		}
+
+
+		for _, v := range list {
+			edbInfoIds = append(edbInfoIds, v.EdbInfoId)
+		}
+	} else {
+		edbIds := strings.Split(req.EdbInfoIds, ",")
+		if len(edbIds) == 0 {
+			br.Msg = "请选择图表"
+			return
+		}
+		for _, id := range edbIds {
+			tmp, e := strconv.Atoi(id)
+			if e != nil {
+				br.Msg = "请选择正确的分类"
+				return
+			}
+			edbInfoIds = append(edbInfoIds, tmp)
+		}
+		if len(edbInfoIds) > 100 {
+			br.Msg = "最多只能选择100个图表"
+			return
+		}
+	}
+
+	err = data_manage.UpdateEdbClassifyIdByChartInfoId(edbInfoIds, req.ClassifyId)
+	if err != nil {
+		br.Msg = "更新失败"
+		br.ErrMsg = "更新图表分类失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 2 - 2
controllers/data_manage/predict_edb_classify.go

@@ -259,7 +259,7 @@ func (this *PredictEdbClassifyController) Edit() {
 		return
 	}
 
-	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ClassifyName, this.Lang, this.SysUser)
+	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ParentId, req.ClassifyName, this.Lang, this.SysUser)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -869,7 +869,7 @@ func (this *PredictEdbClassifyController) ClassifyTree() {
 			button := data.GetPredictEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
 			allList[k].Button = button
 		}
-		nodeAll = data.GetClassifyTreeRecursive(allList, 0)
+		nodeAll = data.GetClassifyTreeRecursive(allList, 0, 0)
 		//根据sort值排序
 		sortList = nodeAll
 		sort.Sort(sortList)

+ 35 - 20
controllers/sandbox/sandbox.go

@@ -2394,16 +2394,21 @@ func (this *SandboxController) LinkEdbInfoCheck() {
 		return
 	}
 	edbList := make([]*sandbox.SandboxLinkCheckItem, 0)
-	for _, v := range edbInfoList {
-		tmp := &sandbox.SandboxLinkCheckItem{
-			Id:         v.EdbInfoId,
-			Name:       v.EdbName,
-			UniqueCode: v.UniqueCode,
-			ClassifyId: v.ClassifyId,
+	for _, id := range req.EdbInfoIdList {
+		for _, v := range edbInfoList {
+			if v.EdbInfoId == id {
+				tmp := &sandbox.SandboxLinkCheckItem{
+					Id:         v.EdbInfoId,
+					Name:       v.EdbName,
+					UniqueCode: v.UniqueCode,
+					ClassifyId: v.ClassifyId,
+				}
+				edbList = append(edbList, tmp)
+			}
 		}
-		edbList = append(edbList, tmp)
 	}
 
+
 	chartList, err := data_manage.GetChartInfoByIdList(req.ChartInfoIdList)
 	if err != nil {
 		br.Msg = `获取失败`
@@ -2411,16 +2416,21 @@ func (this *SandboxController) LinkEdbInfoCheck() {
 		return
 	}
 	chartListTmp := make([]*sandbox.SandboxLinkCheckItem, 0)
-	for _, v := range chartList {
-		tmp := &sandbox.SandboxLinkCheckItem{
-			Id:         v.ChartInfoId,
-			Name:       v.ChartName,
-			UniqueCode: v.UniqueCode,
-			ClassifyId: v.ChartClassifyId,
+	for _, id := range req.ChartInfoIdList {
+		for _, v := range chartList {
+			if v.ChartInfoId == id {
+				tmp := &sandbox.SandboxLinkCheckItem{
+					Id:         v.ChartInfoId,
+					Name:       v.ChartName,
+					UniqueCode: v.UniqueCode,
+					ClassifyId: v.ChartClassifyId,
+				}
+				chartListTmp = append(chartListTmp, tmp)
+			}
 		}
-		chartListTmp = append(chartListTmp, tmp)
 	}
 
+
 	reportList, err := models.GetSimpleReportByIds(req.ReportIdList)
 	if err != nil {
 		br.Msg = `获取失败`
@@ -2428,14 +2438,19 @@ func (this *SandboxController) LinkEdbInfoCheck() {
 		return
 	}
 	reportListTmp := make([]*sandbox.SandboxLinkCheckItem, 0)
-	for _, v := range reportList {
-		tmp := &sandbox.SandboxLinkCheckItem{
-			Id:         v.Id,
-			Name:       v.Title,
-			UniqueCode: v.ReportCode,
+	for _, id := range req.ReportIdList {
+		for _, v := range reportList {
+			if v.Id == id {
+				tmp := &sandbox.SandboxLinkCheckItem{
+					Id:         v.Id,
+					Name:       v.Title,
+					UniqueCode: v.ReportCode,
+				}
+				reportListTmp = append(reportListTmp, tmp)
+			}
 		}
-		reportListTmp = append(reportListTmp, tmp)
 	}
+
 	resp.EdbInfoIdList = edbList
 	resp.ChartInfoIdList = chartListTmp
 	resp.ReportIdList = reportListTmp

+ 233 - 0
models/data_manage/base_from_clarksons_classify.go

@@ -0,0 +1,233 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"fmt"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+// BaseFromClarksonsClassify 卓创红期原始数据分类表
+type BaseFromClarksonsClassify struct {
+	BaseFromClassifyId int       `orm:"column(base_from_clarksons_classify_id);pk"`
+	ClassifyName       string    `description:"分类名称"`
+	ParentId           int       `description:"父级id"`
+	Level              int       `description:"层级"`
+	Sort               int       `description:"排序字段"`
+	ModifyTime         time.Time `description:"修改时间"`
+	CreateTime         time.Time `description:"创建时间"`
+}
+
+type BaseFromClarksonsClassifyItem struct {
+	BaseFromClassifyId int                              `orm:"column(base_from_clarksons_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           []*BaseFromClarksonsClassifyItem `description:"子分类"`
+}
+
+type BaseFromClarksonsClassifyMaxSort struct {
+	BaseFromClassifyId int `description:"分类id"`
+	MaxSort            int `description:"最大排序"`
+}
+
+func (t *BaseFromClarksonsClassify) Add() (insertId int64, err error) {
+	o := orm.NewOrmUsingDB("data")
+	insertId, err = o.Insert(t)
+	return
+}
+
+func (t *BaseFromClarksonsClassify) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(t, cols...)
+	return
+}
+
+func BatchAddClarksonsClassify(items []*BaseFromClarksonsClassify) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+// 获取所有分类
+func GetClarksonsClassifyAll() (items []*BaseFromClarksonsClassifyItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_classify ORDER BY sort ASC, base_from_clarksons_classify_id ASC`
+	_, err = o.Raw(sql).QueryRows(&items)
+	return
+}
+
+// GetChildClarksonsClassifyListById 获取子分类列表
+func GetChildClarksonsClassifyListById(classifyId int) (items []*BaseFromClarksonsClassifyItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_classify WHERE parent_id=? `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetChildClarksonsClassifyIdsById 获取子分类的id集合
+func GetChildClarksonsClassifyIdsById(classifyId int) (items []int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT base_from_clarksons_classify_id FROM base_from_clarksons_classify WHERE parent_id=? `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetChildClarksonsClassifyMaxSortById 获取子分类最大排序
+func GetChildClarksonsClassifyMaxSortById(classifyId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT MAX(sort) AS sort FROM base_from_clarksons_classify WHERE parent_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	return
+}
+
+// GetClarksonsClassifyCountById 获取分类数量
+func GetClarksonsClassifyCountById(classifyId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_clarksons_classify WHERE base_from_clarksons_classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&count)
+	return
+}
+
+// GetClarksonsClassifyById 通过分类id获取分类
+func GetClarksonsClassifyById(classifyId int) (item *BaseFromClarksonsClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_classify WHERE base_from_clarksons_classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}
+
+// GetClarksonsChildClassifyById 通过分类id获取子分类
+func GetClarksonsChildClassifyIdsById(classifyId int) (items []int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT base_from_clarksons_classify_id FROM base_from_clarksons_classify WHERE parent_id=? `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetClarksonsClassifyListByIds 通过分类id获取分类列表
+func GetClarksonsClassifyListByIds(classifyIds []int) (items []*BaseFromClarksonsClassify, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_classify WHERE base_from_clarksons_classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)`
+	_, err = o.Raw(sql, classifyIds).QueryRows(&items)
+	return
+}
+
+// GetClarksonsClassifyCountByName 通过分类名称获取分类
+func GetClarksonsClassifyCountByName(classifyName string) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_clarksons_classify WHERE 1=1`
+
+	sql += ` AND classify_name=? `
+	err = o.Raw(sql, classifyName).QueryRow(&count)
+	return
+}
+
+func GetBaseFromClarksonsClassifyEnCount(classifyNameEn string, parentId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT COUNT(1) AS count FROM base_from_clarksons_classify WHERE classify_name_en=? AND parent_id=? `
+	err = o.Raw(sql, classifyNameEn, parentId).QueryRow(&count)
+	return
+}
+
+func GetBaseFromClarksonsClassifyCount(classifyName string, parentId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT COUNT(1) AS count FROM base_from_clarksons_classify WHERE classify_name=? AND parent_id=? `
+	err = o.Raw(sql, classifyName, parentId).QueryRow(&count)
+	return
+}
+
+func DeleteClarksonsClassifyById(classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` DELETE FROM base_from_clarksons_classify WHERE base_from_clarksons_classify_id=? `
+	_, err = o.Raw(sql, classifyId).Exec()
+	return
+}
+
+// BatchDeleteClarksonsClassifyById 批量删除分类
+func BatchDeleteClarksonsClassifyById(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_clarksons_classify WHERE base_from_clarksons_classify_id IN (` + utils.GetOrmInReplace(len(classifyId)) + `) `
+	_, err = o.Raw(sql, classifyId).Exec()
+
+	return
+}
+
+// DeleteClarksonsClassifyByClassifyId 根据分类id删除对应的指标分类
+func DeleteClarksonsClassifyByClassifyId(classifyIdList []int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	num := len(classifyIdList)
+	if num <= 0 {
+		return
+	}
+	//删除分类
+	sql := `DELETE FROM base_from_clarksons_classify WHERE base_from_clarksons_classify_id IN (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, classifyIdList).Exec()
+	return
+}
+
+// GetClarksonsIndexClassifyMinSort 获取最小不等于0的排序
+func GetClarksonsIndexClassifyMinSort(parentId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT MIN(sort) FROM base_from_clarksons_classify WHERE parent_id=? AND sort <> 0 `
+	err = o.Raw(sql, parentId).QueryRow(&sort)
+	return
+}
+
+// MoveUpClarksonsIndexClassifyBySort 往上移动
+func MoveUpClarksonsIndexClassifyBySort(parentId, nextSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_clarksons_classify set sort = sort + 1 where parent_id=? and sort >= ? and sort< ?`
+	_, err = o.Raw(sql, parentId, nextSort, currentSort).Exec()
+	return
+}
+
+// MoveDownClarksonsIndexClassifyBySort 往下移动
+func MoveDownClarksonsIndexClassifyBySort(parentId, prevSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_clarksons_classify set sort = sort - 1 where parent_id=? and sort <= ? and sort> ? `
+	_, err = o.Raw(sql, parentId, prevSort, currentSort).Exec()
+	return
+}
+
+// UpdateClarksonsClassifySortByParentId 根据父类id更新排序
+func UpdateClarksonsClassifySortByParentId(parentId, classifyId, nowSort int, updateSort string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update base_from_clarksons_classify set sort = ` + updateSort + ` WHERE parent_id=? and sort > ? `
+	if classifyId > 0 {
+		sql += ` or ( base_from_clarksons_classify_id > ` + fmt.Sprint(classifyId) + ` and sort= ` + fmt.Sprint(nowSort) + `)`
+	}
+	_, err = o.Raw(sql, parentId, nowSort).Exec()
+	return
+}
+
+// GetFirstClarksonsClassifyByParentId 获取当前父级分类下的排序第一条的数据
+func GetFirstClarksonsClassifyByParentId(parentId int) (item *ChartClassify, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_classify WHERE parent_id=? order by sort asc,base_from_clarksons_classify_id asc limit 1`
+	err = o.Raw(sql, parentId).QueryRow(&item)
+	return
+}

+ 81 - 0
models/data_manage/base_from_clarksons_data.go

@@ -0,0 +1,81 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type BaseFromClarksonsData struct {
+	BaseFromClarksonsDataId          int       `orm:"column(base_from_clarksons_data_id);pk"`
+	BaseFromClarksonsIndexId int       `description:"指标id"`
+	IndexCode            string    `description:"指标编码"`
+	DataTime             string    `description:"数据日期"`
+	Value                float64   `description:"数据值"`
+	CreateTime           time.Time `description:"创建时间"`
+	ModifyTime           time.Time `description:"修改时间"`
+	DataTimestamp        int64     `description:"数据时间戳"`
+}
+
+// GetClarksonsDataByIndexId 根据指标id获取指标数据
+func GetClarksonsDataByIndexId(indexId int) (items []*BaseFromClarksonsData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_data WHERE base_from_clarksons_index_id=? ORDER BY data_time DESC`
+	_, err = o.Raw(sql, indexId).QueryRows(&items)
+	return
+}
+
+// GetClarksonsDataDataTimeByIndexId 根据指标id获取指标数据的日期列表
+func GetClarksonsDataDataTimeByIndexId(indexIdList []int) (items []string, err error) {
+	if len(indexIdList) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT DISTINCT data_time FROM base_from_clarksons_data WHERE base_from_clarksons_index_id IN (` + utils.GetOrmInReplace(len(indexIdList)) + `) ORDER BY data_time DESC`
+	_, err = o.Raw(sql, indexIdList).QueryRows(&items)
+	return
+}
+
+func GetClarksonsIndexDataByCode(indexCode string) (items []*BaseFromClarksonsData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *  FROM base_from_clarksons_data WHERE index_code=? ORDER BY data_time DESC  `
+	_, err = o.Raw(sql, indexCode).QueryRows(&items)
+	return
+}
+
+func GetClarksonsIndexDataCount(indexCode string) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(1) AS count  FROM base_from_clarksons_data WHERE index_code=? `
+	err = o.Raw(sql, indexCode).QueryRow(&count)
+	return
+}
+
+// GetClarksonsLastUpdateTimeLastByIndexCode 根据指标编码查询 返回ModifyTime最后一条数据
+func GetClarksonsLastUpdateTimeLastByIndexCode(indexCodes []string) (items []*BaseFromClarksonsData, err error) {
+	o := orm.NewOrmUsingDB("data")
+
+	// 构造 SQL 查询
+	sql := `SELECT t1.index_code, t1.data_time, t2.value
+			FROM (
+    			SELECT index_code, MAX(data_time) AS data_time
+   				 FROM base_from_clarksons_data
+    			WHERE index_code IN (` + utils.GetOrmInReplace(len(indexCodes)) + `)
+    			GROUP BY index_code
+			) AS t1
+			JOIN base_from_clarksons_data AS t2 ON t1.index_code = t2.index_code AND t1.data_time = t2.data_time`
+
+	// 执行 SQL 查询
+	_, err = o.Raw(sql, indexCodes).QueryRows(&items)
+	if err != nil {
+		return nil, err
+	}
+	return items, nil
+}
+
+func GetClarksonsIndexData(indexCode string, startSize, pageSize int) (items []*BaseFromClarksonsData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT *  FROM base_from_clarksons_data WHERE index_code=? ORDER BY data_time DESC LIMIT ?,? `
+	_, err = o.Raw(sql, indexCode, startSize, pageSize).QueryRows(&items)
+	return
+}

+ 424 - 0
models/data_manage/base_from_clarksons_index.go

@@ -0,0 +1,424 @@
+package data_manage
+
+import (
+	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type BaseFromClarksonsIndex struct {
+	BaseFromClarksonsIndexId 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:"排序"`
+	CreateTime           time.Time
+	ModifyTime           time.Time
+}
+
+type BaseFromClarksonsIndexView struct {
+	BaseFromClarksonsIndexId 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:"排序"`
+	LatestDate           string  `description:"最后更新时间"`
+	EdbExist             int     `description:"edb是否存在"`
+	ModifyTime           string
+}
+
+type BaseFromClarksonsIndexList struct {
+	BaseFromClarksonsIndexId int     `orm:"pk"`
+	IndexCode          string    // 指标编码
+	IndexName          string    // 指标名称
+	ClassifyId         int       // 分类Id
+	Unit               string    // 单位
+	Frequency          string    // 频度
+	Describe           string    // 指标描述
+	CreateTime         string // 创建时间
+	ModifyTime         string // 修改时间
+	DataList           []*BaseFromClarksonsData
+	Paging             *paging.PagingItem `description:"分页数据"`
+}
+func (b *BaseFromClarksonsIndex) Update(cols []string) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Update(b, cols...)
+	return
+}
+
+// GetClarksonsIndexByCondition 根据条件获取克拉克森指标列表
+func GetClarksonsIndexByCondition(condition string, pars []interface{}) (items []*BaseFromClarksonsIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC, base_from_clarksons_index_id ASC`
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+// GetClarksonsIndexByCondition 根据条件获取克拉克森指标列表
+func GetClarksonsIndexByConditionAndFrequency(condition, frequency string, pars []interface{}) (items []*BaseFromClarksonsIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` AND frequency=?`
+	sql += ` ORDER BY sort ASC, base_from_clarksons_index_id ASC`
+	_, err = o.Raw(sql, pars, frequency).QueryRows(&items)
+	return
+}
+
+func GetClarksonsIndexCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_clarksons_index WHERE 1=1 `
+
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC, base_from_clarksons_index_id ASC`
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+// GetClarksonsIndexAndEdbInfoByCondition 根据条件获取克拉克森index和指标库的信息
+func GetClarksonsIndexAndEdbInfoByCondition(condition string, pars []interface{}) (items []*BaseFromClarksonsIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT b.*, e.edb_info_id FROM base_from_clarksons_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
+}
+
+// GetClarksonsIndexByIndexCode 根据指标编码获取指标信息
+func GetClarksonsIndexByIndexCode(indexCode string) (item *BaseFromClarksonsIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE index_code=? `
+	err = o.Raw(sql, indexCode).QueryRow(&item)
+	return
+}
+
+// GetClarksonsIndexByIndexId 根据指标id获取指标信息
+func GetClarksonsIndexByIndexId(indexId int) (item *BaseFromClarksonsIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE base_from_clarksons_index_id=? `
+	err = o.Raw(sql, indexId).QueryRow(&item)
+	return
+}
+
+// GetClarksonsIndexListByIndexIds 根据指标id获取指标信息
+func GetClarksonsIndexListByIndexIds(indexIds []int) (items []*BaseFromClarksonsIndex, err error) {
+	if len(indexIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE base_from_clarksons_index_id IN (` + utils.GetOrmInReplace(len(indexIds)) + `) `
+	_, err = o.Raw(sql, indexIds).QueryRows(&items)
+	return
+}
+
+// GetClarksonsIndexCountByClassifyIds 获取分类下指标的个数
+func GetClarksonsIndexCountByClassifyIds(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_clarksons_index WHERE classify_id IN (` + utils.GetOrmInReplace(num) + `) `
+	err = o.Raw(sql, classifyIds).QueryRow(&count)
+	return
+}
+
+// GetClarksonsIndexByClassifyId 根据分类id获取克拉克森指标列表
+func GetClarksonsIndexByClassifyId(classifyIds []int, startSize, pageSize int) (items []*BaseFromClarksonsIndexView, 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_clarksons_index AS b
+	LEFT JOIN edb_info AS e ON b.index_code=e.edb_code AND e.source=101
+	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
+}
+
+// GetClarksonsIndexCountByClassifyId 根据分类id获取克拉克森指标数量
+func GetClarksonsIndexCountByClassifyId(classifyIds []int) (count int, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_clarksons_index WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) `
+	err = o.Raw(sql, classifyIds).QueryRow(&count)
+	return
+}
+
+// GetClarksonsIndexCount 获取克拉克森指标数量
+func GetClarksonsIndexCount() (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT COUNT(*) AS count FROM base_from_clarksons_index `
+	err = o.Raw(sql).QueryRow(&count)
+	return
+}
+
+func GetClarksonsIndexByPage(startSize, pageSize int) (items []*BaseFromClarksonsIndexView, 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_clarksons_index AS b
+	LEFT JOIN edb_info AS e ON b.index_code=e.edb_code AND e.source=101
+	ORDER BY b.modify_time DESC LIMIT ?,?`
+	_, err = o.Raw(sql, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+// GetClarksonsIndexBaseInfoByClassifyId 根据分类id获取克拉克森指标列表
+func GetClarksonsIndexBaseInfoByClassifyId(classifyId int) (items []*BaseFromClarksonsIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT base_from_clarksons_index_id, classify_id, index_code, index_name, CONCAT(classify_id, '_', base_from_clarksons_index_id) AS unique_code  FROM base_from_clarksons_index WHERE classify_id = ? ORDER BY sort ASC `
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+// GetClarksonsIndexBaseInfoByClassifyId 根据分类id获取克拉克森指标列表
+func GetClarksonsIndexBaseInfoByCondition(condition string, pars []interface{}) (items []*BaseFromClarksonsIndex, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT base_from_clarksons_index_id, index_code, index_name  FROM base_from_clarksons_index WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY sort ASC `
+	_, err = o.Raw(sql, pars...).QueryRows(&items)
+	return
+}
+
+func GetClarksonsDataMaxCount(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_clarksons_index AS a INNER JOIN base_from_clarksons_data AS b ON a.index_code=b.index_code WHERE 1=1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` GROUP BY a.base_from_clarksons_index_id) AS t `
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+// GetClarksonsIndexMaxSortByClassifyId 根据分类id获取指标最大排序
+func GetClarksonsIndexMaxSortByClassifyId(classifyId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT MAX(sort) FROM base_from_clarksons_index WHERE classify_id=? `
+	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	return
+}
+
+func GetClarksonsFrequency(classifyId int) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_clarksons_index WHERE classify_id=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, classifyId).QueryRows(&items)
+	return
+}
+
+func GetClarksonsFrequencyByCondition(condition string, pars []interface{}) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_clarksons_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 GetClarksonsFrequencyByCode(code string) (items []*string, err error) {
+	sql := `SELECT DISTINCT frequency FROM base_from_clarksons_index WHERE index_code=? ORDER BY FIELD(frequency,'日度','周度','月度','季度','半年','年度') `
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Raw(sql, code).QueryRows(&items)
+	return
+}
+
+// GetClarksonsClassifyMaxSortByClassifyIds 通过分类id获取对应分类的最大sort
+func GetClarksonsClassifyMaxSortByClassifyIds(classifyIds []int) (items []*BaseFromClarksonsClassifyMaxSort, err error) {
+	if len(classifyIds) == 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT bc.base_from_clarksons_classify_id, COALESCE(MAX(bi.sort), 0) AS max_sort FROM base_from_clarksons_classify  AS bc
+	LEFT JOIN base_from_clarksons_index AS bi
+	ON bc.base_from_clarksons_classify_id=bi.classify_id  
+	WHERE bc.base_from_clarksons_classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `)
+	GROUP BY bc.base_from_clarksons_classify_id
+	`
+	// sql = ` SELECT classify_id, MAX(sort) AS max_sort FROM base_from_clarksons_index WHERE classify_id IN (` + utils.GetOrmInReplace(len(classifyIds)) + `) GROUP BY classify_id `
+	_, err = o.Raw(sql, classifyIds).QueryRows(&items)
+	return
+}
+
+func BatchModifyClarksonsIndexClassify(items []*BaseFromClarksonsIndex) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `UPDATE base_from_clarksons_index SET classify_id=?, sort=? WHERE base_from_clarksons_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.BaseFromClarksonsIndexId)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// MoveDownClarksonsIndexBySort 往下移动
+func MoveDownClarksonsIndexBySort(classifyId, prevSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_clarksons_index set sort = sort - 1 where classify_id=? and sort <= ? and sort> ? `
+	_, err = o.Raw(sql, classifyId, prevSort, currentSort).Exec()
+	return
+}
+
+// MoveUpClarksonsIndexBySort 往上移动
+func MoveUpClarksonsIndexBySort(classifyId, nextSort, currentSort int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `update base_from_clarksons_index set sort = sort + 1 where classify_id=? and sort >= ? and sort< ?`
+	_, err = o.Raw(sql, classifyId, nextSort, currentSort).Exec()
+	return
+}
+
+func DeleteClarksonsIndexById(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_clarksons_index WHERE base_from_clarksons_index_id=? `
+	_, err = to.Raw(sql, indexId).Exec()
+	if err != nil {
+		return
+	}
+	sql = `DELETE FROM base_from_clarksons_data WHERE base_from_clarksons_index_id=? `
+	_, err = to.Raw(sql, indexId).Exec()
+	if err != nil {
+		return
+	}
+	return
+}
+
+func DeleteClarksonsIndexByIds(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_clarksons_index WHERE base_from_clarksons_index_id IN (` + utils.GetOrmInReplace(len(indexIds)) + `) `
+	_, err = o.Raw(sql, indexIds).Exec()
+	if err != nil {
+		return
+	}
+	sql = `DELETE FROM base_from_clarksons_data WHERE base_from_clarksons_index_id IN (` + utils.GetOrmInReplace(len(indexIds)) + `) `
+	_, err = o.Raw(sql, indexIds).Exec()
+	if err != nil {
+		return
+	}
+	return
+}
+
+// MoveClarksonsIndex 移动指标分类
+func MoveClarksonsIndex(indexId, classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` UPDATE base_from_clarksons_index
+			SET
+			  classify_id = ?, modify_time=NOW() 
+			WHERE base_from_clarksons_index_id = ?`
+	_, err = o.Raw(sql, classifyId, indexId).Exec()
+	return
+}
+
+// GetClarksonsIndexMinSortByClassifyId 获取最小不等于0的排序
+func GetClarksonsIndexMinSortByClassifyId(classifyId int) (sort int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT min(sort) FROM base_from_clarksons_index WHERE classify_id=? and sort <> 0 `
+	err = o.Raw(sql, classifyId).QueryRow(&sort)
+	return
+}
+
+// GetClarksonsIndexInfoCount 分页查询指标信息行数
+func GetClarksonsIndexInfoCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT count(1) FROM base_from_clarksons_index WHERE index_code not in (select edb_code from edb_info) `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+// GetClarksonsIndexInfoPage 分页查询指标信息
+func GetClarksonsIndexInfoPage(condition string, pars []interface{}) (items []*BaseFromRzdIndexAndData, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE index_code not in (select edb_code from edb_info) `
+	if condition != "" {
+		sql += condition
+	}
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+
+}
+
+func GetClarksonsIndex(condition string, pars interface{}) (items []*BaseFromClarksonsIndexView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM base_from_clarksons_index WHERE 1=1  `
+	if condition != "" {
+		sql += condition
+	}
+	sql += `ORDER BY base_from_clarksons_index_id ASC `
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+func GetClarksonsIndexLatestDate(indexCode string) (ModifyTime string, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT modify_time FROM base_from_clarksons_data WHERE index_code=? ORDER BY modify_time DESC limit 1 `
+	err = o.Raw(sql, indexCode).QueryRow(&ModifyTime)
+	return
+}

+ 2 - 0
models/data_manage/edb_classify.go

@@ -76,6 +76,7 @@ func GetEdbClassifyEnCount(classifyNameEn string, parentId int, classifyType uin
 type EditEdbClassifyReq struct {
 	ClassifyName string `description:"分类名称"`
 	ClassifyId   int    `description:"分类名称"`
+	ParentId     int    `description:"父级分类id"`
 }
 
 func GetEdbClassifyById(classifyId int) (item *EdbClassify, err error) {
@@ -253,6 +254,7 @@ type EdbClassifyItems struct {
 	Button           EdbClassifyItemsButton `description:"操作权限"`
 	IsJoinPermission int                    `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
 	HaveOperaAuth    bool                   `description:"是否有数据权限"`
+	SelectDisable    bool                   `description:"是否可以被选中 前端用"`
 }
 
 type EdbClassifyIdItems struct {

+ 13 - 2
models/data_manage/edb_info.go

@@ -1468,9 +1468,12 @@ func GetEdbInfoListByCondition(condition string, pars []interface{}, startSize,
 
 	sql += ` ORDER BY edb_info_id `
 	sql += orderDesc
-	sql += ` LIMIT ?,? `
+	if pageSize > 0 {
+		sql += ` LIMIT ?,? `
+		pars = append(pars, startSize, pageSize)
+	}
 
-	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
 
@@ -2134,3 +2137,11 @@ type EdbNameCheckResult struct {
 	EdbName string
 	Exist   bool
 }
+
+// UpdateEdbClassifyIdByChartInfoId
+func UpdateEdbClassifyIdByChartInfoId(chartInfoIds []int, classifyId int) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` update edb_info set classify_id = ? WHERE edb_info_id in (` + utils.GetOrmInReplace(len(chartInfoIds)) + `) `
+	_, err = o.Raw(sql, classifyId, chartInfoIds).Exec()
+	return
+}

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

@@ -0,0 +1,45 @@
+package excel
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+type ReferencedExcelConfig struct {
+	ReferencedExcelConfigId int       `orm:"column(referenced_excel_config_id);pk;auto" ` // excel表格配置id
+	UniqueCode              string    // 表格唯一编码
+	ReferencedID            int       // 被引用的id,报告就是报告id,pptId
+	FromScene               int       // 引用类型 1智能研报 2研报列表 3英文研报 4PPT
+	Uuid                    string    // 引用唯一标识
+	WidthList               string    // 宽度数组
+	HeightList              string    // 高度数组
+	OpUserID                int       // 当前编辑操作的用户id
+	OpUserName              string    // 当前编辑的用户名称(冗余字段,避免查表)
+	CreateTime              time.Time // 创建时间
+	Content                 string    // 内容
+	ModifyTime              time.Time // 修改时间
+}
+
+type ExcelReferencesReq struct {
+	UniqueCode   string `description:"表格唯一编码"`
+	ReferencedId int    `description:"被引用的ID"`
+	FromScene    int    `description:"引用类型 1智能研报 2研报列表 3英文研报 4PPT 5英文PPT"`
+	Uuid         string `description:"引用唯一标识"`
+	WidthList    string `description:"宽度数组"`
+	HeightList   string `description:"高度数组"`
+}
+
+// add
+func AddReferencedExcelConfig(items []*ReferencedExcelConfig) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.InsertMulti(len(items), items)
+	return
+}
+
+// getByCode
+func GetReferencedExcelConfigByUniqueCode(uniqueCode string) (item ReferencedExcelConfig, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM referenced_excel_config WHERE referenced_excel_unique_code = ? `
+	err = o.Raw(sql, uniqueCode).QueryRow(&item)
+	return
+}

+ 74 - 0
models/data_manage/request/clarksons_data.go

@@ -0,0 +1,74 @@
+package request
+
+type AddBaseFromClarksonsClassifyReq struct {
+	ParentId     int    `description:"上级id"`
+	ClassifyName string `description:"分类名称"`
+}
+
+// DelBaseFromClarksonsReq 删除卓创红期分类
+type DelBaseFromClarksonsClassifyReq struct {
+	BaseFromClassifyId int `description:"分类id"`
+}
+
+// EditBaseFromSciClassifyReq 编辑卓创红期分类
+type EditBaseFromClarksonsClassifyReq struct {
+	ClassifyName       string `description:"分类名称"`
+	BaseFromClassifyId int    `description:"分类id"`
+}
+
+// EditBaseFromClarksonsReq 编辑卓创红期指标所属分类
+type EditBaseFromClarksonsReq struct {
+	BaseFromClarksonsIndexId int `description:"指标id"`
+	BaseFromClassifyId       int `description:"分类id"`
+}
+
+// DelBaseFromClarksonsReq 删除卓创红期指标
+type DelBaseFromClarksonsReq struct {
+	BaseFromClarksonsIndexId int `description:"指标id"`
+}
+
+// ResetBaseFromClarksonsReq 重置指标所属分类
+type ResetBaseFromClarksonsReq struct {
+	BaseFromClarksonsIndexId int `description:"指标id"`
+}
+
+// ClarksonsDataBatchAddCheckReq 卓创红期指标批量添加校验
+type ClarksonsDataBatchAddCheckReq struct {
+	// MysteelChemicalDataListReq
+	IndexCodes []string `description:"指标编码"`
+}
+
+// ClarksonsDataBatchListReq 卓创红期指标批量列表
+type ClarksonsDataBatchListReq struct {
+	ClassifyIds  string `description:"分类id"`
+	KeyWord      string `description:"关键字"`
+	Frequencies  string `description:"频度"`
+	SelectedId   []int  `description:"已选指标id, 为true时表示反选"`
+	IsSelectAll  bool   `description:"是否查询全部, 默认false, true:全选, false:查询已选"`
+	PageSize     int    `description:"每页条数"`
+	CurrentIndex int    `description:"当前页"`
+}
+
+// MoveBaseFromClarksonsClassifyReq 移动分类请求参数
+type MoveBaseFromClarksonsClassifyReq struct {
+	BaseFromClassifyId int `description:"分类id"`
+	ParentClassifyId   int `description:"父级分类id"`
+	PrevClassifyId     int `description:"上一个兄弟节点分类id"`
+	NextClassifyId     int `description:"下一个兄弟节点分类id"`
+}
+
+// MoveBaseFromClarksonsReq 移动指标请求参数
+type MoveBaseFromClarksonsReq struct {
+	BaseFromClassifyId           int `description:"分类id"`
+	BaseFromClarksonsIndexId     int `description:"指标id"`
+	PrevBaseFromClarksonsIndexId int `description:"上一个兄弟节点id"`
+	NextBaseFromClarksonsIndexId int `description:"下一个兄弟节点id"`
+}
+
+// ExportClarksonsExcelReq导出卓创红期excel指标
+type ExportClarksonsExcelReq struct {
+	KeyWord            string   `description:"关键字, 指标编码或指标ID"`
+	IndexCode          []string `description:"指标编码,全选时,表示反选"`
+	IsSelectedAll      bool     `description:"是否全选:true:全选|false: 无"`
+	BaseFromClassifyId int      `description:"指标id"`
+}

+ 12 - 0
models/data_manage/request/edb_info.go

@@ -6,3 +6,15 @@ type ModifyEdbInfoReq struct {
 	MaxValue  float64 `description:"最大值"`
 	MinValue  float64 `description:"最小值"`
 }
+
+// ModifyEdbListReq 批量编辑指标请求参数
+type ModifyEdbListReq struct {
+	SelectAll        bool
+	SubClassify      bool `description:"是否关联指标子分类"`
+	EdbClassifyIds string
+	SysUserIds       string
+	KeyWord          string
+	EdbInfoIds       string `description:"图表ID"`
+	ClassifyId       int    `description:"新图表分类"`
+	Sources          string
+}

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

@@ -0,0 +1,35 @@
+package response
+
+import (
+	"eta/eta_api/models/data_manage"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type ClarksonsIndexPageListResp struct {
+	List   []*data_manage.BaseFromClarksonsIndexView
+	Paging *paging.PagingItem
+}
+
+type EditClarksonsIndexInfoResp struct {
+	BaseFromClarksonsIndexId int
+	IndexCode            string
+}
+
+type ClarksonsSingleDataResp struct {
+	BaseFromClarksonsIndexId 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.BaseFromClarksonsData
+}

+ 3 - 0
models/db.go

@@ -378,6 +378,9 @@ func initEdbData() {
 		new(data_manage.BaseFromSciHqClassify),
 		new(data_manage.BaseFromSciHqIndex),
 		new(data_manage.BaseFromSciHqData),
+		new(data_manage.BaseFromClarksonsClassify),
+		new(data_manage.BaseFromClarksonsIndex),
+		new(data_manage.BaseFromClarksonsData),
 	)
 }
 

+ 198 - 0
routers/commentsRouter.go

@@ -3949,6 +3949,186 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "Classify",
+            Router: `/clarksons/classify`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "AddClassify",
+            Router: `/clarksons/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "DelClassify",
+            Router: `/clarksons/classify/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "EditClassify",
+            Router: `/clarksons/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "MoveClassify",
+            Router: `/clarksons/classify/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "DeleteClarksonsData",
+            Router: `/clarksons/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "AddCheck",
+            Router: `/clarksons/edb_info/add_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "BatchAdd",
+            Router: `/clarksons/edb_info/batch_add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "BatchDelete",
+            Router: `/clarksons/edb_info/batch_delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "BatchEdit",
+            Router: `/clarksons/edb_info/batch_edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "NameCheck",
+            Router: `/clarksons/edb_info/name_check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "EditClarksons",
+            Router: `/clarksons/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "GetClarksonsIndexInfo",
+            Router: `/clarksons/get/index/info`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "ClarksonsData",
+            Router: `/clarksons/index/data`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "IndexList",
+            Router: `/clarksons/index/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "IndexPageList",
+            Router: `/clarksons/index/page/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "MoveClarksonsData",
+            Router: `/clarksons/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "SearchList",
+            Router: `/clarksons/search_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "SingleData",
+            Router: `/clarksons/single_data`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:ClarksonsDataController"],
+        beego.ControllerComments{
+            Method: "ExportClarksonsList",
+            Router: `/export/clarksonsList`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbBusinessController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbBusinessController"],
         beego.ControllerComments{
             Method: "AddCheck",
@@ -4480,6 +4660,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "ClassifyEdbInfoList",
+            Router: `/classify/edb/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "ComTradeCountryList",
@@ -5272,6 +5461,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
+        beego.ControllerComments{
+            Method: "ModifyEdbList",
+            Router: `/modify/edbList`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage:EdbInfoController"],
         beego.ControllerComments{
             Method: "BatchAdd",

+ 1 - 0
routers/router.go

@@ -185,6 +185,7 @@ func init() {
 				&data_manage.BaseFromLyIndexController{},
 				&data_manage.BaseFromUsdaFasController{},
 				&data_manage.BaseFromRzdIndexController{},
+				&data_manage.ClarksonsDataController{},
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 4 - 0
services/data/base_edb_lib.go

@@ -80,6 +80,8 @@ func AddEdbData(source int, edbCode, frequency string) (resp *models.BaseRespons
 		urlStr = "ly/add"
 	case utils.DATA_SOURCE_RZD:
 		urlStr = "rzd/add"
+	case utils.DATA_SOURCE_CLARKSONS:
+		urlStr = "clarksons/add"
 	default:
 		edbSource := data_manage.EdbSourceIdMap[source]
 		if edbSource != nil {
@@ -282,6 +284,8 @@ func RefreshEdbData(edbInfoId, source, subSource int, edbCode, startDate string)
 		urlStr = "ly/refresh"
 	case utils.DATA_SOURCE_TRADE_ANALYSIS:
 		urlStr = "trade_analysis/edb/refresh"
+	case utils.DATA_SOURCE_CLARKSONS:
+		urlStr = "clarksons/refresh"
 	default:
 		edbSource := data_manage.EdbSourceIdMap[source]
 		if edbSource != nil {

+ 822 - 0
services/data/base_from_clarksons.go

@@ -0,0 +1,822 @@
+package data
+
+import (
+	"errors"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+func AddClarksonsClassify(classifyName string, parentId int) (ok bool, msg string, err error) {
+	var count int
+	count, err = data_manage.GetBaseFromClarksonsClassifyCount(classifyName, parentId)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		return false, "分类已存在", nil
+	}
+
+	sort, err := data_manage.GetChildClarksonsClassifyMaxSortById(parentId)
+	if err != nil {
+		return false, "", err
+	}
+	if parentId > 0 {
+		count, err = data_manage.GetClarksonsClassifyCountById(parentId)
+		if err != nil {
+			return false, "", err
+		}
+		if count == 0 {
+			return false, "", errors.New("父分类不存在")
+		}
+		clarksonsClassify := &data_manage.BaseFromClarksonsClassify{
+			ClassifyName: classifyName,
+			ParentId:     parentId,
+			Level:        2,
+			Sort:         sort + 1,
+			ModifyTime:   time.Now(),
+			CreateTime:   time.Now(),
+		}
+		_, err = clarksonsClassify.Add()
+		if err != nil {
+			return
+		}
+	} else {
+		clarksonsClassify := &data_manage.BaseFromClarksonsClassify{
+			ClassifyName: classifyName,
+			ParentId:     0,
+			Level:        1,
+			Sort:         sort + 1,
+			ModifyTime:   time.Now(),
+			CreateTime:   time.Now(),
+		}
+		_, er := clarksonsClassify.Add()
+		if er != nil {
+			return false, "", er
+		}
+	}
+	return true, "", nil
+}
+
+func DelClarksonsClassify(classifyId int) (err error) {
+	classify, err := data_manage.GetClarksonsClassifyById(classifyId)
+	if err != nil {
+		return
+	}
+	var classifyIds []int
+	classifyIds = append(classifyIds, classify.BaseFromClassifyId)
+	if classify.ParentId == 0 {
+		tmpClassifyIds, er := data_manage.GetChildClarksonsClassifyIdsById(classify.BaseFromClassifyId)
+		if er != nil {
+			err = er
+			return
+		}
+		classifyIds = append(classifyIds, tmpClassifyIds...)
+	}
+	// 获取分类下的所有指标
+	count, err := data_manage.GetClarksonsIndexCountByClassifyIds(classifyIds)
+	if err != nil {
+		err = errors.New("获取分类下的指标信息失败,Err:" + err.Error())
+		return
+	}
+	if count > 0 {
+		err = errors.New("该分类下有指标,不可删除")
+		return
+	}
+	// 删除对应的分类
+	err = data_manage.DeleteClarksonsClassifyByClassifyId(classifyIds)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// ResetClarksonsIndex 指标数据清除分类接口
+func ResetClarksonsIndex(indexId int) (err error) {
+	clarksonsIndex, err := data_manage.GetClarksonsIndexByIndexId(indexId)
+	if err != nil {
+		return
+	}
+
+	// 更新指标在未分类下的排序,永远排在未分类的最后一个
+	//移动排序
+	classifyId := 0
+	updateCol := make([]string, 0)
+	var currentSort, prevSort int
+	currentSort = clarksonsIndex.Sort
+	//未分类的最大的sort值
+	prevSort, err = data_manage.GetClarksonsIndexMaxSortByClassifyId(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
+		}
+		clarksonsIndex.Sort = prevSort
+	}
+
+	//更新
+	clarksonsIndex.ModifyTime = time.Now()
+	clarksonsIndex.ClassifyId = classifyId
+	updateCol = append(updateCol, "Sort", "ModifyTime", "BaseFromClassifyId")
+	err = clarksonsIndex.Update(updateCol)
+	if err != nil {
+		err = errors.New("移动失败,Err:" + err.Error())
+		return
+	}
+	return
+}
+
+// 批量删除克拉克森指标
+func BatchDelClarksonsData(indexIds []int) (existIndex []*data_manage.BaseFromClarksonsIndex, err error) {
+	clarksonsIndexList, err := data_manage.GetClarksonsIndexListByIndexIds(indexIds)
+	if err != nil {
+		return
+	}
+
+	indexCodes := make([]string, 0)
+	codeToIndex := make(map[string]*data_manage.BaseFromClarksonsIndex)
+	for _, v := range clarksonsIndexList {
+		indexCodes = append(indexCodes, v.IndexCode)
+		codeToIndex[v.IndexCode] = v
+	}
+
+	edbInfoList, err := data_manage.GetEdbInfoListByEdbCodes(utils.DATA_SOURCE_CLARKSONS, 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.BaseFromClarksonsIndexId)
+	}
+
+	// 删除对应的指标
+	err = data_manage.DeleteClarksonsIndexByIds(deleteIndexIds)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// DelClarksonsData 删除克拉克森指标
+func DelClarksonsData(indexId int) (err error, errMsg string) {
+	baseFromClarksonsIndex, err := data_manage.GetClarksonsIndexByIndexId(indexId)
+	if err != nil {
+		errMsg = `获取数据失败`
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该指标未入库`
+			err = nil
+		}
+		return
+	}
+
+	// 获取已经加入到EDB指标库的clarksons指标
+	edbInfo, err := data_manage.GetEdbInfoByEdbCode(utils.DATA_SOURCE_CLARKSONS, baseFromClarksonsIndex.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.DeleteClarksonsIndexById(indexId)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// EditClarksonsIndex 编辑克拉克森指标
+func EditClarksonsIndex(indexId, classifyId int) (baseFromClarksonsIndex *data_manage.BaseFromClarksonsIndex, errMsg string, err error) {
+	baseFromClarksonsIndex, err = data_manage.GetClarksonsIndexByIndexId(indexId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该指标未入库`
+			err = nil
+		}
+		return
+	}
+	if classifyId > 0 {
+		classify, e := data_manage.GetClarksonsClassifyById(classifyId)
+		if e != nil {
+			err = e
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = `该分类不存在或已删除`
+				err = nil
+			}
+			return
+		}
+		if classify.Level == 1 { // 顶级分类
+			errMsg = `不合法的编辑`
+			err = nil
+			return
+		}
+	}
+
+	maxSort, err := data_manage.GetChildClarksonsClassifyMaxSortById(classifyId)
+	if err != nil {
+		return
+	}
+
+	baseFromClarksonsIndex.ClassifyId = classifyId
+	baseFromClarksonsIndex.Sort = maxSort + 1
+	baseFromClarksonsIndex.ModifyTime = time.Now()
+	err = baseFromClarksonsIndex.Update([]string{"classify_id", "sort", "modify_time"})
+	return
+}
+
+type ClarksonsIndexSource2EdbReq struct {
+	EdbCode       string
+	EdbName       string
+	Frequency     string
+	Unit          string
+	ClassifyId    int
+	AdminId       int
+	AdminRealName string
+}
+
+// ClarksonsIndexSource2Edb 新增克拉克森数据从数据源到指标库
+func ClarksonsIndexSource2Edb(req ClarksonsIndexSource2EdbReq, 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("ClarksonsIndexSource2Edb新增失败, Err: %s", err.Error())
+			fmt.Println(tips)
+			utils.FileLog.Info(tips)
+		}
+	}()
+	source := utils.DATA_SOURCE_CLARKSONS
+
+	// 是否新增过指标
+	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
+}
+
+// MoveClarksonsClassify 移动克拉克森分类
+func MoveClarksonsClassify(classifyId, parentClassifyId, prevClassifyId, nextClassifyId int) (err error, errMsg string) {
+	//判断分类是否存在
+	classifyInfo, err := data_manage.GetClarksonsClassifyById(classifyId)
+	if err != nil {
+		errMsg = "移动失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+
+	updateCol := make([]string, 0)
+
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if classifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		// 校验移动的父级目录下是否有重名分类
+		count, e := data_manage.GetBaseFromClarksonsClassifyCount(classifyInfo.ClassifyName, parentClassifyId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			errMsg = "移动失败"
+			err = errors.New("获取父级目录下的同名分类失败, Err: " + e.Error())
+			return
+		}
+		if count > 0 {
+			errMsg = "移动失败,分类名称已存在"
+			err = errors.New("该父级目录下已存在同名分类,请重新命名")
+			return
+		}
+
+		parentClassifyInfo, tmpErr := data_manage.GetClarksonsClassifyById(parentClassifyId)
+		if tmpErr != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上级分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+		classifyInfo.ParentId = parentClassifyInfo.BaseFromClassifyId
+		classifyInfo.Level = parentClassifyInfo.Level + 1
+		updateCol = append(updateCol, "ParentId", "Level")
+	}
+	var currentSort, prevSort, nextSort int
+	currentSort = classifyInfo.Sort
+
+	var prevClassify *data_manage.BaseFromClarksonsClassify
+	var nextClassify *data_manage.BaseFromClarksonsClassify
+	//如果有传入 上一个兄弟节点分类id
+	if prevClassifyId > 0 {
+		prevClassify, err = data_manage.GetClarksonsClassifyById(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.GetClarksonsClassifyById(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.GetClarksonsIndexClassifyMinSort(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.MoveDownClarksonsIndexClassifyBySort(parentClassifyId, prevSort, currentSort)
+		if err != nil {
+			err = errors.New("向下移动出错:" + err.Error())
+			return
+		}
+		classifyInfo.Sort = prevSort
+	} else if nextSort <= currentSort && nextSort != 0 {
+		//往上移动
+		err = data_manage.MoveUpClarksonsIndexClassifyBySort(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
+}
+
+// MoveClarksonsData 移动克拉克森指标
+func MoveClarksonsData(indexId, classifyId, prevIndexId, nextIndexId int) (err error, errMsg string) {
+	//分类信息
+	clarksonsIndex, err := data_manage.GetClarksonsIndexByIndexId(indexId)
+	if err != nil {
+		errMsg = `获取数据失败`
+		if err.Error() == utils.ErrNoRow() {
+			errMsg = `该指标未入库`
+			err = nil
+		}
+		return
+	}
+
+	//判断分类是否存在
+	if classifyId > 0 {
+		_, err = data_manage.GetClarksonsClassifyById(classifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取分类信息失败,Err:" + err.Error())
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "找不到该分类"
+				err = nil
+			}
+			return
+		}
+	}
+
+	//如果改变了分类,那么移动该图表数据
+	if clarksonsIndex.ClassifyId != classifyId {
+		tmpErr := data_manage.MoveClarksonsIndex(indexId, classifyId)
+		if tmpErr != nil {
+			errMsg = "移动失败"
+			err = errors.New("移动失败,Err:" + tmpErr.Error())
+			return
+		}
+	}
+
+	//移动排序
+	updateCol := make([]string, 0)
+	var currentSort, prevSort, nextSort int
+	currentSort = clarksonsIndex.Sort
+	//如果有传入 上一个兄弟节点分类id
+	var prevIndex *data_manage.BaseFromClarksonsIndex
+	var nextIndex *data_manage.BaseFromClarksonsIndex
+	if prevIndexId > 0 {
+		prevIndex, err = data_manage.GetClarksonsIndexByIndexId(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.GetClarksonsIndexByIndexId(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.GetClarksonsIndexMinSortByClassifyId(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.MoveDownClarksonsIndexBySort(classifyId, prevSort, currentSort)
+		if err != nil {
+			err = errors.New("向下移动出错:" + err.Error())
+			return
+		}
+		clarksonsIndex.Sort = prevSort
+	} else if nextSort <= currentSort && nextSort != 0 {
+		//往上移动
+		err = data_manage.MoveUpClarksonsIndexBySort(classifyId, nextSort, currentSort)
+		if err != nil {
+			err = errors.New("向上移动出错:" + err.Error())
+			return
+		}
+		clarksonsIndex.Sort = nextSort
+	}
+
+	//更新
+	clarksonsIndex.ModifyTime = time.Now()
+	updateCol = append(updateCol, "Sort", "ModifyTime")
+	err = clarksonsIndex.Update(updateCol)
+	if err != nil {
+		errMsg = "移动失败"
+		err = errors.New("修改失败,Err:" + err.Error())
+		return
+	}
+	return
+}
+
+// GetClarksonsIndexInfo 获取指标信息-分页
+func GetClarksonsIndexInfo(keyWord string, classifyIdList []string, frequencyList []string, currentIndex, startSize, pageSize int) (rzdIndexInfoList *data_manage.BaseFromRzdIndexPage, err error) {
+
+	// 获取指标
+	var condition string
+	var pars []interface{}
+	if keyWord != "" {
+		condition += ` AND (index_name like ? or index_code like ?)`
+		pars = append(pars, "%"+keyWord+"%", "%"+keyWord+"%")
+	}
+	if len(classifyIdList) > 0 {
+		condition += ` AND classify_id IN (`
+		for _, v := range classifyIdList {
+			condition += `?,`
+			pars = append(pars, v)
+		}
+		condition = condition[:len(condition)-1] + `)`
+	}
+	if len(frequencyList) > 0 {
+		condition += ` AND frequency IN (`
+		for _, v := range frequencyList {
+			condition += `?,`
+			pars = append(pars, v)
+		}
+		condition = condition[:len(condition)-1] + `)`
+	}
+
+	count, err := data_manage.GetClarksonsIndexInfoCount(condition, pars)
+	if err != nil {
+		return nil, err
+	}
+	indexPage := data_manage.BaseFromRzdIndexPage{}
+	page := paging.GetPaging(currentIndex, pageSize, count)
+	if count <= 0 {
+		indexPage.Paging = page
+		return &indexPage, nil
+	}
+
+	condition += ` ORDER BY base_from_clarksons_index_id asc`
+
+	// 分页
+	condition += ` LIMIT ?, ?`
+	pars = append(pars, startSize, pageSize)
+
+	indexInfoPage, err := data_manage.GetClarksonsIndexInfoPage(condition, pars)
+	if err != nil {
+		return nil, err
+	}
+	var indexCodes []string
+	for _, indexInfo := range indexInfoPage {
+		indexCodes = append(indexCodes, indexInfo.IndexCode)
+	}
+	IndexDataList, err := data_manage.GetClarksonsLastUpdateTimeLastByIndexCode(indexCodes)
+	if err != nil {
+		return nil, err
+	}
+	var indexDataMap = make(map[string]*data_manage.BaseFromClarksonsData, 0)
+	for _, data := range IndexDataList {
+		indexDataMap[data.IndexCode] = data
+	}
+	for _, indexInfo := range indexInfoPage {
+		if indexDataMap[indexInfo.IndexCode] == nil {
+			continue
+		}
+		indexInfo.ModifyTimeMax = indexDataMap[indexInfo.IndexCode].DataTime
+		indexInfo.Value = indexDataMap[indexInfo.IndexCode].Value
+	}
+
+	indexPage.List = indexInfoPage
+	indexPage.Paging = page
+	return &indexPage, nil
+}
+
+// GetClarkssonsIndexList 获取指标列表
+func GetClarkssonsIndexList(searchParams string) (rzdIndexInfoList []*data_manage.BaseFromRzdIndexList, err error) {
+
+	// 获取指标
+	var condition string
+	var pars []interface{}
+	if searchParams != "" {
+		condition += ` and index_code like ? or index_name like ?`
+		pars = append(pars, "%"+searchParams+"%", "%"+searchParams+"%")
+	}
+	rzdIndexList, err := data_manage.GetRzdIndex(condition, pars)
+	if err != nil {
+		return nil, err
+	}
+
+	return rzdIndexList, nil
+}
+
+// MoveClarksonsClassify 移动克拉克森分类
+func MoveClarksonsClassifyV2(classifyId, parentClassifyId, prevClassifyId, nextClassifyId int) (err error, errMsg string) {
+	//判断分类是否存在
+	classifyInfo, err := data_manage.GetClarksonsClassifyById(classifyId)
+	if err != nil {
+		errMsg = "移动失败"
+		err = errors.New("获取分类信息失败,Err:" + err.Error())
+		return
+	}
+
+	updateCol := make([]string, 0)
+
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if classifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		// 校验移动的父级目录下是否有重名分类
+		count, e := data_manage.GetBaseFromClarksonsClassifyCount(classifyInfo.ClassifyName, parentClassifyId)
+		if e != nil && e.Error() != utils.ErrNoRow() {
+			errMsg = "移动失败"
+			err = errors.New("获取父级目录下的同名分类失败, Err: " + e.Error())
+			return
+		}
+		if count > 0 {
+			errMsg = "移动失败,分类名称已存在"
+			err = errors.New("该父级目录下已存在同名分类,请重新命名")
+			return
+		}
+
+		parentClassifyInfo, tmpErr := data_manage.GetClarksonsClassifyById(parentClassifyId)
+		if tmpErr != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上级分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+		classifyInfo.ParentId = parentClassifyInfo.BaseFromClassifyId
+		classifyInfo.Level = parentClassifyInfo.Level + 1
+		updateCol = append(updateCol, "ParentId", "Level")
+	}
+	//var currentSort, prevSort, nextSort int
+	//currentSort = classifyInfo.Sort
+
+	var prevClassify *data_manage.BaseFromClarksonsClassify
+	var nextClassify *data_manage.BaseFromClarksonsClassify
+	//如果有传入 上一个兄弟节点分类id
+	if prevClassifyId > 0 {
+		prevClassify, err = data_manage.GetClarksonsClassifyById(prevClassifyId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = "移动失败"
+				err = errors.New("上一个兄弟节点分类信息不存在" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		//如果是移动在两个兄弟节点之间
+		if nextClassifyId > 0 {
+			//下一个兄弟节点
+			nextClassify, err = data_manage.GetClarksonsClassifyById(nextClassifyId)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
+				return
+			}
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevClassify.Sort == nextClassify.Sort || prevClassify.Sort == classifyInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+				_ = data_manage.UpdateClarksonsClassifySortByParentId(prevClassify.ParentId, prevClassify.BaseFromClassifyId, prevClassify.Sort, updateSortStr)
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextClassify.Sort-prevClassify.Sort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+					_ = data_manage.UpdateClarksonsClassifySortByParentId(prevClassify.ParentId, 0, prevClassify.Sort, updateSortStr)
+				}
+			}
+		}
+
+		classifyInfo.Sort = prevClassify.Sort + 1
+		classifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		firstClassify, err := data_manage.GetFirstClarksonsClassifyByParentId(classifyInfo.ParentId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + err.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateClarksonsClassifySortByParentId(firstClassify.ParentId, firstClassify.ChartClassifyId-1, 0, updateSortStr)
+		}
+
+		classifyInfo.Sort = 0 //那就是排在第一位
+		classifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	//if nextClassifyId > 0 {
+	//	//下一个兄弟节点
+	//	nextClassify, err = data_manage.GetClarksonsClassifyById(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.GetClarksonsIndexClassifyMinSort(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.MoveDownClarksonsIndexClassifyBySort(parentClassifyId, prevSort, currentSort)
+	//	if err != nil {
+	//		err = errors.New("向下移动出错:" + err.Error())
+	//		return
+	//	}
+	//	classifyInfo.Sort = prevSort
+	//} else if nextSort <= currentSort && nextSort != 0 {
+	//	//往上移动
+	//	err = data_manage.MoveUpClarksonsIndexClassifyBySort(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
+	//}
+	//更新
+	if len(updateCol) > 0 {
+		err = classifyInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+	}
+	return
+}

+ 7 - 6
services/data/chart_classify.go

@@ -979,7 +979,7 @@ func GetChartClassifyParentRecursive(list []*data_manage.ChartClassifyItems, cla
 }
 
 // 修改图表分类,可以修改父级
-func EditChartClassifyV2(chartClassifyId, praentId, source int, chartClassifyName, lang string) (classifyInfo *data_manage.ChartClassify, err error, errMsg string, isSendEmail bool) {
+func EditChartClassifyV2(chartClassifyId, parentId, source int, chartClassifyName, lang string) (classifyInfo *data_manage.ChartClassify, err error, errMsg string, isSendEmail bool) {
 	isSendEmail = true
 	errMsg = "保存失败"
 
@@ -989,14 +989,15 @@ func EditChartClassifyV2(chartClassifyId, praentId, source int, chartClassifyNam
 		return
 	}
 
-	if praentId != classifyInfo.ParentId {
-		parentClassifyInfo, e := data_manage.GetChartClassifyById(praentId)
+	if parentId != classifyInfo.ParentId {
+		parentClassifyInfo, e := data_manage.GetChartClassifyById(parentId)
 		if e != nil {
 			err = e
 			return
 		}
-		if classifyInfo.Level != parentClassifyInfo.Level-1 {
+		if classifyInfo.Level != parentClassifyInfo.Level+1 {
 			err = errors.New("父级分类层级异常")
+			return
 		}
 	}
 
@@ -1011,8 +1012,8 @@ func EditChartClassifyV2(chartClassifyId, praentId, source int, chartClassifyNam
 	// 需要变更的字段
 	updateCols := make([]string, 0)
 
-	if praentId != classifyInfo.ParentId {
-		classifyInfo.ParentId = praentId
+	if parentId != classifyInfo.ParentId {
+		classifyInfo.ParentId = parentId
 		classifyInfo.ModifyTime = time.Now()
 		updateCols = append(updateCols, "ParentId")
 	}

+ 70 - 11
services/data/edb_classify.go

@@ -53,11 +53,15 @@ func edbClassifyHaveChild(allNode []*data_manage.EdbClassifyItems, node *data_ma
 }
 
 // GetClassifyTreeRecursive 递归获取分类树形结构
-func GetClassifyTreeRecursive(list []*data_manage.EdbClassifyItems, parentId int) []*data_manage.EdbClassifyItems {
+func GetClassifyTreeRecursive(list []*data_manage.EdbClassifyItems, parentId, level int) []*data_manage.EdbClassifyItems {
 	res := make([]*data_manage.EdbClassifyItems, 0)
 	for _, v := range list {
+		v.SelectDisable = true
+		if v.Level == level {
+			v.SelectDisable = false
+		}
 		if v.ParentId == parentId {
-			v.Children = GetClassifyTreeRecursive(list, v.ClassifyId)
+			v.Children = GetClassifyTreeRecursive(list, v.ClassifyId, level)
 			res = append(res, v)
 		}
 	}
@@ -395,7 +399,7 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 }
 
 // EditEdbClassify 编辑指标分类
-func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.Admin) (err error, errMsg string) {
+func EditEdbClassify(classifyId, parentId int, classifyName, lang string, sysUser *system.Admin) (err error, errMsg string) {
 	item, err := data_manage.GetEdbClassifyById(classifyId)
 	if err != nil {
 		errMsg = `保存失败`
@@ -432,15 +436,33 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 
 	}
 
+	if parentId != item.ParentId {
+		parentClassifyInfo, e := data_manage.GetEdbClassifyById(parentId)
+		if e != nil {
+			err = e
+			return
+		}
+		if item.Level != parentClassifyInfo.Level+1 {
+			err = errors.New("父级分类层级异常")
+			return
+		}
+	}
+
 	// 需要变更的字段
 	updateCols := make([]string, 0)
 
+	if parentId != item.ParentId {
+		item.ParentId = parentId
+		item.ModifyTime = time.Now()
+		updateCols = append(updateCols, "ParentId", "ModifyTime")
+	}
+
 	switch lang {
 	case utils.EnLangVersion:
-		// 名字相同,那么就直接返回
-		if item.ClassifyNameEn == classifyName {
-			return
-		}
+		//// 名字相同,那么就直接返回
+		//if item.ClassifyNameEn == classifyName {
+		//	return
+		//}
 
 		// 判断名称是否已存在
 		count, tmpErr := data_manage.GetEdbClassifyEnCount(classifyName, item.ParentId, item.ClassifyType)
@@ -460,10 +482,10 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 		item.LastModifyUserRealName = sysUser.RealName
 		updateCols = append(updateCols, "ClassifyNameEn", "LastModifyUserId", "LastModifyUserRealName")
 	default:
-		// 名字相同,那么就直接返回
-		if item.ClassifyName == classifyName {
-			return
-		}
+		//// 名字相同,那么就直接返回
+		//if item.ClassifyName == classifyName {
+		//	return
+		//}
 
 		// 判断名称是否已存在
 		count, tmpErr := data_manage.GetEdbClassifyCount(classifyName, item.ParentId, item.ClassifyType)
@@ -1624,3 +1646,40 @@ func GetEdbClassifyByIsMe(adminId, parentId, edbInfoType int, classifyList []*da
 	}
 	return
 }
+
+// GetEdbClassifyChildrenRecursive 根据父目录递归子级目录
+func GetEdbClassifyChildrenRecursive(list []*data_manage.EdbClassifyItems, parentId int) []*data_manage.EdbClassifyItems {
+	var res []*data_manage.EdbClassifyItems
+
+	for _, v := range list {
+		if v.ParentId == parentId {
+			// 递归调用以获取更深层次的子级
+			children := GetEdbClassifyChildrenRecursive(list, v.ClassifyId)
+			// 将当前节点和所有子节点添加到结果中
+			res = append(res, v)
+			res = append(res, children...)
+		} else if v.ClassifyId == parentId {
+			// 将当前节点添加到结果中
+			res = append(res, v)
+		}
+	}
+	return res
+}
+
+// GetEdbClassifyChildrenRecursiveByParentIds 根据父目录递归子级目录
+func GetEdbClassifyChildrenRecursiveByParentIds(list []*data_manage.EdbClassifyItems, parentIds []string) []*data_manage.EdbClassifyItems {
+	var res []*data_manage.EdbClassifyItems
+	for _, v := range list {
+		for _, id := range parentIds {
+			parentId, _ := strconv.Atoi(id)
+			if v.ParentId == parentId || v.ClassifyId == parentId {
+				// 递归调用以获取更深层次的子级
+				children := GetEdbClassifyChildrenRecursive(list, v.ClassifyId)
+				// 将当前节点和所有子节点添加到结果中
+				res = append(res, v)
+				res = append(res, children...)
+			}
+		}
+	}
+	return res
+}

+ 4 - 1
static/ErrMsgConfig.json

@@ -59,5 +59,8 @@
   "指标已删除,请刷新页面": "Metric deleted, please refresh the page.",
   "删除失败": "Deletion failed.",
   "指标数据异常,请检查": "The metric data is abnormal, please check.",
-  "原指标与替换指标存在引用关系,不允许替换": "Original indicators and replacement indicators have a referencing relationship, which is not allowed to be replaced."
+  "原指标与替换指标存在引用关系,不允许替换": "Original indicators and replacement indicators have a referencing relationship, which is not allowed to be replaced.",
+  "指标名称已存在,请重新填写": "The metric name already exists, please re-enter.",
+  "请选择分类": "Please Select a Category",
+  "分类已存在": "The category already exists."
 }

+ 1 - 0
utils/constants.go

@@ -190,6 +190,7 @@ const (
 	DATA_SOURCE_RZD                                  = 97       // 睿姿得数据
 	DATA_SOURCE_MAPPING_RESIDUAL                     = 99       // 映射残差
 	DATA_SOURCE_FIT_RESIDUAL                         = 100      // 拟合残差
+	DATA_SOURCE_CLARKSONS                            = 101      // 克拉克森数据
 )
 
 // 数据刷新频率