Browse Source

fix:公共指标、审批单等一批接口

Roc 3 months ago
parent
commit
21fb27ce9f
39 changed files with 5590 additions and 383 deletions
  1. 458 0
      controllers/data_manage/data_approve/data_approve.go
  2. 126 0
      controllers/data_manage/data_approve/data_approve_flow.go
  3. 13 7
      controllers/data_manage/edb_info_share.go
  4. 614 0
      controllers/data_manage/edb_public.go
  5. 276 306
      controllers/data_manage/edb_public_classify.go
  6. 5 1
      controllers/fix.go
  7. 3 0
      models/business_conf.go
  8. 223 0
      models/data_manage/data_approve/data_approve.go
  9. 198 0
      models/data_manage/data_approve/data_approve_flow.go
  10. 115 0
      models/data_manage/data_approve/data_approve_message.go
  11. 90 0
      models/data_manage/data_approve/data_approve_node.go
  12. 152 0
      models/data_manage/data_approve/data_approve_record.go
  13. 57 0
      models/data_manage/data_approve/data_approve_relation.go
  14. 21 0
      models/data_manage/data_approve/request/approve.go
  15. 22 0
      models/data_manage/data_approve/request/approve_flow.go
  16. 5 0
      models/data_manage/data_approve/request/approve_message.go
  17. 88 0
      models/data_manage/data_approve/response/approve.go
  18. 46 0
      models/data_manage/data_approve/response/approve_flow.go
  19. 24 0
      models/data_manage/data_approve/response/approve_message.go
  20. 6 6
      models/data_manage/edb_classify.go
  21. 75 0
      models/data_manage/edb_info.go
  22. 1 0
      models/data_manage/edb_info_share.go
  23. 158 26
      models/data_manage/public_edb_classify.go
  24. 39 1
      models/data_manage/public_edb_info.go
  25. 2 2
      models/data_manage/request/edb_info_share.go
  26. 48 0
      models/data_manage/request/edb_public.go
  27. 140 5
      routers/commentsRouter.go
  28. 9 0
      routers/router.go
  29. 1199 0
      services/data/data_approve/approve.go
  30. 174 0
      services/data/data_approve/approve_flow.go
  31. 89 0
      services/data/data_approve/approve_message.go
  32. 31 0
      services/data/data_approve/approve_node.go
  33. 37 0
      services/data/data_approve/constant.go
  34. 16 19
      services/data/edb_classify.go
  35. 2 2
      services/data/edb_info.go
  36. 44 0
      services/data/edb_public.go
  37. 850 0
      services/data/edb_public_classify.go
  38. 123 5
      services/elastic/edb_info.go
  39. 11 3
      utils/constants.go

+ 458 - 0
controllers/data_manage/data_approve/data_approve.go

@@ -0,0 +1,458 @@
+package data_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage/data_approve/request"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	dataApproveServ "eta_gn/eta_api/services/data/data_approve"
+	"eta_gn/eta_api/utils"
+	"fmt"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+// DataApproveController
+// @Description: 数据资产审批
+type DataApproveController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 审批列表
+// @Description 审批列表
+// @Param   PageSize			query	int		true	"每页数据条数"
+// @Param   CurrentIndex		query	int		true	"当前页页码"
+// @Param   ListType			query   int     true	"列表类型:1-待处理;2-已处理;3-我发起的"
+// @Param   ClassifyId			query	int		false	"分类ID"
+// @Param   Keyword				query	string	false	"搜索关键词"
+// @Param   ApproveState		query	int		false	"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"
+// @Param   TimeType			query	int		false	"时间类型:1-提交时间;2-处理时间;3-审批时间"
+// @Param   StartTime			query	string	false	"开始时间"
+// @Param   EndTime				query	string	false	"结束时间"
+// @Param   SortField			query	int		false	"排序字段:1-提交时间;2-处理时间;3-审批时间"
+// @Param   SortRule			query	int		false	"排序方式: 1-正序; 2-倒序(默认)"
+// @Success 200 {object} report_approve.DataApproveListResp
+// @router /list [get]
+func (this *DataApproveController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	sysUser := this.SysUser
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	listType, _ := this.GetInt("ListType")
+	approveState, _ := this.GetInt("ApproveState")
+	timeType, _ := this.GetInt("TimeType")
+	startTime := this.GetString("StartTime")
+	endTime := this.GetString("EndTime")
+	sortField, _ := this.GetInt("SortField")
+	sortRule, _ := this.GetInt("SortRule")
+	classifyId, _ := this.GetInt("ClassifyId")
+	keyword := this.GetString("Keyword")
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize10
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize := paging.StartIndex(currentIndex, pageSize)
+
+	var list []*response.DataApproveItemOrmResp
+	var total int
+	var msg string
+	var err error
+
+	switch listType {
+	case 1:
+		list, total, msg, err = dataApproveServ.ProcessingDataApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 2:
+		list, total, msg, err = dataApproveServ.SolvedDataApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 3:
+		list, total, msg, err = dataApproveServ.MyApplyDataApproves(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	default:
+		br.Msg = "列表类型错误"
+		return
+	}
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批列表失败"
+		}
+		br.ErrMsg = "获取审批列表失败, Err: " + err.Error()
+		return
+	}
+
+	resp := new(response.DataApproveListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+
+	br.Msg = "获取审批列表成功"
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+}
+
+// Approve
+// @Title 通过审批
+// @Description 通过审批
+// @Param	request	body report_approve.DataApprovePassReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /approve [post]
+func (this *DataApproveController) Approve() {
+	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.DataApprovePassReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.DataApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", req.DataApproveId)
+		return
+	}
+
+	// 通过审批
+	msg, err := dataApproveServ.PassDataApprove(req.DataApproveId, sysUser.AdminId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "通过审批失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 审批详情
+// @Description 审批详情
+// @Param   DataApproveId  query  int  true  "审批ID"
+// @Success 200 {object} report_approve.DataApproveDetail
+// @router /detail [get]
+func (this *DataApproveController) Detail() {
+	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
+	}
+	approveId, _ := this.GetInt("DataApproveId")
+	if approveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", approveId)
+		return
+	}
+
+	resp, msg, err := dataApproveServ.GetApproveDetail(approveId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批详情失败"
+		}
+		br.ErrMsg = "获取审批详情失败, Err: " + err.Error()
+		return
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Refuse
+// @Title 驳回审批
+// @Description 驳回审批
+// @Param	request	body request.DataApproveRefuseReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /refuse [post]
+func (this *DataApproveController) Refuse() {
+	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.DataApproveRefuseReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.DataApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", req.DataApproveId)
+		return
+	}
+	maxStrLen := 500
+	approveLen := len([]rune(req.ApproveRemark))
+	if approveLen > maxStrLen {
+		br.Msg = fmt.Sprintf("审批驳回原因不能超过%d字", maxStrLen)
+		return
+	}
+	msg, err := dataApproveServ.DataApproveRefuse(req.DataApproveId, sysUser.AdminId, req.ApproveRemark)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "驳回审批失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Cancel
+// @Title 撤销审批
+// @Description 撤销审批
+// @Param	request	body report_approve.DataApproveCancelReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /cancel [post]
+func (this *DataApproveController) Cancel() {
+	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.DataApproveCancelReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.DataApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, DataApproveId: %d", req.DataApproveId)
+		return
+	}
+
+	// 撤销审批
+	msg, e := dataApproveServ.DataApproveCancel(req.DataApproveId, sysUser.AdminId, sysUser.RealName)
+	if e != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "撤销审批失败, Err: " + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// MessageList
+// @Title 审批消息列表
+// @Description 审批消息列表
+// @Param   PageSize			query	int		true	"每页数据条数"
+// @Param   CurrentIndex		query	int		true	"当前页页码"
+// @Success 200 {object} report_approve.DataApproveMessageListResp
+// @router /message/list [get]
+func (this *DataApproveController) MessageList() {
+	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
+	}
+	currentIndex, _ := this.GetInt("currentIndex")
+	pageSize, _ := this.GetInt("pageSize")
+	// 分页
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	resp := new(response.DataApproveMessageListResp)
+	resp.List = make([]*response.DataApproveMessageItem, 0)
+	list, total, unRead, msg, err := dataApproveServ.GetDataApproveMessage(sysUser.AdminId, startSize, pageSize)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批消息失败"
+		}
+		br.ErrMsg = "获取审批消息失败, Err: " + err.Error()
+		return
+	}
+	resp.List = list
+	resp.UnreadTotal = unRead
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// MessageRead
+// @Title 消息已读
+// @Description 消息已读
+// @Param	request	body report_approve.DataApproveMessageReadReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /message/read [post]
+func (this *DataApproveController) MessageRead() {
+	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.DataApproveMessageReadReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.MessageId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, MessageId: %d", req.MessageId)
+		return
+	}
+
+	msg, err := dataApproveServ.ReadBiMessage(req.MessageId, sysUser.AdminId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "消息已读失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// CheckApproveOpen
+// @Title 校验是否开启审批
+// @Description 校验是否开启审批
+// @Param	request	body report_approve.DataApproveCheckApproveOpenReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /check_open [post]
+func (this *DataApproveController) CheckApproveOpen() {
+	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.DataApproveCheckApproveOpenReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveServ.CheckOpenApprove(req.DataType)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验数据资产是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	br.Data = opening
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 126 - 0
controllers/data_manage/data_approve/data_approve_flow.go

@@ -0,0 +1,126 @@
+package data_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage/data_approve/request"
+	DataApprove "eta_gn/eta_api/services/data/data_approve"
+)
+
+type DataApproveFlowController struct {
+	controllers.BaseAuthController
+}
+
+// Save
+// @Title 保存审批流
+// @Description 保存审批流
+// @Param	request	body request.DataApproveFlowSaveReq true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/save [post]
+func (c *DataApproveFlowController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.DataApproveFlowSaveReq
+	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败, err:" + err.Error()
+		return
+	}
+	//req.FlowName = strings.TrimSpace(req.FlowName)
+	req.FlowName = `审批`
+	switch req.DataType {
+	case 1:
+		req.FlowName = "指标审批"
+	case 2:
+		req.FlowName = "图表审批"
+
+	}
+	if req.FlowName == "" {
+		br.Msg = "审批流名称不能为空"
+		return
+	}
+
+	if len([]rune(req.FlowName)) > 20 {
+		br.Msg = "审批流名称最多输入20个字符"
+		return
+	}
+	if req.DataType <= 0 {
+		br.Msg = "请选择审批类型"
+		return
+	}
+
+	ok, msg, err := DataApprove.SaveDataApproveFlow(req)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "编辑审批流失败"
+		}
+		br.ErrMsg = "编辑审批流失败, err:" + err.Error()
+		return
+	}
+	if !ok {
+		br.Msg = msg
+		return
+	}
+
+	br.Msg = "编辑审批流成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// Detail
+// @Title 审批流详情
+// @Description 审批流详情
+// @Param	request	body request.DataApproveFlowRemoveResp true "type json string"
+// @Param   DataType			query	int		false	"排序字段:1-指标审批;2-图表审批"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/detail [get]
+func (c *DataApproveFlowController) Detail() {
+	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
+	}
+	dataType, _ := c.GetInt("DataType")
+	if dataType <= 0 {
+		br.Msg = "审批流不存在"
+		return
+	}
+	detail, msg, err := DataApprove.GetDataApproveFlowDetail(dataType)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批流详情失败"
+		}
+		br.ErrMsg = "获取审批流详情失败, err:" + err.Error()
+		return
+	}
+	if detail == nil {
+		br.Msg = "审批流不存在"
+		return
+	}
+
+	br.Data = detail
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取审批流详情成功"
+}

+ 13 - 7
controllers/data_manage/edb_info_share.go

@@ -335,14 +335,14 @@ func (c *EdbInfoShareController) List() {
 	br.Data = resp
 }
 
-// EdbInfoFilterByEs
+// ListByEs
 // @Title 指标筛选接口
 // @Description 指标筛选接口
 // @Success 200 {object} data_manage.EdbInfoList
 // @Param	request	body request.SearchEdbInfoShareReq true "type json string"
 // @Success 200 {object} data_manage.EdbInfoFilterDataResp
-// @router /edb_info/share/list_by_es [post]
-func (c *EdbInfoShareController) EdbInfoFilterByEs() {
+// @router /edb_info/share/list/es [post]
+func (c *EdbInfoShareController) ListByEs() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
 		c.Data["json"] = br
@@ -469,7 +469,7 @@ func (c *EdbInfoShareController) EdbInfoFilterByEs() {
 // BatchSave
 // @Title 批量指标设置共享
 // @Description 批量指标设置共享
-// @Param	request	body request.SetEdbInfoShareReq true "type json string"
+// @Param	request	body request.SetEdbSharePermissionReq true "type json string"
 // @Success 200 {object} data_manage.EdbInfo
 // @router /edb_info/share/batch_save [post]
 func (c *EdbInfoShareController) BatchSave() {
@@ -486,7 +486,7 @@ func (c *EdbInfoShareController) BatchSave() {
 		br.Ret = 408
 		return
 	}
-	var req request.SetEdbChartPermissionReq
+	var req request.SetEdbSharePermissionReq
 	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
@@ -525,6 +525,12 @@ func (c *EdbInfoShareController) BatchSave() {
 		selectEdbInfoIdList = req.EdbIdList
 	}
 
+	if len(selectEdbInfoIdList) > 30 {
+		br.Msg = `指标数量不能超过30个`
+		br.IsSendEmail = false
+		return
+	}
+
 	// 设置
 	{
 
@@ -555,7 +561,7 @@ func (c *EdbInfoShareController) BatchSave() {
 // @param userId int
 // @return edbInfoIdList []int
 // @return err error
-func getAllEdbInfoIdListByShared(req request.SetEdbChartPermissionReq, userId int) (edbInfoIdList []int, err error) {
+func getAllEdbInfoIdListByShared(req request.SetEdbSharePermissionReq, userId int) (edbInfoIdList []int, err error) {
 	keyword := req.Keyword
 	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
 
@@ -622,7 +628,7 @@ func getAllEdbInfoIdListByShared(req request.SetEdbChartPermissionReq, userId in
 // @return err error
 func getAllEdbInfoDataByShared(keyword string, currPage, edbShare int, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
 	// 每页获取数据的数量
-	pageSize := 2
+	pageSize := 5000
 	var startSize int
 	if currPage <= 0 {
 		currPage = 1

+ 614 - 0
controllers/data_manage/edb_public.go

@@ -0,0 +1,614 @@
+package data_manage
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/data_manage/request"
+	"eta_gn/eta_api/services/data"
+	dataApproveSerice "eta_gn/eta_api/services/data/data_approve"
+	"eta_gn/eta_api/services/elastic"
+	"eta_gn/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strconv"
+	"strings"
+)
+
+// EdbPublicController 公共指标
+type EdbPublicController struct {
+	controllers.BaseAuthController
+}
+
+// RemoveCheck
+// @Title 删除检测接口
+// @Description 删除检测接口
+// @Param	request	body data_manage.ClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 检测成功
+// @router /edb_public/remove/check [post]
+func (c *EdbPublicController) RemoveCheck() {
+	// TODO
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req data_manage.ClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId < 0 && req.EdbInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+	deleteStatus, tipsMsg, tableList, err, errMsg := data.DeleteEdbPublicCheck(req.EdbInfoId, c.SysUser)
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+	if c.Lang == "en" {
+		if utils.ViperConfig.InConfig(tipsMsg) {
+			tipsMsg = utils.ViperConfig.GetString(tipsMsg)
+		}
+	}
+
+	//var deleteStatus int
+	//var tipsMsg string
+	////删除公共分类
+	//if req.ClassifyId > 0 && req.EdbInfoId == 0 {
+	//	//判断公共分类下,是否含有指标
+	//	count, err := data_manage.GetEdbInfoCountByClassifyId(req.ClassifyId)
+	//	if err != nil {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
+	//		return
+	//	}
+	//
+	//	if count > 0 {
+	//		deleteStatus = 1
+	//		tipsMsg = "若目录关联指标不可删除"
+	//	}
+	//}
+	//
+	//if deleteStatus != 1 && req.EdbInfoId == 0 {
+	//	classifyCount, err := data_manage.GetClassifyCountByClassifyId(req.ClassifyId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "公共分类下是否含有指标失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	if classifyCount > 0 {
+	//		deleteStatus = 2
+	//		tipsMsg = "确认删除当前目录及包含的子目录吗"
+	//	}
+	//}
+	//
+	////删除指标
+	//if req.EdbInfoId > 0 {
+	//	//判断指标是否用于作图,如果用于作图,则不可删除
+	//	chartCount, err := data_manage.GetChartEdbMappingCount(req.EdbInfoId)
+	//	if err != nil && !utils.IsErrNoRow(err) {
+	//		br.Msg = "删除失败"
+	//		br.ErrMsg = "判断指标是否被用于作图失败,Err:" + err.Error()
+	//		return
+	//	}
+	//	if chartCount > 0 {
+	//		deleteStatus = 3
+	//		tipsMsg = "当前指标已用作画图,不可删除"
+	//	}
+	//	//判断指标是否用于计算
+	//	{
+	//		calculateCount, err := data_manage.GetEdbInfoCalculateMappingCount(req.EdbInfoId)
+	//		if err != nil && !utils.IsErrNoRow(err) {
+	//			br.Msg = "删除失败"
+	//			br.ErrMsg = "判断指标是否被用于计算失败,GetEdbInfoCalculateCount Err:" + err.Error()
+	//			return
+	//		}
+	//		if calculateCount > 0 {
+	//			deleteStatus = 4
+	//			tipsMsg = "当前指标已用作,指标运算,不可删除"
+	//		}
+	//	}
+	//}
+
+	resp := new(data_manage.ClassifyDeleteCheckResp)
+	resp.DeleteStatus = deleteStatus
+	resp.TipsMsg = tipsMsg
+	resp.TableList = tableList
+	br.Ret = 200
+	br.Msg = "检测成功"
+	br.Success = true
+	br.Data = resp
+}
+
+// Remove
+// @Title 删除公共分类/指标
+// @Description 删除公共分类/指标接口
+// @Param	request	body data_manage.DeleteEdbClassifyReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /edb_public/remove [post]
+func (c *EdbPublicController) Remove() {
+	// TODO
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req data_manage.DeleteEdbClassifyReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.ClassifyId < 0 && req.EdbInfoId <= 0 {
+		br.Msg = "参数错误"
+		br.IsSendEmail = false
+		return
+	}
+
+	nextItem, _, err, errMsg := data.Delete(req.ClassifyId, req.EdbInfoId, sysUser, string(c.Ctx.Input.RequestBody), c.Ctx.Input.URI())
+	if errMsg != `` {
+		br.Msg = errMsg
+		br.ErrMsg = errMsg
+		if err != nil {
+			br.ErrMsg = err.Error()
+		} else {
+			br.IsSendEmail = false
+		}
+		return
+	}
+
+	resp := data_manage.AddEdbInfoResp{}
+	if nextItem != nil {
+		resp = data_manage.AddEdbInfoResp{
+			EdbInfoId:  nextItem.EdbInfoId,
+			UniqueCode: nextItem.UniqueCode,
+		}
+	}
+
+	br.Ret = 200
+	br.Msg = "删除成功"
+	br.Success = true
+	br.IsAddLog = true
+	br.Data = resp
+}
+
+// Save
+// @Title 单个指标设置公开
+// @Description 单个指标设置公开
+// @Param	request	body request.SetEdbInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfo
+// @router /edb_info/public/save [post]
+func (c *EdbPublicController) Save() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.SetEdbPublicReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if len(req.EdbInfoList) <= 0 {
+		br.Msg = `请选择指标`
+		br.IsSendEmail = false
+	}
+
+	// TODO 校验是否存在已公开的指标
+
+	// 校验是否开启了审批流
+	opening, e := dataApproveSerice.CheckOpenApprove(dataApproveSerice.DataTypeEdb)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验指标公开是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	// 是否忽略审批
+	var isIgnoreApprove bool
+	{
+		businessConf, e := models.GetBusinessConfByKey(models.IgnoreEdbApproveUserId)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取商家配置失败, Err: " + e.Error()
+			return
+		}
+		ignoreEdbApproveUserIdList := strings.Split(businessConf.ConfKey, `,`)
+		if utils.InArrayByStr(ignoreEdbApproveUserIdList, strconv.Itoa(c.SysUser.AdminId)) {
+			isIgnoreApprove = true
+		}
+	}
+
+	edbInfo, err := data_manage.GetEdbInfoById(req.EdbInfoList[0].EdbInfoId)
+	if err != nil {
+		br.Msg = "获取指标失败"
+		br.ErrMsg = "获取指标失败:" + err.Error()
+		return
+	}
+	title := edbInfo.EdbName
+	if len(req.EdbInfoList) > 1 {
+		title += `等指标`
+	}
+	title += `公开审批`
+
+	// 待处理的资产
+	dataPubliItemList := make([]dataApproveSerice.SetDataPublicItem, 0)
+	for _, item := range req.EdbInfoList {
+		dataPubliItemList = append(dataPubliItemList, dataApproveSerice.SetDataPublicItem{
+			DataId:     item.EdbInfoId,
+			ClassifyId: item.ClassifyId,
+		})
+	}
+	// 没开启审批流、或者无需审批
+	if !opening || isIgnoreApprove {
+		err = dataApproveSerice.UpdatePublicByDataList(dataApproveSerice.DataTypeEdb, dataApproveSerice.DataApproveStatePass, dataPubliItemList)
+	} else {
+
+		_, err = dataApproveSerice.SubmitDataApprove(dataApproveSerice.DataTypeEdb, dataPubliItemList, title, strings.TrimSpace(req.Description), c.SysUser.AdminId, c.SysUser.RealName)
+		if err != nil {
+			br.Msg = "提交审批失败"
+			br.ErrMsg = "提交审批失败, Err: " + err.Error()
+			return
+		}
+	}
+
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "保存成功"
+}
+
+// ListByEs
+// @Title 指标筛选接口
+// @Description 指标筛选接口
+// @Success 200 {object} data_manage.EdbInfoList
+// @Param	request	body request.SearchPublicEdbReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfoFilterDataResp
+// @router /edb_info/public/list/es [post]
+func (c *EdbPublicController) ListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.SearchPublicEdbReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	pageSize := req.PageSize
+	currentIndex := req.CurrentIndex
+
+	var total int64
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = paging.StartIndex(currentIndex, pageSize)
+
+	// 获取查询参数
+	keyword, searchEdbPublicList, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, sortMap := getSearchPar(req)
+
+	total, edbInfoList, err := elastic.SearchEdbInfoDataByPublic(keyword, startSize, pageSize, searchEdbPublicList, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, c.SysUser.AdminId, sortMap)
+	if err != nil {
+		edbInfoList = make([]*data_manage.EdbInfoList, 0)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, int(total))
+
+	edbInfoListLen := len(edbInfoList)
+
+	// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+	if len(edbInfoList) > 0 {
+		edbInfoIdList := make([]int, 0)
+		for _, v := range edbInfoList {
+			v.ConvertToResp()
+			v.EdbNameAlias = v.EdbName
+			v.HaveOperaAuth = true
+			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+		}
+
+		tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+			return
+		}
+		edbInfoMap := make(map[int]*data_manage.EdbInfo)
+		for _, v := range tmpEdbList {
+			edbInfoMap[v.EdbInfoId] = v
+		}
+
+		for _, v := range edbInfoList {
+			tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
+			if !ok {
+				continue
+			}
+			v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
+		}
+	}
+
+	for i := 0; i < edbInfoListLen; i++ {
+		for j := 0; j < edbInfoListLen; j++ {
+			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
+				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
+				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
+				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
+			}
+		}
+	}
+
+	resp := data_manage.EdbInfoFilterDataResp{
+		Paging: page,
+		List:   edbInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// AllListByEs
+// @Title 指标筛选接口
+// @Description 指标筛选接口
+// @Success 200 {object} data_manage.EdbInfoList
+// @Param	request	body request.SearchEdbInfoShareReq true "type json string"
+// @Success 200 {object} data_manage.EdbInfoFilterDataResp
+// @router /edb_info/public/list/es/all [post]
+func (c *EdbPublicController) AllListByEs() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	var req request.AllSearchPublicEdbReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	// 选择所有指标,所以需要通过es获取数据
+
+	edbInfoList := make([]*data_manage.EdbInfoList, 0)
+	tmpEdbInfoList, err := getAllEdbInfoListByPublic(req, c.SysUser.AdminId)
+
+	// 如果有过滤指标,那么就过滤吧
+	if len(req.NoEdbIdList) > 0 {
+		noEdbIdMap := make(map[int]bool)
+		for _, v := range req.NoEdbIdList {
+			noEdbIdMap[v] = true
+		}
+
+		for _, v := range tmpEdbInfoList {
+			if _, ok := noEdbIdMap[v.EdbInfoId]; !ok {
+				// 如果不在未选中的指标id列表中,那么就加入到选中的指标id列表
+				edbInfoList = append(edbInfoList, v)
+			}
+		}
+	} else {
+		edbInfoList = tmpEdbInfoList
+	}
+
+	edbInfoListLen := len(edbInfoList)
+
+	// 因为是ES查找的,所以需要重新查一下指标的信息,主要是为了把是否授权字段找出来
+	if len(edbInfoList) > 0 {
+
+		edbInfoIdList := make([]int, 0)
+		for _, v := range edbInfoList {
+			v.ConvertToResp()
+			v.EdbNameAlias = v.EdbName
+			v.HaveOperaAuth = true
+			edbInfoIdList = append(edbInfoIdList, v.EdbInfoId)
+		}
+
+		tmpEdbList, err := data_manage.GetEdbInfoByIdList(edbInfoIdList)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标失败,Err:" + err.Error()
+			return
+		}
+		edbInfoMap := make(map[int]*data_manage.EdbInfo)
+		for _, v := range tmpEdbList {
+			edbInfoMap[v.EdbInfoId] = v
+		}
+
+		for _, v := range edbInfoList {
+			tmpEdbInfo, ok := edbInfoMap[v.EdbInfoId]
+			if !ok {
+				continue
+			}
+			v.IsJoinPermission = tmpEdbInfo.IsJoinPermission
+		}
+	}
+
+	for i := 0; i < edbInfoListLen; i++ {
+		for j := 0; j < edbInfoListLen; j++ {
+			if (edbInfoList[i].EdbNameAlias == edbInfoList[j].EdbNameAlias) &&
+				(edbInfoList[i].EdbInfoId != edbInfoList[j].EdbInfoId) &&
+				!(strings.Contains(edbInfoList[i].EdbName, edbInfoList[i].SourceName)) {
+				edbInfoList[i].EdbName = edbInfoList[i].EdbName + "(" + edbInfoList[i].SourceName + ")"
+			}
+		}
+	}
+
+	resp := data_manage.EdbInfoFilterDataResp{
+		List: edbInfoList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// getSearchPar
+// @Description: 获取查询参数
+// @author: Roc
+// @datetime 2024-12-05 14:13:25
+// @param req request.SearchPublicEdbReq
+// @return keyword string
+// @return searchEdbPublicList []int
+// @return sourceList []int
+// @return classifyIdList []int
+// @return edbTypeList []int
+// @return edbInfoType int
+// @return edbAuth int
+// @return sortMap map[string]string
+func getSearchPar(req request.SearchPublicEdbReq) (keyword string, searchEdbPublicList, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth int, sortMap map[string]string) {
+	keyword = req.Keyword
+	keyword = strings.TrimSpace(keyword) //移除字符串首尾空格
+
+	//指标来源
+	sourceList = req.SourceList
+
+	// 选择的分类
+	classifyIdList = req.ClassifyIdList
+
+	// 指标公开状态:1:未公开,2:已提交;3:已公开。可多选,默认是未公开
+	edbPublicList := req.EdbPublicList
+	if len(edbPublicList) <= 0 {
+		edbPublicList = []int{1}
+	}
+
+	edbInfoType = 0        // 普通指标
+	edbTypeList = []int{2} // 普通指标中的计算指标
+	edbAuth = 1            // 选择范围是:只有我的指标
+
+	searchEdbPublicList = make([]int, 0) // 0:全部,1:未公开,2:已提交;3:已公开
+	if len(edbPublicList) > 0 && !utils.InArrayByInt(edbPublicList, 0) {
+		// 不含全部
+		for _, v := range edbPublicList {
+			switch v {
+			case 1: // 未公开
+				searchEdbPublicList = append(searchEdbPublicList, utils.EdbPublicDefault)
+			case 2: // 已提交
+				searchEdbPublicList = append(searchEdbPublicList, utils.EdbPublicCommit, utils.EdbPublicReject)
+			case 3: // 已公开
+				searchEdbPublicList = append(searchEdbPublicList, utils.EdbPublicSuccess)
+
+			}
+		}
+	} else {
+		searchEdbPublicList = []int{0, 1, 2, 3}
+	}
+
+	sortMap = make(map[string]string)
+	// 如果没有搜索关键词,则默认根据指标编码倒序排序
+	if keyword == `` {
+		sortMap["EdbInfoId"] = `desc`
+	}
+
+	return
+
+}
+
+// getAllEdbInfoListByPublic
+// @Description: 获取所有的指标列表
+// @author: Roc
+// @datetime 2024-12-04 15:43:14
+// @param req request.SetEdbChartPermissionReq
+// @param userId int
+// @return edbInfoIdList []*data_manage.EdbInfoList
+// @return err error
+func getAllEdbInfoListByPublic(req request.AllSearchPublicEdbReq, userId int) (edbInfoList []*data_manage.EdbInfoList, err error) {
+	// 获取查询参数
+	keyword, searchEdbPublicList, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, sortMap := getSearchPar(req.SearchPublicEdbReq)
+
+	_, edbInfoList, err = getAllEdbInfoDataByPublic(keyword, 1, searchEdbPublicList, sourceList, edbClassifyIdList, edbTypeList, edbInfoType, edbAuth, userId, sortMap)
+	if err != nil {
+		return
+	}
+
+	return
+}
+
+// getAllEdbInfoDataByShared
+// @Description: 获取所有的指标列表(设置公开的时候)
+// @author: Roc
+// @datetime 2024-12-04 15:27:53
+// @param keyword string
+// @param currPage int
+// @param edbShare int
+// @param sourceList []int
+// @param classifyIdList []int
+// @param edbTypeList []int
+// @param edbInfoType int
+// @param edbAuth int
+// @param sysUserId int
+// @param sortMap map[string]string
+// @return total int64
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func getAllEdbInfoDataByPublic(keyword string, currPage int, searchEdbPublicList, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
+	// 每页获取数据的数量
+	pageSize := 5000
+	var startSize int
+	if currPage <= 0 {
+		currPage = 1
+	}
+	startSize = paging.StartIndex(currPage, pageSize)
+
+	total, list, err = elastic.SearchEdbInfoDataByPublic(keyword, startSize, pageSize, searchEdbPublicList, sourceList, classifyIdList, edbTypeList, edbInfoType, edbAuth, sysUserId, sortMap)
+	if err != nil {
+		return
+	}
+
+	page := paging.GetPaging(currPage, pageSize, int(total))
+	if !page.IsEnd {
+		_, nextList, tmpErr := getAllEdbInfoDataByPublic(keyword, page.NextIndex, searchEdbPublicList, sourceList, classifyIdList, edbTypeList, edbInfoType, edbAuth, sysUserId, sortMap)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		list = append(list, nextList...)
+	}
+
+	return
+}

+ 276 - 306
controllers/data_manage/edb_public_classify.go

@@ -5,6 +5,7 @@ import (
 	"eta_gn/eta_api/controllers"
 	"eta_gn/eta_api/models"
 	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/data_manage/request"
 	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/services/data"
 	"eta_gn/eta_api/services/data/data_manage_permission"
@@ -23,11 +24,11 @@ type EdbPublicClassifyController struct {
 // @Description 单层公共分类列表
 // @Success 200 {object} data_manage.EdbClassifyListResp
 // @router /edb_public/classify/simple [get]
-func (this *EdbPublicClassifyController) SimpleList() {
+func (c *EdbPublicClassifyController) SimpleList() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 	// 公共分类来源筛选
 	// 目前只有数据加工会涉及到公共分类
@@ -36,7 +37,7 @@ func (this *EdbPublicClassifyController) SimpleList() {
 	// 默认查一级公共分类和一级公共分类下的指标信息,
 	// 如果是 子级公共分类,查询该子级公共分类的下一级公共分类和指标信息
 	// 增加标识判断是文件夹还是指标列表
-	parentId, _ := this.GetInt("ParentId")
+	parentId, _ := c.GetInt("ParentId")
 
 	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
 	rootList, err := edbPublicClassifyObj.GetEdbClassifyItemsByParentId(parentId, int8(classifyType))
@@ -69,7 +70,7 @@ func (this *EdbPublicClassifyController) SimpleList() {
 			// 查询当前公共分类信息
 			for _, v := range allEdbInfo {
 				v.HaveOperaAuth = true
-				button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+				button := data.GetEdbOpButton(c.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
 				button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 				v.Button = button
 				v.Children = make([]*data_manage.EdbClassifyItems, 0)
@@ -81,7 +82,7 @@ func (this *EdbPublicClassifyController) SimpleList() {
 	}
 	if len(rootList) > 0 {
 		// 已授权公共分类id
-		permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
+		permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
@@ -97,7 +98,7 @@ func (this *EdbPublicClassifyController) SimpleList() {
 			// 数据权限
 			v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 			// 按钮权限
-			button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+			button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 			v.Button = button
 			v.Children = make([]*data_manage.EdbClassifyItems, 0)
 			nodeAll = append(nodeAll, v)
@@ -112,7 +113,7 @@ func (this *EdbPublicClassifyController) SimpleList() {
 	language := `CN`
 	// 指标显示的语言
 	{
-		configDetail, _ := system.GetConfigDetailByCode(this.SysUser.AdminId, system.EdbLanguageVar)
+		configDetail, _ := system.GetConfigDetailByCode(c.SysUser.AdminId, system.EdbLanguageVar)
 		if configDetail != nil {
 			language = configDetail.ConfigValue
 		} else {
@@ -125,7 +126,7 @@ func (this *EdbPublicClassifyController) SimpleList() {
 
 	// 是否允许添加一级公共分类
 	canOpClassify := true
-	button := data.GetEdbClassifyOpButton(this.SysUser, 0, true)
+	button := data.GetEdbClassifyOpButton(c.SysUser, 0, true)
 	if !button.AddButton {
 		canOpClassify = false
 	}
@@ -145,11 +146,11 @@ func (this *EdbPublicClassifyController) SimpleList() {
 // @Description 多层公共分类列表树
 // @Success 200 {object} data_manage.EdbClassifyListResp
 // @router /edb_public/classify/tree [get]
-func (this *EdbPublicClassifyController) ClassifyTree() {
+func (c *EdbPublicClassifyController) ClassifyTree() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 	// 公共分类来源筛选
 	classifyType := utils.EdbClassifyTypeCalculate
@@ -168,7 +169,7 @@ func (this *EdbPublicClassifyController) ClassifyTree() {
 			// 数据权限
 			v.HaveOperaAuth = true
 			// 按钮权限
-			button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+			button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 			allList[k].Button = button
 		}
 		allList = data.GetClassifyTreeRecursive(allList, 0)
@@ -180,7 +181,7 @@ func (this *EdbPublicClassifyController) ClassifyTree() {
 
 	// 是否允许添加一级公共分类
 	canOpClassify := true
-	button := data.GetEdbClassifyOpButton(this.SysUser, 0, true)
+	button := data.GetEdbClassifyOpButton(c.SysUser, 0, true)
 	if !button.AddButton {
 		canOpClassify = false
 	}
@@ -195,208 +196,20 @@ func (this *EdbPublicClassifyController) ClassifyTree() {
 	br.Data = resp
 }
 
-// ListV2
-// @Title 公共分类列表
-// @Description 公共分类列表接口
-// @Success 200 {object} data_manage.EdbClassifyListResp
-// @router /edb_public/classify/list [get]
-func (this *EdbPublicClassifyController) ListV2() {
-	br := new(models.BaseResponse).Init()
-	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
-	}()
-	// 公共分类来源筛选
-	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
-	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
-		br.Msg = "参数有误"
-		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
-		return
-	}
-	edbType := utils.EdbTypeBase
-	if classifyType == utils.EdbClassifyTypeCalculate {
-		edbType = utils.EdbTypeCalculate
-	}
-
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
-	if err != nil && !utils.IsErrNoRow(err) {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
-		return
-	}
-	//classifyAll, err := data_manage.GetEdbClassifyAll()
-	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, this.SysUser.AdminId)
-	if err != nil && !utils.IsErrNoRow(err) {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
-		return
-	}
-	// 公共分类map
-	classifyMap := make(map[int]*data_manage.EdbClassifyItems)
-	for _, v := range classifyAll {
-		classifyMap[v.ClassifyId] = v
-	}
-
-	// 已授权公共分类id
-	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
-		return
-	}
-
-	// 获取当前账号的不可见指标
-	obj := data_manage.EdbInfoNoPermissionAdmin{}
-	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
-	if err != nil && !utils.IsErrNoRow(err) {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
-		return
-	}
-	noPermissionEdbInfoIdMap := make(map[int]bool)
-	for _, v := range confList {
-		noPermissionEdbInfoIdMap[v.EdbInfoId] = true
-	}
-	//allEdbInfo, err := data_manage.GetEdbInfoAll(utils.EDB_INFO_TYPE)
-	allEdbInfo, err := data_manage.GetEdbInfoByTypes(utils.EDB_INFO_TYPE, edbType)
-	if err != nil && !utils.IsErrNoRow(err) {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
-		return
-	}
-	edbInfoMap := make(map[int][]*data_manage.EdbClassifyItems)
-	if len(allEdbInfo) > 0 {
-		// 获取所有有权限的指标和公共分类
-		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
-		if err != nil {
-			br.Msg = "获取失败"
-			br.ErrMsg = "获取所有有权限的指标和公共分类失败,Err:" + err.Error()
-			return
-		}
-		for _, v := range allEdbInfo {
-			// 如果指标不可见,那么就不返回该指标
-			if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok {
-				continue
-			}
-			// 数据权限
-			if classifyInfo, ok := classifyMap[v.ClassifyId]; ok {
-				v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
-			}
-
-			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
-			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
-			v.Button = button
-			edbInfoMap[v.ClassifyId] = append(edbInfoMap[v.ClassifyId], v)
-		}
-	}
-	rootChildMap := make(map[int][]*data_manage.EdbClassifyItems)
-	for _, v := range classifyAll {
-		// 数据权限
-		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
-		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
-		button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
-		v.Button = button
-
-		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
-		if existItems, ok := edbInfoMap[v.ClassifyId]; ok {
-			v.Children = existItems
-		} else {
-			items := make([]*data_manage.EdbClassifyItems, 0)
-			v.Children = items
-		}
-	}
-	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
-	for _, v := range rootList {
-		// 数据权限
-		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
-		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
-		v.Button = button
-
-		if existItems, ok := rootChildMap[v.ClassifyId]; ok {
-			v.Children = existItems
-		} else {
-			items := make([]*data_manage.EdbClassifyItems, 0)
-			v.Children = items
-		}
-		nodeAll = append(nodeAll, v)
-	}
-	resp := new(data_manage.EdbClassifyListResp)
-	resp.AllNodes = nodeAll
-	resp.CanOpClassify = true
-	br.Ret = 200
-	br.Success = true
-	br.Msg = "获取成功"
-	br.Data = resp
-}
-
-// Items
-// @Title 获取所有公共分类接口-不包含指标
-// @Description 获取所有公共分类接口-不包含指标
-// @Success 200 {object} data_manage.EdbClassifyListResp
-// @router /edb_public/classify/items [get]
-func (this *EdbPublicClassifyController) Items() {
-	br := new(models.BaseResponse).Init()
-	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
-	}()
-	// 公共分类来源筛选
-	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
-	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
-		br.Msg = "参数有误"
-		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
-		return
-	}
-	//edbType := utils.EdbTypeBase
-	//if classifyType == utils.EdbClassifyTypeCalculate {
-	//	edbType = utils.EdbTypeCalculate
-	//}
-
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
-		return
-	}
-
-	//classifyAll, err := data_manage.GetEdbClassifyAll()
-	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, this.SysUser.AdminId)
-	if err != nil {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
-		return
-	}
-
-	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
-	for k := range rootList {
-		rootNode := rootList[k]
-		data.EdbClassifyItemsMakeTree(classifyAll, rootNode)
-		nodeAll = append(nodeAll, rootNode)
-	}
-	resp := new(data_manage.EdbClassifyListResp)
-	resp.AllNodes = nodeAll
-	br.Ret = 200
-	br.Success = true
-	br.Msg = "获取成功"
-	br.Data = resp
-}
-
 // AddEdbClassify
 // @Title 新增公共分类
 // @Description 新增公共分类接口
 // @Param	request	body data_manage.AddEdbClassifyReq true "type json string"
 // @Success 200 Ret=200 保存成功
 // @router /edb_public/classify/add [post]
-func (this *EdbPublicClassifyController) AddEdbClassify() {
+func (c *EdbPublicClassifyController) AddClassify() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 	var req data_manage.AddEdbClassifyReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
@@ -413,15 +226,10 @@ func (this *EdbPublicClassifyController) AddEdbClassify() {
 		return
 	}
 	// 公共分类来源筛选
-	classifyType := req.ClassifyType
-	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
-		br.Msg = "参数有误"
-		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
-		return
-	}
+	classifyType := utils.EdbClassifyTypeCalculate
 
 	//添加指标
-	_, err, errMsg := data.AddEdbClassify(req.ClassifyName, req.ParentId, req.Level, classifyType, this.SysUser.AdminId, this.SysUser.RealName, this.Lang)
+	_, err, errMsg := data.AddEdbPublicClassify(req.ClassifyName, req.ParentId, req.Level, uint8(classifyType), c.SysUser.AdminId, c.SysUser.RealName)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -453,8 +261,8 @@ func (this *EdbPublicClassifyController) AddEdbClassify() {
 	//classify.HasData = 0
 	//classify.CreateTime = time.Now()
 	//classify.ModifyTime = time.Now()
-	//classify.SysUserId = this.SysUser.AdminId
-	//classify.SysUserRealName = this.SysUser.RealName
+	//classify.SysUserId = c.SysUser.AdminId
+	//classify.SysUserRealName = c.SysUser.RealName
 	//classify.Level = req.Level + 1
 	//timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
 	//classify.UniqueCode = utils.MD5(utils.DATA_PREFIX + "_" + timestamp)
@@ -467,7 +275,7 @@ func (this *EdbPublicClassifyController) AddEdbClassify() {
 	//	return
 	//}
 	br.Ret = 200
-	br.Msg = "保存成功"
+	br.Msg = "新增成功"
 	br.Success = true
 	br.IsAddLog = true
 }
@@ -478,14 +286,14 @@ func (this *EdbPublicClassifyController) AddEdbClassify() {
 // @Param	request	body data_manage.EditEdbClassifyReq true "type json string"
 // @Success 200 Ret=200 修改成功
 // @router /edb_public/classify/edit [post]
-func (this *EdbPublicClassifyController) EditEdbClassify() {
+func (c *EdbPublicClassifyController) EditEdbClassify() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 	var req data_manage.EditEdbClassifyReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
@@ -503,7 +311,7 @@ func (this *EdbPublicClassifyController) EditEdbClassify() {
 		return
 	}
 
-	err, errMsg := data.EditEdbClassify(req.ClassifyId, req.ClassifyName, this.Lang, this.SysUser)
+	err, errMsg := data.EditEdbPublicClassify(req.ClassifyId, req.ClassifyName, c.SysUser)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -514,35 +322,8 @@ func (this *EdbPublicClassifyController) EditEdbClassify() {
 		}
 		return
 	}
-	//item, err := data_manage.GetEdbClassifyById(req.ClassifyId)
-	//if err != nil {
-	//	br.Msg = "保存失败"
-	//	br.Msg = "获取公共分类信息失败,Err:" + err.Error()
-	//	return
-	//}
-	//
-	//if item.ClassifyName != req.ClassifyName {
-	//	count, err := data_manage.GetEdbClassifyCount(req.ClassifyName, item.ParentId)
-	//	if err != nil {
-	//		br.Msg = "判断名称是否已存在失败"
-	//		br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
-	//		return
-	//	}
-	//	if count > 0 {
-	//		br.Msg = "公共分类名称已存在,请重新输入"
-	//		br.IsSendEmail = false
-	//		return
-	//	}
-	//
-	//	err = data_manage.EditEdbClassify(req.ClassifyId, req.ClassifyName)
-	//	if err != nil {
-	//		br.Msg = "保存失败"
-	//		br.ErrMsg = "保存失败,Err:" + err.Error()
-	//		return
-	//	}
-	//}
 	br.Ret = 200
-	br.Msg = "保存成功"
+	br.Msg = "修改成功"
 	br.Success = true
 	br.IsAddLog = true
 }
@@ -550,29 +331,30 @@ func (this *EdbPublicClassifyController) EditEdbClassify() {
 // DeleteEdbClassifyCheck
 // @Title 删除检测接口
 // @Description 删除检测接口
-// @Param	request	body data_manage.ClassifyDeleteCheckReq true "type json string"
+// @Param	request	body request.PublicClassifyDeleteCheckReq true "type json string"
 // @Success 200 Ret=200 检测成功
 // @router /edb_public/classify/delete/check [post]
-func (this *EdbPublicClassifyController) DeleteEdbClassifyCheck() {
+func (c *EdbPublicClassifyController) DeleteClassifyCheck() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
-	var req data_manage.ClassifyDeleteCheckReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+
+	var req request.PublicClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
 
-	if req.ClassifyId < 0 && req.EdbInfoId <= 0 {
+	if req.ClassifyId < 0 {
 		br.Msg = "参数错误"
 		br.IsSendEmail = false
 		return
 	}
-	deleteStatus, tipsMsg, tableList, err, errMsg := data.DeleteCheck(req.ClassifyId, req.EdbInfoId, this.SysUser)
+	deleteStatus, tipsMsg, _, tableList, err, errMsg := data.DeleteEdbPublicClassifyCheck(req.ClassifyId, c.SysUser)
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -583,7 +365,7 @@ func (this *EdbPublicClassifyController) DeleteEdbClassifyCheck() {
 		}
 		return
 	}
-	if this.Lang == "en" {
+	if c.Lang == "en" {
 		if utils.ViperConfig.InConfig(tipsMsg) {
 			tipsMsg = utils.ViperConfig.GetString(tipsMsg)
 		}
@@ -661,37 +443,37 @@ func (this *EdbPublicClassifyController) DeleteEdbClassifyCheck() {
 // DeleteEdbClassify
 // @Title 删除公共分类/指标
 // @Description 删除公共分类/指标接口
-// @Param	request	body data_manage.DeleteEdbClassifyReq true "type json string"
-// @Success 200 Ret=200 新增成功
+// @Param	request	body request.PublicClassifyDeleteCheckReq true "type json string"
+// @Success 200 Ret=200 删除成功
 // @router /edb_public/classify/delete [post]
-func (this *EdbPublicClassifyController) DeleteEdbClassify() {
+func (c *EdbPublicClassifyController) DeleteClassify() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
-	sysUser := this.SysUser
+	sysUser := c.SysUser
 	if sysUser == nil {
 		br.Msg = "请登录"
 		br.ErrMsg = "请登录,SysUser Is Empty"
 		br.Ret = 408
 		return
 	}
-	var req data_manage.DeleteEdbClassifyReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	var req request.PublicClassifyDeleteCheckReq
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
 
-	if req.ClassifyId < 0 && req.EdbInfoId <= 0 {
+	if req.ClassifyId < 0 {
 		br.Msg = "参数错误"
 		br.IsSendEmail = false
 		return
 	}
 
-	nextItem, _, err, errMsg := data.Delete(req.ClassifyId, req.EdbInfoId, sysUser, string(this.Ctx.Input.RequestBody), this.Ctx.Input.URI())
+	nextItem, _, err, errMsg := data.DeleteEdbPublicClassify(req.ClassifyId, sysUser, string(c.Ctx.Input.RequestBody), c.Ctx.Input.URI())
 	if errMsg != `` {
 		br.Msg = errMsg
 		br.ErrMsg = errMsg
@@ -718,19 +500,207 @@ func (this *EdbPublicClassifyController) DeleteEdbClassify() {
 	br.Data = resp
 }
 
+// ListV2
+// @Title 公共分类列表
+// @Description 公共分类列表接口
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/list [get]
+func (c *EdbPublicClassifyController) ListV2() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	classifyType, _ := c.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	edbType := utils.EdbTypeBase
+	if classifyType == utils.EdbClassifyTypeCalculate {
+		edbType = utils.EdbTypeCalculate
+	}
+
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), c.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	//classifyAll, err := data_manage.GetEdbClassifyAll()
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, c.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	// 公共分类map
+	classifyMap := make(map[int]*data_manage.EdbClassifyItems)
+	for _, v := range classifyAll {
+		classifyMap[v.ClassifyId] = v
+	}
+
+	// 已授权公共分类id
+	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
+		return
+	}
+
+	// 获取当前账号的不可见指标
+	obj := data_manage.EdbInfoNoPermissionAdmin{}
+	confList, err := obj.GetAllListByAdminId(c.SysUser.AdminId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
+		return
+	}
+	noPermissionEdbInfoIdMap := make(map[int]bool)
+	for _, v := range confList {
+		noPermissionEdbInfoIdMap[v.EdbInfoId] = true
+	}
+	//allEdbInfo, err := data_manage.GetEdbInfoAll(utils.EDB_INFO_TYPE)
+	allEdbInfo, err := data_manage.GetEdbInfoByTypes(utils.EDB_INFO_TYPE, edbType)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+	edbInfoMap := make(map[int][]*data_manage.EdbClassifyItems)
+	if len(allEdbInfo) > 0 {
+		// 获取所有有权限的指标和公共分类
+		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(c.SysUser.AdminId, 0, 0)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取所有有权限的指标和公共分类失败,Err:" + err.Error()
+			return
+		}
+		for _, v := range allEdbInfo {
+			// 如果指标不可见,那么就不返回该指标
+			if _, ok := noPermissionEdbInfoIdMap[v.EdbInfoId]; ok {
+				continue
+			}
+			// 数据权限
+			if classifyInfo, ok := classifyMap[v.ClassifyId]; ok {
+				v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
+			}
+
+			button := data.GetEdbOpButton(c.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+			v.Button = button
+			edbInfoMap[v.ClassifyId] = append(edbInfoMap[v.ClassifyId], v)
+		}
+	}
+	rootChildMap := make(map[int][]*data_manage.EdbClassifyItems)
+	for _, v := range classifyAll {
+		// 数据权限
+		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+		// 按钮权限
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
+		v.Button = button
+
+		rootChildMap[v.ParentId] = append(rootChildMap[v.ParentId], v)
+		if existItems, ok := edbInfoMap[v.ClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.EdbClassifyItems, 0)
+			v.Children = items
+		}
+	}
+	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
+	for _, v := range rootList {
+		// 数据权限
+		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
+		// 按钮权限
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
+		v.Button = button
+
+		if existItems, ok := rootChildMap[v.ClassifyId]; ok {
+			v.Children = existItems
+		} else {
+			items := make([]*data_manage.EdbClassifyItems, 0)
+			v.Children = items
+		}
+		nodeAll = append(nodeAll, v)
+	}
+	resp := new(data_manage.EdbClassifyListResp)
+	resp.AllNodes = nodeAll
+	resp.CanOpClassify = true
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Items
+// @Title 获取所有公共分类接口-不包含指标
+// @Description 获取所有公共分类接口-不包含指标
+// @Success 200 {object} data_manage.EdbClassifyListResp
+// @router /edb_public/classify/items [get]
+func (c *EdbPublicClassifyController) Items() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	// 公共分类来源筛选
+	classifyType, _ := c.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
+		return
+	}
+	//edbType := utils.EdbTypeBase
+	//if classifyType == utils.EdbClassifyTypeCalculate {
+	//	edbType = utils.EdbTypeCalculate
+	//}
+
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), c.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	//classifyAll, err := data_manage.GetEdbClassifyAll()
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, c.SysUser.AdminId)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取数据失败,Err:" + err.Error()
+		return
+	}
+
+	nodeAll := make([]*data_manage.EdbClassifyItems, 0)
+	for k := range rootList {
+		rootNode := rootList[k]
+		data.EdbClassifyItemsMakeTree(classifyAll, rootNode)
+		nodeAll = append(nodeAll, rootNode)
+	}
+	resp := new(data_manage.EdbClassifyListResp)
+	resp.AllNodes = nodeAll
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
 // EdbClassifyMove
 // @Title 公共分类移动接口
 // @Description 公共分类移动接口
 // @Success 200 {object} data_manage.MoveEdbClassifyReq
 // @router /edb_classify/move [post]
-func (this *EdbPublicClassifyController) EdbClassifyMove() {
+func (c *EdbPublicClassifyController) EdbClassifyMove() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 
-	sysUser := this.SysUser
+	sysUser := c.SysUser
 	if sysUser == nil {
 		br.Msg = "请登录"
 		br.ErrMsg = "请登录,SysUser Is Empty"
@@ -739,7 +709,7 @@ func (this *EdbPublicClassifyController) EdbClassifyMove() {
 	}
 
 	var req data_manage.MoveEdbClassifyReq
-	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	err := json.Unmarshal(c.Ctx.Input.RequestBody, &req)
 	if err != nil {
 		br.Msg = "参数解析异常!"
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
@@ -868,14 +838,14 @@ func (this *EdbPublicClassifyController) EdbClassifyMove() {
 // @Description 公共分类列表接口
 // @Success 200 {object} data_manage.EdbClassifyListResp
 // @router /edb_public/classify/items/v2 [get]
-func (this *EdbPublicClassifyController) ItemsV2() {
+func (c *EdbPublicClassifyController) ItemsV2() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 	// 公共分类来源筛选
-	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	classifyType, _ := c.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
 	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
 		br.Msg = "参数有误"
 		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
@@ -886,21 +856,21 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 	//	edbType = utils.EdbTypeCalculate
 	//}
 
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), c.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	//classifyAll, err := data_manage.GetEdbClassifyAll()
-	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, this.SysUser.AdminId)
+	classifyAll, err := data_manage.GetChildEdbClassifyByClassifyType(classifyType, c.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
 	// 已授权公共分类id
-	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
+	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
@@ -914,7 +884,7 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 	//}
 	//edbInfoMap := make(map[int][]*data_manage.EdbClassifyItems)
 	//for _, v := range allEdbInfo {
-	//	button := data.GetEdbOpButton(this.SysUser, v.SysUserId)
+	//	button := data.GetEdbOpButton(c.SysUser, v.SysUserId)
 	//	button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 	//	v.Button = button
 	//	edbInfoMap[v.ClassifyId] = append(edbInfoMap[v.ClassifyId], v)
@@ -924,7 +894,7 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 		// 数据权限
 		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 		button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 		v.Button = button
 
@@ -941,7 +911,7 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 		// 数据权限
 		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 		v.Button = button
 
 		if existItems, ok := rootChildMap[v.ClassifyId]; ok {
@@ -955,7 +925,7 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 	language := `CN`
 	// 指标显示的语言
 	{
-		configDetail, _ := system.GetConfigDetailByCode(this.SysUser.AdminId, system.EdbLanguageVar)
+		configDetail, _ := system.GetConfigDetailByCode(c.SysUser.AdminId, system.EdbLanguageVar)
 		if configDetail != nil {
 			language = configDetail.ConfigValue
 		} else {
@@ -968,7 +938,7 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 
 	// 是否允许添加一级公共分类
 	canOpClassify := true
-	//button := data.GetEdbClassifyOpButton(this.SysUser, 0)
+	//button := data.GetEdbClassifyOpButton(c.SysUser, 0)
 	//if !button.AddButton {
 	//	canOpClassify = false
 	//}
@@ -991,14 +961,14 @@ func (this *EdbPublicClassifyController) ItemsV2() {
 // @Param   ClassifyId   query   int  true       "公共分类id"
 // @Success 200 {object} data_manage.EdbClassifyListResp
 // @router /edb_public/classify/edb_info/list [get]
-func (this *EdbPublicClassifyController) ClassifyEdbInfoList() {
+func (c *EdbPublicClassifyController) ClassifyEdbInfoList() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 
-	classifyId, _ := this.GetInt("ClassifyId")
+	classifyId, _ := c.GetInt("ClassifyId")
 	if classifyId <= 0 {
 		br.Msg = "参数错误,请刷新页面"
 		return
@@ -1013,7 +983,7 @@ func (this *EdbPublicClassifyController) ClassifyEdbInfoList() {
 
 	// 获取当前账号的不可见指标
 	obj := data_manage.EdbInfoNoPermissionAdmin{}
-	confList, err := obj.GetAllListByAdminId(this.SysUser.AdminId)
+	confList, err := obj.GetAllListByAdminId(c.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
@@ -1033,7 +1003,7 @@ func (this *EdbPublicClassifyController) ClassifyEdbInfoList() {
 		edbType = 2
 	}
 	// 无权限指标 和 无权限指标公共分类id
-	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionList(this.SysUser.AdminId, utils.EDB_INFO_TYPE, edbType)
+	noPermissionEdbInfoIdList, noPermissionEdbClassifyIdList, err := data_manage_permission.GetUserAllEdbAndClassifyNoPermissionList(c.SysUser.AdminId, utils.EDB_INFO_TYPE, edbType)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取不可见指标配置数据失败,Err:" + err.Error()
@@ -1051,7 +1021,7 @@ func (this *EdbPublicClassifyController) ClassifyEdbInfoList() {
 
 	if len(allEdbInfo) > 0 {
 		// 获取所有有权限的指标和公共分类
-		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(this.SysUser.AdminId, 0, 0)
+		permissionEdbIdList, permissionClassifyIdList, err := data_manage_permission.GetUserEdbAndClassifyPermissionList(c.SysUser.AdminId, 0, 0)
 		if err != nil {
 			br.Msg = "获取失败"
 			br.ErrMsg = "获取所有有权限的指标和公共分类失败,Err:" + err.Error()
@@ -1063,7 +1033,7 @@ func (this *EdbPublicClassifyController) ClassifyEdbInfoList() {
 				continue
 			}
 			v.HaveOperaAuth = data_manage_permission.CheckEdbPermissionByPermissionIdList(v.IsJoinPermission, classifyInfo.IsJoinPermission, v.EdbInfoId, v.ClassifyId, permissionEdbIdList, permissionClassifyIdList)
-			button := data.GetEdbOpButton(this.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
+			button := data.GetEdbOpButton(c.SysUser, v.SysUserId, v.EdbType, utils.EDB_INFO_TYPE, v.HaveOperaAuth)
 			button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 			v.Button = button
 
@@ -1084,14 +1054,14 @@ func (this *EdbPublicClassifyController) ClassifyEdbInfoList() {
 // @Description 公共分类列表接口
 // @Success 200 {object} data_manage.EdbClassifyListResp
 // @router /edb_public/classify/items/v3 [get]
-func (this *EdbPublicClassifyController) ItemsV3() {
+func (c *EdbPublicClassifyController) ItemsV3() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
-		this.Data["json"] = br
-		this.ServeJSON()
+		c.Data["json"] = br
+		c.ServeJSON()
 	}()
 	// 公共分类来源筛选
-	classifyType, _ := this.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
+	classifyType, _ := c.GetInt("ClassifyType", utils.EdbClassifyTypeBase) // 默认指标库的
 	if classifyType != utils.EdbClassifyTypeBase && classifyType != utils.EdbClassifyTypeCalculate {
 		br.Msg = "参数有误"
 		br.ErrMsg = fmt.Sprintf("指标公共分类类型有误, ClassifyType: %d", classifyType)
@@ -1103,7 +1073,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 	//}
 
 	// TODO:9级改造
-	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), this.SysUser.AdminId)
+	rootList, err := data_manage.GetEdbClassifyByParentId(0, int8(classifyType), c.SysUser.AdminId)
 	if err != nil && !utils.IsErrNoRow(err) {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
@@ -1122,7 +1092,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 		return
 	}
 	// 已授权公共分类id
-	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(this.SysUser.AdminId, 0)
+	permissionClassifyIdList, err := data_manage_permission.GetUserEdbClassifyPermissionList(c.SysUser.AdminId, 0)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取已授权公共分类id数据失败,Err:" + err.Error()
@@ -1134,7 +1104,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 		// 数据权限
 		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 		v.Button = button
 
 		rootTwoMap[v.ParentId] = append(rootTwoMap[v.ParentId], v)
@@ -1144,7 +1114,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 		// 数据权限
 		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 		v.Button = button
 		if v.Level == 3 {
 			rootTwoChildMap[v.ParentId] = append(rootTwoChildMap[v.ParentId], v)
@@ -1156,7 +1126,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 		// 数据权限
 		v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 		// 按钮权限
-		button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+		button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 		v.Button = button
 
 		if existItems, ok := rootTwoMap[v.ClassifyId]; ok {
@@ -1165,7 +1135,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 				// 数据权限
 				v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 				// 按钮权限
-				button := data.GetEdbClassifyOpButton(this.SysUser, item.SysUserId, v.HaveOperaAuth)
+				button := data.GetEdbClassifyOpButton(c.SysUser, item.SysUserId, v.HaveOperaAuth)
 				item.Button = button
 
 				if existItems, ok := rootTwoChildMap[item.ClassifyId]; ok {
@@ -1173,7 +1143,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 						// 数据权限
 						v.HaveOperaAuth = data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(v.IsJoinPermission, v.ClassifyId, permissionClassifyIdList)
 						// 按钮权限
-						button := data.GetEdbClassifyOpButton(this.SysUser, v.SysUserId, v.HaveOperaAuth)
+						button := data.GetEdbClassifyOpButton(c.SysUser, v.SysUserId, v.HaveOperaAuth)
 						button.AddButton = false //不管有没有权限,指标都是没有添加按钮的
 						existItem.Button = button
 					}
@@ -1192,7 +1162,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 	language := `CN`
 	// 指标显示的语言
 	{
-		configDetail, _ := system.GetConfigDetailByCode(this.SysUser.AdminId, system.EdbLanguageVar)
+		configDetail, _ := system.GetConfigDetailByCode(c.SysUser.AdminId, system.EdbLanguageVar)
 		if configDetail != nil {
 			language = configDetail.ConfigValue
 		} else {
@@ -1205,7 +1175,7 @@ func (this *EdbPublicClassifyController) ItemsV3() {
 
 	// 是否允许添加一级公共分类
 	canOpClassify := true
-	button := data.GetEdbClassifyOpButton(this.SysUser, 0, true)
+	button := data.GetEdbClassifyOpButton(c.SysUser, 0, true)
 	if !button.AddButton {
 		canOpClassify = false
 	}

+ 5 - 1
controllers/fix.go

@@ -26,6 +26,10 @@ func init() {
 	//// ### 2.2 衍生指标
 	//initFixSelfClassify(utils.EdbClassifyTypePredict)
 	//
+
+	// ### 3、修复ES数据
+	//initEs()
+
 	//fmt.Println("修复完成")
 }
 
@@ -353,7 +357,7 @@ func initEs() {
 	// 更新ES中的指标数据
 	data.AddOrEditAllEdbInfoToEs()
 	// 更新es中的图表数据
-	data.AddAllChartInfo()
+	//data.AddAllChartInfo()
 
 	fmt.Println("全部es数据修复完成")
 }

+ 3 - 0
models/business_conf.go

@@ -56,6 +56,9 @@ const (
 
 	BusinessConfEdbStopRefreshRule = "EdbStopRefreshRule" // 是否停止指标刷新规则
 	BusinessConfOuterReportApiUrl  = "OuterReportApiUrl"  // 智力共享-报告API地址
+
+	IgnoreEdbApproveUserId   = `IgnoreEdbApproveUserId`   // 忽略指标审批用户id集合
+	IgnoreChartApproveUserId = `IgnoreChartApproveUserId` //忽略图表审批用户id集合
 )
 
 const (

+ 223 - 0
models/data_manage/data_approve/data_approve.go

@@ -0,0 +1,223 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+type DataApprove struct {
+	DataApproveId int       `gorm:"column:data_approve_id;primary_key"`
+	Title         string    `gorm:"column:title"`
+	DataType      int       `gorm:"column:data_type"`
+	State         int       `gorm:"column:state"` //  '审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回'
+	FlowId        int       `gorm:"column:flow_id"`
+	FlowVersion   int       `gorm:"column:flow_version"`
+	StartNodeId   int       `gorm:"column:start_node_id"`
+	CurrNodeId    int       `gorm:"column:curr_node_id"`
+	ApplyUserId   int       `gorm:"column:apply_user_id"`
+	ApplyUserName string    `gorm:"column:apply_user_name"`
+	ApproveRemark string    `gorm:"column:approve_remark"`
+	ApproveTime   time.Time `gorm:"column:approve_time"`
+	CreateTime    time.Time `gorm:"column:create_time"`
+	ModifyTime    time.Time `gorm:"column:update_time"`
+}
+
+var DataApproveCols = struct {
+	DataApproveId string
+	Title         string
+	DataType      string // 资产类型:1:指标、2:图表
+	State         string //  '审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回'
+	FlowId        string
+	FlowVersion   string
+	StartNodeId   string
+	CurrNodeId    string
+	ApplyUserId   string
+	ApplyUserName string
+	ApproveRemark string
+	ApproveTime   string
+	CreateTime    string
+	ModifyTime    string
+}{
+	DataApproveId: "data_approve_id",
+	Title:         "title",
+	DataType:      "data_type",
+	State:         "state",
+	FlowId:        "flow_id",
+	FlowVersion:   "flow_version",
+	StartNodeId:   "start_node_id",
+	CurrNodeId:    "curr_node_id",
+	ApplyUserId:   "apply_user_id",
+	ApplyUserName: "apply_user_name",
+	ApproveRemark: "approve_remark",
+	ApproveTime:   "approve_time",
+	CreateTime:    "create_time",
+	ModifyTime:    "modify_time",
+}
+
+type DataApproveItemOrm struct {
+	DataApproveId       int       `description:"审批ID"`
+	DataApproveRecordId int       `description:"审批记录ID"`
+	Title               string    `description:"审批标题"`
+	DataType            int       `description:"资产类型"`
+	State               int       `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	RecordState         int       `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
+	FlowId              int       `description:"审批流ID"`
+	FlowVersion         int       `description:"审批流版本"`
+	StartNodeId         int       `description:"开始节点ID"`
+	CurrNodeId          int       `description:"当前节点ID"`
+	ApplyUserId         int       `description:"申请人ID"`
+	ApplyUserName       string    `description:"申请人姓名"`
+	ApproveRemark       string    `description:"审批备注"`
+	ApproveTime         time.Time `description:"审批时间"`
+	HandleTime          time.Time `description:"处理时间"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"修改时间"`
+	NodeState           int       `description:"当前节点审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回" json:"-"`
+	NodeApproveTime     time.Time `description:"当前节点审批时间" json:"-"`
+}
+
+func (b *DataApprove) TableName() string {
+	return "data_approve"
+}
+
+func (b *DataApprove) Update(cols []string) (err error) {
+	db := global.DmSQL["data"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *DataApprove) Create() (err error) {
+	db := global.DmSQL["data"]
+	err = db.Create(b).Error
+	return
+}
+
+// AddDataApprove
+// @Description: 添加审批单
+// @author: Roc
+// @datetime 2024-12-06 09:46:04
+// @param dataApprove *DataApprove
+// @param relationList []*DataApproveRelation
+// @return err error
+func AddDataApprove(dataApprove *DataApprove, relationList []*DataApproveRelation) (err error) {
+	db := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			db.Rollback()
+		} else {
+			db.Commit()
+		}
+	}()
+
+	err = db.Create(dataApprove).Error
+	if err != nil {
+		return
+	}
+
+	if len(relationList) > 0 {
+		for _, v := range relationList {
+			v.DataApproveId = dataApprove.DataApproveId
+		}
+		err = db.CreateInBatches(relationList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+func GetDataApproveByFlowIdAndVersionId(dataFlowId int, flowVersion int) (item []*DataApprove, err error) {
+	db := global.DmSQL["data"]
+	err = db.Where("flow_id = ? AND flow_version = ?", dataFlowId, flowVersion).Find(&item).Error
+	return
+}
+
+func GetDataApproveById(DataApproveId int) (item *DataApprove, err error) {
+	db := global.DmSQL["data"]
+	err = db.Where("data_approve_id = ?", DataApproveId).First(&item).Error
+	return
+}
+
+// GetApprovingDataApproveCount 获取待处理的审批分页列表总数
+func GetApprovingDataApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.data_approve_record_id
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id AND a.node_id = b.curr_node_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovingDataApprovePageList 获取待处理的审批列表-分页
+func GetApprovingDataApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*DataApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.data_approve_record_id, a.state AS record_state, b.*
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id AND a.node_id = b.curr_node_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApprovedDataApproveCount 获取已处理的审批分页列表总数
+func GetApprovedDataApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.data_approve_record_id
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovedDataApprovePageList 获取已处理的审批列表-分页
+func GetApprovedDataApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*DataApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.data_approve_record_id, a.node_state AS record_state,a.node_state,a.node_approve_time, a.node_approve_time AS handle_time, b.*
+		FROM data_approve_record AS a
+		JOIN data_approve AS b ON a.data_approve_id = b.data_approve_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApplyDataApproveCount 获取我发起的审批分页列表总数
+func GetApplyDataApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.* FROM data_approve AS a WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApplyDataApprovePageList 获取我发起的审批列表-分页
+func GetApplyDataApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*DataApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.* FROM data_approve AS a WHERE 1 = 1 %s %s LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func GetDataApproveCountByState(state int) (count int, err error) {
+	db := global.DmSQL["data"]
+	sql := `SELECT COUNT(*) FROM data_approve WHERE state = ?`
+	err = db.Raw(sql, state).Scan(&count).Error
+	return
+}

+ 198 - 0
models/data_manage/data_approve/data_approve_flow.go

@@ -0,0 +1,198 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"time"
+)
+
+type DataApproveFlow struct {
+	DataApproveFlowId int       `gorm:"column:data_approve_flow_id;primaryKey"`
+	FlowName          string    `gorm:"column:flow_name"`
+	DataType          int       `gorm:"column:data_type"`
+	Remark            string    `gorm:"column:remark"`
+	CurrVersion       int       `gorm:"column:curr_version"`
+	CreateTime        time.Time `gorm:"column:create_time"`
+	ModifyTime        time.Time `gorm:"column:modify_time"`
+}
+
+var DataApproveFlowCols = struct {
+	DataApproveFlowId string
+	FlowName          string
+	DataType          string // 资产类型:1:指标、2:图表
+	CurrVersion       string
+	CreateTime        string
+	ModifyTime        string
+}{
+	DataApproveFlowId: "data_approve_flow_id",
+	FlowName:          "flow_name",
+	DataType:          "data_type",
+	CurrVersion:       "curr_version",
+	CreateTime:        "create_time",
+	ModifyTime:        "modify_time",
+}
+
+func (b *DataApproveFlow) TableName() string {
+	return "data_approve_flow"
+}
+
+func (b *DataApproveFlow) Add(node []*DataApproveNode) (err error) {
+	prevNodes := make([]*DataApproveNode, 0)
+	o := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+
+		// 更新每个节点的下一个节点信息, 放在事务中会更新失败
+		if e := UpdateNextNodes(prevNodes); e != nil {
+			err = fmt.Errorf("UpdatePrevNodes err: %s", e.Error())
+			return
+		}
+	}()
+
+	err = o.Create(b).Error
+	if err != nil {
+		err = fmt.Errorf("insert approve err: %v", err)
+		return
+	}
+
+	nodesLen := len(node)
+	if nodesLen == 0 {
+		return
+	}
+	prevId := 0
+	prevNode := new(DataApproveNode)
+	for k, v := range node {
+		v.DataApproveFlowId = b.DataApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.DataApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.DataApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	return
+}
+
+func (b *DataApproveFlow) Update(cols []string, node []*DataApproveNode) (err error) {
+	prevNodes := make([]*DataApproveNode, 0)
+	o := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			o.Rollback()
+		} else {
+			o.Commit()
+		}
+
+		// 更新每个节点的下一个节点信息, 放在事务中会更新失败
+		if e := UpdateNextNodes(prevNodes); e != nil {
+			err = fmt.Errorf("UpdatePrevNodes err: %s", e.Error())
+			return
+		}
+	}()
+	err = o.Model(b).Select(cols).Updates(b).Error
+	if err != nil {
+		return
+	}
+
+	nodesLen := len(node)
+	if nodesLen == 0 {
+		return
+	}
+	prevId := 0
+	prevNode := new(DataApproveNode)
+	for k, v := range node {
+		v.DataApproveFlowId = b.DataApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.DataApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.DataApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	
+	return
+}
+
+func (b *DataApproveFlow) Delete() error {
+	return global.DmSQL["data"].Delete(b).Error
+}
+
+func (m *DataApproveFlow) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *DataApproveFlow, err error) {
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s `, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).First(&item).Error
+	return
+}
+
+func GetDataApproveFlowById(DataApproveFlowId int) (item *DataApproveFlow, err error) {
+	err = global.DmSQL["data"].Where("data_approve_flow_id = ?", DataApproveFlowId).First(&item).Error
+	return
+}
+
+// GetDataApproveFlowByDataType
+// @Description: 根据数据类型获取审核流
+// @author: Roc
+// @datetime 2024-12-05 16:06:52
+// @param dataType int
+// @return item *DataApproveFlow
+// @return err error
+func GetDataApproveFlowByDataType(dataType int) (item *DataApproveFlow, err error) {
+	err = global.DmSQL["data"].Where("data_type = ?", dataType).First(&item).Error
+	return
+}
+
+func GetDataApproveFlowByClassifyId(classifyId int) (item *DataApproveFlow, err error) {
+	err = global.DmSQL["data"].Where("classify_id = ?", classifyId).First(&item).Error
+	return
+}
+
+func GetDataApproveFlowByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*DataApproveFlow, err error) {
+	o := global.DmSQL["data"]
+	sql := "SELECT * FROM data_approve_flow WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	sql += " LIMIT ?,?"
+	pars = append(pars, startSize, pageSize)
+	err = o.Raw(sql, pars...).Scan(&items).Error
+	return
+}
+
+func GetDataApproveFlowCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := global.DmSQL["data"]
+	sql := "SELECT COUNT(*) AS count FROM data_approve_flow WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func UpdateFlowClassifyName(classifyId int, classifyName string) (err error) {
+	o := global.DmSQL["data"]
+	err = o.Model(&DataApproveFlow{}).Where("classify_id = ?", classifyId).Update("classify_name", classifyName).Error
+	return
+}

+ 115 - 0
models/data_manage/data_approve/data_approve_message.go

@@ -0,0 +1,115 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type DataApproveMessage struct {
+	Id            int       `gorm:"primaryKey;column:id"`
+	SendUserId    int       `gorm:"column:send_user_id"`    // 发送人Id
+	ReceiveUserId int       `gorm:"column:receive_user_id"` // 接收者Id
+	Content       string    `gorm:"column:content"`         // 消息内容
+	Remark        string    `gorm:"column:remark"`          // 备注信息
+	DataApproveId int       `gorm:"column:data_approve_id"` // 审批Id
+	ApproveState  int       `gorm:"column:approve_state"`   // 审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回
+	IsRead        int       `gorm:"column:is_read"`         // 是否已读:0-未读;1-已读
+	CreateTime    time.Time `gorm:"column:create_time"`     // 创建时间
+	ModifyTime    time.Time `gorm:"column:modify_time"`     // 修改时间
+}
+
+var DataApproveMessageCols = struct {
+	Id            string
+	SendUserId    string
+	ReceiveUserId string
+	Content       string
+	Remark        string
+	DataApproveId string
+	ApproveState  string
+	IsRead        string
+	CreateTime    string
+	ModifyTime    string
+}{
+	Id:            "id",
+	SendUserId:    "send_user_id",
+	ReceiveUserId: "receive_user_id",
+	Content:       "content",
+	Remark:        "remark",
+	DataApproveId: "data_approve_id",
+	ApproveState:  "approve_state",
+	IsRead:        "is_read",
+	CreateTime:    "create_time",
+	ModifyTime:    "modify_time",
+}
+
+func (r *DataApproveMessage) TableName() string {
+	return "data_approve_message"
+}
+
+func (r *DataApproveMessage) Create() (err error) {
+	o := global.DmSQL["data"]
+	err = o.Create(r).Error
+	return err
+}
+
+func (m *DataApproveMessage) PrimaryId() string {
+	return DataApproveMessageCols.Id
+}
+
+func (r *DataApproveMessage) CreateMulti(items []*DataApproveMessage) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := global.DmSQL["data"]
+	err = o.CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *DataApproveMessage) GetCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
+	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func (m *DataApproveMessage) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*DataApproveMessage, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *DataApproveMessage) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*DataApproveMessage, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *DataApproveMessage) GetItemById(id int) (item *DataApproveMessage, err error) {
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? `, m.TableName(), m.PrimaryId())
+	err = global.DmSQL["data"].Raw(sql, id).First(&item).Error
+	return
+}
+
+func (m *DataApproveMessage) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Model(m).Select(cols).Updates(m).Error
+	return
+}

+ 90 - 0
models/data_manage/data_approve/data_approve_node.go

@@ -0,0 +1,90 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type DataApproveNode struct {
+	DataApproveNodeId int       `gorm:"column:data_approve_node_id;primaryKey"`
+	DataApproveFlowId int       `gorm:"column:data_approve_flow_id"`
+	PrevNodeId        int       `gorm:"column:prev_node_id"`
+	NextNodeId        int       `gorm:"column:next_node_id"`
+	NodeType          int       `gorm:"column:node_type"`
+	ApproveType       int       `gorm:"column:approve_type"`
+	Users             string    `gorm:"column:users"`
+	CurrVersion       int       `gorm:"column:curr_version"`
+	CreatedTime       time.Time `gorm:"column:created_time"`
+}
+
+var DataApproveNodeCols = struct {
+	DataApproveNodeId string
+	DataApproveFlowId string
+	PrevNodeId        string
+	NextNodeId        string
+	NodeType          string
+	ApproveType       string
+	Users             string
+	CurrVersion       string
+	CreatedTime       string
+}{
+	DataApproveNodeId: "data_approve_node_id",
+	DataApproveFlowId: "data_approve_flow_id",
+	PrevNodeId:        "prev_node_id",
+	NextNodeId:        "next_node_id",
+	NodeType:          "node_type",
+	ApproveType:       "approve_type",
+	Users:             "users",
+	CurrVersion:       "curr_version",
+	CreatedTime:       "created_time",
+}
+
+func (b *DataApproveNode) TableName() string {
+	return "data_approve_node"
+}
+
+func (m *DataApproveNode) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*DataApproveNode, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY created_time DESC, data_approve_node_id ASC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func UpdateNextNodes(nodes []*DataApproveNode) (err error) {
+	if len(nodes) == 0 {
+		return
+	}
+	updateCols := []string{"NextNodeId"}
+	for _, v := range nodes {
+		e := global.DmSQL["data"].Select(updateCols).Updates(v).Error
+		if e != nil {
+			err = fmt.Errorf("prev node update err: %v", e)
+			return
+		}
+	}
+	return
+}
+
+func GetDataApproveNodeByCondition(condition string, pars []interface{}) (node []*DataApproveNode, err error) {
+	o := global.DmSQL["data"]
+	sql := "SELECT * FROM data_approve_node WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Find(&node).Error
+	return
+}
+
+func GetDataApproveNodeByFlowIdAndVersionId(flowId int, versionId int) (node []*DataApproveNode, err error) {
+	err = global.DmSQL["data"].Model(&DataApproveNode{}).Where("data_approve_flow_id =? AND curr_version =?", flowId, versionId).Scan(&node).Error
+	return
+}

+ 152 - 0
models/data_manage/data_approve/data_approve_record.go

@@ -0,0 +1,152 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type DataApproveRecord struct {
+	DataApproveRecordId int       `gorm:"column:data_approve_record_id;primary_key"`
+	DataApproveId       int       `gorm:"column:data_approve_id"`
+	State               int       `gorm:"column:state"`
+	NodeId              int       `gorm:"column:node_id"`
+	NodeType            int       `gorm:"column:node_type"`
+	PrevNodeId          int       `gorm:"column:prev_node_id"`
+	NextNodeId          int       `gorm:"column:next_node_id"`
+	ApproveType         int       `gorm:"column:approve_type"`
+	ApproveUserId       int       `gorm:"column:approve_user_id"`
+	ApproveUserName     string    `gorm:"column:approve_user_name"`
+	ApproveUserSort     int       `gorm:"column:approve_user_sort"`
+	ApproveRemark       string    `gorm:"column:approve_remark"`
+	ApproveTime         time.Time `gorm:"column:approve_time"`
+	CreateTime          time.Time `gorm:"column:create_time"`
+	ModifyTime          time.Time `gorm:"column:modify_time"`
+	NodeState           int       `gorm:"column:node_state"`
+	NodeApproveUserId   int       `gorm:"column:node_approve_user_id"`
+	NodeApproveUserName string    `gorm:"column:node_approve_user_name"`
+	NodeApproveTime     time.Time `gorm:"column:node_approve_time"`
+}
+
+var DataApproveRecordCols = struct {
+	DataApproveRecordId string
+	DataApproveId       string
+	State               string
+	NodeId              string
+	NodeType            string
+	PrevNodeId          string
+	NextNodeId          string
+	ApproveType         string
+	ApproveUserId       string
+	ApproveUserName     string
+	ApproveUserSort     string
+	ApproveRemark       string
+	ApproveTime         string
+	CreateTime          string
+	ModifyTime          string
+	NodeState           string
+	NodeApproveUserId   string
+	NodeApproveUserName string
+	NodeApproveTime     string
+}{
+	DataApproveRecordId: "data_approve_record_id",
+	DataApproveId:       "data_approve_id",
+	State:               "state",
+	NodeId:              "node_id",
+	NodeType:            "node_type",
+	PrevNodeId:          "prev_node_id",
+	NextNodeId:          "next_node_id",
+	ApproveType:         "approve_type",
+	ApproveUserId:       "approve_user_id",
+	ApproveUserName:     "approve_user_name",
+	ApproveUserSort:     "approve_user_sort",
+	ApproveRemark:       "approve_remark",
+	ApproveTime:         "approve_time",
+	CreateTime:          "create_time",
+	ModifyTime:          "modify_time",
+	NodeState:           "node_state",
+	NodeApproveUserId:   "node_approve_user_id",
+	NodeApproveUserName: "node_approve_user_name",
+	NodeApproveTime:     "node_approve_time",
+}
+
+func (b *DataApproveRecord) TableName() string {
+	return "data_approve_record"
+}
+
+func (b *DataApproveRecord) Create() (err error) {
+	o := global.DmSQL["data"]
+	err = o.Create(b).Error
+	return
+}
+
+func (b *DataApproveRecord) CreateMulti(items []*DataApproveRecord) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := global.DmSQL["data"]
+	err = o.CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (b *DataApproveRecord) Update(cols []string) (err error) {
+	o := global.DmSQL["data"]
+	err = o.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func GetDataApproveRecordByCondition(condition string, pars []interface{}) (record *DataApproveRecord, err error) {
+	o := global.DmSQL["data"]
+	sql := `SELECT * FROM data_approve_record WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).First(&record).Error
+	return
+}
+
+func GetDataApproveRecordItemsByCondition(condition string, pars []interface{}) (items []*DataApproveRecord, err error) {
+	order := `ORDER BY create_time DESC`
+	sql := fmt.Sprintf(`SELECT * FROM data_approve_record WHERE 1=1 %s %s`, condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (b *DataApproveRecord) UpdateNodeState(DataApproveId, nodeId, nodeState, nodeApproveUserId int, nodeApproveUserName string, nodeApproveTime time.Time) (err error) {
+	pars := make([]interface{}, 0)
+	pars = append(pars, nodeState, nodeApproveUserId, nodeApproveUserName, nodeApproveTime)
+
+	// 更新条件
+	whereParas := []interface{}{DataApproveId, nodeId}
+	pars = append(pars, whereParas...)
+
+	sql := fmt.Sprintf(`UPDATE %s SET node_state=?,node_approve_user_id=?,node_approve_user_name=?,node_approve_time=? WHERE data_approve_id = ? AND node_id = ?`, b.TableName())
+	err = global.DmSQL["data"].Exec(sql, pars...).Error
+	return
+}
+
+func (m *DataApproveRecord) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*DataApproveRecord, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *DataApproveRecord) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *DataApproveRecord, err error) {
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order)
+	err = global.DmSQL["data"].Raw(sql, pars...).First(&item).Error
+	return
+}

+ 57 - 0
models/data_manage/data_approve/data_approve_relation.go

@@ -0,0 +1,57 @@
+package data_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"time"
+)
+
+type DataApproveRelation struct {
+	DataApproveRelationId int       `gorm:"column:data_approve_relation_id;primary_key"`
+	DataApproveId         int       `gorm:"column:data_approve_id"`
+	DataId                int       `gorm:"column:data_id"`
+	ClassifyId            int       `gorm:"column:classify_id"`
+	CreateTime            time.Time `gorm:"column:create_time"`
+}
+
+var DataApproveRelationCols = struct {
+	DataApproveRelationId string
+	DataApproveId         string
+	DataId                string // 资产类型:1:指标、2:图表
+	ClassifyId            string //
+	CreateTime            string
+}{
+	DataApproveRelationId: "data_approve_relation_id",
+	DataApproveId:         "data_approve_id",
+	DataId:                "data_id",
+	ClassifyId:            "classify_id",
+	CreateTime:            "create_time",
+}
+
+func (b *DataApproveRelation) TableName() string {
+	return "data_approve_relation"
+}
+
+func (b *DataApproveRelation) Update(cols []string) (err error) {
+	db := global.DmSQL["data"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *DataApproveRelation) Create() (err error) {
+	db := global.DmSQL["data"]
+	err = db.Create(b).Error
+	return
+}
+
+// GetListByDataApproveId
+// @Description: 根据审批id获取关联的资产(指标、图表)
+// @author: Roc
+// @datetime 2024-12-05 17:23:39
+// @param dataApproveId int
+// @return dataIdList []int
+// @return err error
+func (b *DataApproveRelation) GetListByDataApproveId(dataApproveId int) (dataIdList []*DataApproveRelation, err error) {
+	sql := `SELECT * FROM data_approve_relation AS a WHERE data_approve_id = ? `
+	err = global.DmSQL["data"].Raw(sql, dataApproveId).Scan(&dataIdList).Error
+	return
+}

+ 21 - 0
models/data_manage/data_approve/request/approve.go

@@ -0,0 +1,21 @@
+package request
+
+type DataApprovePassReq struct {
+	DataApproveId int `description:"审批ID"`
+}
+
+// DataApproveRefuseReq 审批驳回请求体
+type DataApproveRefuseReq struct {
+	DataApproveId int    `description:"审批ID"`
+	ApproveRemark string `description:"驳回理由"`
+}
+
+// DataApproveCancelReq 撤销审批请求体
+type DataApproveCancelReq struct {
+	DataApproveId int `description:"审批ID"`
+}
+
+// DataApproveCheckApproveOpenReq 校验当前资产是否打开审批请求体
+type DataApproveCheckApproveOpenReq struct {
+	DataType int `description:"资产类型"`
+}

+ 22 - 0
models/data_manage/data_approve/request/approve_flow.go

@@ -0,0 +1,22 @@
+package request
+
+type DataApproveFlowSaveReq struct {
+	DataType int
+	FlowName string
+	Nodes    []Node
+}
+
+type Node struct {
+	ApproveType int `description:"审批类型: 1-依次审批, 2-会签, 3-或签"`
+	Users       []User
+}
+
+type User struct {
+	UserId   int    `description:"用户ID"`
+	UserName string `description:"用户名"`
+	UserType string `description:"用户类型: user-用户 role-角色"`
+}
+
+type DataApproveFlowRemoveResp struct {
+	DataApproveFlowId int
+}

+ 5 - 0
models/data_manage/data_approve/request/approve_message.go

@@ -0,0 +1,5 @@
+package request
+
+type DataApproveMessageReadReq struct {
+	MessageId int `description:"审批消息ID"`
+}

+ 88 - 0
models/data_manage/data_approve/response/approve.go

@@ -0,0 +1,88 @@
+package response
+
+// DataApproveDetail 审批详情信息
+type DataApproveDetail struct {
+	Approve          *DataApproveDetailItem    `description:"审批信息"`
+	ApproveFlowNodes []*DataApproveDetailNodes `description:"审批节点信息"`
+	DataList         []DataApproveDetailData   `description:"指标/图表列表"`
+}
+
+// DataApproveDetailData 审批详情-报告信息
+type DataApproveDetailData struct {
+	DataId       int    `description:"数据ID"`
+	DataName     string `description:"数据名称"`
+	DataCode     string `description:"数据code"`
+	DataClassify int    `description:"数据所属分类"`
+}
+
+// DataApproveDetailItem 审批详情-审批信息
+type DataApproveDetailItem struct {
+	DataApproveId int    `description:"审批ID"`
+	State         int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	FlowId        int    `description:"审批流ID"`
+	FlowVersion   int    `description:"审批流版本"`
+	StartNodeId   int    `description:"开始节点ID"`
+	CurrNodeId    int    `description:"当前节点ID"`
+	ApplyUserId   int    `description:"申请人ID"`
+	ApplyUserName string `description:"申请人姓名"`
+	ApproveTime   string `description:"审批时间"`
+	CreateTime    string `description:"创建时间"`
+	ModifyTime    string `description:"修改时间"`
+}
+
+// DataApproveDetailNodes 审批详情-节点信息
+type DataApproveDetailNodes struct {
+	DataApproveNodeId int                          `description:"看板审批节点ID"`
+	DataApproveFlowId int                          `description:"看板审批流ID"`
+	PrevNodeId        int                          `description:"上一个节点ID(0为开始节点)"`
+	NextNodeId        int                          `description:"下一个节点ID(0为结束节点)"`
+	NodeType          int                          `description:"节点类型:0-审批;1-抄送"`
+	ApproveType       int                          `description:"审批类型:1-依次审批;2-会签;3-或签"`
+	Users             []*DataApproveDetailNodeUser `description:"审批人信息"`
+}
+
+// DataApproveDetailNodeUser 审批详情-节点用户信息
+type DataApproveDetailNodeUser struct {
+	DataApproveNodeUserReq
+	ApproveRecord *DataApproveDetailNodeUserRecord `description:"用户审批记录"`
+}
+
+// DataApproveNodeUserReq 报告审批节点用户请求体
+type DataApproveNodeUserReq struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+
+// DataApproveDetailNodeUserRecord 审批详情-节点用户审批记录
+type DataApproveDetailNodeUserRecord struct {
+	DataApproveRecordId int    `description:"审批记录ID"`
+	State               int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	ApproveUserId       int    `description:"审批人ID"`
+	ApproveUserName     string `description:"审批人姓名"`
+	ApproveRemark       string `description:"审批备注"`
+	ApproveTime         string `description:"审批时间"`
+}
+
+type DataApproveItemOrmResp struct {
+	DataApproveId       int    `description:"审批ID"`
+	DataApproveRecordId int    `description:"审批记录ID"`
+	Title               string `description:"审批标题"`
+	DataType            int    `description:"自查类型"`
+	State               int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	RecordState         int    `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
+	FlowId              int    `description:"审批流ID"`
+	FlowVersion         int    `description:"审批流版本"`
+	StartNodeId         int    `description:"开始节点ID"`
+	CurrNodeId          int    `description:"当前节点ID"`
+	ApplyUserId         int    `description:"申请人ID"`
+	ApplyUserName       string `description:"申请人姓名"`
+	ApproveRemark       string `description:"审批备注"`
+	ApproveTime         string `description:"审批时间"`
+	HandleTime          string `description:"处理时间"`
+	CreateTime          string `description:"创建时间"`
+	ModifyTime          string `description:"修改时间"`
+	NodeState           int    `description:"当前节点审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回" json:"-"`
+	NodeApproveTime     string `description:"当前节点审批时间" json:"-"`
+}

+ 46 - 0
models/data_manage/data_approve/response/approve_flow.go

@@ -0,0 +1,46 @@
+package response
+
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type DataApproveFlowItem struct {
+	DataApproveFlowId int    `description:"主键"`
+	FlowName          string `description:"bi审批流程名称"`
+	DataType          int    `description:"资产类型"`
+	ClassifyName      string `description:"分类名称"`
+	CurrVersion       int    `description:"当前版本"`
+	CreateTime        string `description:"创建时间"`
+	ModifyTime        string `description:"修改时间"`
+}
+
+type DataApproveFlowListResp struct {
+	List   []*DataApproveFlowItem
+	Paging *paging.PagingItem
+}
+
+type DataApproveFlowDetailResp struct {
+	DataApproveFlowItem `description:"审批流信息"`
+	Nodes               []*DataApproveNodeItem `description:"节点信息"`
+}
+
+type DataApproveNodeUser struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+type DataApproveNodeItem struct {
+	DataApproveNodeId int                    `description:"BI审批节点ID"`
+	DataApproveFlowId int                    `description:"BI审批流ID"`
+	PrevNodeId        int                    `description:"上一个节点ID(0为开始节点)"`
+	NextNodeId        int                    `description:"下一个节点ID(0为结束节点)"`
+	NodeType          int                    `description:"节点类型:0-审批;1-抄送"`
+	ApproveType       int                    `description:"审批类型:1-依次审批;2-会签;3-或签"`
+	Users             []*DataApproveNodeUser `description:"审批人信息"`
+}
+
+type DataApproveListResp struct {
+	List   []*DataApproveItemOrmResp
+	Paging *paging.PagingItem
+}

+ 24 - 0
models/data_manage/data_approve/response/approve_message.go

@@ -0,0 +1,24 @@
+package response
+
+import "github.com/rdlucklib/rdluck_tools/paging"
+
+// DataApproveMessageListResp 审批消息列表响应体
+type DataApproveMessageListResp struct {
+	List        []*DataApproveMessageItem
+	Paging      *paging.PagingItem `description:"分页数据"`
+	UnreadTotal int                `description:"消息未读数"`
+}
+
+// DataApproveMessageItem 报告审批消息信息
+type DataApproveMessageItem struct {
+	Id            int
+	SendUserId    int    `description:"发送人ID"`
+	ReceiveUserId int    `description:"接收者ID"`
+	Content       string `description:"消息内容"`
+	Remark        string `description:"备注信息"`
+	DataApproveId int    `description:"审批ID"`
+	ApproveState  int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	IsRead        int    `description:"是否已读:0-未读;1-已读"`
+	CreateTime    string `description:"创建时间"`
+	ModifyTime    string `description:"修改时间"`
+}

+ 6 - 6
models/data_manage/edb_classify.go

@@ -51,9 +51,9 @@ type AddEdbClassifyReq struct {
 // @param classifyType uint8
 // @return count int
 // @return err error
-func GetEdbClassifyCount(classifyName string, parentId int, classifyType uint8) (count int, err error) {
-	sql := `SELECT COUNT(1) AS count FROM edb_classify WHERE parent_id=? AND classify_name=? AND classify_type = ? `
-	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyType).Scan(&count).Error
+func GetEdbClassifyCount(classifyName string, parentId, sysUserId int, classifyType uint8) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM edb_classify WHERE parent_id=? AND classify_name=? AND classify_type = ? AND sys_user_id = ?  `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyType, sysUserId).Scan(&count).Error
 
 	return
 }
@@ -67,9 +67,9 @@ func GetEdbClassifyCount(classifyName string, parentId int, classifyType uint8)
 // @param classifyType uint8
 // @return count int
 // @return err error
-func GetEdbClassifyEnCount(classifyNameEn string, parentId int, classifyType uint8) (count int, err error) {
-	sql := `SELECT COUNT(1) AS count FROM edb_classify WHERE parent_id=? AND classify_name_en = ? AND classify_type = ? `
-	err = global.DmSQL["data"].Raw(sql, parentId, classifyNameEn, classifyType).Scan(&count).Error
+func GetEdbClassifyEnCount(classifyNameEn string, parentId, sysUserId int, classifyType uint8) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM edb_classify WHERE parent_id=? AND classify_name_en = ? AND classify_type = ? AND sys_user_id = ? `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyNameEn, classifyType, sysUserId).Scan(&count).Error
 
 	return
 }

+ 75 - 0
models/data_manage/edb_info.go

@@ -414,6 +414,7 @@ type EdbInfoList struct {
 	SharedUserIdList      []int                   `description:"共享用户id列表" gorm:"-"`
 	PublicStatus          int                     `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
 	EdbPublicClassifyId   int                     `description:"指标公开分类id"`
+	PublicTime            time.Time               `description:"设置公开的时间"`
 }
 
 type EdbDataInsertConfigItem struct {
@@ -500,6 +501,17 @@ func GetEdbInfoByCondition(condition string, pars []interface{}) (item *EdbInfoL
 	return
 }
 
+func GetEdbInfoEsByCondition(condition string, pars []interface{}) (item *EdbInfoEs, err error) {
+	o := global.DmSQL["data"]
+	sql := ` SELECT * FROM edb_info WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).First(&item).Error
+
+	return
+}
+
 func GetEdbDataCountByCondition(condition string, pars []interface{}, source, subSource int) (count int, err error) {
 	o := global.DmSQL["data"]
 	tableName := GetEdbDataTableName(source, subSource)
@@ -1279,6 +1291,69 @@ func GetEdbInfoFilterList(condition string, pars []interface{}, startSize, pageS
 	return
 }
 
+// EdbInfoEs 写入es的指标数据结构
+type EdbInfoEs struct {
+	EdbInfoId             int        `orm:"column(edb_info_id);pk" gorm:"primaryKey" `
+	EdbInfoType           int        `description:"指标类型,0:普通指标,1:预测指标"`
+	SourceName            string     `description:"来源名称"`
+	Source                int        `description:"来源id"`
+	EdbCode               string     `description:"指标编码"`
+	EdbNameEn             string     `description:"英文指标名称"`
+	EdbName               string     `description:"指标名称"`
+	Frequency             string     `description:"频率"`
+	FrequencyEn           string     `description:"英文频率"`
+	Unit                  string     `description:"单位"`
+	UnitEn                string     `description:"英文单位"`
+	StartDate             string     `description:"起始日期"`
+	EndDate               string     `description:"终止日期"`
+	LatestDate            string     `description:"数据最新日期(实际日期)"`
+	LatestValue           float64    `description:"数据最新值(实际值)"`
+	EndValue              float64    `description:"数据的最新值(预测日期的最新值)"`
+	ClassifyId            int        `description:"分类id"`
+	UniqueCode            string     `description:"指标唯一编码"`
+	SysUserId             int        `description:"创建人id"`
+	SysUserRealName       string     `description:"创建人姓名"`
+	ModifyTime            string     `description:"最新修改时间"`
+	CreateTime            string     `description:"创建时间"`
+	EdbNameAlias          string     `json:"-" description:"指标名称,别名"`
+	EdbType               int        `description:"指标类型:1:基础指标,2:计算指标"`
+	ChartImage            string     `description:"图表图片"`
+	RuleType              int        `description:"预测规则,1:最新,2:固定值"`
+	FixedValue            float64    `description:"固定值"`
+	IsEnEdb               bool       `description:"是否展示英文标识"`
+	DataDateType          string     `description:"数据日期类型,枚举值:交易日、自然日"`
+	SubSource             int        `description:"子数据来源:0:经济数据库,1:日期序列"`
+	SubSourceName         string     `description:"子数据来源名称"`
+	IndicatorCode         string     `description:"指标代码"`
+	StockCode             string     `description:"证券代码"`
+	NoUpdate              int8       `description:"是否停止更新,0:继续更新;1:停止更新"`
+	IsJoinPermission      int        `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+	HaveOperaAuth         bool       `description:"是否有数据权限,默认:false"`
+	IsSupplierStop        int        `description:"是否供应商停更:1:停更,0:未停更"`
+	CollectClassifyIdList []int      `description:"所属收藏分类id列表" gorm:"-"`
+	SharedUserIdList      []int      `description:"共享用户id列表" gorm:"-"`
+	PublicStatus          int        `description:"公开状态;0:未公开;1:审批中;2:已驳回;3:已公开"`
+	EdbPublicClassifyId   int        `description:"指标公开分类id"`
+	PublicTime            *time.Time `description:"设置公开的时间"`
+}
+
+// GetEsEdbInfo 获取指指标列表数据接口
+func GetEsEdbInfo(condition string, pars []interface{}, startSize, pageSize int) (total int64, list []*EdbInfoEs, err error) {
+	o := global.DmSQL["data"]
+
+	sql := ` SELECT count(1) total FROM edb_info where 1=1 ` + condition + ` ORDER BY edb_info_id DESC `
+	err = o.Raw(sql, pars...).Scan(&total).Error
+	if err != nil {
+		return
+	}
+
+	sql = ` SELECT * FROM edb_info where 1=1 ` + condition + ` ORDER BY edb_info_id DESC  LIMIT ?,? `
+	pars = append(pars, startSize, pageSize)
+	err = o.Raw(sql, pars...).Scan(&list).Error
+
+	return
+}
+
 // SetEdbInfoImageReq 设置指标图片
 type SetEdbInfoImageReq struct {
 	EdbInfoId int    `description:"指标ID"`

+ 1 - 0
models/data_manage/edb_info_share.go

@@ -53,6 +53,7 @@ func (m EdbInfoShare) GetListByEdbInfoId(edbInfoId int) (items []*EdbInfoShare,
 // @param shareType int8
 // @return err error
 func (m EdbInfoShare) SaveEdbInfoShare(edbInfoIdList, userIdList []int, shareType int8) (err error) {
+	// TODO 保存之前,得先做关联校验
 	addList := make([]*EdbInfoShare, 0)
 	for _, edbInfoId := range edbInfoIdList {
 		for _, userId := range userIdList {

+ 158 - 26
models/data_manage/public_edb_classify.go

@@ -2,6 +2,7 @@ package data_manage
 
 import (
 	"eta_gn/eta_api/global"
+	"fmt"
 	"time"
 )
 
@@ -27,6 +28,73 @@ type EdbPublicClassify struct {
 	EdbPublicClassifyIdPath   string    `description:"分类的完整路径,格式为:父级ID,当前ID"`
 }
 
+func (m EdbPublicClassify) ToEdbClassifyItems() *EdbClassifyItems {
+	return &EdbClassifyItems{
+		ClassifyId: m.EdbPublicClassifyId,
+		//EdbInfoId:        0,
+		ClassifyType:   m.ClassifyType,
+		ClassifyName:   m.EdbPublicClassifyName,
+		ClassifyNameEn: m.EdbPublicClassifyName,
+		ParentId:       m.ParentId,
+		RootId:         m.RootId,
+		Level:          m.Level,
+		Sort:           m.Sort,
+		UniqueCode:     m.UniqueCode,
+		//Source:           0,
+		//SourceName:       "",
+		SysUserId:       m.SysUserId,
+		SysUserRealName: m.SysUserRealName,
+		//StartDate:        "",
+		//EdbCode:          "",
+		//EdbType:          0,
+		//Children:         nil,
+		//Button:           EdbClassifyItemsButton{},
+		//IsJoinPermission: 0,
+		//HaveOperaAuth:    false,
+		ClassifyIdPath: m.EdbPublicClassifyIdPath,
+	}
+}
+
+// Add
+// @Description: 添加分类
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 17:00:18
+// @return err error
+func (m *EdbPublicClassify) Add() (err error) {
+	err = global.DmSQL["data"].Create(m).Error
+
+	return
+}
+
+// Update
+// @Description: 更新分类基础信息
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 17:01:51
+// @param cols []string
+// @return err error
+func (m *EdbPublicClassify) Update(cols []string) (err error) {
+	err = global.DmSQL["data"].Select(cols).Updates(m).Error
+
+	return
+}
+
+// GetEdbClassifyById
+// @Description: 根据id获取分类
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-04 16:56:15
+// @param classifyId int
+// @return item *EdbPublicClassify
+// @return err error
+func (m EdbPublicClassify) GetEdbClassifyById(classifyId int) (item *EdbPublicClassify, err error) {
+	sql := `SELECT * FROM edb_public_classify WHERE edb_public_classify_id=? `
+	err = global.DmSQL["data"].Raw(sql, classifyId).First(&item).Error
+
+	return
+}
+
 // GetEdbClassifyListByParentId
 // @Description: 根据父级id获取下级分类列表
 // @author: Roc
@@ -38,7 +106,7 @@ type EdbPublicClassify struct {
 // @return err error
 func (m EdbPublicClassify) GetEdbClassifyListByParentId(parentId int, classifyType int8) (items []*EdbPublicClassify, err error) {
 	o := global.DmSQL["data"]
-	sql := `SELECT * FROM edb_public_classify WHERE parent_id=? AND classify_type = ? order by sort asc,classify_id asc `
+	sql := `SELECT * FROM edb_public_classify WHERE parent_id=? AND classify_type = ? order by sort asc,edb_public_classify_id asc `
 	err = o.Raw(sql, parentId, classifyType).Find(&items).Error
 
 	return
@@ -77,7 +145,7 @@ func (m EdbPublicClassify) GetEdbClassifyItemsByParentId(parentId int, classifyT
 // @return err error
 func (m EdbPublicClassify) GetEdbClassifyListByType(classifyType int8) (items []*EdbPublicClassify, err error) {
 	o := global.DmSQL["data"]
-	sql := `SELECT * FROM edb_public_classify WHERE classify_type = ? order by sort asc,classify_id asc `
+	sql := `SELECT * FROM edb_public_classify WHERE classify_type = ? order by sort asc,edb_public_classify_id asc `
 	err = o.Raw(sql, classifyType).Find(&items).Error
 
 	return
@@ -97,29 +165,93 @@ func (m EdbPublicClassify) GetAllEdbClassifyByType(classifyType int8) (items []*
 	return
 }
 
-func (m EdbPublicClassify) ToEdbClassifyItems() *EdbClassifyItems {
-	return &EdbClassifyItems{
-		ClassifyId: m.EdbPublicClassifyId,
-		//EdbInfoId:        0,
-		ClassifyType:   m.ClassifyType,
-		ClassifyName:   m.EdbPublicClassifyName,
-		ClassifyNameEn: m.EdbPublicClassifyName,
-		ParentId:       m.ParentId,
-		RootId:         m.RootId,
-		Level:          m.Level,
-		Sort:           m.Sort,
-		UniqueCode:     m.UniqueCode,
-		//Source:           0,
-		//SourceName:       "",
-		SysUserId:       m.SysUserId,
-		SysUserRealName: m.SysUserRealName,
-		//StartDate:        "",
-		//EdbCode:          "",
-		//EdbType:          0,
-		//Children:         nil,
-		//Button:           EdbClassifyItemsButton{},
-		//IsJoinPermission: 0,
-		//HaveOperaAuth:    false,
-		ClassifyIdPath: m.EdbPublicClassifyIdPath,
+func (m EdbPublicClassify) GetEdbClassifyCount(classifyName string, parentId int, classifyType uint8) (count int, err error) {
+	sql := `SELECT COUNT(1) AS count FROM edb_public_classify WHERE parent_id=? AND edb_public_classify_name=? AND classify_type = ?  `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyName, classifyType).Scan(&count).Error
+
+	return
+}
+
+// UpdateEdbClassifyNameAndNamePath
+// @Description: 更新分类信息
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 09:27:33
+// @param cols []string
+// @param oldClassifyNamePath string
+// @param newClassifyNamePath string
+// @return err error
+func (m *EdbPublicClassify) UpdateEdbClassifyNameAndNamePath(cols []string, oldClassifyNamePath, newClassifyNamePath string) (err error) {
+	tx := global.DmSQL["data"].Begin()
+	defer func() {
+		if err != nil {
+			_ = tx.Rollback()
+			return
+		}
+		_ = tx.Commit()
+	}()
+
+	// 变更分类信息
+	err = tx.Select(cols).Updates(m).Error
+	if err != nil {
+		return
 	}
+
+	// 更改子分类的完整的路径
+	if oldClassifyNamePath != `` && newClassifyNamePath != `` {
+		sql := `UPDATE edb_public_classify SET edb_public_classify_name_path = REPLACE(edb_public_classify_name_path,?,?) WHERE edb_public_classify_id_path LIKE ?`
+		err = tx.Exec(sql, oldClassifyNamePath, newClassifyNamePath, fmt.Sprint(m.EdbPublicClassifyIdPath+`,%`)).Error
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+// GetEdbClassifyMaxSort 获取分类下最大的排序数
+func (m EdbPublicClassify) GetEdbClassifyMaxSort(parentId int, classifyType uint8) (sort int, err error) {
+	sql := `SELECT COALESCE(Max(sort), 0) AS sort FROM edb_public_classify WHERE parent_id=? AND classify_type=? `
+	err = global.DmSQL["data"].Raw(sql, parentId, classifyType).Scan(&sort).Error
+
+	return
+}
+
+// GetEdbInfoCountByClassifyIdList
+// @Description: 根据公共分类id集合获取名下指标数量
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 09:59:56
+// @param classifyIdList []int
+// @return count int
+// @return err error
+func (m EdbPublicClassify) GetEdbInfoCountByClassifyIdList(classifyIdList []int) (count int, err error) {
+	if len(classifyIdList) <= 0 {
+		return
+	}
+	sql := `SELECT COUNT(1) total FROM edb_info  WHERE edb_public_classify_id IN (?) `
+	err = global.DmSQL["data"].Raw(sql, classifyIdList).Scan(&count).Error
+
+	return
+}
+
+func (m *EdbPublicClassify) GetAllChildClassifyIdList() (items []int, err error) {
+	sql := ` SELECT edb_public_classify_id FROM edb_public_classify  WHERE edb_public_classify_id_path LIKE ?  ORDER BY create_time DESC `
+	err = global.DmSQL["data"].Raw(sql, fmt.Sprint(m.EdbPublicClassifyIdPath+`,%`)).Scan(&items).Error
+
+	return
+}
+
+// BatchesDel
+// @Description: 根据分类id批量删除
+// @author: Roc
+// @receiver m
+// @datetime 2024-12-05 11:13:06
+// @param classifyIdList []int
+// @return err error
+func (m *EdbPublicClassify) BatchesDel(classifyIdList []int) (err error) {
+	sql := ` DELETE FROM edb_public_classify  WHERE edb_public_classify_id IN (?) `
+	err = global.DmSQL["data"].Exec(sql, classifyIdList).Error
+
+	return
 }

+ 39 - 1
models/data_manage/public_edb_info.go

@@ -1,6 +1,9 @@
 package data_manage
 
-import "eta_gn/eta_api/global"
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+)
 
 // GetEdbInfoByPublicClassifyId
 // @Description: 根据公共分类id获取指标列表
@@ -28,3 +31,38 @@ func GetEdbInfoByPublicClassifyId(classifyId, edbInfoType, edbType int) (items [
 
 	return
 }
+
+// UpdatePublicEdbSuccess
+// @Description: 更新指标的公开成功状态
+// @author: Roc
+// @datetime 2024-12-06 13:37:01
+// @param edbInfoId int
+// @param classifyId int
+// @return err error
+func UpdatePublicEdbSuccess(edbInfoId, classifyId int) (err error) {
+	sql := `UPDATE edb_info set public_status = ?,edb_public_classify_id = ? ,modify_time=now(),public_time = now()  WHERE edb_info_id  = ?`
+	err = global.DmSQL["data"].Exec(sql, utils.EdbPublicSuccess, classifyId, edbInfoId).Error
+
+	return
+}
+
+// UpdatePublicEdb
+// @Description: 更新指标的公开状态
+// @author: Roc
+// @datetime 2024-12-06 11:10:53
+// @param edbInfoIdList []int
+// @param status int
+// @return err error
+func UpdatePublicEdb(edbInfoIdList []int, status int) (err error) {
+	if len(edbInfoIdList) <= 0 {
+		return
+	}
+	sql := `UPDATE edb_info set public_status = ?,modify_time=now() `
+	if status == utils.EdbPublicSuccess {
+		sql += `,public_time = now() `
+	}
+	sql += ` WHERE edb_info_id in (?) `
+	err = global.DmSQL["data"].Exec(sql, status, edbInfoIdList).Error
+
+	return
+}

+ 2 - 2
models/data_manage/request/edb_info_share.go

@@ -19,9 +19,9 @@ type SearchEdbInfoShareReq struct {
 	PageSize       int    `description:"每页数据条数"`
 }
 
-// SetEdbChartPermissionReq
+// SetEdbSharePermissionReq
 // @Description: 设置数据权限请求
-type SetEdbChartPermissionReq struct {
+type SetEdbSharePermissionReq struct {
 	SearchEdbInfoShareReq
 	EdbIdList   []int `description:"选中的指标id列表"`
 	NoEdbIdList []int `description:"未选中的指标id列表"`

+ 48 - 0
models/data_manage/request/edb_public.go

@@ -0,0 +1,48 @@
+package request
+
+// PublicClassifyDeleteCheckReq
+// @Description: 公共分类删除请求
+type PublicClassifyDeleteCheckReq struct {
+	ClassifyId int `description:"分类id"`
+}
+
+// SetEdbPublicReq
+// @Description: 设置指标公开的请求
+type SetEdbPublicReq struct {
+	EdbInfoList []SetEdbPublicEdbReq `description:"待设置的指标"`
+	Description string               `description:"备注"`
+}
+
+type SetEdbPublicEdbReq struct {
+	EdbInfoId  int `description:"指标id列表"`
+	ClassifyId int `description:"公共分类id"`
+}
+
+// SearchPublicEdbReq
+// @Description: 获取指标列表(设置公开的时候)请求结构体
+type SearchPublicEdbReq struct {
+	EdbPublicList  []int  `description:"指标公开状态:1:未公开,2:已提交;3:已公开。可多选,默认是未公开"`
+	SourceList     []int  `description:"来源id"`
+	Keyword        string `description:"关键字"`
+	ClassifyIdList []int  `description:"分类选择,如果不指定分类,那么就是所有分类"`
+	CurrentIndex   int    `description:"当前页页码,从1开始"`
+	PageSize       int    `description:"每页数据条数"`
+}
+
+// AllSearchPublicEdbReq
+// @Description: 获取所有指标列表(设置公开的时候)请求结构体
+type AllSearchPublicEdbReq struct {
+	SearchPublicEdbReq
+	EdbIdList   []int `description:"选中的指标id列表"`
+	NoEdbIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll bool  `description:"是否选择所有指标"`
+}
+
+// SetPublicEdbPermissionReq
+// @Description: 设置数据权限请求
+type SetPublicEdbPermissionReq struct {
+	SearchPublicEdbReq
+	EdbIdList   []int `description:"选中的指标id列表"`
+	NoEdbIdList []int `description:"未选中的指标id列表"`
+	IsSelectAll bool  `description:"是否选择所有指标"`
+}

+ 140 - 5
routers/commentsRouter.go

@@ -862,6 +862,96 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Approve",
+            Router: `/approve`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "CheckApproveOpen",
+            Router: `/check_open`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "MessageList",
+            Router: `/message/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "MessageRead",
+            Router: `/message/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveController"],
+        beego.ControllerComments{
+            Method: "Refuse",
+            Router: `/refuse`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/flow/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_approve:DataApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/flow/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_manage_permission:DataMangePermissionController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/data_manage_permission:DataMangePermissionController"],
         beego.ControllerComments{
             Method: "MoveAllEdbChartUser",
@@ -4203,8 +4293,8 @@ func init() {
 
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbInfoShareController"],
         beego.ControllerComments{
-            Method: "EdbInfoFilterByEs",
-            Router: `/edb_info/share/list_by_es`,
+            Method: "ListByEs",
+            Router: `/edb_info/share/list/es`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
             Filters: nil,
@@ -4248,7 +4338,7 @@ func init() {
 
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
         beego.ControllerComments{
-            Method: "AddEdbClassify",
+            Method: "AddClassify",
             Router: `/edb_public/classify/add`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
@@ -4257,7 +4347,7 @@ func init() {
 
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
         beego.ControllerComments{
-            Method: "DeleteEdbClassify",
+            Method: "DeleteClassify",
             Router: `/edb_public/classify/delete`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
@@ -4266,7 +4356,7 @@ func init() {
 
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicClassifyController"],
         beego.ControllerComments{
-            Method: "DeleteEdbClassifyCheck",
+            Method: "DeleteClassifyCheck",
             Router: `/edb_public/classify/delete/check`,
             AllowHTTPMethods: []string{"post"},
             MethodParams: param.Make(),
@@ -4345,6 +4435,51 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "ListByEs",
+            Router: `/edb_info/public/list/es`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "AllListByEs",
+            Router: `/edb_info/public/list/es/all`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "Save",
+            Router: `/edb_info/public/save`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "Remove",
+            Router: `/edb_public/remove`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:EdbPublicController"],
+        beego.ControllerComments{
+            Method: "RemoveCheck",
+            Router: `/edb_public/remove/check`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:FactorEdbSeriesController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage:FactorEdbSeriesController"],
         beego.ControllerComments{
             Method: "Add",

+ 9 - 0
routers/router.go

@@ -14,6 +14,7 @@ import (
 	"eta_gn/eta_api/controllers/data_manage"
 	"eta_gn/eta_api/controllers/data_manage/correlation"
 	"eta_gn/eta_api/controllers/data_manage/cross_variety"
+	"eta_gn/eta_api/controllers/data_manage/data_approve"
 	"eta_gn/eta_api/controllers/data_manage/data_manage_permission"
 	"eta_gn/eta_api/controllers/data_manage/excel"
 	future_good2 "eta_gn/eta_api/controllers/data_manage/future_good"
@@ -161,6 +162,14 @@ func init() {
 				&data_manage.EdbCollectController{},
 				&data_manage.EdbCollectClassifyController{},
 				&data_manage.EdbInfoShareController{},
+				&data_manage.EdbPublicController{},
+				&data_manage.EdbPublicClassifyController{},
+			),
+			web.NSNamespace("/data_approve",
+				web.NSInclude(
+					&data_approve.DataApproveController{},
+					&data_approve.DataApproveFlowController{},
+				),
 			),
 		),
 		web.NSNamespace("/my_chart",

+ 1199 - 0
services/data/data_approve/approve.go

@@ -0,0 +1,1199 @@
+package data_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models/data_manage"
+	dataApproveModel "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"eta_gn/eta_api/services/data"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strings"
+	"time"
+)
+
+var (
+	timeField   = map[int]string{1: fmt.Sprintf("a.%s", dataApproveModel.DataApproveRecordCols.CreateTime), 2: fmt.Sprintf("a.%s", dataApproveModel.DataApproveRecordCols.NodeApproveTime), 3: fmt.Sprintf("b.%s", dataApproveModel.DataApproveCols.ApproveTime)}
+	myTimeField = map[int]string{1: dataApproveModel.DataApproveCols.CreateTime, 3: dataApproveModel.DataApproveCols.ApproveTime}
+	orderRules  = map[int]string{1: "ASC", 2: "DESC"}
+)
+
+func PassDataApprove(approveId int, adminId int) (msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	if approveItem.State != DataApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	var ApprovePars []interface{}
+	ApproveCond := ` AND data_approve_id =? AND approve_user_id =? AND state =? `
+	ApprovePars = append(ApprovePars, approveId, adminId, DataApproveStateApproving)
+
+	recordItem, er := dataApproveModel.GetDataApproveRecordByCondition(ApproveCond, ApprovePars)
+	if er != nil {
+		if utils.IsErrNoRow(er) {
+			msg = "无权审批"
+			err = er
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	// 查询审批流和审批流节点
+	flowItem, e := dataApproveModel.GetDataApproveFlowById(approveItem.FlowId)
+	if e != nil {
+		err = fmt.Errorf("获取审批流失败, Err: %s", e.Error())
+		return
+	}
+	nodePars := make([]interface{}, 0)
+	nodeCond := ` AND data_approve_flow_id =? AND curr_version =? `
+	nodePars = append(nodePars, flowItem.DataApproveFlowId, flowItem.CurrVersion)
+	nodeItems, e := dataApproveModel.GetDataApproveNodeByCondition(nodeCond, nodePars)
+	if e != nil {
+		err = fmt.Errorf("ApproveNodes GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	if len(nodeItems) == 0 {
+		err = fmt.Errorf("无审批节点")
+		return
+	}
+	nodeMap := make(map[int]*dataApproveModel.DataApproveNode)
+	for _, v := range nodeItems {
+		nodeMap[v.DataApproveNodeId] = v
+	}
+
+	// 取出审批记录的节点
+	currNodeItem := nodeMap[recordItem.NodeId]
+	if currNodeItem == nil {
+		err = fmt.Errorf("当前节点信息有误")
+		return
+	}
+	currNode, e := FormatDataApproveNode2Item(currNodeItem)
+	if e != nil {
+		err = fmt.Errorf("当前节点信息有误, Err: %s", e.Error())
+		return
+	}
+	now := time.Now().Local()
+	recordItem.State = DataApproveStatePass
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+	recordItem.NodeState = DataApproveStatePass
+	recordItem.NodeApproveUserId = recordItem.ApproveUserId
+	recordItem.NodeApproveUserName = recordItem.ApproveUserName
+	recordItem.NodeApproveTime = now
+
+	recordCols := []string{"State", "ApproveTime", "ModifyTime", "NodeState", "NodeApproveUserId", "NodeApproveUserName", "NodeApproveTime"}
+	lastApprove := false
+
+	// 依次审批
+	if currNode.ApproveType == NodeApproveTypeRoll {
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		// 检查依次审批情况
+		sort.Slice(currNode.Users, func(k, j int) bool {
+			return currNode.Users[k].Sort < currNode.Users[j].Sort
+		})
+		userLen := len(currNode.Users)
+		//lastRoll := false
+		nextUser := new(response.DataApproveNodeUser) // 下一个审批人, 为nil则表示当前审批人即为最后
+		for k, v := range currNode.Users {
+			// 当前审批人
+			if v.UserId == adminId && recordItem.ApproveUserSort == v.Sort {
+				if (k + 1) < userLen {
+					nextUser = currNode.Users[k+1]
+				}
+			}
+		}
+		// 当前节点下一个审批人, 生成下一个审批记录且return
+		if nextUser.UserId > 0 {
+			newRecord := new(dataApproveModel.DataApproveRecord)
+			newRecord.DataApproveId = recordItem.DataApproveId
+			newRecord.State = DataApproveStateApproving
+			newRecord.NodeId = currNode.DataApproveNodeId
+			newRecord.PrevNodeId = currNode.PrevNodeId
+			newRecord.NextNodeId = currNode.NextNodeId
+			newRecord.ApproveType = currNode.ApproveType
+			newRecord.ApproveUserId = nextUser.UserId
+			newRecord.ApproveUserName = nextUser.UserName
+			newRecord.ApproveUserSort = nextUser.Sort
+			newRecord.CreateTime = now
+			newRecord.ModifyTime = now
+			newRecord.NodeState = DataApproveStateApproving
+			if e = newRecord.Create(); e != nil {
+				err = fmt.Errorf("生成审批记录失败, Err: %s", e.Error())
+				return
+			}
+
+			// 推送审批消息
+			go func() {
+				messageItem := new(dataApproveModel.DataApproveMessage)
+				messageItem.SendUserId = approveItem.ApplyUserId
+				messageItem.ReceiveUserId = nextUser.UserId
+				messageItem.Content = "您有新的待办任务"
+				messageItem.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", approveItem.ApplyUserName, approveItem.Title)
+				messageItem.DataApproveId = approveItem.DataApproveId
+				messageItem.ApproveState = DataApproveStateApproving
+				messageItem.CreateTime = now
+				messageItem.ModifyTime = now
+				if e = messageItem.Create(); e != nil {
+					utils.FileLog.Info(fmt.Sprintf("PassDataApprove message err: %s", e.Error()))
+					return
+				}
+			}()
+			return
+		}
+
+		// 更新审批当前节点并进入下一个节点
+		if currNode.NextNodeId > 0 {
+			nextNode := nodeMap[currNode.NextNodeId]
+			approveItem.CurrNodeId = currNode.NextNodeId
+			approveItem.ModifyTime = now
+			if e = approveItem.Update([]string{"CurrNodeId", "ModifyTime"}); e != nil {
+				err = fmt.Errorf("更新审批当前节点失败, Err: %s", e.Error())
+				return
+			}
+			err = BuildNextNodeRecordAndMsg(nextNode, approveItem.DataApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.Title)
+			return
+		} else {
+			// 最后一个节点
+			lastApprove = true
+		}
+	}
+
+	// 会签
+	if currNode.ApproveType == NodeApproveTypeAll {
+		// 查询其他审批人是否已审批
+		otherCond := ` AND data_approve_id =? AND node_id =? AND approve_user_id <> ? `
+		otherPars := make([]interface{}, 0)
+		otherPars = append(otherPars, approveItem.DataApproveId, recordItem.NodeId, adminId)
+		otherRecords, e := dataApproveModel.GetDataApproveRecordItemsByCondition(otherCond, otherPars)
+		if e != nil {
+			err = fmt.Errorf("获取节点审批记录失败, Err: %s", e.Error())
+			return
+		}
+		otherPass := true
+		for _, v := range otherRecords {
+			if v.State != DataApproveStatePass {
+				otherPass = false
+			}
+		}
+
+		// 其他人未审批, 仅更新当前审批记录
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		// 其他人已审批且为最后节点
+		if otherPass && currNode.NextNodeId == 0 {
+			lastApprove = true
+		}
+
+		// 其他人已审批且不为最后节点, 进入下一节点
+		if otherPass && currNode.NextNodeId > 0 {
+			nextNode := nodeMap[currNode.NextNodeId]
+			approveItem.CurrNodeId = currNode.NextNodeId
+			approveItem.ModifyTime = now
+			if e = approveItem.Update([]string{"CurrNodeId", "ModifyTime"}); e != nil {
+				err = fmt.Errorf("更新审批当前节点失败, Err: %s", e.Error())
+				return
+			}
+			err = BuildNextNodeRecordAndMsg(nextNode, approveItem.DataApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.Title)
+			return
+		}
+	}
+
+	// 或签
+	if currNode.ApproveType == NodeApproveTypeAny {
+		// 需检查一下审批的当前节点和记录的节点是否匹配, 不匹配可能是因为另外的审批人已通过, 所以此处应给提示
+		// 前端也有做相应的判断,但是两个人同时进入审批详情页时就可能出现这种情况
+		if approveItem.CurrNodeId != recordItem.NodeId {
+			msg = "该节点已完成审批, 请刷新页面"
+			return
+		}
+
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		// 将该审批的同一个节点的记录标记为已审批
+		if e = recordItem.UpdateNodeState(recordItem.DataApproveId, recordItem.NodeId, recordItem.NodeState, recordItem.NodeApproveUserId, recordItem.NodeApproveUserName, recordItem.NodeApproveTime); e != nil {
+			err = fmt.Errorf("更新同一节点的其他审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+
+		if currNode.NextNodeId == 0 {
+			lastApprove = true
+		}
+		if currNode.NextNodeId > 0 {
+			nextNode := nodeMap[currNode.NextNodeId]
+			approveItem.CurrNodeId = currNode.NextNodeId
+			approveItem.ModifyTime = now
+			if e = approveItem.Update([]string{"CurrNodeId", "ModifyTime"}); e != nil {
+				err = fmt.Errorf("更新审批当前节点失败, Err: %s", e.Error())
+				return
+			}
+			err = BuildNextNodeRecordAndMsg(nextNode, approveItem.DataApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.Title)
+			return
+		}
+	}
+
+	// 最后一个审批, 更新审批记录、审批、报告状态、推送消息给申请人
+	if lastApprove {
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+		approveItem.State = DataApproveStatePass
+		approveItem.ApproveTime = now
+		approveItem.ModifyTime = now
+		approveCols := []string{"State", "ApproveTime", "ModifyTime"}
+		if e = approveItem.Update(approveCols); e != nil {
+			err = fmt.Errorf("更新审批信息失败, Err: %s", e.Error())
+			return
+		}
+		if e = updateDataApproveState(approveItem, DataApproveStatePass); e != nil {
+			err = fmt.Errorf("更新报告审批状态失败, Err: %s", e.Error())
+			return
+		}
+
+		go func() {
+			messageItem := new(dataApproveModel.DataApproveMessage)
+			messageItem.SendUserId = adminId
+			messageItem.ReceiveUserId = approveItem.ApplyUserId
+			messageItem.Content = "您提交的审批已通过"
+			messageItem.Remark = fmt.Sprintf("您提交的【%s】已通过", approveItem.Title)
+			messageItem.DataApproveId = approveItem.DataApproveId
+			messageItem.ApproveState = DataApproveStatePass
+			messageItem.CreateTime = now
+			messageItem.ModifyTime = now
+			if e = messageItem.Create(); e != nil {
+				utils.FileLog.Info(fmt.Sprintf("PassDataApprove message err: %s", e.Error()))
+				return
+			}
+		}()
+	}
+	return
+
+}
+
+// BuildNextNodeRecordAndMsg 生成下一个节点的审批记录并推送消息
+func BuildNextNodeRecordAndMsg(approveNodeItem *dataApproveModel.DataApproveNode, approveId, sysAdminId int, sysAdminName, title string) (err error) {
+	if approveNodeItem == nil {
+		err = fmt.Errorf("approve node nil")
+		return
+	}
+
+	// 根据节点审批方式生成审批记录
+	now := time.Now().Local()
+	approveNode, e := FormatDataApproveNode2Item(approveNodeItem)
+	if e != nil {
+		err = fmt.Errorf("FormatDataApproveNode2Item err: %s", e.Error())
+		return
+	}
+	if len(approveNode.Users) == 0 {
+		err = fmt.Errorf("审批节点用户有误")
+		return
+	}
+	newRecords := make([]*dataApproveModel.DataApproveRecord, 0)
+	sort.Slice(approveNode.Users, func(k, j int) bool {
+		return approveNode.Users[k].Sort < approveNode.Users[j].Sort
+	})
+	for _, u := range approveNode.Users {
+		r := new(dataApproveModel.DataApproveRecord)
+		r.DataApproveId = approveId
+		r.State = DataApproveStateApproving
+		r.NodeId = approveNode.DataApproveNodeId
+		r.PrevNodeId = approveNode.PrevNodeId
+		r.NextNodeId = approveNode.NextNodeId
+		r.ApproveType = approveNode.ApproveType
+		r.ApproveUserId = u.UserId
+		r.ApproveUserName = u.UserName
+		r.ApproveUserSort = u.Sort
+		r.CreateTime = now
+		r.ModifyTime = now
+		r.NodeState = DataApproveStateApproving // 当前节点审批状态
+		newRecords = append(newRecords, r)
+		// 依次审批仅生成一条记录
+		if approveNode.ApproveType == NodeApproveTypeRoll {
+			break
+		}
+	}
+
+	recordOb := new(dataApproveModel.DataApproveRecord)
+	if e = recordOb.CreateMulti(newRecords); e != nil {
+		err = fmt.Errorf("生成节点审批记录失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送审批消息
+	go func() {
+		messageOb := new(dataApproveModel.DataApproveMessage)
+		messages := make([]*dataApproveModel.DataApproveMessage, 0)
+		for _, v := range newRecords {
+			m := new(dataApproveModel.DataApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = "您有新的待办任务"
+			m.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", sysAdminName, title)
+			m.DataApproveId = approveId
+			m.ApproveState = DataApproveStateApproving
+			m.CreateTime = now
+			m.ModifyTime = now
+			messages = append(messages, m)
+		}
+		e = messageOb.CreateMulti(messages)
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("BuildNextNodeRecordAndMsg messages err: %s", e.Error()))
+			return
+		}
+	}()
+
+	return
+}
+
+// updateDataApproveState 更新待审批资产的审批状态
+func updateDataApproveState(dataApprove *dataApproveModel.DataApprove, state int) (err error) {
+	// TODO 根据审批单去通过、驳回公开图库申请
+	obj := dataApproveModel.DataApproveRelation{}
+	dataList, err := obj.GetListByDataApproveId(dataApprove.DataApproveId)
+	if err != nil {
+		return
+	}
+
+	dataItemList := make([]SetDataPublicItem, 0)
+	for _, v := range dataList {
+		dataItemList = append(dataItemList, SetDataPublicItem{ClassifyId: v.ClassifyId, DataId: v.DataId})
+	}
+
+	err = UpdatePublicByDataList(dataApprove.DataType, state, dataItemList)
+
+	return
+}
+
+// UpdatePublicByDataList
+// @Description: 更新公共资产权限
+// @author: Roc
+// @datetime 2024-12-06 13:44:20
+// @param dataType int
+// @param dataApproveState int
+// @param dataList []SetDataPublicItem
+// @return err error
+func UpdatePublicByDataList(dataType, dataApproveState int, dataList []SetDataPublicItem) (err error) {
+	dataIdList := make([]int, 0)
+	for _, v := range dataList {
+		dataIdList = append(dataIdList, v.DataId)
+	}
+	switch dataType {
+	case DataTypeEdb:
+		switch dataApproveState {
+		case DataApproveStateApproving:
+			err = data_manage.UpdatePublicEdb(dataIdList, utils.EdbPublicSuccess)
+		case DataApproveStatePass:
+			for _, dataItem := range dataList {
+				err = data_manage.UpdatePublicEdbSuccess(dataItem.DataId, dataItem.ClassifyId)
+			}
+		case DataApproveStateRefuse:
+			err = data_manage.UpdatePublicEdb(dataIdList, utils.EdbPublicReject)
+		case DataApproveStateCancel:
+			err = data_manage.UpdatePublicEdb(dataIdList, utils.EdbPublicDefault)
+		}
+
+		// 更新ES
+		for _, dataId := range dataIdList {
+			data.AddOrEditEdbInfoToEs(dataId)
+		}
+	// 指标库
+	case DataTypeChart:
+		// 图库
+		// TODO
+	}
+
+	return
+}
+
+func ProcessingDataApprove(adminId, dataType, timeType, sortField, sortRule, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.DataApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND b.%s = ? AND a.%s = ?`, dataApproveModel.DataApproveRecordCols.State, dataApproveModel.DataApproveCols.State, dataApproveModel.DataApproveRecordCols.ApproveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, DataApproveStateApproving, DataApproveStateApproving, adminId)
+	order := ""
+
+	// 筛选条件
+	if dataType > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, dataApproveModel.DataApproveCols.DataType)
+		pars = append(pars, dataType)
+	}
+	if timeType <= 0 {
+		timeType = 1
+	}
+	if timeType == 1 && startTime != "" && endTime != "" {
+		_, e := time.Parse(utils.FormatDate, startTime)
+		if e != nil {
+			msg = "开始时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime, e := time.Parse(utils.FormatDate, endTime)
+		if e != nil {
+			msg = "结束时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime = tmpEndTime.AddDate(0, 0, 1)
+		cond += fmt.Sprintf(` AND (b.%s BETWEEN ? AND ?)`, dataApproveModel.DataApproveCols.CreateTime)
+		pars = append(pars, startTime, tmpEndTime)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND b.%s LIKE ?`, dataApproveModel.DataApproveCols.Title)
+		pars = append(pars, kw)
+	}
+	if sortField > 0 && sortRule > 0 {
+		orderField := timeField[sortField]
+		if orderField == "" {
+			msg = "时间排序字段有误"
+			return
+		}
+		orderRule := orderRules[sortRule]
+		if orderRule == "" {
+			msg = "时间排序方式有误"
+			return
+		}
+		order = fmt.Sprintf("%s %s", orderField, orderRule)
+	}
+	total, e := dataApproveModel.GetApprovingDataApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingDataApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := dataApproveModel.GetApprovingDataApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingDataApprovePageList err: %s", e.Error())
+		return
+	}
+
+	respList = toDataApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+// SolvedDataApprove 已处理的审批
+func SolvedDataApprove(adminId, dataType, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.DataApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND a.%s IN (?)`, dataApproveModel.DataApproveRecordCols.ApproveUserId, dataApproveModel.DataApproveRecordCols.NodeState)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId, []int{DataApproveStatePass, DataApproveStateRefuse})
+	order := ""
+
+	// 筛选条件
+	if dataType > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, dataApproveModel.DataApproveCols.DataType)
+		pars = append(pars, dataType)
+	}
+	if timeType > 0 && startTime != "" && endTime != "" {
+		_, e := time.Parse(utils.FormatDate, startTime)
+		if e != nil {
+			msg = "开始时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime, e := time.Parse(utils.FormatDate, endTime)
+		if e != nil {
+			msg = "结束时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime = tmpEndTime.AddDate(0, 0, 1)
+		cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, timeField[timeType])
+		pars = append(pars, startTime, tmpEndTime)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND b.%s LIKE ?`, dataApproveModel.DataApproveCols.Title)
+		pars = append(pars, kw)
+	}
+	if sortField > 0 && sortRule > 0 {
+		orderField := timeField[sortField]
+		if orderField == "" {
+			msg = "时间排序字段有误"
+			return
+		}
+		orderRule := orderRules[sortRule]
+		if orderRule == "" {
+			msg = "时间排序方式有误"
+			return
+		}
+		order = fmt.Sprintf("%s %s", orderField, orderRule)
+	}
+	if approveState > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveRecordCols.NodeState)
+		pars = append(pars, approveState)
+	}
+	total, e := dataApproveModel.GetApprovedDataApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedDataApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := dataApproveModel.GetApprovedDataApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedDataApprovePageList err: %s", e.Error())
+		return
+	}
+
+	for _, v := range list {
+		// 这个时候的状态,用审批状态
+		v.RecordState = v.NodeState
+		v.ApproveTime = v.NodeApproveTime
+	}
+	respList = toDataApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+func MyApplyDataApproves(adminId, dataType, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.DataApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveCols.ApplyUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := ""
+
+	// 筛选条件
+	if dataType > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveCols.DataType)
+		pars = append(pars, dataType)
+	}
+	if timeType > 0 && startTime != "" && endTime != "" {
+		_, e := time.Parse(utils.FormatDate, startTime)
+		if e != nil {
+			msg = "开始时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTime, e := time.Parse(utils.FormatDate, endTime)
+		if e != nil {
+			msg = "结束时间格式有误"
+			err = e
+			return
+		}
+		tmpEndTimeStr := tmpEndTime.AddDate(0, 0, 1).Format(utils.FormatDate)
+		cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, myTimeField[timeType])
+		pars = append(pars, startTime, tmpEndTimeStr)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND a.%s LIKE ?`, dataApproveModel.DataApproveCols.Title)
+		pars = append(pars, kw)
+	}
+	if sortField > 0 && sortRule > 0 {
+		orderField := myTimeField[sortField]
+		if orderField == "" {
+			msg = "时间排序字段有误"
+			return
+		}
+		orderRule := orderRules[sortRule]
+		if orderRule == "" {
+			msg = "时间排序方式有误"
+			return
+		}
+		order = fmt.Sprintf("%s %s", orderField, orderRule)
+	}
+	if approveState > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, dataApproveModel.DataApproveRecordCols.State)
+		pars = append(pars, approveState)
+	}
+	total, e := dataApproveModel.GetApplyDataApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyDataApproveCount err: %s", e.Error())
+		return
+	}
+	respTotal = total
+	list, e := dataApproveModel.GetApplyDataApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyDataApprovePageList err: %s", e.Error())
+		return
+	}
+	respList = toDataApproveItemOrmResp(list)
+	return
+}
+
+func GetApproveDetail(approveId int) (resp *response.DataApproveDetail, msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批已被删除, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemById err: %s", e.Error())
+		return
+	}
+
+	// 审批信息
+	detail := new(response.DataApproveDetail)
+	detail.Approve = new(response.DataApproveDetailItem)
+	detail.Approve.DataApproveId = approveItem.DataApproveId
+	detail.Approve.State = approveItem.State
+	detail.Approve.FlowId = approveItem.FlowId
+	detail.Approve.FlowVersion = approveItem.FlowVersion
+	detail.Approve.StartNodeId = approveItem.StartNodeId
+	detail.Approve.CurrNodeId = approveItem.CurrNodeId
+	detail.Approve.ApplyUserId = approveItem.ApplyUserId
+	detail.Approve.ApplyUserName = approveItem.ApplyUserName
+	detail.Approve.ApproveTime = utils.TimeTransferString(utils.FormatDateTime, approveItem.ApproveTime)
+	detail.Approve.CreateTime = utils.TimeTransferString(utils.FormatDateTime, approveItem.CreateTime)
+	detail.Approve.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, approveItem.ModifyTime)
+
+	// 审批节点
+	nodeOb := new(dataApproveModel.DataApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, dataApproveModel.DataApproveNodeCols.DataApproveFlowId, dataApproveModel.DataApproveNodeCols.CurrVersion)
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, approveItem.FlowId, approveItem.FlowVersion)
+	nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemsByCondition err: %s", e.Error())
+		return
+	}
+
+	// 审批记录
+	recordOb := new(dataApproveModel.DataApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveRecordCols.DataApproveId)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.DataApproveId)
+	recordItems, e := recordOb.GetItemsByCondition(recordCond, recordPars, []string{}, fmt.Sprintf("%s DESC", dataApproveModel.DataApproveRecordCols.ApproveTime))
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	recordMap := make(map[string]*dataApproveModel.DataApproveRecord)
+	for _, v := range recordItems {
+		k := fmt.Sprintf("%d-%d", v.NodeId, v.ApproveUserId)
+		recordMap[k] = v
+	}
+
+	// 审批流节点详情
+	detail.ApproveFlowNodes = make([]*response.DataApproveDetailNodes, 0)
+	for _, v := range nodeItems {
+		t := new(response.DataApproveDetailNodes)
+		t.DataApproveNodeId = v.DataApproveNodeId
+		t.DataApproveFlowId = v.DataApproveFlowId
+		t.PrevNodeId = v.PrevNodeId
+		t.NextNodeId = v.NextNodeId
+		t.NodeType = v.NodeType
+		t.ApproveType = v.ApproveType
+		t.Users = make([]*response.DataApproveDetailNodeUser, 0)
+		us := make([]*response.DataApproveNodeUserReq, 0)
+		if v.Users != "" {
+			e = json.Unmarshal([]byte(v.Users), &us)
+			if e != nil {
+				msg = "获取失败"
+				err = fmt.Errorf("json.Unmarshal err: %s", e.Error())
+				return
+			}
+		}
+		for _, vu := range us {
+			u := new(response.DataApproveDetailNodeUser)
+			u.UserType = vu.UserType
+			u.UserId = vu.UserId
+			u.UserName = vu.UserName
+			u.Sort = vu.Sort
+			// 审批记录
+			k := fmt.Sprintf("%d-%d", v.DataApproveNodeId, vu.UserId)
+			r := recordMap[k]
+			if r != nil {
+				u.ApproveRecord = new(response.DataApproveDetailNodeUserRecord)
+				u.ApproveRecord.DataApproveRecordId = r.DataApproveRecordId
+				u.ApproveRecord.State = r.State
+				u.ApproveRecord.ApproveUserId = r.ApproveUserId
+				u.ApproveRecord.ApproveUserName = r.ApproveUserName
+				u.ApproveRecord.ApproveRemark = r.ApproveRemark
+				u.ApproveRecord.ApproveTime = utils.TimeTransferString(utils.FormatDateTime, r.ApproveTime)
+			}
+			t.Users = append(t.Users, u)
+		}
+		sort.Slice(t.Users, func(k, j int) bool {
+			return t.Users[k].Sort < t.Users[j].Sort
+		})
+		detail.ApproveFlowNodes = append(detail.ApproveFlowNodes, t)
+	}
+
+	// 返回审批数据明细
+	dataList := make([]response.DataApproveDetailData, 0)
+	{
+		obj := new(dataApproveModel.DataApproveRelation)
+		dataItemList, tmpErr := obj.GetListByDataApproveId(approveItem.DataApproveId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		dataIdList := make([]int, 0)
+		dataIdClassifyIdMap := make(map[int]int)
+		for _, v := range dataItemList {
+			dataIdList = append(dataIdList, v.DataId)
+			dataIdClassifyIdMap[v.DataId] = v.ClassifyId
+		}
+
+		switch approveItem.DataType {
+		case DataTypeEdb: // 指标库
+			tmpList, tmpErr := data_manage.GetEdbInfoByIdList(dataIdList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			for _, v := range tmpList {
+				item := response.DataApproveDetailData{
+					DataId:       v.EdbInfoId,
+					DataName:     v.EdbName,
+					DataCode:     v.UniqueCode,
+					DataClassify: dataIdClassifyIdMap[v.EdbInfoId],
+				}
+				dataList = append(dataList, item)
+			}
+		case DataTypeChart: // 图库
+			tmpList, tmpErr := data_manage.GetChartInfoByIdList(dataIdList)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			for _, v := range tmpList {
+				item := response.DataApproveDetailData{
+					DataId:       v.ChartInfoId,
+					DataName:     v.ChartName,
+					DataCode:     v.UniqueCode,
+					DataClassify: dataIdClassifyIdMap[v.ChartInfoId],
+				}
+				dataList = append(dataList, item)
+			}
+		}
+	}
+
+	detail.DataList = dataList
+	resp = detail
+	return
+}
+
+func DataApproveRefuse(DataApproveId, adminId int, approveRemark string) (msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(DataApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetDataApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.State != DataApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	// 校验审批记录和审批
+	recordOb := new(dataApproveModel.DataApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?`, dataApproveModel.DataApproveRecordCols.DataApproveId, dataApproveModel.DataApproveRecordCols.ApproveUserId, dataApproveModel.DataApproveRecordCols.State)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.DataApproveId, adminId, DataApproveStateApproving)
+	recordItem, e := recordOb.GetItemByCondition(recordCond, recordPars, "")
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "无权审批"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 驳回审批
+	if e = refuseDataApprove(approveItem, recordItem, approveRemark, adminId); e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("RefuseDataApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// refuseDataApprove 驳回审批
+func refuseDataApprove(approveItem *dataApproveModel.DataApprove, recordItem *dataApproveModel.DataApproveRecord, approveRemark string, sysAdminId int) (err error) {
+	if approveItem == nil {
+		err = fmt.Errorf("审批信息有误")
+		return
+	}
+	if recordItem == nil {
+		err = fmt.Errorf("审批记录有误")
+		return
+	}
+
+	// 更新审批记录
+	now := time.Now().Local()
+	recordItem.State = DataApproveStateRefuse
+	recordItem.ApproveRemark = approveRemark
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+
+	recordItem.NodeState = DataApproveStateRefuse
+	recordItem.NodeApproveUserId = recordItem.ApproveUserId
+	recordItem.NodeApproveUserName = recordItem.ApproveUserName
+	recordItem.NodeApproveTime = now
+
+	recordCols := []string{"State", "ApproveRemark", "ApproveTime", "ModifyTime", "NodeState", "NodeApproveUserId", "NodeApproveUserName", "NodeApproveTime"}
+	if e := recordItem.Update(recordCols); e != nil {
+		err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 将该审批的同一个节点的记录标记为已审批
+	if e := recordItem.UpdateNodeState(recordItem.DataApproveId, recordItem.NodeId, recordItem.NodeState, recordItem.NodeApproveUserId, recordItem.NodeApproveUserName, recordItem.NodeApproveTime); e != nil {
+		err = fmt.Errorf("更新同一节点的其他审批记录状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 驳回-更新审批, 报告状态, 推送消息
+	approveItem.State = DataApproveStateRefuse
+	approveItem.ApproveRemark = approveRemark
+	approveItem.ApproveTime = now
+	approveItem.ModifyTime = now
+	approveCols := []string{"State", "ApproveRemark", "ApproveTime", "ModifyTime"}
+	if e := approveItem.Update(approveCols); e != nil {
+		err = fmt.Errorf("更新审批状态失败, Err: %s", e.Error())
+		return
+	}
+
+	if e := updateDataApproveState(approveItem, DataApproveStateRefuse); e != nil {
+		err = fmt.Errorf("更新报告状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送驳回消息给申请人
+	go func() {
+		messageItem := new(dataApproveModel.DataApproveMessage)
+		messageItem.SendUserId = sysAdminId
+		messageItem.ReceiveUserId = approveItem.ApplyUserId
+		messageItem.Content = "您提交的审批被驳回"
+		messageItem.Remark = fmt.Sprintf("您提交的【%s】已被驳回", approveItem.Title)
+		messageItem.DataApproveId = approveItem.DataApproveId
+		messageItem.ApproveState = DataApproveStateRefuse
+		messageItem.CreateTime = now
+		messageItem.ModifyTime = now
+		if e := messageItem.Create(); e != nil {
+			utils.FileLog.Info(fmt.Sprintf("ApproveData message err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+func DataApproveCancel(DataApproveId, adminId int, adminName string) (msg string, err error) {
+	approveItem, e := dataApproveModel.GetDataApproveById(DataApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批已被删除, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetDataApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.ApplyUserId != adminId {
+		msg = "非申请人不可撤销"
+		err = fmt.Errorf("非申请人不可撤销")
+		return
+	}
+
+	// 撤销审批
+	e = cancelDataApprove(approveItem, approveItem.DataApproveId, adminId, adminName)
+	if e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("cancelDataApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// cancelDataApprove 撤回审批
+func cancelDataApprove(item *dataApproveModel.DataApprove, approveId, sysAdminId int, sysAdminName string) (err error) {
+	// todo
+	//// 默认内部审批, 如果是走的第三方审批, 那么仅修改状态
+	//confMap, e := models.GetBusinessConf()
+	//if e != nil {
+	//	err = fmt.Errorf("GetBusinessConf err: %s", e.Error())
+	//	return
+	//}
+	//openMap := map[string]bool{"false": false, "true": true}
+	//openApprove := openMap[confMap[models.BusinessConfIsDataApprove]]
+	//if !openApprove {
+	//	//err = fmt.Errorf("未开启审批")
+	//	return
+	//}
+
+	// 修改审批信息状态
+	approveItem, e := dataApproveModel.GetDataApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			err = e
+			return
+		}
+		err = fmt.Errorf("approve GetItemById err: %s", e.Error())
+		return
+	}
+	if approveItem.State == DataApproveStateCancel {
+		return
+	}
+	approveItem.State = DataApproveStateCancel
+	approveItem.ModifyTime = time.Now()
+	cols := []string{"State", "ModifyTime"}
+	if e = approveItem.Update(cols); e != nil {
+		err = fmt.Errorf("approve Update err: %s", e.Error())
+		return
+	}
+
+	// 修改报告状态
+	e = updateDataApproveState(approveItem, DataApproveStateCancel)
+	if e != nil {
+		err = fmt.Errorf("更新报告审批撤回失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送撤回消息
+	go func() {
+		recordOb := new(dataApproveModel.DataApproveRecord)
+		recordCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveRecordCols.DataApproveId)
+		recordPars := make([]interface{}, 0)
+		recordPars = append(recordPars, approveId)
+		recordItems, e := recordOb.GetItemsByCondition(recordCond, recordPars, []string{}, "")
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("approve record GetItemsByCondition err: %s", e.Error()))
+			return
+		}
+
+		messageOb := new(dataApproveModel.DataApproveMessage)
+		messages := make([]*dataApproveModel.DataApproveMessage, 0)
+		for _, v := range recordItems {
+			m := new(dataApproveModel.DataApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = fmt.Sprintf("%s提交的【%s】已撤回", sysAdminName, approveItem.Title)
+			m.DataApproveId = approveId
+			m.ApproveState = DataApproveStateCancel
+			m.CreateTime = time.Now().Local()
+			m.ModifyTime = time.Now().Local()
+			messages = append(messages, m)
+		}
+		e = messageOb.CreateMulti(messages)
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("CancelDataApprove messages err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+// CheckOpenApprove 校验报告是否开启了审批流
+func CheckOpenApprove(dataType int) (opening bool, err error) {
+	// 查询对应分类是否有审批流
+	flowOb := new(dataApproveModel.DataApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveFlowCols.DataType)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, dataType)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			return
+		}
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 查看审批节点
+	if flowItem.DataApproveFlowId > 0 {
+
+		nodeOb := new(dataApproveModel.DataApproveNode)
+		nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ? `, dataApproveModel.DataApproveNodeCols.DataApproveFlowId, dataApproveModel.DataApproveNodeCols.CurrVersion)
+		nodePars := make([]interface{}, 0)
+		nodePars = append(nodePars, flowItem.DataApproveFlowId, flowItem.CurrVersion)
+		nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+		if e != nil {
+			err = e
+			return
+		}
+
+		// 如果有审批节点,那么就确实有审批流,那么就返回true
+		if len(nodeItems) > 0 {
+			opening = true
+			return
+		}
+	}
+
+	return
+}
+
+type SetDataPublicItem struct {
+	DataId     int
+	ClassifyId int
+}
+
+// SubmitDataApprove
+// @Description: 提交审批
+// @author: Roc
+// @datetime 2024-12-06 10:13:40
+// @param dataType int
+// @param dataIdList []int
+// @param title string
+// @param description string
+// @param sysAdminId int
+// @param sysAdminName string
+// @return approveId int
+// @return err error
+func SubmitDataApprove(dataType int, dataList []SetDataPublicItem, title, description string, sysAdminId int, sysAdminName string) (approveId int, err error) {
+	// 查询审批流
+	flowOb := new(dataApproveModel.DataApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, dataApproveModel.DataApproveFlowCols.DataType)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, dataType)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 查询审批节点
+	nodeOb := new(dataApproveModel.DataApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, dataApproveModel.DataApproveNodeCols.DataApproveFlowId, dataApproveModel.DataApproveNodeCols.CurrVersion)
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, flowItem.DataApproveFlowId, flowItem.CurrVersion)
+	nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "")
+	if e != nil {
+		err = fmt.Errorf("ApproveNodes GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	if len(nodeItems) == 0 {
+		err = fmt.Errorf("无审批节点")
+		return
+	}
+
+	// 取出首个节点
+	firstNodeItem := new(dataApproveModel.DataApproveNode)
+	for _, v := range nodeItems {
+		if v.PrevNodeId == 0 {
+			firstNodeItem = v
+			continue
+		}
+	}
+	if firstNodeItem == nil {
+		err = fmt.Errorf("首个审批节点有误")
+		return
+	}
+
+	// 审批信息
+	now := time.Now().Local()
+	newApprove := new(dataApproveModel.DataApprove)
+	newApprove.Title = title
+	newApprove.ApproveRemark = description
+	newApprove.DataType = dataType
+	newApprove.State = DataApproveStateApproving
+	newApprove.FlowId = flowItem.DataApproveFlowId
+	newApprove.FlowVersion = flowItem.CurrVersion
+	newApprove.StartNodeId = firstNodeItem.DataApproveNodeId
+	newApprove.CurrNodeId = firstNodeItem.DataApproveNodeId
+	newApprove.ApplyUserId = sysAdminId
+	newApprove.ApplyUserName = sysAdminName
+	newApprove.CreateTime = now
+	newApprove.ModifyTime = now
+
+	relationList := make([]*dataApproveModel.DataApproveRelation, 0)
+	for _, dataItem := range dataList {
+		relationList = append(relationList, &dataApproveModel.DataApproveRelation{
+			DataApproveRelationId: 0,
+			DataApproveId:         0,
+			DataId:                dataItem.DataId,
+			ClassifyId:            dataItem.ClassifyId,
+			CreateTime:            now,
+		})
+	}
+	e = dataApproveModel.AddDataApprove(newApprove, relationList)
+	if e != nil {
+		err = fmt.Errorf("生成审批信息失败, Err: %s", e.Error())
+		return
+	}
+
+	approveId = newApprove.DataApproveId
+
+	// 生成节点审批记录
+	err = BuildNextNodeRecordAndMsg(firstNodeItem, newApprove.DataApproveId, sysAdminId, sysAdminName, newApprove.Title)
+
+	return
+}
+
+func toDataApproveItemOrmResp(src []*dataApproveModel.DataApproveItemOrm) (res []*response.DataApproveItemOrmResp) {
+	for _, v := range src {
+		r := new(response.DataApproveItemOrmResp)
+		r.DataApproveId = v.DataApproveId
+		r.DataApproveRecordId = v.DataApproveRecordId
+		r.Title = v.Title
+		r.DataType = v.DataType
+		r.State = v.State
+		r.RecordState = v.RecordState
+		r.FlowId = v.FlowId
+		r.FlowVersion = v.FlowVersion
+		r.StartNodeId = v.StartNodeId
+		r.CurrNodeId = v.CurrNodeId
+		r.ApplyUserId = v.ApplyUserId
+		r.ApplyUserName = v.ApplyUserName
+		r.ApproveRemark = v.ApproveRemark
+		r.ApproveTime = utils.TimeTransferString(utils.FormatDateTime, v.ApproveTime)
+		r.HandleTime = utils.TimeTransferString(utils.FormatDateTime, v.HandleTime)
+		r.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime)
+		r.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime)
+		r.NodeState = v.NodeState
+		res = append(res, r)
+	}
+	return
+}
+
+// CheckHasDataApproving
+// @Description: 查询是否还存在带审批的审批单
+// @author: Roc
+// @datetime 2024-12-06 10:43:00
+// @return ok bool
+// @return err error
+func CheckHasDataApproving() (ok bool, err error) {
+	count, err := dataApproveModel.GetDataApproveCountByState(DataApproveStateApproving)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		ok = true
+	}
+	return
+}

+ 174 - 0
services/data/data_approve/approve_flow.go

@@ -0,0 +1,174 @@
+package data_approve
+
+import (
+	"encoding/json"
+	DataApprove "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/request"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// SaveDataApproveFlow 保存审批流
+func SaveDataApproveFlow(flow *request.DataApproveFlowSaveReq) (ok bool, msg string, err error) {
+
+	flowInfo, err := DataApprove.GetDataApproveFlowByDataType(flow.DataType)
+	if err != nil {
+		if !utils.IsErrNoRow(err) {
+			msg = "保存审批流失败, 查找审批流失败"
+			return
+		}
+	}
+
+	if flowInfo.DataApproveFlowId <= 0 {
+		// 之前没有过记录,所以走新增
+		var remark string
+		switch flow.DataType {
+		case 1:
+			remark = `指标审批`
+		case 2:
+			remark = `图表审批`
+		}
+		t := &DataApprove.DataApproveFlow{
+			FlowName:    flow.FlowName,
+			DataType:    flow.DataType,
+			Remark:      remark,
+			CurrVersion: 1,
+			CreateTime:  time.Now(),
+			ModifyTime:  time.Now(),
+		}
+		flowNodeItems := make([]*DataApprove.DataApproveNode, 0)
+		for _, node := range flow.Nodes {
+			flowNode := new(DataApprove.DataApproveNode)
+			flowNode.ApproveType = node.ApproveType
+			flowNode.CurrVersion = t.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			flowNode.Users = string(userBytes)
+			flowNode.CreatedTime = time.Now()
+			flowNodeItems = append(flowNodeItems, flowNode)
+		}
+		err = t.Add(flowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	} else {
+		ok, err = CheckDeleteDataApproveFlow(flowInfo.DataApproveFlowId)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		if !ok {
+			msg = "保存审批流失败, 存在还未审批的报告"
+			return
+		}
+		var updateCols []string
+		if flowInfo.FlowName != flow.FlowName {
+			flowInfo.FlowName = flow.FlowName
+			updateCols = append(updateCols, "flow_name")
+		}
+		flowInfo.CurrVersion += 1
+		flowInfo.ModifyTime = time.Now()
+		updateCols = append(updateCols, "modify_time", "curr_version")
+
+		biFlowNodeItems := make([]*DataApprove.DataApproveNode, 0)
+		for _, node := range flow.Nodes {
+			flowNode := new(DataApprove.DataApproveNode)
+			flowNode.ApproveType = node.ApproveType
+			flowNode.CurrVersion = flowInfo.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			flowNode.Users = string(userBytes)
+			flowNode.CreatedTime = time.Now()
+			biFlowNodeItems = append(biFlowNodeItems, flowNode)
+		}
+
+		err = flowInfo.Update(updateCols, biFlowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	}
+	return
+}
+
+// GetDataApproveFlowDetail 获取审批流详情
+func GetDataApproveFlowDetail(dataType int) (detail *response.DataApproveFlowDetailResp, msg string, err error) {
+	flowInfo, err := DataApprove.GetDataApproveFlowByDataType(dataType)
+	if err != nil && !utils.IsErrNoRow(err) {
+		msg = "获取审批流详情失败"
+		return
+	}
+	flowNodes := make([]*DataApprove.DataApproveNode, 0)
+
+	// 如果有配置的话
+	if flowInfo.DataApproveFlowId > 0 {
+		flowNodes, err = DataApprove.GetDataApproveNodeByFlowIdAndVersionId(flowInfo.DataApproveFlowId, flowInfo.CurrVersion)
+		if err != nil {
+			msg = "获取审批流详情失败"
+			return
+		}
+	}
+
+	detail, err = FormatFlowAndNodesItem2Detail(flowInfo, flowNodes)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	return
+}
+
+// CheckDeleteDataApproveFlow 检查是否可以删除审批流
+func CheckDeleteDataApproveFlow(flowId int) (ok bool, err error) {
+	flowInfo, err := DataApprove.GetDataApproveFlowById(flowId)
+	if err != nil {
+		return
+	}
+	// 检查是否存在还未审批的Bi看报
+	approveList, err := DataApprove.GetDataApproveByFlowIdAndVersionId(flowInfo.DataApproveFlowId, flowInfo.CurrVersion)
+	if err != nil {
+		return
+	}
+	for _, v := range approveList {
+		if v.State == DataApproveStateApproving {
+			return false, nil
+		}
+	}
+
+	ok = true
+	return
+}
+
+func FormatFlowAndNodesItem2Detail(flowItem *DataApprove.DataApproveFlow, nodeItems []*DataApprove.DataApproveNode) (detail *response.DataApproveFlowDetailResp, err error) {
+	if flowItem == nil {
+		return
+	}
+	detail = new(response.DataApproveFlowDetailResp)
+	detail.DataApproveFlowId = flowItem.DataApproveFlowId
+	detail.FlowName = flowItem.FlowName
+	detail.DataType = flowItem.DataType
+	detail.CreateTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.CreateTime)
+	detail.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.ModifyTime)
+	detail.Nodes = make([]*response.DataApproveNodeItem, 0)
+	for _, v := range nodeItems {
+		t, e := FormatDataApproveNode2Item(v)
+		if e != nil {
+			err = fmt.Errorf("format node err: %s", e.Error())
+			return
+		}
+		detail.Nodes = append(detail.Nodes, t)
+	}
+	return
+}

+ 89 - 0
services/data/data_approve/approve_message.go

@@ -0,0 +1,89 @@
+package data_approve
+
+import (
+	DataApprove "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+func GetDataApproveMessage(adminId, startSize, pageSize int) (list []*response.DataApproveMessageItem, total, unread int, msg string, err error) {
+	cond := fmt.Sprintf(` AND %s = ?`, DataApprove.DataApproveMessageCols.ReceiveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := fmt.Sprintf(`%s ASC, %s DESC`, DataApprove.DataApproveMessageCols.IsRead, DataApprove.DataApproveMessageCols.CreateTime)
+
+	messageOb := new(DataApprove.DataApproveMessage)
+	total, e := messageOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetCountByCondition, Err: %s", e.Error())
+		return
+	}
+	tmpList, e := messageOb.GetPageItemsByCondition(cond, pars, []string{}, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetPageItemsByCondition, Err: %s", e.Error())
+		return
+	}
+	for _, v := range tmpList {
+		t := FormatDataApproveMessage2Item(v)
+		list = append(list, t)
+	}
+
+	// 未读消息数
+	cond += fmt.Sprintf(` AND %s = ?`, DataApprove.DataApproveMessageCols.IsRead)
+	pars = append(pars, 0)
+	unreadTotal, e := messageOb.GetCountByCondition(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetCountByCondition, Err: %s", e.Error())
+		return
+	}
+	unread = unreadTotal
+	return
+}
+
+func ReadBiMessage(msgId int, adminId int) (msg string, err error) {
+	messageOb := new(DataApprove.DataApproveMessage)
+	messageItem, e := messageOb.GetItemById(msgId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "消息不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "获取失败"
+		err = fmt.Errorf("message.GetItemById, Err: %s", e.Error())
+		return
+	}
+	messageItem.IsRead = 1
+	messageItem.ModifyTime = time.Now().Local()
+	cols := []string{"IsRead", "ModifyTime"}
+	if e = messageItem.Update(cols); e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("message.Update, Err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// FormatDataApproveMessage2Item 格式化报告审批消息
+func FormatDataApproveMessage2Item(origin *DataApprove.DataApproveMessage) (item *response.DataApproveMessageItem) {
+	item = new(response.DataApproveMessageItem)
+	if origin == nil {
+		return
+	}
+	item.Id = origin.Id
+	item.SendUserId = origin.SendUserId
+	item.ReceiveUserId = origin.ReceiveUserId
+	item.Content = origin.Content
+	item.Remark = origin.Remark
+	item.DataApproveId = origin.DataApproveId
+	item.ApproveState = origin.ApproveState
+	item.IsRead = origin.IsRead
+	item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, origin.CreateTime)
+	item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ModifyTime)
+	return
+}

+ 31 - 0
services/data/data_approve/approve_node.go

@@ -0,0 +1,31 @@
+package data_approve
+
+import (
+	"encoding/json"
+	DataApprove "eta_gn/eta_api/models/data_manage/data_approve"
+	"eta_gn/eta_api/models/data_manage/data_approve/response"
+	"fmt"
+)
+
+// FormatDataApproveNode2Item 格式化报告审批节点信息
+func FormatDataApproveNode2Item(origin *DataApprove.DataApproveNode) (item *response.DataApproveNodeItem, err error) {
+	if origin == nil {
+		return
+	}
+	item = new(response.DataApproveNodeItem)
+	item.DataApproveNodeId = origin.DataApproveNodeId
+	item.DataApproveFlowId = origin.DataApproveFlowId
+	item.PrevNodeId = origin.PrevNodeId
+	item.NextNodeId = origin.NextNodeId
+	item.NodeType = origin.NodeType
+	item.ApproveType = origin.ApproveType
+	item.Users = make([]*response.DataApproveNodeUser, 0)
+	if origin.Users != "" {
+		e := json.Unmarshal([]byte(origin.Users), &item.Users)
+		if e != nil {
+			err = fmt.Errorf("node users unmarshal err: %s", e.Error())
+			return
+		}
+	}
+	return
+}

+ 37 - 0
services/data/data_approve/constant.go

@@ -0,0 +1,37 @@
+package data_approve
+
+// 看板状态
+const (
+	BiStateUnpublished = 1 // 未公开
+	// BiStatePublished   = 2 // 已发布
+	// BiStateWaitSubmit  = 3 // 待提交
+	BiStateWaitApprove = 4 // 待审批
+	BiStateRefused     = 5 // 已驳回
+	BiStatePass        = 6 // 已通过
+)
+
+const (
+	DataTypeEdb   = 1 // 指标审批
+	DataTypeChart = 2 // 图库审批
+)
+
+// 节点审批方式
+const (
+	NodeApproveTypeRoll = 1 // 依次审批
+	NodeApproveTypeAll  = 2 // 会签
+	NodeApproveTypeAny  = 3 // 或签
+)
+
+// 节点审批人类型
+const (
+	NodeUserTypeNormal = "user" // 用户
+	NodeUserTypeRole   = "role" // 角色
+)
+
+// 报告审批状态
+const (
+	DataApproveStateApproving = 1 // 待审批
+	DataApproveStatePass      = 2 // 已审批
+	DataApproveStateRefuse    = 3 // 已驳回
+	DataApproveStateCancel    = 4 // 已撤销
+)

+ 16 - 19
services/data/edb_classify.go

@@ -263,9 +263,9 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 		var count int
 		switch lang {
 		case utils.EnLangVersion:
-			count, err = data_manage.GetEdbClassifyEnCount(classifyName, parentId, classifyType)
+			count, err = data_manage.GetEdbClassifyEnCount(classifyName, parentId, sysUserId, classifyType)
 		default:
-			count, err = data_manage.GetEdbClassifyCount(classifyName, parentId, classifyType)
+			count, err = data_manage.GetEdbClassifyCount(classifyName, parentId, sysUserId, classifyType)
 		}
 		if err != nil {
 			errMsg = `判断名称是否已存在失败`
@@ -337,21 +337,6 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 		errMsg = "保存分类失败"
 		return
 	}
-	// 更改分类id完整路径path
-	classifyInfo.ClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.ClassifyId)
-	_ = classifyInfo.Update([]string{"ClassifyIdPath"})
-
-	// 继承分类权限
-	{
-		source := utils.EdbPermissionSourceBase
-		if classifyType == 1 {
-			source = utils.EdbPermissionSourcePredict
-		}
-		if classifyType == utils.EdbClassifyTypeCalculate {
-			source = utils.EdbPermissionSourceCalculate
-		}
-		go data_manage_permission.InheritParentClassify(source, int(classifyType), classifyInfo.ClassifyId, classifyInfo.ParentId, classifyInfo.ClassifyName)
-	}
 
 	// 更改分类id完整路径path
 	updateCols := []string{"ClassifyIdPath"}
@@ -368,6 +353,18 @@ func AddEdbClassify(classifyName string, parentId, level int, classifyType uint8
 		return
 	}
 
+	// 继承分类权限
+	{
+		source := utils.EdbPermissionSourceBase
+		if classifyType == 1 {
+			source = utils.EdbPermissionSourcePredict
+		}
+		if classifyType == utils.EdbClassifyTypeCalculate {
+			source = utils.EdbPermissionSourceCalculate
+		}
+		go data_manage_permission.InheritParentClassify(source, int(classifyType), classifyInfo.ClassifyId, classifyInfo.ParentId, classifyInfo.ClassifyName)
+	}
+
 	return
 }
 
@@ -423,7 +420,7 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 		}
 
 		// 判断名称是否已存在
-		count, tmpErr := data_manage.GetEdbClassifyEnCount(classifyName, item.ParentId, item.ClassifyType)
+		count, tmpErr := data_manage.GetEdbClassifyEnCount(classifyName, item.ParentId, sysUser.AdminId, item.ClassifyType)
 		if tmpErr != nil {
 			err = tmpErr
 			errMsg = "判断名称是否已存在失败"
@@ -446,7 +443,7 @@ func EditEdbClassify(classifyId int, classifyName, lang string, sysUser *system.
 		}
 
 		// 判断名称是否已存在
-		count, tmpErr := data_manage.GetEdbClassifyCount(classifyName, item.ParentId, item.ClassifyType)
+		count, tmpErr := data_manage.GetEdbClassifyCount(classifyName, item.ParentId, sysUser.AdminId, item.ClassifyType)
 		if tmpErr != nil {
 			err = tmpErr
 			errMsg = "判断名称是否已存在失败"

+ 2 - 2
services/data/edb_info.go

@@ -702,7 +702,7 @@ func AddEdbInfo(secName, unit, frequency, noticeTime, mobile string, classifyId,
 // AddOrEditEdbInfoToEs 添加/修改ES中的指标
 func AddOrEditEdbInfoToEs(edbInfoId int) {
 	//添加es
-	itemInfo, _ := data_manage.GetEdbInfoByCondition("AND edb_info_id=?", []interface{}{edbInfoId})
+	itemInfo, _ := data_manage.GetEdbInfoEsByCondition("AND edb_info_id=?", []interface{}{edbInfoId})
 	obj := data_manage.EdbInfoShare{}
 	list, _ := obj.GetListByEdbInfoId(edbInfoId)
 	sharedList := make([]int, 0)
@@ -717,7 +717,7 @@ func AddOrEditEdbInfoToEs(edbInfoId int) {
 // AddOrEditAllEdbInfoToEs 修复ES中的所有指标
 func AddOrEditAllEdbInfoToEs() {
 	//添加es
-	total, itemInfoList, _ := data_manage.GetEdbInfoFilterList("", []interface{}{}, 0, 100000)
+	total, itemInfoList, _ := data_manage.GetEsEdbInfo("", []interface{}{}, 0, 100000)
 	obj := data_manage.EdbInfoShare{}
 	for k, itemInfo := range itemInfoList {
 		list, _ := obj.GetListByEdbInfoId(itemInfo.EdbInfoId)

+ 44 - 0
services/data/edb_public.go

@@ -0,0 +1,44 @@
+package data
+
+import (
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/system"
+)
+
+// DeleteEdbPublicCheck
+// @Description: 移除指标公共检测
+// @author: Roc
+// @datetime 2024-12-05 10:23:01
+// @param classifyId int
+// @param edbInfoId int
+// @param sysUser *system.Admin
+// @return deleteStatus int
+// @return tipsMsg string
+// @return tableList []*data_manage.ExcelBaseInfo
+// @return err error
+// @return errMsg string
+func DeleteEdbPublicCheck(edbInfoId int, sysUser *system.Admin) (deleteStatus int, tipsMsg string, tableList []*data_manage.ExcelBaseInfo, err error, errMsg string) {
+	// TODO 操作权限校验
+	{
+
+	}
+
+	// 移除指标
+	if edbInfoId > 0 {
+
+		// TODO 需要判断该指标是否被其他人给收藏了
+
+		//if edbInfo == nil {
+		//	errMsg = "指标已删除,请刷新页面"
+		//	return
+		//}
+		//if chartCount > 0 {
+		//	deleteStatus = 3
+		//	tipsMsg = "当前指标已用作画图,不可删除"
+		//	return
+		//}
+		return
+	}
+
+	return
+}

+ 850 - 0
services/data/edb_public_classify.go

@@ -0,0 +1,850 @@
+package data
+
+import (
+	"errors"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/system"
+	"eta_gn/eta_api/services/data/data_manage_permission"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"time"
+)
+
+// AddEdbPublicClassify
+// @Description: 添加公共指标分类
+// @author: Roc
+// @datetime 2024-12-04 18:00:22
+// @param classifyName string
+// @param parentId int
+// @param level int
+// @param classifyType uint8
+// @param sysUserId int
+// @param sysUserName string
+// @return classifyInfo *data_manage.EdbPublicClassify
+// @return err error
+// @return errMsg string
+func AddEdbPublicClassify(classifyName string, parentId, level int, classifyType uint8, sysUserId int, sysUserName string) (classifyInfo *data_manage.EdbPublicClassify, err error, errMsg string) {
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	// 校验分类名称相同的数量
+	{
+		var count int
+		count, err = edbPublicClassifyObj.GetEdbClassifyCount(classifyName, parentId, classifyType)
+		if err != nil {
+			errMsg = `判断名称是否已存在失败`
+			return
+		}
+		if count > 0 {
+			errMsg = `分类名称已存在,请重新输入`
+			err = errors.New(errMsg)
+			return
+		}
+	}
+
+	// 层级校验
+	if level > utils.EdbClassifyMaxLevel {
+		errMsg = fmt.Sprintf("最高只支持添加%d级分类", level)
+		return
+	}
+
+	//获取该层级下最大的排序数
+	maxSort, err := GetEdbPublicClassifyMaxSort(parentId, classifyType)
+	if err != nil {
+		errMsg = "获取失败"
+		err = errors.New("查询排序信息失败,Err:" + err.Error())
+		return
+	}
+	//查询顶级rootId
+	rootId := 0
+	var classifyNamePath, classifyIdPath string
+	if parentId > 0 {
+		parentClassify, tErr := edbPublicClassifyObj.GetEdbClassifyById(parentId)
+		if tErr != nil {
+			if utils.IsErrNoRow(tErr) {
+				errMsg = "父级分类不存在"
+				err = errors.New(errMsg)
+				return
+			}
+			errMsg = "获取失败"
+			err = errors.New("获取分类信息失败,Err:" + tErr.Error())
+			return
+		}
+		rootId = parentClassify.RootId
+
+		classifyNamePath = fmt.Sprint(parentClassify.EdbPublicClassifyNamePath, "|", classifyName)
+		classifyIdPath = fmt.Sprint(parentClassify.EdbPublicClassifyIdPath, ",")
+	} else {
+		classifyNamePath = classifyName
+	}
+
+	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
+	classifyInfo = &data_manage.EdbPublicClassify{
+		//EdbPublicClassifyId:       0,
+		ClassifyType:              classifyType,
+		EdbPublicClassifyName:     classifyName,
+		ParentId:                  parentId,
+		HasData:                   0,
+		RootId:                    rootId,
+		CreateTime:                time.Now(),
+		ModifyTime:                time.Now(),
+		SysUserId:                 sysUserId,
+		SysUserRealName:           sysUserName,
+		Level:                     level + 1,
+		UniqueCode:                utils.MD5(utils.PUBLIC_CLASSIFY_PREFIX + "_" + timestamp),
+		Sort:                      maxSort + 1,
+		LastModifyUserId:          sysUserId,
+		LastModifyUserRealName:    sysUserName,
+		EdbPublicClassifyNamePath: classifyNamePath,
+		EdbPublicClassifyIdPath:   "",
+	}
+	err = classifyInfo.Add()
+	if err != nil {
+		errMsg = "保存分类失败"
+		return
+	}
+
+	// 更改分类id完整路径path
+	updateCols := []string{"EdbPublicClassifyIdPath"}
+	classifyInfo.EdbPublicClassifyIdPath = fmt.Sprint(classifyIdPath, classifyInfo.EdbPublicClassifyId)
+	if parentId == 0 { //一级目录的rootId等于自己本身
+		classifyInfo.RootId = classifyInfo.EdbPublicClassifyId
+		updateCols = append(updateCols, "RootId")
+
+	}
+	err = classifyInfo.Update(updateCols)
+	if err != nil {
+		errMsg = "更新分类失败"
+		return
+	}
+
+	return
+}
+
+// EditEdbPublicClassify
+// @Description: 编辑指标分类
+// @author: Roc
+// @datetime 2024-12-05 09:29:38
+// @param classifyId int
+// @param classifyName string
+// @param sysUser *system.Admin
+// @return err error
+// @return errMsg string
+func EditEdbPublicClassify(classifyId int, classifyName string, sysUser *system.Admin) (err error, errMsg string) {
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	item, err := edbPublicClassifyObj.GetEdbClassifyById(classifyId)
+	if err != nil {
+		errMsg = `修改失败`
+		return
+	}
+
+	// TODO 操作权限校验
+	{
+	}
+
+	// 需要变更的字段
+	updateCols := make([]string, 0)
+
+	// 旧完整路径  , 新的完整路径
+	var oldClassifyNamePath, newClassifyNamePath string
+
+	// 名字相同,那么就直接返回
+	if item.EdbPublicClassifyName == classifyName {
+		return
+	}
+
+	// 判断名称是否已存在
+	count, tmpErr := edbPublicClassifyObj.GetEdbClassifyCount(classifyName, item.ParentId, item.ClassifyType)
+	if tmpErr != nil {
+		err = tmpErr
+		errMsg = "判断名称是否已存在失败"
+		return
+	}
+	if count > 0 {
+		errMsg = "分类名称已存在,请重新输入"
+		err = errors.New(errMsg)
+		return
+	}
+
+	// 旧完整路径
+	oldClassifyNamePath = item.EdbPublicClassifyNamePath
+
+	if item.ParentId > 0 {
+		parentItem, tmpErr := edbPublicClassifyObj.GetEdbClassifyById(item.ParentId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		newClassifyNamePath = fmt.Sprint(parentItem.EdbPublicClassifyNamePath, "|", classifyName)
+	} else {
+		newClassifyNamePath = classifyName
+	}
+
+	// 更新自己的信息
+	item.EdbPublicClassifyName = classifyName
+	item.EdbPublicClassifyNamePath = newClassifyNamePath
+	item.LastModifyUserId = sysUser.AdminId
+	item.LastModifyUserRealName = sysUser.RealName
+	updateCols = append(updateCols, "EdbPublicClassifyName", "EdbPublicClassifyNamePath", "LastModifyUserId", "LastModifyUserRealName")
+
+	// 修改数据
+	if len(updateCols) > 0 {
+		err = item.UpdateEdbClassifyNameAndNamePath(updateCols, oldClassifyNamePath, newClassifyNamePath)
+		if err != nil {
+			errMsg = "保存失败"
+		}
+	}
+
+	return
+}
+
+// GetEdbPublicClassifyMaxSort
+// @Description: 获取最大排序值
+// @author: Roc
+// @datetime 2024-12-04 16:54:57
+// @param parentId int
+// @param classifyType uint8
+// @return maxSort int
+// @return err error
+func GetEdbPublicClassifyMaxSort(parentId int, classifyType uint8) (maxSort int, err error) {
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	//获取该层级下最大的排序数
+	classifyMaxSort, err := edbPublicClassifyObj.GetEdbClassifyMaxSort(parentId, classifyType)
+	if err != nil {
+		return
+	}
+	maxSort = classifyMaxSort
+	edbMaxSort, err := data_manage.GetEdbInfoMaxSortByClassifyId(parentId)
+	if err != nil {
+		return
+	}
+	if maxSort < edbMaxSort {
+		maxSort = edbMaxSort
+	}
+
+	return
+}
+
+// DeleteEdbPublicClassifyCheck 删除检测
+func DeleteEdbPublicClassifyCheck(classifyId int, sysUser *system.Admin) (deleteStatus int, tipsMsg string, allClassifyIdList []int, tableList []*data_manage.ExcelBaseInfo, err error, errMsg string) {
+	// TODO 操作权限校验
+	{
+
+	}
+
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	// 查找当前分类
+	item, tmpErr := edbPublicClassifyObj.GetEdbClassifyById(classifyId)
+	if tmpErr != nil {
+		errMsg = `查找分类失败`
+		err = tmpErr
+		return
+	}
+
+	// 查找分类下所有子分类
+	childClassifyIdList, tmpErr := item.GetAllChildClassifyIdList()
+	if tmpErr != nil {
+		errMsg = `查找下级分类失败`
+		err = tmpErr
+		return
+	}
+	allClassifyIdList = childClassifyIdList
+	allClassifyIdList = append(allClassifyIdList, item.EdbPublicClassifyId)
+
+	// 判断分类下,是否含有指标
+	{
+		//判断分类下,是否含有指标
+		count, tmpErr := edbPublicClassifyObj.GetEdbInfoCountByClassifyIdList(allClassifyIdList)
+		if tmpErr != nil {
+			errMsg = "删除失败"
+			err = errors.New("分类下是否含有指标失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		if count > 0 {
+			deleteStatus = 1
+			tipsMsg = "目录关联指标不可删除"
+			return
+		}
+	}
+
+	// 子目录数量校验
+	if len(childClassifyIdList) > 0 {
+		deleteStatus = 2
+		tipsMsg = "确认删除当前目录及包含的子目录吗"
+		return
+	}
+
+	return
+}
+
+// DeleteEdbPublicClassify 删除分类/指标
+func DeleteEdbPublicClassify(classifyId int, sysUser *system.Admin, requestBody, requestUrl string) (nextItem *data_manage.EdbInfo, tableList []*data_manage.ExcelBaseInfo, err error, errMsg string) {
+	//删除分类校验
+	deleteStatus, tipsMsg, allClassifyIdList, _, err, errMsg := DeleteEdbPublicClassifyCheck(classifyId, sysUser)
+	// 0:可以;2:删除子目录;1:不可删除(有关联指标)
+	if deleteStatus == 1 {
+		if tipsMsg != `` {
+			errMsg = tipsMsg
+		}
+		if err == nil {
+			err = errors.New(errMsg)
+		}
+		return
+	}
+
+	edbPublicClassifyObj := data_manage.EdbPublicClassify{}
+	err = edbPublicClassifyObj.BatchesDel(allClassifyIdList)
+	if err != nil {
+		errMsg = "删除失败"
+		return
+	}
+
+	return
+}
+
+// MoveEdbClassify 移动指标分类
+func MoveEdbPublicClassify(req data_manage.MoveEdbClassifyReq, sysUser *system.Admin, classifyType uint8) (err error, errMsg string) {
+	// req.ClassifyId, req.ParentClassifyId, req.PrevClassifyId, req.NextClassifyId
+	classifyId := req.ClassifyId
+	parentClassifyId := req.ParentClassifyId
+	prevClassifyId := req.PrevClassifyId
+	nextClassifyId := req.NextClassifyId
+
+	edbInfoId := req.EdbInfoId
+	prevEdbInfoId := req.PrevEdbInfoId
+	nextEdbInfoId := req.NextEdbInfoId
+
+	//首先确定移动的对象是分类还是指标
+	//判断上一个节点是分类还是指标
+	//判断下一个节点是分类还是指标
+	//同时更新分类目录下的分类sort和指标sort
+	//更新当前移动的分类或者指标sort
+
+	var parentEdbClassifyInfo *data_manage.EdbClassify
+	if parentClassifyId > 0 {
+		parentEdbClassifyInfo, err = data_manage.GetEdbClassifyById(parentClassifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上级分类信息失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	//如果有传入 上一个兄弟节点分类id
+	var (
+		edbClassifyInfo *data_manage.EdbClassify
+		prevClassify    *data_manage.EdbClassify
+		nextClassify    *data_manage.EdbClassify
+
+		edbInfo     *data_manage.EdbInfo
+		prevEdbInfo *data_manage.EdbInfo
+		nextEdbInfo *data_manage.EdbInfo
+		prevSort    int
+		nextSort    int
+	)
+
+	// 移动对象为分类, 判断权限
+	if edbInfoId == 0 {
+		edbClassifyInfo, err = data_manage.GetEdbClassifyById(classifyId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				errMsg = "当前分类不存在"
+				err = errors.New("获取分类信息失败,Err:" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取分类信息失败,Err:" + err.Error())
+			return
+		}
+		if edbClassifyInfo.SysUserId != sysUser.AdminId {
+			errMsg = "不是本人目录,您没有操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+		if parentClassifyId > 0 && parentEdbClassifyInfo.Level == 6 {
+			errMsg = "最高只支持添加6级分类"
+			err = errors.New(errMsg)
+			return
+		}
+		// 如果是移动目录, 那么校验一下父级目录下是否有重名目录
+		exists, e := data_manage.GetEdbClassifyByParentIdAndName(parentClassifyId, edbClassifyInfo.ClassifyName, classifyId, classifyType)
+		if e != nil && !utils.IsErrNoRow(e) {
+			errMsg = "移动失败"
+			err = fmt.Errorf("获取父级分类下的同名分类失败, Err: %s", e.Error())
+			return
+		}
+		if exists != nil && exists.ClassifyId > 0 {
+			errMsg = "移动失败,分类名称已存在"
+			return
+		}
+
+		// 权限校验
+		{
+			// 已授权分类id
+			permissionClassifyIdList, tmpErr := data_manage_permission.GetUserEdbClassifyPermissionList(sysUser.AdminId, classifyId)
+			if tmpErr != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取已授权分类id数据失败,Err:" + tmpErr.Error())
+				return
+			}
+			// 数据权限
+			haveOperaAuth := data_manage_permission.CheckEdbClassifyPermissionByPermissionIdList(edbClassifyInfo.IsJoinPermission, edbClassifyInfo.ClassifyId, permissionClassifyIdList)
+
+			if edbClassifyInfo.ClassifyType == 0 { // 普通指标
+				button := GetEdbClassifyOpButton(sysUser, edbClassifyInfo.SysUserId, haveOperaAuth)
+				if !button.MoveButton {
+					errMsg = "无操作权限"
+					err = errors.New(errMsg)
+					return
+				}
+			} else if edbClassifyInfo.ClassifyType == 1 { // 预测指标
+				button := GetPredictEdbClassifyOpButton(sysUser, edbClassifyInfo.SysUserId, haveOperaAuth)
+				if !button.MoveButton {
+					errMsg = "无操作权限"
+					err = errors.New(errMsg)
+					return
+				}
+			}
+		}
+
+	} else {
+		edbInfo, err = data_manage.GetEdbInfoById(req.EdbInfoId)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				errMsg = "当前指标不存在"
+				err = errors.New("获取分类信息失败,Err:" + err.Error())
+				return
+			}
+			errMsg = "移动失败"
+			err = errors.New("获取分类信息失败,Err:" + err.Error())
+			return
+		}
+
+		if edbInfo.SysUserId != sysUser.AdminId {
+			errMsg = "不是本人指标,您没有操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+
+		if parentClassifyId == 0 {
+			errMsg = "移动失败,指标必须挂在分类下"
+			err = errors.New(errMsg)
+			return
+		}
+
+		var haveOperaAuth bool
+		// 权限校验
+		{
+			haveOperaAuth, err = data_manage_permission.CheckEdbPermissionByEdbInfoId(edbInfo.EdbInfoId, edbInfo.ClassifyId, edbInfo.IsJoinPermission, sysUser.AdminId)
+			if err != nil {
+				errMsg = "移动失败"
+				err = errors.New("获取指标权限信息失败,Err:" + err.Error())
+				return
+			}
+		}
+
+		// 移动权限校验
+		button := GetEdbOpButton(sysUser, edbInfo.SysUserId, edbInfo.EdbType, edbInfo.EdbInfoType, haveOperaAuth)
+		if !button.MoveButton {
+			errMsg = "无操作权限"
+			err = errors.New(errMsg)
+			return
+		}
+	}
+
+	if prevClassifyId > 0 {
+		prevClassify, err = data_manage.GetEdbClassifyById(prevClassifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		prevSort = prevClassify.Sort
+	} else if prevEdbInfoId > 0 {
+		prevEdbInfo, err = data_manage.GetEdbInfoById(prevEdbInfoId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取上一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		prevSort = prevEdbInfo.Sort
+	}
+
+	if nextClassifyId > 0 {
+		//下一个兄弟节点
+		nextClassify, err = data_manage.GetEdbClassifyById(nextClassifyId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		nextSort = nextClassify.Sort
+	} else if nextEdbInfoId > 0 {
+		//下一个兄弟节点
+		nextEdbInfo, err = data_manage.GetEdbInfoById(nextEdbInfoId)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("获取下一个兄弟节点分类信息失败,Err:" + err.Error())
+			return
+		}
+		nextSort = nextEdbInfo.Sort
+	}
+
+	err, errMsg = moveEdbOrClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	return
+}
+
+// moveEdbOrClassify 移动指标分类
+func moveEdbOrPublicClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+
+	if edbClassifyInfo != nil {
+		// 移动分类
+		return moveEdbClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	} else {
+		// 移动指标
+		return moveEdb(prevClassify, nextClassify, edbInfo, prevEdbInfo, nextEdbInfo, parentClassifyId, prevSort, nextSort, classifyType)
+	}
+
+	return
+}
+
+// moveEdb
+// @Description: 移动指标
+// @author: Roc
+// @datetime 2024-11-26 16:07:37
+// @param prevClassify *data_manage.EdbClassify
+// @param nextClassify *data_manage.EdbClassify
+// @param edbInfo *data_manage.EdbInfo
+// @param prevEdbInfo *data_manage.EdbInfo
+// @param nextEdbInfo *data_manage.EdbInfo
+// @param parentClassifyId int
+// @param prevSort int
+// @param nextSort int
+// @param classifyType uint8
+// @return err error
+// @return errMsg string
+func movePublicEdb(prevClassify, nextClassify *data_manage.EdbClassify, edbInfo, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	if edbInfo == nil {
+		errMsg = "当前指标不存在"
+		err = errors.New(errMsg)
+		return
+	}
+	//如果改变了分类,那么移动该指标数据
+	if edbInfo.ClassifyId != parentClassifyId {
+		edbInfo.ClassifyId = parentClassifyId
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ClassifyId", "ModifyTime")
+	}
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == edbInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+				} else {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+				}
+
+				//变更指标
+				if prevEdbInfo != nil {
+					//变更兄弟节点的排序
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
+					} else {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+					}
+
+					//变更指标
+					if prevEdbInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+				}
+			}
+		}
+
+		edbInfo.Sort = prevSort + 1
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		edbInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
+			//该分类下的所有指标也需要+1
+			_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
+		} else {
+			//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
+				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
+			}
+		}
+
+		edbInfo.Sort = 0 //那就是排在第一位
+		edbInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	//更新
+	if len(updateCol) > 0 {
+		err = edbInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+	}
+
+	return
+}
+
+// moveEdbClassify
+// @Description: 移动指标分类
+// @author: Roc
+// @datetime 2024-11-26 16:07:44
+// @param parentEdbClassifyInfo *data_manage.EdbClassify
+// @param edbClassifyInfo *data_manage.EdbClassify
+// @param prevClassify *data_manage.EdbClassify
+// @param nextClassify *data_manage.EdbClassify
+// @param edbInfo *data_manage.EdbInfo
+// @param prevEdbInfo *data_manage.EdbInfo
+// @param nextEdbInfo *data_manage.EdbInfo
+// @param parentClassifyId int
+// @param prevSort int
+// @param nextSort int
+// @param classifyType uint8
+// @return err error
+// @return errMsg string
+func moveEdbPublicClassify(parentEdbClassifyInfo, edbClassifyInfo, prevClassify, nextClassify *data_manage.EdbClassify, prevEdbInfo, nextEdbInfo *data_manage.EdbInfo, parentClassifyId int, prevSort, nextSort int, classifyType uint8) (err error, errMsg string) {
+	updateCol := make([]string, 0)
+
+	// 移动对象为分类, 判断分类是否存在
+	oldParentId := edbClassifyInfo.ParentId
+	oldLevel := edbClassifyInfo.Level
+	var classifyIds []int
+	if oldParentId != parentClassifyId {
+		//更新子分类对应的level
+		childList, e, m := GetChildClassifyByClassifyId(edbClassifyInfo.ClassifyId)
+		if e != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询子分类失败,Err:" + e.Error() + m)
+			return
+		}
+
+		if len(childList) > 0 {
+			for _, v := range childList {
+				if v.ClassifyId == edbClassifyInfo.ClassifyId {
+					continue
+				}
+				classifyIds = append(classifyIds, v.ClassifyId)
+			}
+		}
+	}
+	//判断上级id是否一致,如果不一致的话,那么需要移动该分类层级
+	if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId != 0 {
+		if edbClassifyInfo.Level != parentEdbClassifyInfo.Level+1 { //禁止层级调整
+			errMsg = "移动失败"
+			err = errors.New("不支持目录层级变更")
+			return
+		}
+		edbClassifyInfo.ParentId = parentEdbClassifyInfo.ClassifyId
+		edbClassifyInfo.RootId = parentEdbClassifyInfo.RootId
+		edbClassifyInfo.Level = parentEdbClassifyInfo.Level + 1
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "ParentId", "RootId", "Level", "ModifyTime")
+	} else if edbClassifyInfo.ParentId != parentClassifyId && parentClassifyId == 0 {
+		errMsg = "移动失败"
+		err = errors.New("不支持目录层级变更")
+		return
+	}
+
+	if prevSort > 0 {
+		//如果是移动在两个兄弟节点之间
+		if nextSort > 0 {
+			//下一个兄弟节点
+			//如果上一个兄弟与下一个兄弟的排序权重是一致的,那么需要将下一个兄弟(以及下个兄弟的同样排序权重)的排序权重+2,自己变成上一个兄弟的排序权重+1
+			if prevSort == nextSort || prevSort == edbClassifyInfo.Sort {
+				//变更兄弟节点的排序
+				updateSortStr := `sort + 2`
+
+				//变更分类
+				if prevClassify != nil {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevClassify.Sort, updateSortStr, classifyType)
+				} else {
+					_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+				}
+
+				//变更指标
+				if prevEdbInfo != nil {
+					//变更兄弟节点的排序
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+				} else {
+					_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+				}
+			} else {
+				//如果下一个兄弟的排序权重正好是上个兄弟节点的下一层,那么需要再加一层了
+				if nextSort-prevSort == 1 {
+					//变更兄弟节点的排序
+					updateSortStr := `sort + 1`
+
+					//变更分类
+					if prevClassify != nil {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, prevClassify.ClassifyId, prevSort, updateSortStr, classifyType)
+					} else {
+						_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, prevSort, updateSortStr, classifyType)
+					}
+
+					//变更指标
+					if prevEdbInfo != nil {
+						//变更兄弟节点的排序
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, prevEdbInfo.EdbInfoId, updateSortStr)
+					} else {
+						_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, prevSort, 0, updateSortStr)
+					}
+
+				}
+			}
+		}
+
+		edbClassifyInfo.Sort = prevSort + 1
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else if prevClassify == nil && nextClassify == nil && prevEdbInfo == nil && nextEdbInfo == nil && parentClassifyId > 0 {
+		//处理只拖动到目录里,默认放到目录底部的情况
+		var maxSort int
+		maxSort, err = GetEdbClassifyMaxSort(parentClassifyId, classifyType)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("查询组内排序信息失败,Err:" + err.Error())
+			return
+		}
+		edbClassifyInfo.Sort = maxSort + 1 //那就是排在组内最后一位
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	} else {
+		// 拖动到父级分类的第一位
+		firstClassify, tmpErr := data_manage.GetFirstEdbClassifyByParentId(parentClassifyId)
+		if tmpErr != nil && !utils.IsErrNoRow(tmpErr) {
+			errMsg = "移动失败"
+			err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tmpErr.Error())
+			return
+		}
+
+		//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+		if firstClassify != nil && firstClassify.ClassifyId > 0 && firstClassify.Sort == 0 {
+			updateSortStr := ` sort + 1 `
+			_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, firstClassify.ClassifyId-1, 0, updateSortStr, classifyType)
+			//该分类下的所有指标也需要+1
+			_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, 0, updateSortStr)
+		} else {
+			//如果该分类下存在指标,且第一个指标的排序等于0,那么需要调整排序
+			firstEdb, tErr := data_manage.GetFirstEdbInfoByClassifyId(parentClassifyId)
+			if tErr != nil && !utils.IsErrNoRow(tErr) {
+				errMsg = "移动失败"
+				err = errors.New("获取获取当前父级分类下的排序第一条的分类信息失败,Err:" + tErr.Error())
+				return
+			}
+
+			//如果该分类下存在其他分类,且第一个其他分类的排序等于0,那么需要调整排序
+			if firstEdb != nil && firstEdb.ClassifyId > 0 && firstEdb.Sort == 0 {
+				updateSortStr := ` sort + 1 `
+				_ = data_manage.UpdateEdbInfoSortByClassifyId(parentClassifyId, 0, firstEdb.EdbInfoId-1, updateSortStr)
+				_ = data_manage.UpdateEdbClassifySortByParentId(parentClassifyId, 0, 0, updateSortStr, classifyType)
+			}
+		}
+
+		edbClassifyInfo.Sort = 0 //那就是排在第一位
+		edbClassifyInfo.ModifyTime = time.Now()
+		updateCol = append(updateCol, "Sort", "ModifyTime")
+	}
+
+	oldClassifyIdPath := edbClassifyInfo.ClassifyIdPath
+	oldClassifyNamePath := edbClassifyInfo.ClassifyNamePath
+	newClassifyNamePath := fmt.Sprint(parentEdbClassifyInfo.ClassifyNamePath, `|`, edbClassifyInfo.ClassifyName)
+	newClassifyIdPath := fmt.Sprint(parentEdbClassifyInfo.ClassifyIdPath, `,`, edbClassifyInfo.ClassifyId)
+
+	//更新
+	if len(updateCol) > 0 {
+		edbClassifyInfo.ClassifyNamePath = newClassifyNamePath
+		edbClassifyInfo.ClassifyIdPath = newClassifyIdPath
+		updateCol = append(updateCol, "ClassifyNamePath", "ClassifyIdPath")
+
+		err = edbClassifyInfo.Update(updateCol)
+		if err != nil {
+			errMsg = "移动失败"
+			err = errors.New("修改失败,Err:" + err.Error())
+			return
+		}
+		//更新对应分类的root_id和层级
+		if oldParentId != parentClassifyId {
+			if len(classifyIds) > 0 {
+				levelStep := edbClassifyInfo.Level - oldLevel
+				err = data_manage.UpdateEdbClassifyChildByParentClassifyId(classifyIds, edbClassifyInfo.RootId, levelStep)
+				if err != nil {
+					errMsg = "移动失败"
+					err = errors.New("更新子分类失败,Err:" + err.Error())
+					return
+				}
+			}
+
+			// 更改了上级分类,那么需要同步去更改自己的分类全路径
+			tmpErr := data_manage.UpdateEdbClassifyNameAndNamePathByOldClassifyIdPath(oldClassifyIdPath, newClassifyIdPath, oldClassifyNamePath, newClassifyNamePath)
+			if tmpErr != nil {
+				utils.FileLog.Error(fmt.Sprintf("更新分类全路径失败,分类id:%d;失败原因Err:%s", edbClassifyInfo.ClassifyId, tmpErr.Error()))
+			}
+		}
+
+	}
+
+	return
+}

+ 123 - 5
services/elastic/edb_info.go

@@ -10,7 +10,7 @@ import (
 )
 
 // EsAddOrEditEdbInfoData 新增/修改es中的指标数据
-func EsAddOrEditEdbInfoData(indexName, docId string, item *data_manage.EdbInfoList) (err error) {
+func EsAddOrEditEdbInfoData(indexName, docId string, item *data_manage.EdbInfoEs) (err error) {
 	defer func() {
 		if err != nil {
 			fmt.Println("EsAddOrEditData Err:", err.Error())
@@ -316,7 +316,7 @@ func SearchEdbInfoData(keywordStr string, from, size, filterSource, source int,
 			// 公开的指标
 			shouldTermList = append(shouldTermList, map[string]interface{}{
 				"term": map[string]interface{}{
-					"PublicStatus": 3,
+					"PublicStatus": utils.EdbPublicSuccess,
 				},
 			})
 		default:
@@ -335,7 +335,7 @@ func SearchEdbInfoData(keywordStr string, from, size, filterSource, source int,
 			// 公开的指标
 			shouldTermList = append(shouldTermList, map[string]interface{}{
 				"term": map[string]interface{}{
-					"PublicStatus": 3,
+					"PublicStatus": utils.EdbPublicSuccess,
 				},
 			})
 
@@ -553,7 +553,7 @@ func SearchEdbInfoDataByShared(keywordStr string, from, size, edbShare int, sour
 			query = query.Must(elastic.NewTermQuery(`SysUserId`, sysUserId))
 		case 2:
 			// 公开的指标
-			query = query.Must(elastic.NewTermQuery(`PublicStatus`, 3))
+			query = query.Must(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
 		default:
 			tmpShouldQuery := elastic.NewBoolQuery()
 			// 自己的指标
@@ -561,7 +561,125 @@ func SearchEdbInfoDataByShared(keywordStr string, from, size, edbShare int, sour
 			// 分享给我的指标
 			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermsQuery(`SharedUserIdList`, sysUserId))
 			//公开的指标
-			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`PublicStatus`, 3))
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
+			//shouldQuery = shouldQuery.Should(tmpShouldQuery)
+			query = query.Must(tmpShouldQuery)
+		}
+	}
+
+	// 排序
+	sortList := make([]*elastic.FieldSort, 0)
+	// 如果没有关键字,那么就走指标id倒序
+
+	for orderKey, orderType := range sortMap {
+		switch orderType {
+		case "asc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Asc())
+		case "desc":
+			sortList = append(sortList, elastic.NewFieldSort(orderKey).Desc())
+
+		}
+
+	}
+
+	return searchEdbInfoDataV2(indexName, query, sortList, from, size)
+}
+
+// SearchEdbInfoDataByPublic
+// @Description: 查询es中的指标数据
+// @author: Roc
+// @datetime 2024-12-05 13:33:36
+// @param keywordStr string
+// @param from int
+// @param size int
+// @param edbPublicList []int
+// @param sourceList []int
+// @param classifyIdList []int
+// @param edbTypeList []int
+// @param edbInfoType int
+// @param edbAuth int
+// @param sysUserId int
+// @param sortMap map[string]string
+// @return total int64
+// @return list []*data_manage.EdbInfoList
+// @return err error
+func SearchEdbInfoDataByPublic(keywordStr string, from, size int, edbPublicList, sourceList, classifyIdList, edbTypeList []int, edbInfoType, edbAuth, sysUserId int, sortMap map[string]string) (total int64, list []*data_manage.EdbInfoList, err error) {
+	indexName := utils.DATA_INDEX_NAME
+	list = make([]*data_manage.EdbInfoList, 0)
+	defer func() {
+		if err != nil {
+			fmt.Println("SearchEdbInfoData Err:", err.Error())
+		}
+	}()
+
+	query := elastic.NewBoolQuery()
+
+	//指标来源
+	if len(sourceList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range sourceList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("Source", termsList...))
+	}
+
+	// classifyIdList 指定分类下的指标
+	if len(classifyIdList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range classifyIdList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("ClassifyId", termsList...))
+	}
+
+	// 指标类型:0-基础+计算;1-基础指标;2-计算指标;3-预测指标
+	if len(edbTypeList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range edbTypeList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("EdbType", termsList...))
+	}
+
+	// 如果指定了指标公开状态,那么就添加指标公开状态的筛选
+	// 公开状态;0:未公开;1:审批中;2:已驳回;3:已公开
+	if len(edbPublicList) > 0 {
+		termsList := make([]interface{}, 0)
+		for _, v := range edbPublicList {
+			termsList = append(termsList, v)
+		}
+		query = query.Must(elastic.NewTermsQuery("PublicStatus", termsList...))
+	}
+
+	if edbInfoType >= 0 {
+		query = query.Must(elastic.NewTermQuery("EdbInfoType", edbInfoType))
+	}
+
+	// 指标名称、编码匹配
+	if keywordStr != `` {
+		// 默认使用中文名字字段去匹配
+		keywordNameKey := `EdbName`
+		query = query.Must(elastic.NewMultiMatchQuery(keywordStr, keywordNameKey, "EdbCode"))
+	}
+
+	// 指标与用户的权限匹配
+	{
+		//指标权限范围,0-全部;1-我的;2-公共
+		switch edbAuth {
+		case 1:
+			// 自己的指标
+			query = query.Must(elastic.NewTermQuery(`SysUserId`, sysUserId))
+		case 2:
+			// 公开的指标
+			query = query.Must(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
+		default:
+			tmpShouldQuery := elastic.NewBoolQuery()
+			// 自己的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`SysUserId`, sysUserId))
+			// 分享给我的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermsQuery(`SharedUserIdList`, sysUserId))
+			//公开的指标
+			tmpShouldQuery = tmpShouldQuery.Should(elastic.NewTermQuery(`PublicStatus`, utils.EdbPublicSuccess))
 			//shouldQuery = shouldQuery.Should(tmpShouldQuery)
 			query = query.Must(tmpShouldQuery)
 		}

+ 11 - 3
utils/constants.go

@@ -179,9 +179,10 @@ const (
 )
 
 const (
-	DATA_PREFIX       = "hz_data"
-	CHART_PREFIX      = "hz_chart"
-	EXCEL_DATA_PREFIX = "hz_excel_data"
+	DATA_PREFIX            = "hz_data"
+	CHART_PREFIX           = "hz_chart"
+	EXCEL_DATA_PREFIX      = "hz_excel_data"
+	PUBLIC_CLASSIFY_PREFIX = "hz_data_public_classify"
 )
 
 const (
@@ -454,6 +455,13 @@ const (
 	EdbPermissionSourceCalculate = 7 // 指标权限来源-计算指标
 )
 
+const (
+	EdbPublicDefault = 0 // 指标公开状态-默认未提交
+	EdbPublicCommit  = 1 // 指标公开状态-已提交
+	EdbPublicReject  = 2 // 指标公开状态-已驳回
+	EdbPublicSuccess = 3 // 指标公开状态-成功
+)
+
 // BaseEdbRefreshStartDate 指标的基础刷新开始日期
 const BaseEdbRefreshStartDate = `1899-01-01`