Browse Source

Merge branch 'eta/1.3.1' into debug

# Conflicts:
#	routers/router.go
Roc 1 year ago
parent
commit
dd8950fa58

+ 9 - 56
controllers/data_manage/chart_classify.go

@@ -95,7 +95,7 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 			return
 		}
 		// 移除没有权限的图表
-		allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+		allNodes := data.HandleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
 		resp.AllNodes = allNodes
 
 		br.Ret = 200
@@ -110,11 +110,11 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 	key := utils.CACHE_CHART_CLASSIFY
 	if utils.Re == nil {
 		if utils.Re == nil && utils.Rc.IsExist(key) {
-			if data, err1 := utils.Rc.RedisBytes(key); err1 == nil {
-				err := json.Unmarshal(data, &resp)
+			if redisData, err1 := utils.Rc.RedisBytes(key); err1 == nil {
+				err := json.Unmarshal(redisData, &resp)
 				if err == nil && resp != nil {
 					// 移除没有权限的图表
-					allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+					allNodes := data.HandleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
 					resp.AllNodes = allNodes
 
 					br.Ret = 200
@@ -185,12 +185,12 @@ func (this *ChartClassifyController) ChartClassifyListV2() {
 
 	// 将数据加入缓存
 	if utils.Re == nil {
-		data, _ := json.Marshal(resp)
-		utils.Rc.Put(key, data, 2*time.Hour)
+		redisData, _ := json.Marshal(resp)
+		utils.Rc.Put(key, redisData, 2*time.Hour)
 	}
 
 	// 移除没有权限的图表
-	allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+	allNodes := data.HandleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
 	resp.AllNodes = allNodes
 
 	br.Ret = 200
@@ -248,53 +248,6 @@ func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartCl
 	return
 }
 
-// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
-func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
-	// 移除没有权限的图表
-	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
-	for _, node := range allNodes {
-		// 二级分类
-		tmpNodeInfo := *node
-		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
-		if node.Children != nil {
-			for _, chartList := range node.Children {
-				tmpInfo := *chartList
-				tmpList := make([]*data_manage.ChartClassifyItems, 0)
-
-				if chartList.Children != nil {
-					for _, chartInfo := range chartList.Children {
-						thirdInfo := *chartInfo
-						thirdList := make([]*data_manage.ChartClassifyItems, 0)
-						// 如果指标不可见,那么就不返回该指标
-						if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
-							continue
-						}
-						tmpList = append(tmpList, chartInfo)
-
-						if chartInfo.Children != nil {
-							for _, thirdChart := range chartInfo.Children {
-								// 如果指标不可见,那么就不返回该指标
-								if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
-									continue
-								}
-								thirdList = append(thirdList, thirdChart)
-							}
-						}
-						thirdInfo.Children = thirdList
-						tmpList = append(tmpList, &thirdInfo)
-					}
-				}
-				tmpInfo.Children = tmpList
-				tmpNodeList = append(tmpNodeList, &tmpInfo)
-			}
-		}
-		tmpNodeInfo.Children = tmpNodeList
-		newAllNodes = append(newAllNodes, &tmpNodeInfo)
-	}
-
-	return
-}
-
 // ChartClassifyItems
 // @Title 获取所有图表分类接口-不包含图表
 // @Description 获取所有图表分类接口-不包含图表
@@ -1015,7 +968,7 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 			return
 		}
 		// 移除没有权限的图表
-		allNodes := handleNoPermissionChart(allChartInfo, noPermissionChartIdMap)
+		allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap)
 		resp.AllNodes = allNodes
 
 		br.Ret = 200
@@ -1033,7 +986,7 @@ func (this *ChartClassifyController) ChartClassifyChartListV2() {
 		return
 	}
 	// 移除没有权限的图表
-	allNodes := handleNoPermissionChart(allChartInfo, noPermissionChartIdMap)
+	allNodes := data.HandleNoPermissionChart(allChartInfo, noPermissionChartIdMap)
 
 	for k, item := range allNodes {
 		item.Button = data.GetChartOpButton(this.SysUser, item.SysUserId)

+ 1 - 27
controllers/data_manage/correlation/correlation_chart_classify.go

@@ -104,7 +104,7 @@ func (this *CorrelationChartClassifyController) ChartClassifyList() {
 	}
 
 	// 移除没有权限的图表
-	allNodes := handleNoPermissionChart(rootList, noPermissionChartIdMap)
+	allNodes := data.HandleNoPermissionChart(rootList, noPermissionChartIdMap)
 	resp.AllNodes = allNodes
 
 	br.Ret = 200
@@ -162,32 +162,6 @@ func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartCl
 	return
 }
 
-// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
-func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
-	// 移除没有权限的图表
-	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
-	for _, node := range allNodes {
-		// 二级分类
-		tmpNodeInfo := *node
-		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
-
-		if node.Children != nil {
-			for _, chartInfo := range node.Children {
-				// 如果指标不可见,那么就不返回该指标
-				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
-					continue
-				}
-				tmpNodeList = append(tmpNodeList, chartInfo)
-			}
-		}
-
-		tmpNodeInfo.Children = tmpNodeList
-		newAllNodes = append(newAllNodes, &tmpNodeInfo)
-	}
-
-	return
-}
-
 // ChartClassifyItems
 // @Title 获取所有相关性图表分类接口-不包含图表
 // @Description 获取所有相关性图表分类接口-不包含图表

+ 193 - 0
controllers/data_manage/cross_variety/chart_info.go

@@ -0,0 +1,193 @@
+package cross_variety
+
+import (
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/services/data"
+	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+)
+
+// ChartInfoController
+// @Description: 跨品种分析图表
+type ChartInfoController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 相关性图表列表接口
+// @Description 相关性图表列表接口
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ChartClassifyId   query   int  true       "分类id"
+// @Param   Keyword   query   string  true       "搜索关键词"
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Param   Source   query   int  true       "图表类型,3:相关性,4:滚动相关性"
+// @Success 200 {object} data_manage.ChartListResp
+// @router /chart_info/list [get]
+func (c *ChartInfoController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	chartClassifyId, _ := c.GetInt("ChartClassifyId")
+
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	keyword := c.GetString("KeyWord")
+
+	var total int
+	page := paging.GetPaging(currentIndex, pageSize, total)
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	source, _ := c.GetInt("Source")
+	if source <= 0 {
+		source = utils.CHART_SOURCE_CORRELATION
+	}
+
+	var condition string
+	var pars []interface{}
+
+	// 普通图表
+	condition += ` AND source = ? `
+	pars = append(pars, source)
+
+	if chartClassifyId > 0 {
+		chartClassifyId, err := data_manage.GetChartClassify(chartClassifyId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取图表信息失败"
+			br.ErrMsg = "获取信息失败,GetChartClassify,Err:" + err.Error()
+			return
+		}
+		condition += " AND chart_classify_id IN(" + chartClassifyId + ") "
+	}
+	if keyword != "" {
+		condition += ` AND  ( chart_name LIKE '%` + keyword + `%' )`
+	}
+
+	//只看我的
+	isShowMe, _ := c.GetBool("IsShowMe")
+	if isShowMe {
+		condition += ` AND sys_user_id = ? `
+		pars = append(pars, sysUser.AdminId)
+	}
+
+	// 获取当前账号的不可见指标
+	noPermissionChartIdList := make([]int, 0)
+	{
+		obj := data_manage.EdbInfoNoPermissionAdmin{}
+		confList, err := obj.GetAllChartListByAdminId(c.SysUser.AdminId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range confList {
+			noPermissionChartIdList = append(noPermissionChartIdList, v.ChartInfoId)
+		}
+	}
+
+	lenNoPermissionChartIdList := len(noPermissionChartIdList)
+	if lenNoPermissionChartIdList > 0 {
+		condition += ` AND chart_info_id not in (` + utils.GetOrmInReplace(lenNoPermissionChartIdList) + `) `
+		pars = append(pars, noPermissionChartIdList)
+	}
+
+	//获取图表信息
+	list, err := data_manage.GetChartListByCondition(condition, pars, startSize, pageSize)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Success = true
+		br.Msg = "获取图表信息失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	myChartList, err := data_manage.GetMyChartListByAdminId(sysUser.AdminId)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取图表信息失败"
+		br.ErrMsg = "获取我的图表信息失败,Err:" + err.Error()
+		return
+	}
+	myChartMap := make(map[int]*data_manage.MyChartView)
+	for _, v := range myChartList {
+		myChartMap[v.ChartInfoId] = v
+	}
+	listLen := len(list)
+	chartEdbMap := make(map[int][]*data_manage.ChartEdbInfoMapping)
+	if listLen > 0 {
+		chartInfoIds := ""
+		for _, v := range list {
+			chartInfoIds += strconv.Itoa(v.ChartInfoId) + ","
+		}
+		if chartInfoIds != "" {
+			chartInfoIds = strings.Trim(chartInfoIds, ",")
+			//判断是否需要展示英文标识
+			edbList, e := data_manage.GetChartEdbMappingListByChartInfoIds(chartInfoIds)
+			if e != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取图表,指标信息失败,Err:" + e.Error()
+				return
+			}
+			for _, v := range edbList {
+				chartEdbMap[v.ChartInfoId] = append(chartEdbMap[v.ChartInfoId], v)
+			}
+		}
+	}
+	for i := 0; i < listLen; i++ {
+		//判断是否需要展示英文标识
+		if edbTmpList, ok := chartEdbMap[list[i].ChartInfoId]; ok {
+			list[i].IsEnChart = data.CheckIsEnChart(list[i].ChartNameEn, edbTmpList, list[i].Source, list[i].ChartType)
+		}
+
+		if existItem, ok := myChartMap[list[i].ChartInfoId]; ok {
+			list[i].IsAdd = true
+			list[i].MyChartId = existItem.MyChartId
+			list[i].MyChartClassifyId = existItem.MyChartClassifyId
+		}
+	}
+
+	resp := new(data_manage.ChartListResp)
+	if list == nil || len(list) <= 0 || (err != nil && err.Error() == utils.ErrNoRow()) {
+		items := make([]*data_manage.ChartInfoView, 0)
+		resp.Paging = page
+		resp.List = items
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		return
+	}
+
+	dataCount, err := data_manage.GetChartListCountByCondition(condition, pars)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取指标信息失败"
+		br.ErrMsg = "获取指标数据总数失败,Err:" + err.Error()
+		return
+	}
+	page = paging.GetPaging(currentIndex, pageSize, dataCount)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 99 - 0
controllers/data_manage/cross_variety/classify.go

@@ -0,0 +1,99 @@
+package cross_variety
+
+import (
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage"
+	"eta/eta_api/services/data"
+	"eta/eta_api/utils"
+)
+
+// ClassifyController
+// @Description: 跨品种分析分类
+type ClassifyController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 跨品种分析分类列表
+// @Description 跨品种分析分类列表接口
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Param   Source   query   int  true       "图表类型,3:相关性,4:滚动相关性"
+// @Success 200 {object} data_manage.ChartClassifyListResp
+// @router /classify/list [get]
+func (c *ClassifyController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	resp := new(data_manage.ChartClassifyListResp)
+
+	// 获取当前账号的不可见指标
+	noPermissionChartIdMap := make(map[int]bool)
+	{
+		obj := data_manage.EdbInfoNoPermissionAdmin{}
+		confList, err := obj.GetAllChartListByAdminId(c.SysUser.AdminId)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range confList {
+			noPermissionChartIdMap[v.ChartInfoId] = true
+		}
+	}
+
+	isShowMe, _ := c.GetBool("IsShowMe")
+
+	source, _ := c.GetInt("Source")
+	if source <= 0 {
+		source = utils.CHART_SOURCE_CROSS_HEDGING
+	}
+
+	rootList, err := data_manage.GetChartClassifyByParentId(0, utils.CHART_SOURCE_CROSS_HEDGING)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	allChartInfo, err := data_manage.GetChartInfoAll([]int{source})
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取图表信息失败,Err:" + err.Error()
+		return
+	}
+
+	chartInfoMap := make(map[int][]*data_manage.ChartClassifyItems)
+	for _, v := range allChartInfo {
+		if !isShowMe {
+			chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+			continue
+		}
+		if v.SysUserId != c.SysUser.AdminId {
+			continue
+		}
+		chartInfoMap[v.ChartClassifyId] = append(chartInfoMap[v.ChartClassifyId], v)
+	}
+	rootChildMap := make(map[int][]*data_manage.ChartClassifyItems)
+
+	// 移除没有图表的分类
+	allNodes := make([]*data_manage.ChartClassifyItems, 0)
+	for _, v := range rootList {
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := chartInfoMap[v.ChartClassifyId]; ok {
+			v.Children = existItems
+			allNodes = append(allNodes, v)
+		}
+	}
+
+	// 移除没有权限的图表
+	allNodes = data.HandleNoPermissionChart(allNodes, noPermissionChartIdMap)
+	resp.AllNodes = allNodes
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}

+ 320 - 0
controllers/data_manage/cross_variety/tag.go

@@ -0,0 +1,320 @@
+package cross_variety
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage/cross_variety"
+	"eta/eta_api/models/data_manage/cross_variety/request"
+	"eta/eta_api/models/data_manage/cross_variety/response"
+	"eta/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+// TagController
+// @Description: 标签列表
+type TagController struct {
+	controllers.BaseAuthController
+}
+
+// Add
+// @Title 新增标签
+// @Description 新增标签接口
+// @Param	request	body request.AddTagReq true "type json string"
+// @Success 200 Ret=200 添加成功
+// @router /tag/add [post]
+func (c *TagController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.AddTagReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.TagName == "" {
+		br.Msg = "请输入标签名称"
+		br.IsSendEmail = false
+		return
+	}
+	TagName := utils.TrimStr(req.TagName)
+	item, err := cross_variety.GetTagByName(TagName)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+	if item != nil {
+		br.Msg = "添加失败,标签名称不能重复"
+		br.IsSendEmail = false
+		return
+	}
+
+	tag := &cross_variety.ChartTag{
+		ChartTagId:      0,
+		ChartTagName:    TagName,
+		SysUserId:       c.SysUser.AdminId,
+		SysUserRealName: c.SysUser.RealName,
+		ModifyTime:      time.Now(),
+		CreateTime:      time.Now(),
+	}
+	err = cross_variety.AddTag(tag)
+	if err != nil {
+		br.Msg = "添加标签失败"
+		br.ErrMsg = "添加标签失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "添加成功"
+	br.IsAddLog = true
+	br.Success = true
+}
+
+// Edit
+// @Title 编辑标签接口
+// @Description 编辑标签接口
+// @Param	request	body request.EditTagReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /tag/edit [post]
+func (c *TagController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.EditTagReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartTagId <= 0 {
+		br.Msg = "请选择标签"
+		br.IsSendEmail = false
+		return
+	}
+	if req.TagName == "" {
+		br.Msg = "请输入标签名称"
+		br.IsSendEmail = false
+		return
+	}
+	TagName := utils.TrimStr(req.TagName)
+
+	item, err := cross_variety.GetTagByName(TagName)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+	if item != nil && item.ChartTagId != req.ChartTagId {
+		br.Msg = "添加失败,标签名称不能重复"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取标签详情
+	varietyInfo, err := cross_variety.GetTagById(req.ChartTagId)
+	if err != nil {
+		br.Msg = "查询标签失败"
+		br.ErrMsg = "查询标签失败;ERR:" + err.Error()
+		return
+	}
+
+	// 编辑
+	varietyInfo.ChartTagName = TagName
+	varietyInfo.ModifyTime = time.Now()
+	err = varietyInfo.Update([]string{"ChartTagName", "ModifyTime"})
+	if err != nil {
+		br.Msg = "修改标签失败"
+		br.ErrMsg = "修改标签失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "修改成功"
+	br.IsAddLog = true
+	br.Success = true
+}
+
+// DeleteCheck
+// @Title 删除标签检测接口
+// @Description 删除标签检测接口
+// @Param	request	body request.DelTagReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /tag/delete/check [post]
+func (c *TagController) DeleteCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.DelTagReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartTagId <= 0 {
+		br.Msg = "请选择标签"
+		br.IsSendEmail = false
+		return
+	}
+	var deleteStatus int
+	var tipsMsg string
+
+	// todo 校验标签与图表的关系
+	//deleteStatus = 1
+	//tipsMsg = "已关联图表的标签,不允许删除!"
+	resp := response.TagDeleteCheckResp{
+		DeleteStatus: deleteStatus,
+		TipsMsg:      tipsMsg,
+	}
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// Delete
+// @Title 删除标签
+// @Description 删除标签接口
+// @Param	request	body request.DeleteChartClassifyReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /tag/delete [post]
+func (c *TagController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.DelTagReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartTagId <= 0 {
+		br.Msg = "请选择标签"
+		br.IsSendEmail = false
+		return
+	}
+
+	// todo 校验标签与图表的关系
+	//deleteStatus = 1
+	//tipsMsg = "已关联图表的标签,不允许删除!"
+
+	varietyInfo, err := cross_variety.GetTagById(req.ChartTagId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "该标签不存在或已删除"
+			br.IsSendEmail = false
+		} else {
+			br.Msg = "删除失败"
+			br.ErrMsg = "查找标签失败,ERR:" + err.Error()
+		}
+		return
+	}
+	err = varietyInfo.Delete()
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除标签失败,ERR:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+}
+
+// VarietyEdbList
+// @Title 获取标签中的指标与品种的映射关系
+// @Description 获取标签中的指标与品种的映射关系
+// @Param   ChartTagId   query   int  true       "标签id"
+// @Success 200 Ret=200 保存成功
+// @router /tag/variety_edb/list [get]
+func (c *TagController) VarietyEdbList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	chartTagId, _ := c.GetInt("ChartTagId")
+	if chartTagId <= 0 {
+		br.Msg = "请选择标签"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取数据
+	list, err := cross_variety.GetChartTagVarietyItemListByTag(chartTagId)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,ERR:" + err.Error()
+		return
+	}
+	dataCount := len(list)
+	page := paging.GetPaging(1, dataCount, dataCount)
+
+	resp := response.VarietyEdbListResp{
+		List:   list,
+		Paging: page,
+	}
+
+	br.Ret = 200
+	br.Msg = "保存成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// SaveVarietyEdb
+// @Title 配置标签中的指标与品种的映射关系
+// @Description 配置标签中的指标与品种的映射关系
+// @Param	request	body request.SaveTagVarietyEdbReq true "type json string"
+// @Success 200 Ret=200 保存成功
+// @router /tag/variety_edb/save [post]
+func (c *TagController) SaveVarietyEdb() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.SaveTagVarietyEdbReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartTagId <= 0 {
+		br.Msg = "请选择标签"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 保存配置
+	err = cross_variety.SaveVarietyEdb(req.ChartTagId, req.VarietyEdb, c.SysUser.AdminId, c.SysUser.RealName)
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存失败,ERR:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "保存成功"
+	br.Success = true
+	br.IsAddLog = true
+}

+ 238 - 0
controllers/data_manage/cross_variety/variety.go

@@ -0,0 +1,238 @@
+package cross_variety
+
+import (
+	"encoding/json"
+	"eta/eta_api/controllers"
+	"eta/eta_api/models"
+	"eta/eta_api/models/data_manage/cross_variety"
+	"eta/eta_api/models/data_manage/cross_variety/request"
+	"eta/eta_api/models/data_manage/cross_variety/response"
+	"eta/eta_api/utils"
+	"time"
+)
+
+// VarietyController
+// @Description: 品种列表
+type VarietyController struct {
+	controllers.BaseAuthController
+}
+
+// Add
+// @Title 新增品种
+// @Description 新增品种接口
+// @Param	request	body request.AddVarietyReq true "type json string"
+// @Success 200 Ret=200 添加成功
+// @router /variety/add [post]
+func (c *VarietyController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.AddVarietyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.VarietyName == "" {
+		br.Msg = "请输入品种名称"
+		br.IsSendEmail = false
+		return
+	}
+	varietyName := utils.TrimStr(req.VarietyName)
+	item, err := cross_variety.GetVarietyByName(varietyName)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+	if item != nil {
+		br.Msg = "添加失败,品种名称不能重复"
+		br.IsSendEmail = false
+		return
+	}
+
+	variety := &cross_variety.ChartVariety{
+		ChartVarietyId:   0,
+		ChartVarietyName: varietyName,
+		SysUserId:        c.SysUser.AdminId,
+		SysUserRealName:  c.SysUser.RealName,
+		ModifyTime:       time.Now(),
+		CreateTime:       time.Now(),
+	}
+	err = cross_variety.AddVariety(variety)
+	if err != nil {
+		br.Msg = "添加品种失败"
+		br.ErrMsg = "添加品种失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "添加成功"
+	br.IsAddLog = true
+	br.Success = true
+}
+
+// Edit
+// @Title 编辑品种接口
+// @Description 编辑品种接口
+// @Param	request	body request.EditVarietyReq true "type json string"
+// @Success 200 Ret=200 修改成功
+// @router /variety/edit [post]
+func (c *VarietyController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.EditVarietyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ChartVarietyId <= 0 {
+		br.Msg = "请选择品种"
+		br.IsSendEmail = false
+		return
+	}
+	if req.VarietyName == "" {
+		br.Msg = "请输入品种名称"
+		br.IsSendEmail = false
+		return
+	}
+	varietyName := utils.TrimStr(req.VarietyName)
+
+	item, err := cross_variety.GetVarietyByName(varietyName)
+	if err != nil && err.Error() != utils.ErrNoRow() {
+		br.Msg = "添加失败"
+		br.ErrMsg = "添加失败,Err:" + err.Error()
+		return
+	}
+	if item != nil && item.ChartVarietyId != req.ChartVarietyId {
+		br.Msg = "添加失败,品种名称不能重复"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 获取品种详情
+	varietyInfo, err := cross_variety.GetVarietyById(req.ChartVarietyId)
+	if err != nil {
+		br.Msg = "查询品种失败"
+		br.ErrMsg = "查询品种失败;ERR:" + err.Error()
+		return
+	}
+
+	// 编辑
+	varietyInfo.ChartVarietyName = varietyName
+	varietyInfo.ModifyTime = time.Now()
+	err = varietyInfo.Update([]string{"ChartVarietyName", "ModifyTime"})
+	if err != nil {
+		br.Msg = "修改品种失败"
+		br.ErrMsg = "修改品种失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "修改成功"
+	br.IsAddLog = true
+	br.Success = true
+}
+
+// DeleteCheck
+// @Title 删除品种检测接口
+// @Description 删除品种检测接口
+// @Param	request	body request.DelVarietyReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /variety/delete/check [post]
+func (c *VarietyController) DeleteCheck() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.DelVarietyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartVarietyId <= 0 {
+		br.Msg = "请选择品种"
+		br.IsSendEmail = false
+		return
+	}
+	var deleteStatus int
+	var tipsMsg string
+
+	// todo 校验品种与图表的关系
+	//deleteStatus = 1
+	//tipsMsg = "已关联图表的品种,不允许删除!"
+	resp := response.VarietyDeleteCheckResp{
+		DeleteStatus: deleteStatus,
+		TipsMsg:      tipsMsg,
+	}
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// Delete
+// @Title 删除品种
+// @Description 删除品种接口
+// @Param	request	body request.DeleteChartClassifyReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /variety/delete [post]
+func (c *VarietyController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req request.DelVarietyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ChartVarietyId <= 0 {
+		br.Msg = "请选择品种"
+		br.IsSendEmail = false
+		return
+	}
+
+	// todo 校验品种与图表的关系
+	//deleteStatus = 1
+	//tipsMsg = "已关联图表的品种,不允许删除!"
+
+	varietyInfo, err := cross_variety.GetVarietyById(req.ChartVarietyId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "该品种不存在或已删除"
+			br.IsSendEmail = false
+		} else {
+			br.Msg = "删除失败"
+			br.ErrMsg = "查找品种失败,ERR:" + err.Error()
+		}
+		return
+	}
+	err = varietyInfo.Delete()
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除品种失败,ERR:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+}

+ 2 - 28
controllers/data_manage/future_good/future_good_chart_classify.go

@@ -56,7 +56,7 @@ func (this *FutureGoodChartClassifyController) ChartClassifyList() {
 			return
 		}
 		// 移除没有权限的图表
-		allNodes := handleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
+		allNodes := data.HandleNoPermissionChart(resp.AllNodes, noPermissionChartIdMap)
 		resp.AllNodes = allNodes
 
 		br.Ret = 200
@@ -97,7 +97,7 @@ func (this *FutureGoodChartClassifyController) ChartClassifyList() {
 	}
 
 	// 移除没有权限的图表
-	allNodes := handleNoPermissionChart(rootList, noPermissionChartIdMap)
+	allNodes := data.HandleNoPermissionChart(rootList, noPermissionChartIdMap)
 	resp.AllNodes = allNodes
 
 	br.Ret = 200
@@ -139,32 +139,6 @@ func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartCl
 	return
 }
 
-// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
-func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
-	// 移除没有权限的图表
-	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
-	for _, node := range allNodes {
-		// 二级分类
-		tmpNodeInfo := *node
-		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
-
-		if node.Children != nil {
-			for _, chartInfo := range node.Children {
-				// 如果指标不可见,那么就不返回该指标
-				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
-					continue
-				}
-				tmpNodeList = append(tmpNodeList, chartInfo)
-			}
-		}
-
-		tmpNodeInfo.Children = tmpNodeList
-		newAllNodes = append(newAllNodes, &tmpNodeInfo)
-	}
-
-	return
-}
-
 // ChartClassifyItems
 // @Title 获取所有商品价格图表分类接口-不包含图表
 // @Description 获取所有商品价格图表分类接口-不包含图表

+ 1 - 27
controllers/data_manage/line_equation/line_chart_classify.go

@@ -101,7 +101,7 @@ func (this *LineEquationChartClassifyController) ChartClassifyList() {
 	}
 
 	// 移除没有权限的图表
-	allNodes := handleNoPermissionChart(rootList, noPermissionChartIdMap)
+	allNodes := data.HandleNoPermissionChart(rootList, noPermissionChartIdMap)
 	resp.AllNodes = allNodes
 
 	br.Ret = 200
@@ -144,32 +144,6 @@ func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartCl
 	return
 }
 
-// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
-func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
-	// 移除没有权限的图表
-	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
-	for _, node := range allNodes {
-		// 二级分类
-		tmpNodeInfo := *node
-		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
-
-		if node.Children != nil {
-			for _, chartInfo := range node.Children {
-				// 如果指标不可见,那么就不返回该指标
-				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
-					continue
-				}
-				tmpNodeList = append(tmpNodeList, chartInfo)
-			}
-		}
-
-		tmpNodeInfo.Children = tmpNodeList
-		newAllNodes = append(newAllNodes, &tmpNodeInfo)
-	}
-
-	return
-}
-
 // ChartClassifyItems
 // @Title 获取所有拟合方程图表分类接口-不包含图表
 // @Description 获取所有拟合方程图表分类接口-不包含图表

+ 1 - 27
controllers/data_manage/line_feature/classify.go

@@ -101,7 +101,7 @@ func (this *LineFeaturesChartClassifyController) ChartClassifyList() {
 	}
 
 	// 移除没有权限的图表
-	allNodes := handleNoPermissionChart(rootList, noPermissionChartIdMap)
+	allNodes := data.HandleNoPermissionChart(rootList, noPermissionChartIdMap)
 	resp.AllNodes = allNodes
 
 	br.Ret = 200
@@ -144,32 +144,6 @@ func getChartClassifyListForMe(adminInfo system.Admin, resp *data_manage.ChartCl
 	return
 }
 
-// handleNoPermissionChart 图表列表返回,将没有权限的图表移除
-func handleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
-	// 移除没有权限的图表
-	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
-	for _, node := range allNodes {
-		// 二级分类
-		tmpNodeInfo := *node
-		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
-
-		if node.Children != nil {
-			for _, chartInfo := range node.Children {
-				// 如果指标不可见,那么就不返回该指标
-				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
-					continue
-				}
-				tmpNodeList = append(tmpNodeList, chartInfo)
-			}
-		}
-
-		tmpNodeInfo.Children = tmpNodeList
-		newAllNodes = append(newAllNodes, &tmpNodeInfo)
-	}
-
-	return
-}
-
 // ChartClassifyItems
 // @Title 获取所有统计特征图表分类接口-不包含图表
 // @Description 获取所有统计特征图表分类接口-不包含图表

+ 1 - 1
models/data_manage/chart_info.go

@@ -72,7 +72,7 @@ func GetChartInfoAll(sourceList []int) (items []*ChartClassifyItems, err error)
 	o := orm.NewOrmUsingDB("data")
 	sql := ` SELECT chart_info_id,chart_classify_id,chart_name AS chart_classify_name,
              unique_code,sys_user_id,sys_user_real_name,date_type,start_date,end_date,chart_type,calendar,season_start_date,season_end_date,source
-            FROM chart_info WHERE source in (` + utils.GetOrmInReplace(num) + `)  ORDER BY sort asc,create_time ASC `
+            FROM chart_info WHERE source in (` + utils.GetOrmInReplace(num) + `)  ORDER BY sort asc,chart_info_id ASC `
 	_, err = o.Raw(sql, sourceList).QueryRows(&items)
 	return
 }

+ 86 - 0
models/data_manage/cross_variety/chart_tag.go

@@ -0,0 +1,86 @@
+package cross_variety
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartTag
+// @Description: chart_tag 图表标签表
+type ChartTag struct {
+	ChartTagId      int       `orm:"column(chart_tag_id);pk"`
+	ChartTagName    string    `description:"标签名称"`
+	SysUserId       int       `description:"创建人id"`
+	SysUserRealName string    `description:"创建人姓名"`
+	ModifyTime      time.Time `description:"修改时间"`
+	CreateTime      time.Time `description:"创建时间"`
+}
+
+// GetTagById
+// @Description: 根据标签id获取标签详情
+// @author: Roc
+// @datetime 2023-11-21 14:55:31
+// @param id int
+// @return item *ChartTag
+// @return err error
+func GetTagById(id int) (item *ChartTag, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_tag WHERE chart_tag_id = ?`
+	err = o.Raw(sql, id).QueryRow(&item)
+
+	return
+}
+
+// GetTagByName
+// @Description: 根据标签名称获取标签详情
+// @author: Roc
+// @datetime 2023-11-21 14:55:20
+// @param name string
+// @return item *ChartTag
+// @return err error
+func GetTagByName(name string) (item *ChartTag, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_tag WHERE chart_tag_name = ?`
+	err = o.Raw(sql, name).QueryRow(&item)
+
+	return
+}
+
+// AddTag
+// @Description: 添加标签
+// @author: Roc
+// @datetime 2023-11-21 14:52:56
+// @param item *ChartTag
+// @return err error
+func AddTag(item *ChartTag) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+
+	item.ChartTagId = int(lastId)
+
+	return
+}
+
+// Update
+// @Description: 更新标签
+// @author: Roc
+// @receiver item
+// @datetime 2023-11-21 15:15:17
+// @param updateColList []string
+// @return err error
+func (item *ChartTag) Update(updateColList []string) (err error) {
+	to := orm.NewOrmUsingDB("data")
+	_, err = to.Update(item, updateColList...)
+
+	return
+}
+
+// Delete 删除
+func (item *ChartTag) Delete() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Delete(item)
+	return
+}

+ 180 - 0
models/data_manage/cross_variety/chart_tag_variety.go

@@ -0,0 +1,180 @@
+package cross_variety
+
+import (
+	"eta/eta_api/models/data_manage/cross_variety/request"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"strings"
+	"time"
+)
+
+// ChartTagVariety
+// @Description: chart_tag_variety 图表标签品种关系表
+type ChartTagVariety struct {
+	Id                        int       `orm:"column(id);pk"`
+	ChartTagId                int       `description:"标签id"`
+	ChartVarietyId            int       `description:"品种id"`
+	EdbInfoId                 int       `description:"指标id"`
+	LastUpdateSysUserId       int       `description:"最后一次操作人"`
+	LastUpdateSysUserRealName string    `description:"最后一次操作人真实姓名"`
+	ModifyTime                time.Time `description:"修改时间"`
+	CreateTime                time.Time `description:"创建时间"`
+}
+
+// GetChartTagVarietyByTagAndVariety
+// @Description: 根据标签id和品种id获取关系
+// @author: Roc
+// @datetime 2023-11-22 10:42:50
+// @param chartTagId int
+// @param chartVarietyId int
+// @return item *ChartTagVariety
+// @return err error
+func GetChartTagVarietyByTagAndVariety(chartTagId, chartVarietyId int) (item *ChartTagVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_tag_variety WHERE chart_tag_id = ? AND chart_variety_id = ?`
+	err = o.Raw(sql, chartTagId, chartVarietyId).QueryRow(&item)
+
+	return
+}
+
+// GetChartTagVarietyListByTag
+// @Description: 根据标签id获取所有绑定的品种列表
+// @author: Roc
+// @datetime 2023-11-22 10:44:35
+// @param chartTagId int
+// @param chartVarietyId int
+// @return items []*ChartTagVariety
+// @return err error
+func GetChartTagVarietyListByTag(chartTagId int) (items []*ChartTagVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_tag_variety WHERE chart_tag_id = ? `
+	_, err = o.Raw(sql, chartTagId).QueryRows(&items)
+
+	return
+}
+
+// ChartTagVarietyItem
+// @Description: 图表标签/品种/指标数据
+type ChartTagVarietyItem struct {
+	Id             int     `orm:"column(id);pk"`
+	ChartTagId     int     `description:"标签id"`
+	ChartVarietyId int     `description:"品种id"`
+	EdbInfoId      int     `description:"指标id"`
+	EdbCode        string  `description:"指标编码"`
+	EdbName        string  `description:"指标名称"`
+	EndDate        string  `description:"数据的最晚日期"`
+	EndValue       float64 `description:"数据最新值"`
+}
+
+// GetChartTagVarietyItemListByTag
+// @Description: 根据标签id获取所有绑定的品种列表
+// @author: Roc
+// @datetime 2023-11-22 10:44:35
+// @param chartTagId int
+// @param chartVarietyId int
+// @return items []*ChartTagVariety
+// @return err error
+func GetChartTagVarietyItemListByTag(chartTagId int) (items []*ChartTagVarietyItem, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT a.*,b.edb_code,b.edb_name,b.end_date,b.end_value FROM chart_tag_variety a 
+         join edb_info b on a.edb_info_id=b.edb_info_id WHERE chart_tag_id = ? `
+	_, err = o.Raw(sql, chartTagId).QueryRows(&items)
+
+	return
+}
+
+// SaveVarietyEdb
+// @Description: 配置标签中的指标与品种的映射关系
+// @author: Roc
+// @datetime 2023-11-22 14:26:24
+// @param chartTagId int
+// @param list []request.VarietyEdbReq
+// @param sysUserId int
+// @param sysUserName string
+// @return err error
+func SaveVarietyEdb(chartTagId int, list []request.VarietyEdbReq, sysUserId int, sysUserName string) (err error) {
+	o, err := orm.NewOrmUsingDB("data").Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			_ = o.Rollback()
+		} else {
+			_ = o.Commit()
+		}
+	}()
+
+	// 查找现在已经存在的品种和指标的关系
+	var items []*ChartTagVariety
+	sql := `SELECT * FROM chart_tag_variety WHERE chart_tag_id = ? `
+	_, err = o.Raw(sql, chartTagId).QueryRows(&items)
+	if err != nil {
+		return
+	}
+
+	hasMap := make(map[int]*ChartTagVariety)
+	existMap := make(map[int]*ChartTagVariety)
+	for _, v := range items {
+		hasMap[v.ChartVarietyId] = v
+		existMap[v.ChartVarietyId] = v
+	}
+
+	// 待添加的配置
+	addList := make([]*ChartTagVariety, 0)
+	for _, v := range list {
+		tmpChartTagVariety, ok := hasMap[v.ChartVarietyId]
+
+		// 找不到就插入
+		if !ok {
+			addList = append(addList, &ChartTagVariety{
+				Id:                        0,
+				ChartTagId:                chartTagId,
+				ChartVarietyId:            v.ChartVarietyId,
+				EdbInfoId:                 v.EdbInfoId,
+				LastUpdateSysUserId:       sysUserId,
+				LastUpdateSysUserRealName: sysUserName,
+				ModifyTime:                time.Now(),
+				CreateTime:                time.Now(),
+			})
+			continue
+		}
+
+		delete(existMap, v.ChartVarietyId)
+
+		// 找到了,如果指标不一致那就修改
+		if tmpChartTagVariety.EdbInfoId != v.EdbInfoId {
+			tmpChartTagVariety.EdbInfoId = v.EdbInfoId
+			tmpChartTagVariety.LastUpdateSysUserId = sysUserId
+			tmpChartTagVariety.LastUpdateSysUserRealName = sysUserName
+			tmpChartTagVariety.ModifyTime = time.Now()
+			_, err = o.Update(tmpChartTagVariety, "EdbInfoId", "LastUpdateSysUserId", "LastUpdateSysUserRealName", "ModifyTime")
+			if err != nil {
+				return
+			}
+		}
+	}
+
+	// 删除不要了的
+	if len(existMap) > 0 {
+		idStrList := make([]string, 0)
+		for id, _ := range existMap {
+			idStrList = append(idStrList, fmt.Sprint(id))
+		}
+		removeIdStr := strings.Join(idStrList, `,`)
+		sql = fmt.Sprintf(` DELETE FROM chart_tag_variety WHERE id in (%s) `, removeIdStr)
+		_, err = o.Raw(sql).Exec()
+		if err != nil {
+			return
+		}
+	}
+
+	// 添加配置
+	if len(addList) > 0 {
+		_, err = o.InsertMulti(len(addList), addList)
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 86 - 0
models/data_manage/cross_variety/chart_variety.go

@@ -0,0 +1,86 @@
+package cross_variety
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"time"
+)
+
+// ChartVariety
+// @Description: chart_variety 图表品种表
+type ChartVariety struct {
+	ChartVarietyId   int       `orm:"column(chart_variety_id);pk"`
+	ChartVarietyName string    `description:"品种名称"`
+	SysUserId        int       `description:"创建人id"`
+	SysUserRealName  string    `description:"创建人姓名"`
+	ModifyTime       time.Time `description:"修改时间"`
+	CreateTime       time.Time `description:"创建时间"`
+}
+
+// GetVarietyById
+// @Description: 根据品种id获取品种详情
+// @author: Roc
+// @datetime 2023-11-21 14:55:31
+// @param id int
+// @return item *ChartVariety
+// @return err error
+func GetVarietyById(id int) (item *ChartVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_variety WHERE chart_variety_id = ?`
+	err = o.Raw(sql, id).QueryRow(&item)
+
+	return
+}
+
+// GetVarietyByName
+// @Description: 根据品种名称获取品种详情
+// @author: Roc
+// @datetime 2023-11-21 14:55:20
+// @param name string
+// @return item *ChartVariety
+// @return err error
+func GetVarietyByName(name string) (item *ChartVariety, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM chart_variety WHERE chart_variety_name = ?`
+	err = o.Raw(sql, name).QueryRow(&item)
+
+	return
+}
+
+// AddVariety
+// @Description: 添加品种
+// @author: Roc
+// @datetime 2023-11-21 14:52:56
+// @param item *ChartVariety
+// @return err error
+func AddVariety(item *ChartVariety) (err error) {
+	o := orm.NewOrmUsingDB("data")
+	lastId, err := o.Insert(item)
+	if err != nil {
+		return
+	}
+
+	item.ChartVarietyId = int(lastId)
+
+	return
+}
+
+// Update
+// @Description: 更新品种
+// @author: Roc
+// @receiver item
+// @datetime 2023-11-21 15:15:17
+// @param updateColList []string
+// @return err error
+func (item *ChartVariety) Update(updateColList []string) (err error) {
+	to := orm.NewOrmUsingDB("data")
+	_, err = to.Update(item, updateColList...)
+
+	return
+}
+
+// Delete 删除
+func (item *ChartVariety) Delete() (err error) {
+	o := orm.NewOrmUsingDB("data")
+	_, err = o.Delete(item)
+	return
+}

+ 31 - 0
models/data_manage/cross_variety/request/tag.go

@@ -0,0 +1,31 @@
+package request
+
+// AddTagReq 添加标签请求
+type AddTagReq struct {
+	TagName string `description:"标签名称"`
+}
+
+// EditTagReq 编辑标签请求
+type EditTagReq struct {
+	ChartTagId int    `description:"标签id"`
+	TagName    string `description:"标签名称"`
+}
+
+// DelTagReq 删除标签请求
+type DelTagReq struct {
+	ChartTagId int `description:"标签id"`
+}
+
+// SaveTagVarietyEdbReq
+// @Description: 配置标签中的指标与品种的映射关系
+type SaveTagVarietyEdbReq struct {
+	ChartTagId int             `description:"标签id"`
+	VarietyEdb []VarietyEdbReq `description:"品种和指标的映射关系"`
+}
+
+// VarietyEdbReq
+// @Description: 品种和指标的映射关系
+type VarietyEdbReq struct {
+	ChartVarietyId int `description:"品种id"`
+	EdbInfoId      int `description:"指标id"`
+}

+ 17 - 0
models/data_manage/cross_variety/request/variety.go

@@ -0,0 +1,17 @@
+package request
+
+// AddVarietyReq 添加品种请求
+type AddVarietyReq struct {
+	VarietyName string `description:"品种名称"`
+}
+
+// EditVarietyReq 编辑品种请求
+type EditVarietyReq struct {
+	ChartVarietyId int    `description:"品种id"`
+	VarietyName    string `description:"品种名称"`
+}
+
+// DelVarietyReq 删除品种请求
+type DelVarietyReq struct {
+	ChartVarietyId int `description:"品种id"`
+}

+ 19 - 0
models/data_manage/cross_variety/response/tag.go

@@ -0,0 +1,19 @@
+package response
+
+import (
+	"eta/eta_api/models/data_manage/cross_variety"
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// TagDeleteCheckResp 标签删除检测数据返回
+type TagDeleteCheckResp struct {
+	DeleteStatus int    `description:"检测状态:0:默认值,如果为0,继续走其他校验,1:该标签已关联图表,不允许删除!"`
+	TipsMsg      string `description:"提示信息"`
+}
+
+// VarietyEdbListResp
+// @Description: 品种与关系的数据返回
+type VarietyEdbListResp struct {
+	List   []*cross_variety.ChartTagVarietyItem `description:"列表数据"`
+	Paging *paging.PagingItem
+}

+ 7 - 0
models/data_manage/cross_variety/response/variety.go

@@ -0,0 +1,7 @@
+package response
+
+// VarietyDeleteCheckResp 品种删除检测数据返回
+type VarietyDeleteCheckResp struct {
+	DeleteStatus int    `description:"检测状态:0:默认值,如果为0,继续走其他校验,1:已关联图表的品种,不允许删除!"`
+	TipsMsg      string `description:"提示信息"`
+}

+ 9 - 6
models/data_manage/edb_info.go

@@ -36,8 +36,9 @@ type EdbInfo struct {
 	CalculateFormula string  `description:"计算公式"`
 	EdbType          int     `description:"指标类型:1:基础指标,2:计算指标"`
 	Sort             int     `description:"排序字段"`
-	LatestDate       string  `description:"数据最新日期"`
-	LatestValue      float64 `description:"数据最新值"`
+	LatestDate       string  `description:"数据最新日期(实际日期)"`
+	LatestValue      float64 `description:"数据最新值(实际值)"`
+	EndValue         float64 `description:"数据的最新值(预测日期的最新值)"`
 	MoveType         int     `description:"移动方式:1:领先(默认),2:滞后"`
 	MoveFrequency    string  `description:"移动频度"`
 	NoUpdate         int8    `description:"是否停止更新,0:继续更新;1:停止更新"`
@@ -270,8 +271,9 @@ type EdbInfoList struct {
 	UnitEn           string                  `description:"英文单位"`
 	StartDate        string                  `description:"起始日期"`
 	EndDate          string                  `description:"终止日期"`
-	LatestDate       string                  `description:"数据最新日期"`
-	LatestValue      float64                 `description:"数据最新值"`
+	LatestDate       string                  `description:"数据最新日期(实际日期)"`
+	LatestValue      float64                 `description:"数据最新值(实际值)"`
+	EndValue         float64                 `description:"数据的最新值(预测日期的最新值)"`
 	ClassifyId       int                     `description:"分类id"`
 	UniqueCode       string                  `description:"指标唯一编码"`
 	SysUserId        int                     `description:"创建人id"`
@@ -1521,8 +1523,9 @@ type EdbInfoView struct {
 	EdbType          int     `description:"指标类型:1:基础指标,2:计算指标"`
 	Sort             int     `description:"排序字段"`
 	IsUpdate         int     `description:"当天是否已更新,1:未更新,2:已更新"`
-	LatestDate       string  `description:"数据最新日期"`
-	LatestValue      float64 `description:"数据最新值"`
+	LatestDate       string  `description:"数据最新日期(实际日期)"`
+	LatestValue      float64 `description:"数据最新值(实际值)"`
+	EndValue         float64 `description:"数据的最新值(预测日期的最新值)"`
 }
 
 // 获取指标的所有计算指标,以及计算指标所依赖计算指标

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

@@ -100,7 +100,7 @@ func GetAllExcelEdbMappingByExcelInfoId(excelInfoId int) (items []*ExcelEdbMappi
 // DeleteCustomAnalysisExcelEdbMappingByEdbInfoId
 // @Description: 根据指标id删除与自定义分析表格的关系
 // @author: Roc
-// @datetime2023-11-02 13:20:02
+// @datetime 2023-11-02 13:20:02
 // @param excelInfoId int
 // @return err error
 func DeleteCustomAnalysisExcelEdbMappingByEdbInfoId(excelInfoId int) (err error) {

+ 13 - 0
models/db.go

@@ -3,6 +3,7 @@ package models
 import (
 	"eta/eta_api/models/company"
 	"eta/eta_api/models/data_manage"
+	"eta/eta_api/models/data_manage/cross_variety"
 	"eta/eta_api/models/data_manage/excel"
 	future_good2 "eta/eta_api/models/data_manage/future_good"
 	"eta/eta_api/models/data_manage/supply_analysis"
@@ -157,6 +158,9 @@ func init() {
 	// 初始化EXCEL的表
 	initExcel()
 
+	// 初始化跨品种分析表
+	initCrossVariety()
+
 	// 初始化部分数据表变量(直接init会有顺序问题=_=!)
 	data_manage.InitEdbSourceVar()
 }
@@ -471,3 +475,12 @@ func initSmartReport() {
 		new(smart_report.SmartReportSaveLog), // 智能研报-保存记录表
 	)
 }
+
+// initCrossVariety 跨品种分析
+func initCrossVariety() {
+	orm.RegisterModel(
+		new(cross_variety.ChartVariety),    // 品种表
+		new(cross_variety.ChartTag),        // 标签表
+		new(cross_variety.ChartTagVariety), // 标签、品种、指标关系表
+	)
+}

+ 108 - 0
routers/commentsRouter.go

@@ -178,6 +178,114 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:ChartInfoController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:ChartInfoController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/chart_info/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:ClassifyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:ClassifyController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/tag/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/tag/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"],
+        beego.ControllerComments{
+            Method: "DeleteCheck",
+            Router: `/tag/delete/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/tag/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"],
+        beego.ControllerComments{
+            Method: "VarietyEdbList",
+            Router: `/tag/variety_edb/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:TagController"],
+        beego.ControllerComments{
+            Method: "SaveVarietyEdb",
+            Router: `/tag/variety_edb/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/variety/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/variety/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"],
+        beego.ControllerComments{
+            Method: "DeleteCheck",
+            Router: `/variety/delete/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/cross_variety:VarietyController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/variety/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:CustomAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/data_manage/excel:CustomAnalysisController"],
         beego.ControllerComments{
             Method: "Add",

+ 9 - 0
routers/router.go

@@ -11,6 +11,7 @@ import (
 	"eta/eta_api/controllers"
 	"eta/eta_api/controllers/data_manage"
 	"eta/eta_api/controllers/data_manage/correlation"
+	"eta/eta_api/controllers/data_manage/cross_variety"
 	"eta/eta_api/controllers/data_manage/excel"
 	future_good2 "eta/eta_api/controllers/data_manage/future_good"
 	"eta/eta_api/controllers/data_manage/line_equation"
@@ -318,6 +319,14 @@ func init() {
 				&data_manage.ChartFrameworkController{},
 			),
 		),
+		web.NSNamespace("/cross_variety", //跨品种分析
+			web.NSInclude(
+				&cross_variety.ClassifyController{},
+				&cross_variety.ChartInfoController{},
+				&cross_variety.VarietyController{},
+				&cross_variety.TagController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 26 - 0
services/data/chart_classify.go

@@ -141,3 +141,29 @@ func GetChartOpButton(sysUser *system.Admin, belongUserId int) (button data_mana
 
 	return
 }
+
+// HandleNoPermissionChart 图表列表返回,将没有权限的图表移除
+func HandleNoPermissionChart(allNodes []*data_manage.ChartClassifyItems, noPermissionChartIdMap map[int]bool) (newAllNodes []*data_manage.ChartClassifyItems) {
+	// 移除没有权限的图表
+	newAllNodes = make([]*data_manage.ChartClassifyItems, 0)
+	for _, node := range allNodes {
+		// 二级分类
+		tmpNodeInfo := *node
+		tmpNodeList := make([]*data_manage.ChartClassifyItems, 0)
+
+		if node.Children != nil {
+			for _, chartInfo := range node.Children {
+				// 如果指标不可见,那么就不返回该指标
+				if _, ok := noPermissionChartIdMap[chartInfo.ChartInfoId]; ok {
+					continue
+				}
+				tmpNodeList = append(tmpNodeList, chartInfo)
+			}
+		}
+
+		tmpNodeInfo.Children = tmpNodeList
+		newAllNodes = append(newAllNodes, &tmpNodeInfo)
+	}
+
+	return
+}

+ 1 - 1
services/data/edb_info.go

@@ -70,7 +70,7 @@ func EdbInfoRefreshAllFromBaseV3Bak(edbInfoIdList []int, refreshAll, isSync bool
 //
 //	@Description: 全部刷新指标(切换到edb_lib服务)
 //	@author: Roc
-//	@datetime2023-10-23 09:57:55
+//	@datetime 2023-10-23 09:57:55
 //	@param edbInfoIdList []int
 //	@param refreshAll bool
 //	@param isSync bool

+ 8 - 7
utils/constants.go

@@ -263,13 +263,14 @@ const (
 const (
 	CHART_SOURCE_DEFAULT                         = 1
 	CHART_SOURCE_FUTURE_GOOD                     = 2
-	CHART_SOURCE_CORRELATION                     = 3 // 相关性图表
-	CHART_SOURCE_ROLLING_CORRELATION             = 4 // 滚动相关性图表
-	CHART_SOURCE_FUTURE_GOOD_PROFIT              = 5 // 商品利润曲线
-	CHART_SOURCE_LINE_EQUATION                   = 6 // 拟合方程图表
-	CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION = 7 // 统计特征-标准差图表
-	CHART_SOURCE_LINE_FEATURE_PERCENTILE         = 8 // 统计特征-百分位图表
-	CHART_SOURCE_LINE_FEATURE_FREQUENCY          = 9 // 统计特征-频率分布图表
+	CHART_SOURCE_CORRELATION                     = 3  // 相关性图表
+	CHART_SOURCE_ROLLING_CORRELATION             = 4  // 滚动相关性图表
+	CHART_SOURCE_FUTURE_GOOD_PROFIT              = 5  // 商品利润曲线
+	CHART_SOURCE_LINE_EQUATION                   = 6  // 拟合方程图表
+	CHART_SOURCE_LINE_FEATURE_STANDARD_DEVIATION = 7  // 统计特征-标准差图表
+	CHART_SOURCE_LINE_FEATURE_PERCENTILE         = 8  // 统计特征-百分位图表
+	CHART_SOURCE_LINE_FEATURE_FREQUENCY          = 9  // 统计特征-频率分布图表
+	CHART_SOURCE_CROSS_HEDGING                   = 10 // 跨品种分析图表
 )
 
 // 批量配置图表的位置来源