Преглед на файлове

Merge branch 'dm' into feature/knowledge

# Conflicts:
#	routers/router.go
xyxie преди 8 месеца
родител
ревизия
adc74336c7
променени са 94 файла, в които са добавени 5747 реда и са изтрити 503 реда
  1. 6 1
      controllers/base_auth.go
  2. 499 0
      controllers/bi_approve/bi_approve.go
  3. 302 0
      controllers/bi_approve/bi_approve_flow.go
  4. 903 0
      controllers/bi_dashboard.go
  5. 0 161
      controllers/report.go
  6. 1 1
      controllers/report_author.go
  7. 6 5
      controllers/report_chapter_type.go
  8. 183 0
      models/bi_approve/bi_approve.go
  9. 179 0
      models/bi_approve/bi_approve_flow.go
  10. 114 0
      models/bi_approve/bi_approve_message.go
  11. 90 0
      models/bi_approve/bi_approve_node.go
  12. 152 0
      models/bi_approve/bi_approve_record.go
  13. 21 0
      models/bi_approve/request/bi_approve.go
  14. 23 0
      models/bi_approve/request/bi_approve_flow.go
  15. 5 0
      models/bi_approve/request/bi_approve_message.go
  16. 90 0
      models/bi_approve/response/bi_approve.go
  17. 46 0
      models/bi_approve/response/bi_approve_flow.go
  18. 24 0
      models/bi_approve/response/bi_approve_message.go
  19. 126 0
      models/bi_dashboard/bi_dashboard.go
  20. 112 0
      models/bi_dashboard/bi_dashboard_classify.go
  21. 66 0
      models/bi_dashboard/bi_dashboard_detail.go
  22. 63 0
      models/bi_dashboard/bi_dashboard_grant.go
  23. 1 0
      models/business_conf.go
  24. 1 1
      models/business_conf_operation_record.go
  25. 24 24
      models/chart_permission.go
  26. 6 6
      models/classify_menu.go
  27. 4 4
      models/classify_menu_relation.go
  28. 8 8
      models/cloud_disk_menu.go
  29. 1 1
      models/data_manage/base_from_sci_hq_index.go
  30. 1 1
      models/data_manage/base_from_smm.go
  31. 1 1
      models/data_manage/chart_classify.go
  32. 123 56
      models/data_manage/chart_info.go
  33. 1 1
      models/data_manage/chart_theme/chart_theme.go
  34. 8 8
      models/data_manage/chart_theme/chart_theme_type.go
  35. 1 1
      models/data_manage/edb_classify.go
  36. 1 1
      models/data_manage/edb_data_pb.go
  37. 1 1
      models/data_manage/edb_data_ths.go
  38. 1 1
      models/data_manage/edb_data_wind.go
  39. 1 1
      models/data_manage/edb_info.go
  40. 1 1
      models/data_manage/edb_info_calculate.go
  41. 1 1
      models/data_manage/excel/excel_info.go
  42. 1 1
      models/data_manage/excel/excel_sheet.go
  43. 1 1
      models/data_manage/excel_style.go
  44. 1 1
      models/data_manage/factor_edb_series_calculate_data_qjjs.go
  45. 1 1
      models/data_manage/manual_classify.go
  46. 2 2
      models/data_manage/manual_user.go
  47. 1 1
      models/data_manage/my_chart.go
  48. 1 1
      models/data_manage/search_keyword.go
  49. 6 3
      models/data_manage/supply_analysis/variety.go
  50. 531 0
      models/db2.go
  51. 1 1
      models/english_company.go
  52. 1 1
      models/english_company_log.go
  53. 1 1
      models/english_company_todo.go
  54. 1 1
      models/english_company_todo_public.go
  55. 1 1
      models/english_policy_report.go
  56. 1 1
      models/english_report_email.go
  57. 1 1
      models/english_report_email_log.go
  58. 1 1
      models/english_report_email_op_log.go
  59. 1 1
      models/english_report_email_pv.go
  60. 1 1
      models/english_video.go
  61. 7 7
      models/permission.go
  62. 1 1
      models/ppt_v2.go
  63. 14 5
      models/report.go
  64. 3 1
      models/report_approve/report_approve.go
  65. 3 1
      models/report_approve/report_approve_flow.go
  66. 1 1
      models/report_author.go
  67. 4 1
      models/report_chapter.go
  68. 24 24
      models/report_chapter_type.go
  69. 3 2
      models/report_v2.go
  70. 1 1
      models/research_report.go
  71. 1 1
      models/search_key_word.go
  72. 1 1
      models/system/sys_department.go
  73. 1 1
      models/system/sys_group.go
  74. 2 2
      models/system/sys_menu_button.go
  75. 6 6
      models/system/sys_role.go
  76. 1 1
      models/system/sys_role_admin.go
  77. 1 1
      models/system/sys_session.go
  78. 2 1
      models/system/sys_user.go
  79. 1 1
      models/system/sys_user_login_record.go
  80. 1 1
      models/target.go
  81. 1 1
      models/variety_tag.go
  82. 1 1
      models/wechat_send_msg.go
  83. 252 0
      routers/commentsRouter.go
  84. 12 0
      routers/router.go
  85. 1181 0
      services/bi_approve/bi_approve.go
  86. 243 0
      services/bi_approve/bi_approve_flow.go
  87. 89 0
      services/bi_approve/bi_approve_message.go
  88. 31 0
      services/bi_approve/bi_approve_node.go
  89. 42 0
      services/bi_approve/constant.go
  90. 22 95
      services/classify.go
  91. 1 1
      services/data/chart_classify.go
  92. 20 18
      services/report_v2.go
  93. 6 5
      utils/common.go
  94. 16 15
      utils/constants.go

+ 6 - 1
controllers/base_auth.go

@@ -180,7 +180,12 @@ func (c *BaseAuthController) Prepare() {
 				}
 
 				if loginInfo != "1" {
-					msg := `该账号于` + admin.LastLoginTime + "在其他网络登录。此客户端已退出登录。"
+					lastLoginTime := admin.LastLoginTime
+
+					lastLoginTimeObj, err := time.Parse(utils.FormatDateWallWithLoc, lastLoginTime)
+					fmt.Println(lastLoginTimeObj, err)
+
+					msg := `该账号于` + lastLoginTimeObj.Format(utils.FormatDateTime) + "在其他网络登录。此客户端已退出登录。"
 					c.JSON(models.BaseResponse{Ret: 408, Msg: msg, ErrMsg: msg}, false, false)
 					c.StopRun()
 					return

+ 499 - 0
controllers/bi_approve/bi_approve.go

@@ -0,0 +1,499 @@
+package biapprove
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/bi_approve/request"
+	"eta_gn/eta_api/models/bi_approve/response"
+	biapprove "eta_gn/eta_api/services/bi_approve"
+	"eta_gn/eta_api/utils"
+	"fmt"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type BiApproveController 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.BiApproveListResp
+// @router /list [get]
+func (this *BiApproveController) 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.BiApproveItemOrmResp
+	var total int
+	var msg string
+	var err error
+
+	classifyList, msg, err := biapprove.GetBiClassifyAll()
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批列表成功"
+		}
+		br.ErrMsg = "获取分类列表失败, Err: " + err.Error()
+		return
+	}
+	classifyMap := make(map[int]string)
+	for _, v := range classifyList {
+		classifyMap[v.BiDashboardClassifyId] = v.BiDashboardClassifyName
+	}
+
+	switch listType {
+	case 1:
+		list, total, msg, err = biapprove.ProcessingBiApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 2:
+		list, total, msg, err = biapprove.SolvedBiApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 3:
+		list, total, msg, err = biapprove.MyApplyBiApproves(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
+	}
+	for _, v := range list {
+		v.ClassifyName = classifyMap[v.ClassifyId]
+	}
+
+	resp := new(response.BiApproveListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+
+	br.Msg = "获取审批列表成功"
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+}
+
+// list
+// @Title 公共看板分类列表
+// @Description 公共看板分类列表
+// @Success 200 {object} report_approve.BiApproveFlowDetailItem
+// @router /classify/list [get]
+func (this *BiApproveController) ClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	res, msg, err := biapprove.GetPulicBiClassifyList()
+	if err != nil {
+		if msg == "" {
+			br.Msg = "获取分类列表失败"
+		} else {
+			br.Msg = msg
+		}
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	br.Data = res
+	br.Msg = "获取分类列表成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// Approve
+// @Title 通过审批
+// @Description 通过审批
+// @Param	request	body report_approve.BiApprovePassReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /approve [post]
+func (this *BiApproveController) 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.BiApprovePassReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.BiApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", req.BiApproveId)
+		return
+	}
+
+	// 通过审批
+	msg, err := biapprove.PassBiApprove(req.BiApproveId, 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   BiApproveId  query  int  true  "审批ID"
+// @Success 200 {object} report_approve.BiApproveDetail
+// @router /detail [get]
+func (this *BiApproveController) 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("BiApproveId")
+	if approveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", approveId)
+		return
+	}
+
+	resp, msg, err := biapprove.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.BiApproveRefuseReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /refuse [post]
+func (this *BiApproveController) 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.BiApproveRefuseReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.BiApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", req.BiApproveId)
+		return
+	}
+	msg, err := biapprove.BiApproveRefuse(req.BiApproveId, 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.BiApproveCancelReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /cancel [post]
+func (this *BiApproveController) 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.BiApproveCancelReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.BiApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", req.BiApproveId)
+		return
+	}
+
+	// 撤销审批
+	msg, e := biapprove.BiApproveCancel(req.BiApproveId, 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.BiApproveMessageListResp
+// @router /message/list [get]
+func (this *BiApproveController) 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.BiApproveMessageListResp)
+	resp.List = make([]*response.BiApproveMessageItem, 0)
+	list, total, unRead, msg, err := biapprove.GetBiApproveMessage(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.BiApproveMessageReadReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /message/read [post]
+func (this *BiApproveController) 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.BiApproveMessageReadReq
+	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 := biapprove.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.BiApproveCheckApproveOpenReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /classify/check_open [post]
+func (this *BiApproveController) 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.BiApproveCheckApproveOpenReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	// 校验是否开启了审批流
+	opening, e := biapprove.CheckBiOpenApprove(req.ClassifyId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验报告是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	br.Data = opening
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 302 - 0
controllers/bi_approve/bi_approve_flow.go

@@ -0,0 +1,302 @@
+package biapprove
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/bi_approve/request"
+	"eta_gn/eta_api/models/bi_approve/response"
+	biapprove "eta_gn/eta_api/services/bi_approve"
+	"eta_gn/eta_api/utils"
+	"strings"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type BiApproveFlowController struct {
+	controllers.BaseAuthController
+}
+
+// List
+// @Title 审批流列表
+// @Description 审批流列表
+// @Param   PageSize			query	int		true	"每页数据条数"
+// @Param   CurrentIndex		query	int		true	"当前页页码"
+// @Param   ClassifyId		query	int		false	"分类ID"
+// @Param   Keyword				query	string	false	"搜索关键词"
+// @Param   SortRule			query	int		false	"排序方式: 1-正序; 2-倒序(默认)"
+// @Success 200 {object} report_approve.ReportApproveListResp
+// @router /flow/list [get]
+func (c *BiApproveFlowController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	pageSize, _ := c.GetInt("PageSize")
+	currentIndex, _ := c.GetInt("CurrentIndex")
+	keyword := c.GetString("Keyword")
+	classifyId, _ := c.GetInt("ClassifyId", 0)
+	sortRule, _ := c.GetInt("SortRule", 2)
+	if pageSize <= 0 {
+		pageSize = utils.PageSize10
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	var condition string
+	var pars []interface{}
+	if keyword != "" {
+		condition = ` AND flow_name LIKE ?`
+		pars = utils.GetLikeKeywordPars(pars, keyword, 1)
+	}
+	if classifyId > 0 {
+		condition += ` AND classify_id = ?`
+		pars = append(pars, classifyId)
+	}
+	startSize := paging.StartIndex(currentIndex, pageSize)
+	orderMap := map[int]string{1: "ASC", 2: "DESC"}
+	condition += " ORDER BY create_time " + orderMap[sortRule]
+
+	res, total, msg, err := biapprove.GetBiApproveFlowList(condition, pars, startSize, pageSize)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批流列表失败"
+		}
+		br.ErrMsg = "获取审批流列表失败, err:" + err.Error()
+		return
+	}
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.BiApproveFlowListResp)
+	resp.List = res
+	resp.Paging = page
+
+	br.Data = resp
+	br.Msg = "获取审批流列表成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// Add
+// @Title 新增审批流
+// @Description 新增审批流
+// @Param	request	body request.BiApproveFlowSaveReq true "type json string"
+// @Success 200
+// @router /flow/add [post]
+func (c *BiApproveFlowController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.BiApproveFlowSaveReq
+	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)
+	if req.FlowName == "" {
+		br.Msg = "审批流名称不能为空"
+		return
+	}
+
+	if len([]rune(req.FlowName)) > 20 {
+		br.Msg = "审批流名称最多输入20个字符"
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择审批分类"
+		return
+	}
+	if len(req.Nodes) == 0 {
+		br.Msg = "请添加审批流程"
+		return
+	}
+
+	if req.BiApproveFlowId > 0 {
+		br.Msg = "审批流已存在"
+		return
+	}
+
+	_, msg, err := biapprove.SaveBiApproveFlow(req)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "新增审批流失败"
+		}
+		br.ErrMsg = "新增审批流失败, err:" + err.Error()
+		return
+	}
+
+	br.Msg = "新增审批流成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// edit
+// @Title 新增审批流
+// @Description 新增审批流
+// @Param	request	body request.BiApproveFlowSaveReq true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/edit [post]
+func (c *BiApproveFlowController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.BiApproveFlowSaveReq
+	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)
+	if req.FlowName == "" {
+		br.Msg = "审批流名称不能为空"
+		return
+	}
+
+	if len([]rune(req.FlowName)) > 20 {
+		br.Msg = "审批流名称最多输入20个字符"
+		return
+	}
+	if req.ClassifyId <= 0 {
+		br.Msg = "请选择审批分类"
+		return
+	}
+	if len(req.Nodes) == 0 {
+		br.Msg = "请添加审批流程"
+		return
+	}
+
+	if req.BiApproveFlowId == 0 {
+		br.Msg = "审批流不存在, 请刷新重试"
+		return
+	}
+
+	ok, msg, err := biapprove.SaveBiApproveFlow(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
+}
+
+// delete
+// @Title 新增审批流
+// @Description 新增审批流
+// @Param	request	body request.BiApproveFlowRemoveResp true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/remove [post]
+func (c *BiApproveFlowController) Remove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.BiApproveFlowRemoveResp
+	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败, err:" + err.Error()
+		return
+	}
+	if req.BiApproveFlowId <= 0 {
+		br.Msg = "审批流不存在, 请刷新重试"
+		return
+	}
+	ok, msg, err := biapprove.DeleteBiApproveFlow(req.BiApproveFlowId)
+	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.BiApproveFlowRemoveResp true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/detail [get]
+func (c *BiApproveFlowController) 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
+	}
+	flowId, _ := c.GetInt("BiApproveFlowId")
+	if flowId <= 0 {
+		br.Msg = "审批流不存在"
+		return
+	}
+	detail, msg, err := biapprove.GetBiApproveFlowDetail(flowId)
+	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 = "获取审批流详情成功"
+}

+ 903 - 0
controllers/bi_dashboard.go

@@ -0,0 +1,903 @@
+package controllers
+
+import (
+	"encoding/json"
+	"errors"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/bi_dashboard"
+	"eta_gn/eta_api/models/system"
+	biapprove "eta_gn/eta_api/services/bi_approve"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
+	"time"
+)
+
+type BIDaShboardController struct {
+	BaseAuthController
+}
+
+// GroupList
+// @Title 获取我的列表
+// @Description 获取我的列表接口
+// @Success 200 {object} models.RespGroupList
+// @router /my_list [get]
+func (this *BIDaShboardController) MyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	// 获取我的看板列表
+	privateCond := ` AND sys_admin_id = ? AND state IN (1,6) `
+	privatePars := []interface{}{this.SysUser.AdminId}
+	privateList, err := bi_dashboard.GetBiDashboardList(privateCond, privatePars)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "查询成功"
+	br.Data = privateList
+	return
+}
+
+// AddDashboard
+// @Title 新增看板
+// @Description 新增看板接口
+// @Param	request	body models.AddDashboardReq true "type json string"
+// @Success 200 Ret=200 新增成功
+// @router /add [post]
+func (this *BIDaShboardController) AddDashboard() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.AddDashboardReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BiDashboardName == "" {
+		br.Msg = "名称不能为空"
+		return
+	}
+
+	item := &bi_dashboard.BiDashboard{
+		//BiDashboardClassifyId: req.ClassifyId,
+		BiDashboardName: req.BiDashboardName,
+		SysAdminId:      this.SysUser.AdminId,
+		SysAdminName:    this.SysUser.AdminName,
+		//Sort:                  0,
+		CreateTime: time.Now(),
+		ModifyTime: time.Now(),
+		State:      1,
+	}
+	id, e := bi_dashboard.AddBiDashboard(item)
+	if e != nil {
+		err = e
+		br.Msg = "新增失败"
+		br.ErrMsg = "新增失败,Err:" + e.Error()
+		return
+	}
+	detailList := make([]*bi_dashboard.BiDashboardDetail, 0)
+	for i, v := range req.List {
+		item := &bi_dashboard.BiDashboardDetail{
+			BiDashboardId: int(id),
+			Type:          v.Type,
+			UniqueCode:    v.UniqueCode,
+			Sort:          i + 1,
+			CreateTime:    time.Now(),
+			ModifyTime:    time.Now(),
+		}
+		detailList = append(detailList, item)
+	}
+	err = bi_dashboard.AddBiDashboardDetailMulti(detailList)
+	if err != nil {
+		br.Msg = "新增详情失败"
+		br.ErrMsg = "新增详情失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+	//br.Data =
+}
+
+// EditPpt
+// @Title 编辑看板
+// @Description 编辑看板接口
+// @Param	request	body bi_dashboard.EditDashboardReq true "type json string"
+// @Success 200 Ret=200 编辑成功
+// @router /edit [post]
+func (this *BIDaShboardController) EditDashboard() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.EditDashboardReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BiDashboardName == "" {
+		br.Msg = "标题不能为空"
+		return
+	}
+	item, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据异常!"
+		br.ErrMsg = "获取数据异常,Err:" + err.Error()
+		return
+	}
+
+	// 判断权限
+	if item.SysAdminId != this.SysUser.AdminId {
+		br.Msg = `无权编辑`
+		return
+	}
+
+	// 修改
+	item.BiDashboardName = req.BiDashboardName
+	item.ModifyTime = time.Now()
+
+	err = bi_dashboard.EditDashboard(item)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+
+	err = bi_dashboard.DeleteBiDashboardDetail(req.BiDashboardId)
+	if err != nil {
+		br.Msg = "删除详情失败"
+		br.ErrMsg = "删除详情失败,Err:" + err.Error()
+		return
+	}
+
+	detailList := make([]*bi_dashboard.BiDashboardDetail, 0)
+	for _, v := range req.List {
+		item := &bi_dashboard.BiDashboardDetail{
+			BiDashboardId: req.BiDashboardId,
+			Type:          v.Type,
+			UniqueCode:    v.UniqueCode,
+			Sort:          v.Sort,
+			CreateTime:    time.Now(),
+			ModifyTime:    time.Now(),
+		}
+		detailList = append(detailList, item)
+	}
+	err = bi_dashboard.AddBiDashboardDetailMulti(detailList)
+	if err != nil {
+		br.Msg = "新增详情失败"
+		br.ErrMsg = "新增详情失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "编辑成功"
+	br.IsAddLog = true
+}
+
+// DeleteDashboard
+// @Title 删除看板
+// @Description 删除看板接口
+// @Param	request	body bi_dashboard.DelDashboardReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /delete [post]
+func (this *BIDaShboardController) DeleteDashboard() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.DelDashboardReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BiDashboardId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	item, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据异常!"
+		br.ErrMsg = "获取数据异常,Err:" + err.Error()
+		return
+	}
+	if item.SysAdminId != this.SysUser.AdminId {
+		br.Msg = "无权删除"
+		return
+	}
+	err = bi_dashboard.DelDashboard(req.BiDashboardId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	err = bi_dashboard.DelDashboard(req.BiDashboardId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "删除成功"
+}
+
+// DeleteDashboard
+// @Title 删除看板详情
+// @Description 删除看板详情接口
+// @Param	request	body bi_dashboard.DelDashboardDetailReq true "type json string"
+// @Success 200 Ret=200 删除成功
+// @router /detail/delete [post]
+func (this *BIDaShboardController) DeleteDashboardDetail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.DelDashboardDetailReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.BiDashboardDetailId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	err = bi_dashboard.DeleteBiDashboardDetailByDetailId(req.BiDashboardDetailId)
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "删除成功"
+}
+
+// DetailDashboard
+// @Title 获取看板详情
+// @Description 获取看板详情接口
+// @Param   PptId   query   int  true       "PptId"
+// @Success 200 {object} models.PptV2
+// @router /detail [get]
+func (this *BIDaShboardController) DetailDashboard() {
+	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
+	}
+	dashboardId, _ := this.GetInt("DashboardId")
+
+	dashboardItem, err := bi_dashboard.GetDashboardById(dashboardId)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		br.Msg = "我的看板列表查询出错"
+		br.ErrMsg = err.Error()
+		return
+	}
+
+	detailList, err := bi_dashboard.GetBiDashboardDetailById(dashboardId)
+	if err != nil {
+		br.Msg = "详情获取失败"
+		br.ErrMsg = "详情获取失败,Err:" + err.Error()
+		return
+	}
+
+	resp := new(bi_dashboard.DashboardDetailResp)
+	resp.BiDashboard = dashboardItem
+	resp.List = detailList
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// MoveDashboard
+// @Title 移动看板详情
+// @Description 移动看板详情接口
+// @Param	request	body bi_dashboard.MoveDashboardDetailReq true "type json string"
+// @Success 200 Ret=200 移动成功
+// @router /detail/move [post]
+func (this *BIDaShboardController) MoveDashboard() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.MoveDashboardDetailReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BiDashboardId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+	if req.BiDashboardDetailId == req.OtherDetailId || req.BiDashboardDetailId <= 0 || req.OtherDetailId <= 0 {
+		br.Msg = "看板Id有误"
+		return
+	}
+	if req.Sort < 0 || req.OtherSort < 0 || req.Sort == req.OtherSort {
+		br.Msg = "排序有误"
+		return
+	}
+
+	item, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据异常!"
+		br.ErrMsg = "获取数据异常,Err:" + err.Error()
+		return
+	}
+
+	// 判断权限
+	if item.SysAdminId != this.SysUser.AdminId {
+		br.Msg = `无权移动`
+		return
+	}
+
+	// 修改
+	detailItem := &bi_dashboard.BiDashboardDetail{
+		BiDashboardDetailId: req.BiDashboardDetailId,
+		Sort:                req.OtherSort,
+		ModifyTime:          time.Now(),
+	}
+	err = bi_dashboard.EditBiDashboardDetail(detailItem)
+	if err != nil {
+		br.Msg = "编辑详情失败"
+		br.ErrMsg = "编辑详情失败,Err:" + err.Error()
+		return
+	}
+
+	otherItem := &bi_dashboard.BiDashboardDetail{
+		BiDashboardDetailId: req.OtherDetailId,
+		Sort:                req.Sort,
+		ModifyTime:          time.Now(),
+	}
+	err = bi_dashboard.EditBiDashboardDetail(otherItem)
+	if err != nil {
+		br.Msg = "编辑详情失败"
+		br.ErrMsg = "编辑详情失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "编辑成功"
+	br.IsAddLog = true
+}
+
+// ShareList
+// @Title 获取共享列表
+// @Description 获取共享列表接口
+// @Success 200 {object} models.RespGroupList
+// @router /share_list [get]
+func (this *BIDaShboardController) ShareList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	//myPptList := make([]*bi_dashboard.BiDashboard, 0)
+	//otherPptList := make([]*bi_dashboard.BiDashboard, 0)
+	grantList := bi_dashboard.RespGroupList{}
+
+	// 获取我的看板列表
+	ShareCond := ` AND sys_admin_id = ? AND state IN (1,6) `
+	SharePars := []interface{}{this.SysUser.AdminId}
+	ShareList, err := bi_dashboard.GetBiDashboardList(ShareCond, SharePars)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		br.ErrMsg = err.Error()
+		br.Msg = "查询失败"
+		return
+	}
+	grantList.MyList = ShareList
+
+	//dashboardMap := make(map[int]*bi_dashboard.BiDashboard)
+	adminIdList := make([]int, 0)   //需要查询的创建人admin_id列表集合
+	adminIdMap := make(map[int]int) //需要查询的创建人admin_id集合,用来去重的,避免重复id
+	grantDashboardList, err := bi_dashboard.GetAllGrantList(this.SysUser.AdminId)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		br.ErrMsg = err.Error()
+		br.Msg = "查询失败"
+		return
+	}
+
+	publicAdminIdList := make([]int, 0)
+	publicDashboardListMap := make(map[int][]*bi_dashboard.BiDashboard)
+	for _, v := range grantDashboardList {
+		publicDashboardList, ok := publicDashboardListMap[v.SysAdminId]
+		if !ok {
+			publicDashboardList = make([]*bi_dashboard.BiDashboard, 0)
+			publicAdminIdList = append(publicAdminIdList, v.SysAdminId)
+			if _, ok := adminIdMap[v.SysAdminId]; !ok {
+				adminIdList = append(adminIdList, v.SysAdminId) //需要查询的创建人admin_id列表集合
+				adminIdMap[v.SysAdminId] = v.SysAdminId         //需要查询的创建人admin_id集合,用来去重的,避免重复id
+			}
+		}
+
+		tmp := &bi_dashboard.BiDashboard{
+			BiDashboardId:   v.BiDashboardId,
+			BiDashboardName: v.BiDashboardName,
+			CreateTime:      v.CreateTime,
+			ModifyTime:      v.ModifyTime,
+			Sort:            v.Sort,
+			State:           v.State,
+			SysAdminId:      v.SysAdminId,
+			SysAdminName:    v.SysAdminName,
+		}
+		publicDashboardList = append(publicDashboardList, tmp)
+		publicDashboardListMap[v.SysAdminId] = publicDashboardList
+	}
+	// 创建人信息
+	systemAdminMap := make(map[int]*system.Admin)
+	systemAdminList, err := system.GetAdminListByIdList(adminIdList)
+	if err != nil {
+		return
+	}
+	for _, v := range systemAdminList {
+		systemAdminMap[v.AdminId] = v
+	}
+
+	for _, v := range publicAdminIdList {
+		systemAdmin, ok := systemAdminMap[v]
+		if !ok {
+			continue
+		}
+
+		// 看板 列表信息
+		respGroupNameListItemList, ok := publicDashboardListMap[v]
+		if !ok {
+			respGroupNameListItemList = make([]*bi_dashboard.BiDashboard, 0)
+		}
+
+		// ppt 分组信息
+		tmpRespGroupListItem := &bi_dashboard.RespOtherGroupListItem{
+			GroupId:       int64(systemAdmin.AdminId),
+			GroupName:     systemAdmin.RealName,
+			AdminId:       systemAdmin.AdminId,
+			DashboardList: respGroupNameListItemList,
+		}
+		grantList.OtherList = append(grantList.OtherList, tmpRespGroupListItem)
+	}
+	//if len(dashboradIds) > 0 {
+	//	// 通过dashboradIds列表字段获取所有的看板信息
+	//	dashboradList, tmpErr := bi_dashboard.GetDashboradByIds(dashboradIds)
+	//	if tmpErr != nil {
+	//		err = errors.New("查询dashborad详情出错:" + err.Error())
+	//		br.Msg = "查询dashborad详情出错"
+	//		br.ErrMsg = err.Error()
+	//		return
+	//	}
+	//	for _, v := range dashboradList {
+	//		dashboardMap[v.BiDashboardId] = v
+	//	}
+	//}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "查询成功"
+	br.Data = grantList
+	return
+}
+
+// PublicList
+// @Title 获取公共列表
+// @Description 获取公共列表接口
+// @Success 200 {object} models.RespGroupList
+// @router /public_list [get]
+func (this *BIDaShboardController) PublicList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	grantList := bi_dashboard.RespGroupList{}
+	// 获取公共看板列表
+	publicCond := ` AND state = 6 `
+	publicPars := []interface{}{this.SysUser.AdminId}
+	publicList, err := bi_dashboard.GetBiDashboardList(publicCond, publicPars)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		return
+	}
+
+	//dashboardMap := make(map[int]*bi_dashboard.BiDashboard)
+	adminIdList := make([]int, 0)   //需要查询的创建人admin_id列表集合
+	adminIdMap := make(map[int]int) //需要查询的创建人admin_id集合,用来去重的,避免重复id
+
+	publicAdminIdList := make([]int, 0)
+	publicDashboardListMap := make(map[int][]*bi_dashboard.BiDashboard)
+	for _, v := range publicList {
+		publicDashboardList, ok := publicDashboardListMap[v.SysAdminId]
+		if !ok {
+			publicDashboardList = make([]*bi_dashboard.BiDashboard, 0)
+			publicAdminIdList = append(publicAdminIdList, v.SysAdminId)
+			if _, ok := adminIdMap[v.SysAdminId]; !ok {
+				adminIdList = append(adminIdList, v.SysAdminId) //需要查询的创建人admin_id列表集合
+				adminIdMap[v.SysAdminId] = v.SysAdminId         //需要查询的创建人admin_id集合,用来去重的,避免重复id
+			}
+		}
+
+		tmp := &bi_dashboard.BiDashboard{
+			BiDashboardId:   v.BiDashboardId,
+			BiDashboardName: v.BiDashboardName,
+			CreateTime:      v.CreateTime,
+			ModifyTime:      v.ModifyTime,
+			Sort:            v.Sort,
+			State:           v.State,
+			SysAdminId:      v.SysAdminId,
+			SysAdminName:    v.SysAdminName,
+		}
+		publicDashboardList = append(publicDashboardList, tmp)
+		publicDashboardListMap[v.SysAdminId] = publicDashboardList
+	}
+	// 创建人信息
+	systemAdminMap := make(map[int]*system.Admin)
+	systemAdminList, err := system.GetAdminListByIdList(adminIdList)
+	if err != nil {
+		return
+	}
+	for _, v := range systemAdminList {
+		systemAdminMap[v.AdminId] = v
+	}
+
+	for _, v := range publicAdminIdList {
+		systemAdmin, ok := systemAdminMap[v]
+		if !ok {
+			continue
+		}
+
+		// 看板 列表信息
+		respGroupNameListItemList, ok := publicDashboardListMap[v]
+		if !ok {
+			respGroupNameListItemList = make([]*bi_dashboard.BiDashboard, 0)
+		}
+
+		// ppt 分组信息
+		tmpRespGroupListItem := &bi_dashboard.RespOtherGroupListItem{
+			GroupId:       int64(systemAdmin.AdminId),
+			GroupName:     systemAdmin.RealName,
+			AdminId:       systemAdmin.AdminId,
+			DashboardList: respGroupNameListItemList,
+		}
+		grantList.OtherList = append(grantList.OtherList, tmpRespGroupListItem)
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "查询成功"
+	br.Data = publicList
+	return
+}
+
+// AddDashboardClassify
+// @Title 新增看板分类
+// @Description 新增看板分类接口
+// @Param	request	body bi_dashboard.AddDashboardClassifyReq true "type json string"
+// @Success 200 Ret=200 新增成功
+// @router /classify/add [post]
+func (this *BIDaShboardController) AddDashboardClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.AddDashboardClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "名称不能为空"
+		return
+	}
+	maxSort, err := bi_dashboard.GetBiDashboardClassifyMaxSort()
+	if err != nil {
+		br.Msg = "获取最大排序值失败"
+		br.ErrMsg = "获取最大排序值失败,Err:" + err.Error()
+		return
+	}
+
+	item := &bi_dashboard.BiDashboardClassify{
+		BiDashboardClassifyName: req.ClassifyName,
+		Sort:                    maxSort + 1,
+		CreateTime:              time.Now(),
+		ModifyTime:              time.Now(),
+	}
+	_, e := bi_dashboard.AddBiDashboardClassify(item)
+	if e != nil {
+		err = e
+		br.Msg = "新增失败"
+		br.ErrMsg = "新增失败,Err:" + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+	//br.Data =
+}
+
+// EditDashboardClassify
+// @Title 编辑看板分类
+// @Description 编辑看板分类接口
+// @Param	request	body bi_dashboard.EditDashboardReq true "type json string"
+// @Success 200 Ret=200 编辑成功
+// @router /classify/edit [post]
+func (this *BIDaShboardController) EditDashboardClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.EditDashboardClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "标题不能为空"
+		return
+	}
+	if req.BiDashboardClassifyId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiDashboardClassifyId: %d", req.BiDashboardClassifyId)
+		return
+	}
+	item, err := bi_dashboard.GetBiDashboardClassifyById(req.BiDashboardClassifyId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据异常!"
+		br.ErrMsg = "获取数据异常,Err:" + err.Error()
+		return
+	}
+
+	// 修改
+	item.BiDashboardClassifyName = req.ClassifyName
+	item.ModifyTime = time.Now()
+
+	err = bi_dashboard.EditDashboardClassify(item)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "编辑成功"
+	br.IsAddLog = true
+}
+
+// EditDashboardClassify
+// @Title 删除看板分类
+// @Description 删除看板分类接口
+// @Param	request	body bi_dashboard.DelDashboardClassifyReq true "type json string"
+// @Success 200 Ret=200 编辑成功
+// @router /classify/del [post]
+func (this *BIDaShboardController) DelDashboardClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.DelDashboardClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.BiDashboardClassifyId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiDashboardClassifyId: %d", req.BiDashboardClassifyId)
+		return
+	}
+
+	err = bi_dashboard.DelBiDashboardClassify(req.BiDashboardClassifyId)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "删除成功"
+	br.IsAddLog = true
+}
+
+// Grant
+// @Title 分配看板权限
+// @Description 分配看板权限接口
+// @Param	request	body models.GrantPptReq true "type json string"
+// @Success 200 Ret=200 分配成功
+// @router /grant [post]
+func (this *BIDaShboardController) Grant() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.GrantDashboardReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.AdminIdStr == "" {
+		br.Msg = "参数错误"
+		return
+	}
+	if req.BiDashboardId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	dashboardItem, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		br.Msg = "我的看板列表查询出错"
+		br.ErrMsg = err.Error()
+		return
+	}
+	if dashboardItem.SysAdminId != this.SysUser.AdminId {
+		br.Msg = "无权配置"
+		return
+	}
+
+	list := make([]*bi_dashboard.BiDashboardGrant, 0)
+
+
+	grantAdminIdStrList := strings.Split(req.AdminIdStr, ",")
+	lenGrantAdminIdStrList := len(grantAdminIdStrList) //指定用户的人数
+	for _, v := range grantAdminIdStrList {
+		grantAdminId, tmpErr := strconv.Atoi(v)
+		if tmpErr != nil {
+			br.Msg = "参数有误"
+			br.ErrMsg = fmt.Sprintf("参数有误,Err:%s", tmpErr.Error())
+			return
+		}
+
+		//如果只选择了自己作为指定的人,那么就提示他报错。如果多人,那么就过滤自己
+		if grantAdminId == this.SysUser.AdminId {
+			if lenGrantAdminIdStrList == 1 {
+				br.Msg = "不能指定自己为权限用户"
+				br.ErrMsg = fmt.Sprintf("参数有误,Err:%s", tmpErr.Error())
+				return
+			}
+			continue
+		}
+		tmpV := &bi_dashboard.BiDashboardGrant{
+			BiDashboardId: req.BiDashboardId,
+			GrantAdminId:  grantAdminId,
+			CreateTime:    time.Now(),
+		}
+		list = append(list, tmpV)
+	}
+
+	if len(list) <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误,Err:%s", "指定用户为空")
+		return
+	}
+
+	err = bi_dashboard.MultiAddDashboardGrant(req.BiDashboardId, list)
+	if err != nil {
+		br.Msg = "分配失败"
+		br.ErrMsg = fmt.Sprintf("分配失败,Err:%s", err.Error())
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "分配成功"
+}
+
+// Public
+// @Title
+// @Description 设置公共看板
+// @Param	request	body models.GrantPptReq true "type json string"
+// @Success 200 Ret=200 分配成功
+// @router /public [post]
+func (this *BIDaShboardController) Public() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.PublicDashboardReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	// 校验是否开启了审批流
+	opening, e := biapprove.CheckBiOpenApprove(req.ClassifyId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验报告是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+
+	item, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据异常!"
+		br.ErrMsg = "获取数据异常,Err:" + err.Error()
+		return
+	}
+
+	if opening {
+		_, err = biapprove.SubmitBiApprove(req.BiDashboardId, item.BiDashboardName, req.ClassifyId, this.SysUser.AdminId, this.SysUser.RealName)
+		if err != nil {
+			br.Msg = "提交审批失败"
+			br.ErrMsg = "提交审批失败, Err: " + err.Error()
+			return
+		}
+	}
+	
+	item.BiDashboardClassifyId = req.ClassifyId
+
+	err = bi_dashboard.EditDashboard(item)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "分配成功"
+}

+ 0 - 161
controllers/report.go

@@ -72,167 +72,6 @@ func (this *ReportController) Delete() {
 	br.Msg = "删除成功"
 }
 
-//func (this *ReportController) Edit() {
-//	br := new(models.BaseResponse).Init()
-//	defer func() {
-//		this.Data["json"] = br
-//		this.ServeJSON()
-//	}()
-//	sysUser := this.SysUser
-//	if sysUser == nil {
-//		br.Msg = "请登录"
-//		br.ErrMsg = "请登录,SysUser Is Empty"
-//		br.Ret = 408
-//		return
-//	}
-//
-//	var req models.EditReq
-//	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
-//	if err != nil {
-//		br.Msg = "参数解析异常!"
-//		br.ErrMsg = "参数解析失败,Err:" + err.Error()
-//		return
-//	}
-//	if req.Content == "" {
-//		br.Msg = "报告内容不能为空"
-//		return
-//	}
-//	var contentSub string
-//	if req.Content != "" {
-//		e := utils.ContentXssCheck(req.Content)
-//		if e != nil {
-//			br.Msg = "存在非法标签"
-//			br.ErrMsg = "存在非法标签, Err: " + e.Error()
-//			return
-//		}
-//		content, e := services.FilterReportContentBr(req.Content)
-//		if e != nil {
-//			br.Msg = "内容去除前后空格失败"
-//			br.ErrMsg = "内容去除前后空格失败, Err: " + e.Error()
-//			return
-//		}
-//		req.Content = content
-//
-//		contentSub, err = services.GetReportContentSub(req.Content)
-//		if err != nil {
-//			go alarm_msg.SendAlarmMsg("解析 ContentSub 失败,Err:"+err.Error(), 3)
-//			//utils.SendEmail(utils.APPNAME+"失败提醒", "解析 ContentSub 失败,Err:"+err.Error(), utils.EmailSendToUsers)
-//		}
-//	}
-//
-//	//更新标记key
-//	markStatus, err := services.UpdateReportEditMark(int(req.ReportId), sysUser.AdminId, 1, sysUser.RealName, this.Lang)
-//	if err != nil {
-//		br.Msg = err.Error()
-//		return
-//	}
-//	if markStatus.Status == 1 {
-//		br.Msg = markStatus.Msg
-//		//br.Ret = 202 //202 服务器已接受请求,但尚未处理。
-//		return
-//	}
-//
-//	var stage int
-//	report, e := models.GetReportByReportId(int(req.ReportId))
-//	if e != nil {
-//		if utils.IsErrNoRow(e) {
-//			br.Msg = "报告已被删除, 请刷新页面"
-//			return
-//		}
-//		br.Msg = "操作失败"
-//		br.ErrMsg = "获取报告失败, Err: " + e.Error()
-//		return
-//	}
-//	if report.State == models.ReportStatePublished || report.State == models.ReportStatePass {
-//		br.Msg = "该报告已发布,不允许编辑"
-//		br.ErrMsg = "该报告已发布,不允许编辑"
-//		return
-//	}
-//	if report.ClassifyNameFirst != req.ClassifyNameFirst || report.ClassifyNameSecond != req.ClassifyNameSecond {
-//		maxStage, _ := models.GetReportStageEdit(req.ClassifyIdFirst, req.ClassifyIdSecond, int(req.ReportId))
-//		maxStage = maxStage + 1
-//		stage = maxStage
-//	} else {
-//		stage = report.Stage
-//	}
-//	//if req.State != report.State {
-//	//	recordItem := &models.ReportStateRecord{
-//	//		ReportId:   int(req.ReportId),
-//	//		ReportType: 1,
-//	//		State:      req.State,
-//	//		AdminId:    this.SysUser.AdminId,
-//	//		AdminName:  this.SysUser.AdminName,
-//	//		CreateTime: time.Now(),
-//	//	}
-//	//	go func() {
-//	//		_, _ = models.AddReportStateRecord(recordItem)
-//	//	}()
-//	//}
-//
-//	//item := new(models.Report)
-//	report.ClassifyIdFirst = req.ClassifyIdFirst
-//	report.ClassifyNameFirst = req.ClassifyNameFirst
-//	report.ClassifyIdSecond = req.ClassifyIdSecond
-//	report.ClassifyNameSecond = req.ClassifyNameSecond
-//	report.ClassifyIdThird = req.ClassifyIdThird
-//	report.ClassifyNameThird = req.ClassifyNameThird
-//	report.Title = req.Title
-//	report.Abstract = req.Abstract
-//	report.Author = req.Author
-//	report.Frequency = req.Frequency
-//	//report.State = report.State // 编辑不变更状态
-//	report.Stage = stage
-//	report.Content = html.EscapeString(req.Content)
-//	report.ContentSub = html.EscapeString(contentSub)
-//	report.CreateTime = req.CreateTime
-//	//report.CollaborateType = req.CollaborateType
-//	//report.ReportLayout = req.ReportLayout
-//	if req.IsPublicPublish <= 0 {
-//		req.IsPublicPublish = 1
-//	}
-//	report.IsPublicPublish = req.IsPublicPublish
-//	err = report.Update([]string{"ClassifyIdFirst", "ClassifyNameFirst", "ClassifyIdSecond", "ClassifyNameSecond", "ClassifyIdThird", "ClassifyNameThird", "Title", "Abstract", "Author", "Frequency", "Stage", "Content", "ContentSub", "CreateTime", "IsPublicPublish"})
-//	if err != nil {
-//		br.Msg = "保存失败"
-//		br.ErrMsg = "保存失败,Err:" + err.Error()
-//		return
-//	}
-//
-//	//处理权限
-//	//if utils.BusinessCode == utils.BusinessCodeRelease || utils.BusinessCode == utils.BusinessCodeSandbox {
-//	go func() {
-//		e := models.RemoveChartPermissionChapterMapping(req.ReportId)
-//		if e != nil {
-//			alarm_msg.SendAlarmMsg("修改删除报告权限失败,Err:"+e.Error(), 3)
-//			return
-//		}
-//		permissionItems, e := models.GetPermission(req.ClassifyIdSecond)
-//		if e != nil {
-//			alarm_msg.SendAlarmMsg("获取权限失败,Err:"+e.Error(), 3)
-//			return
-//		}
-//		for _, v := range permissionItems {
-//			e = models.AddChartPermissionChapterMapping(v.ChartPermissionId, req.ReportId)
-//			if e != nil {
-//				alarm_msg.SendAlarmMsg("新增权限失败,Err:"+e.Error(), 3)
-//				return
-//			}
-//		}
-//		// 同步crm权限
-//		_ = services.EditReportPermissionSync(req.ReportId, req.ClassifyIdSecond)
-//	}()
-//	//}
-//
-//	reportCode := utils.MD5(strconv.Itoa(int(req.ReportId)))
-//	resp := new(models.EditResp)
-//	resp.ReportId = req.ReportId
-//	resp.ReportCode = reportCode
-//	br.Ret = 200
-//	br.Success = true
-//	br.Msg = "保存成功"
-//	br.Data = resp
-//}
-
 // Upload
 // @Title 图片上传
 // @Description 图片上传接口

+ 1 - 1
controllers/report_author.go

@@ -175,7 +175,7 @@ func (this *ReportAuthorController) EditAuthor() {
 		br.ErrMsg = "获取数据异常,Err:" + err.Error()
 		return
 	}
-	if otherItem != nil {
+	if otherItem != nil && otherItem.Id > 0 {
 		br.Msg = "已存在该作者名称,请重新输入"
 		br.ErrMsg = "已存在该作者名称,请重新输入"
 		br.IsSendEmail = false

+ 6 - 5
controllers/report_chapter_type.go

@@ -168,7 +168,8 @@ func (this *ReportChapterTypeController) Add() {
 		return
 	}
 
-	cond = ` and product_id=1`
+	// 国能补充需求调整
+	/*cond = ` and product_id=1`
 	pars = make([]interface{}, 0)
 	permissionList, e := services.GetChartPermissionList(cond, pars)
 	if e != nil {
@@ -179,15 +180,15 @@ func (this *ReportChapterTypeController) Add() {
 	permissionIdName := make(map[int]string)
 	for i := range permissionList {
 		permissionIdName[permissionList[i].ChartPermissionId] = permissionList[i].PermissionName
-	}
+	}*/
 
 	newPermissions := make([]*models.ReportChapterTypePermission, 0) // 报告章节权限表(新)
-	for i := range req.ChartPermissionIdList {
+	for range req.ChartPermissionIdList {
 		newPermissions = append(newPermissions, &models.ReportChapterTypePermission{
 			ReportChapterTypeId:   item.ReportChapterTypeId,
 			ReportChapterTypeName: item.ReportChapterTypeName,
-			ChartPermissionId:     req.ChartPermissionIdList[i],
-			PermissionName:        permissionIdName[req.ChartPermissionIdList[i]],
+			ChartPermissionId:     0,
+			PermissionName:        "",
 			ResearchType:          item.ResearchType,
 			CreatedTime:           nowTime,
 		})

+ 183 - 0
models/bi_approve/bi_approve.go

@@ -0,0 +1,183 @@
+package biapprove
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"time"
+)
+
+type BiApprove struct {
+	BiApproveId   int       `gorm:"column:bi_approve_id;primary_key"`
+	BiId          int       `gorm:"column:bi_id"`
+	BiTitle       string    `gorm:"column:bi_title"`
+	ClassifyId    int       `gorm:"column:classify_id"`
+	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 BiApproveCols = struct {
+	BiApproveId   string
+	BiId          string
+	BiTitle       string
+	ClassifyId    string
+	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
+}{
+	BiApproveId:   "bi_approve_id",
+	BiId:          "bi_id",
+	BiTitle:       "bi_title",
+	ClassifyId:    "classify_id",
+	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 BiApproveItemOrm struct {
+	BiApproveId       int       `description:"审批ID"`
+	BiApproveRecordId int       `description:"审批记录ID"`
+	BiId              int       `description:"报告ID"`
+	BiTitle           string    `description:"报告标题"`
+	ClassifyId        int       `description:"分类ID"`
+	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 *BiApprove) TableName() string {
+	return "bi_approve"
+}
+
+func (b *BiApprove) Update(cols []string) (err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *BiApprove) Create() (err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Create(b).Error
+	return
+}
+
+func GetBiApproveByFlowIdAndVersionId(biFlowId int, flowVersion int) (item []*BiApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("flow_id = ? AND flow_version = ?", biFlowId, flowVersion).Find(&item).Error
+	return
+}
+
+func GetBiApproveById(biApproveId int) (item *BiApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("bi_approve_id = ?", biApproveId).First(&item).Error
+	return
+}
+
+// GetApprovingBiApproveCount 获取待处理的审批分页列表总数
+func GetApprovingBiApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.bi_approve_record_id
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_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["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovingBiApprovePageList 获取待处理的审批列表-分页
+func GetApprovingBiApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*BiApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.bi_approve_record_id, a.state AS record_state, b.*
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_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["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApprovedBiApproveCount 获取已处理的审批分页列表总数
+func GetApprovedBiApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.bi_approve_record_id
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_approve_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovedBiApprovePageList 获取已处理的审批列表-分页
+func GetApprovedBiApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*BiApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.bi_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 bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_approve_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApplyBiApproveCount 获取我发起的审批分页列表总数
+func GetApplyBiApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.* FROM Bi_approve AS a WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApplyBiApprovePageList 获取我发起的审批列表-分页
+func GetApplyBiApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*BiApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.* FROM bi_approve AS a WHERE 1 = 1 %s %s LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}

+ 179 - 0
models/bi_approve/bi_approve_flow.go

@@ -0,0 +1,179 @@
+package biapprove
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"time"
+)
+
+type BiApproveFlow struct {
+	BiApproveFlowId int       `gorm:"column:bi_approve_flow_id;primaryKey"`
+	FlowName        string    `gorm:"column:flow_name"`
+	ClassifyId      int       `gorm:"column:classify_id"`
+	ClassifyName    string    `gorm:"column:classify_name"`
+	CurrVersion     int       `gorm:"column:curr_version"`
+	CreateTime      time.Time `gorm:"column:create_time"`
+	ModifyTime      time.Time `gorm:"column:modify_time"`
+}
+
+var BiApproveFlowCols = struct {
+	BiApproveFlowId string
+	FlowName        string
+	ClassifyId      string
+	CurrVersion     string
+	CreateTime      string
+	ModifyTime      string
+}{
+	BiApproveFlowId: "bi_approve_flow_id",
+	FlowName:        "flow_name",
+	ClassifyId:      "classify_id",
+	CurrVersion:     "curr_version",
+	CreateTime:      "create_time",
+	ModifyTime:      "modify_time",
+}
+
+func (b *BiApproveFlow) TableName() string {
+	return "bi_approve_flow"
+}
+
+func (b *BiApproveFlow) Add(node []*BiApproveNode) (err error) {
+	prevNodes := make([]*BiApproveNode, 0)
+	o := global.DmSQL["rddp"].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(BiApproveNode)
+	for k, v := range node {
+		v.BiApproveFlowId = b.BiApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.BiApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.BiApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	return
+}
+
+func (b *BiApproveFlow) Update(cols []string, node []*BiApproveNode) (err error) {
+	prevNodes := make([]*BiApproveNode, 0)
+	o := global.DmSQL["rddp"].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(BiApproveNode)
+	for k, v := range node {
+		v.BiApproveFlowId = b.BiApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.BiApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.BiApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	return
+}
+
+func (b *BiApproveFlow) Delete() error {
+	return global.DmSQL["rddp"].Delete(b).Error
+}
+
+func (m *BiApproveFlow) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *BiApproveFlow, 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["rddp"].Raw(sql, pars...).First(&item).Error
+	return
+}
+
+func GetBiApproveFlowById(biApproveFlowId int) (item *BiApproveFlow, err error) {
+	err = global.DmSQL["rddp"].Where("bi_approve_flow_id = ?", biApproveFlowId).First(&item).Error
+	return
+}
+
+func GetBiApproveFlowByClassifyId(classifyId int) (item *BiApproveFlow, err error) {
+	err = global.DmSQL["rddp"].Where("classify_id = ?", classifyId).First(&item).Error
+	return
+}
+
+func GetBiApproveFlowByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*BiApproveFlow, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT * FROM bi_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 GetBiApproveFlowCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT COUNT(*) AS count FROM bi_approve_flow WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Scan(&count).Error
+	return
+}

+ 114 - 0
models/bi_approve/bi_approve_message.go

@@ -0,0 +1,114 @@
+package biapprove
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type BiApproveMessage 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"`          // 备注信息
+	BiApproveId   int       `gorm:"column:bi_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 BiApproveMessageCols = struct {
+	Id            string
+	SendUserId    string
+	ReceiveUserId string
+	Content       string
+	Remark        string
+	BiApproveId   string
+	ApproveState  string
+	IsRead        string
+	CreateTime    string
+	ModifyTime    string
+}{
+	Id:            "id",
+	SendUserId:    "send_user_id",
+	ReceiveUserId: "receive_user_id",
+	Content:       "content",
+	Remark:        "remark",
+	BiApproveId:   "bi_approve_id",
+	ApproveState:  "approve_state",
+	IsRead:        "is_read",
+	CreateTime:    "create_time",
+	ModifyTime:    "modify_time",
+}
+
+func (r *BiApproveMessage) TableName() string {
+	return "bi_approve_message"
+}
+
+func (r *BiApproveMessage) Create() (err error) {
+	o := global.DmSQL["rddp"]
+	err = o.Create(r).Error
+	return err
+}
+
+func (m *BiApproveMessage) PrimaryId() string {
+	return BiApproveMessageCols.Id
+}
+
+func (r *BiApproveMessage) CreateMulti(items []*BiApproveMessage) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := global.DmSQL["rddp"]
+	err = o.CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (m *BiApproveMessage) 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["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func (m *BiApproveMessage) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*BiApproveMessage, 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["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *BiApproveMessage) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*BiApproveMessage, 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)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *BiApproveMessage) GetItemById(id int) (item *BiApproveMessage, err error) {
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.PrimaryId())
+	err = global.DmSQL["rddp"].Raw(sql, id).First(&item).Error
+	return
+}
+
+func (m *BiApproveMessage) Update(cols []string) (err error) {
+	err = global.DmSQL["rddp"].Model(m).Select(cols).Updates(m).Error
+	return
+}

+ 90 - 0
models/bi_approve/bi_approve_node.go

@@ -0,0 +1,90 @@
+package biapprove
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type BiApproveNode struct {
+	BiApproveNodeId int       `gorm:"column:bi_approve_node_id;primaryKey"`
+	BiApproveFlowId int       `gorm:"column:bi_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 BiApproveNodeCols = struct {
+	BiApproveNodeId string
+	BiApproveFlowId string
+	PrevNodeId      string
+	NextNodeId      string
+	NodeType        string
+	ApproveType     string
+	Users           string
+	CurrVersion     string
+	CreatedTime     string
+}{
+	BiApproveNodeId: "bi_approve_node_id",
+	BiApproveFlowId: "bi_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 *BiApproveNode) TableName() string {
+	return "bi_approve_node"
+}
+
+func (m *BiApproveNode) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*BiApproveNode, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY created_time DESC, bi_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["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func UpdateNextNodes(nodes []*BiApproveNode) (err error) {
+	if len(nodes) == 0 {
+		return
+	}
+	updateCols := []string{"NextNodeId"}
+	for _, v := range nodes {
+		e := global.DmSQL["rddp"].Select(updateCols).Updates(v).Error
+		if e != nil {
+			err = fmt.Errorf("prev node update err: %v", e)
+			return
+		}
+	}
+	return
+}
+
+func GetBiApproveNodeByCondition(condition string, pars []interface{}) (node []*BiApproveNode, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT * FROM bi_approve_node WHERE 1=1 "
+	if condition != "" {
+		sql += " AND " + condition
+	}
+	err = o.Raw(sql, pars...).Find(&node).Error
+	return
+}
+
+func GetBiApproveNodeByFlowIdAndVersionId(flowId int, versionId int) (node []*BiApproveNode, err error) {
+	err = global.DmSQL["rddp"].Model(&BiApproveNode{}).Where("bi_approve_flow_id =? AND curr_version =?", flowId, versionId).Scan(&node).Error
+	return
+}

+ 152 - 0
models/bi_approve/bi_approve_record.go

@@ -0,0 +1,152 @@
+package biapprove
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type BiApproveRecord struct {
+	BiApproveRecordId   int       `gorm:"column:bi_approve_record_id;primary_key"`
+	BiApproveId         int       `gorm:"column:bi_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 BiApproveRecordCols = struct {
+	BiApproveRecordId   string
+	BiApproveId         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
+}{
+	BiApproveRecordId:   "bi_approve_record_id",
+	BiApproveId:         "bi_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 *BiApproveRecord) TableName() string {
+	return "bi_approve_record"
+}
+
+func (b *BiApproveRecord) Create() (err error) {
+	o := global.DmSQL["rddp"]
+	err = o.Create(b).Error
+	return
+}
+
+func (b *BiApproveRecord) CreateMulti(items []*BiApproveRecord) (err error) {
+	if len(items) == 0 {
+		return
+	}
+	o := global.DmSQL["rddp"]
+	err = o.CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (b *BiApproveRecord) Update(cols []string) (err error) {
+	o := global.DmSQL["rddp"]
+	err = o.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func GetBiApproveRecordByCondition(condition string, pars []interface{}) (record *BiApproveRecord, err error) {
+	o := global.DmSQL["rddp"]
+	sql := `SELECT * FROM bi_approve_record WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).First(&record).Error
+	return
+}
+
+func GetBiApproveRecordItemsByCondition(condition string, pars []interface{}) (items []*BiApproveRecord, err error) {
+	order := `ORDER BY create_time DESC`
+	sql := fmt.Sprintf(`SELECT * FROM bi_approve_record WHERE 1=1 %s %s`, condition, order)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (b *BiApproveRecord) UpdateNodeState(biApproveId, nodeId, nodeState, nodeApproveUserId int, nodeApproveUserName string, nodeApproveTime time.Time) (err error) {
+	pars := make([]interface{}, 0)
+	pars = append(pars, nodeState, nodeApproveUserId, nodeApproveUserName, nodeApproveTime)
+
+	// 更新条件
+	whereParas := []interface{}{biApproveId, 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 bi_approve_id = ? AND node_id = ?`, b.TableName())
+	err = global.DmSQL["rddp"].Exec(sql, pars...).Error
+	return
+}
+
+func (m *BiApproveRecord) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*BiApproveRecord, 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["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func (m *BiApproveRecord) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *BiApproveRecord, 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["rddp"].Raw(sql, pars...).First(&item).Error
+	return
+}

+ 21 - 0
models/bi_approve/request/bi_approve.go

@@ -0,0 +1,21 @@
+package request
+
+type BiApprovePassReq struct {
+	BiApproveId int `description:"审批ID"`
+}
+
+// BiApproveRefuseReq 审批驳回请求体
+type BiApproveRefuseReq struct {
+	BiApproveId   int    `description:"审批ID"`
+	ApproveRemark string `description:"驳回理由"`
+}
+
+// BiApproveCancelReq 撤销审批请求体
+type BiApproveCancelReq struct {
+	BiApproveId int `description:"审批ID"`
+}
+
+// BiApproveCheckApproveOpenReq 校验分类是否打开审批请求体
+type BiApproveCheckApproveOpenReq struct {
+	ClassifyId int `description:"一级分类ID"`
+}

+ 23 - 0
models/bi_approve/request/bi_approve_flow.go

@@ -0,0 +1,23 @@
+package request
+
+type BiApproveFlowSaveReq struct {
+	BiApproveFlowId int
+	ClassifyId      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 BiApproveFlowRemoveResp struct {
+	BiApproveFlowId int
+}

+ 5 - 0
models/bi_approve/request/bi_approve_message.go

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

+ 90 - 0
models/bi_approve/response/bi_approve.go

@@ -0,0 +1,90 @@
+package response
+
+// BiApproveDetail 审批详情信息
+type BiApproveDetail struct {
+	Bi               *BiApproveDetailBi      `description:"报告信息"`
+	Approve          *BiApproveDetailItem    `description:"审批信息"`
+	ApproveFlowNodes []*BiApproveDetailNodes `description:"审批节点信息"`
+}
+
+// BiApproveDetailBi 审批详情-报告信息
+type BiApproveDetailBi struct {
+	BiId       int    `description:"看板ID"`
+	BiTitle    string `description:"看板标题"`
+	BiCode     string `description:"看板code"`
+	BiClassify string `description:"看板分类"`
+}
+
+// BiApproveDetailItem 审批详情-审批信息
+type BiApproveDetailItem struct {
+	BiApproveId   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:"修改时间"`
+}
+
+// BiApproveDetailNodes 审批详情-节点信息
+type BiApproveDetailNodes struct {
+	BiApproveNodeId int                        `description:"看板审批节点ID"`
+	BiApproveFlowId 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           []*BiApproveDetailNodeUser `description:"审批人信息"`
+}
+
+// BiApproveDetailNodeUser 审批详情-节点用户信息
+type BiApproveDetailNodeUser struct {
+	BiApproveNodeUserReq
+	ApproveRecord *BiApproveDetailNodeUserRecord `description:"用户审批记录"`
+}
+
+// BiApproveNodeUserReq 报告审批节点用户请求体
+type BiApproveNodeUserReq struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+
+// BiApproveDetailNodeUserRecord 审批详情-节点用户审批记录
+type BiApproveDetailNodeUserRecord struct {
+	BiApproveRecordId int    `description:"审批记录ID"`
+	State             int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	ApproveUserId     int    `description:"审批人ID"`
+	ApproveUserName   string `description:"审批人姓名"`
+	ApproveRemark     string `description:"审批备注"`
+	ApproveTime       string `description:"审批时间"`
+}
+
+type BiApproveItemOrmResp struct {
+	BiApproveId       int    `description:"审批ID"`
+	BiApproveRecordId int    `description:"审批记录ID"`
+	BiId              int    `description:"报告ID"`
+	BiTitle           string `description:"报告标题"`
+	ClassifyId        int    `description:"分类ID"`
+	ClassifyName      string `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/bi_approve/response/bi_approve_flow.go

@@ -0,0 +1,46 @@
+package response
+
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type BiApproveFlowItem struct {
+	BiApproveFlowId int    `description:"主键"`
+	FlowName        string `description:"bi审批流程名称"`
+	ClassifyId      int    `description:"分类ID"`
+	ClassifyName    string `description:"分类名称"`
+	CurrVersion     int    `description:"当前版本"`
+	CreateTime      string `description:"创建时间"`
+	ModifyTime      string `description:"修改时间"`
+}
+
+type BiApproveFlowListResp struct {
+	List   []*BiApproveFlowItem
+	Paging *paging.PagingItem
+}
+
+type BiApproveFlowDetailResp struct {
+	BiApproveFlowItem `description:"审批流信息"`
+	Nodes             []*BiApproveNodeItem `description:"节点信息"`
+}
+
+type BiApproveNodeUser struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+type BiApproveNodeItem struct {
+	BiApproveNodeId int                  `description:"BI审批节点ID"`
+	BiApproveFlowId 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           []*BiApproveNodeUser `description:"审批人信息"`
+}
+
+type BiApproveListResp struct {
+	List   []*BiApproveItemOrmResp
+	Paging *paging.PagingItem
+}

+ 24 - 0
models/bi_approve/response/bi_approve_message.go

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

+ 126 - 0
models/bi_dashboard/bi_dashboard.go

@@ -0,0 +1,126 @@
+package bi_dashboard
+
+import (
+	"eta_gn/eta_api/global"
+	"time"
+)
+
+type BiDashboard struct {
+	BiDashboardId         int       `gorm:"primaryKey;autoIncrement;column:bi_dashboard_id"` // bi看板id
+	BiDashboardClassifyId int       `gorm:"column:bi_dashboard_classify_id" `                // 看板分类id
+	BiDashboardName       string    `gorm:"column:bi_dashboard_name;size:255"`               // 看板名称
+	SysAdminId            int       `gorm:"column:sys_admin_id" `                            // 创建人ID
+	SysAdminName          string    `gorm:"column:sys_admin_name;size:128" `                 // 创建人姓名
+	Sort                  int       `gorm:"column:sort" `                                    // 排序字段
+	CreateTime            time.Time `gorm:"column:create_time" `                             // 创建时间
+	ModifyTime            time.Time `gorm:"column:modify_time"`                              // 更新时间
+	State                 int       `gorm:"column:state"`                                    // 状态
+}
+
+// tableName
+func (m *BiDashboard) TableName() string {
+	return "bi_dashboard"
+}
+
+func (m *BiDashboard) Update(cols []string) (err error) {
+	err = global.DEFAULT_DmSQL.Model(m).Select(cols).Updates(m).Error
+	return
+}
+
+// AddBiDashboard 新增看板
+func AddBiDashboard(item *BiDashboard) (lastId int64, err error) {
+	err = global.DEFAULT_DmSQL.Create(item).Error
+	lastId = int64(item.BiDashboardId)
+	return
+}
+
+// GetShareDashboard 获取公开分享的看板
+func GetShareDashboard() (items []*BiDashboard, err error) {
+	//o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM bi_dashboard WHERE 1=1 AND state = 6 `
+
+	sql += `ORDER BY create_time DESC`
+	//sql += `ORDER BY create_time DESC LIMIT ?,?`
+	//_, err = o.Raw(sql).QueryRows(&items)
+	err = global.DEFAULT_DmSQL.Raw(sql).Find(&items).Error
+	return
+}
+
+func GetBiDashboardList(condition string, pars []interface{}) (items []*BiDashboard, err error) {
+	sql := `SELECT * FROM bi_dashboard WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	//
+	sql += `ORDER BY modify_time DESC `
+	//sql += `ORDER BY create_time DESC LIMIT ?,?`
+	//_, err = o.Raw(sql, pars...).QueryRows(&items)
+	err = global.DEFAULT_DmSQL.Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetDashboardById 获取看板
+func GetDashboardById(id int) (item *BiDashboard, err error) {
+	//o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM bi_dashboard WHERE bi_dashboard_id = ? limit 1`
+
+	//sql += `ORDER BY create_time DESC LIMIT ?,?`
+	//_, err = o.Raw(sql).QueryRows(&items)
+	err = global.DEFAULT_DmSQL.Raw(sql, id).First(&item).Error
+	return
+}
+
+// del
+func DelDashboard(id int) (err error) {
+	return global.DEFAULT_DmSQL.Delete(&BiDashboard{BiDashboardId: id}).Error
+}
+
+// DashboardDetailResp 详情响应体
+type DashboardDetailResp struct {
+	*BiDashboard
+	List []*BiDashboardDetail
+}
+
+type AddDashboardReq struct {
+	List            []*AddDashboardListReq
+	BiDashboardName string `description:"看板名称"`
+}
+
+type AddDashboardListReq struct {
+	Type       int
+	UniqueCode string
+	Sort       int
+}
+
+type EditDashboardReq struct {
+	List            []*AddDashboardListReq
+	BiDashboardId   int    `description:"看板id"`
+	BiDashboardName string `description:"看板名称"`
+}
+
+// update
+func EditDashboard(item *BiDashboard) (err error) {
+	return global.DEFAULT_DmSQL.Model(item).Updates(item).Error
+}
+
+type DelDashboardReq struct {
+	BiDashboardId int `description:"看板id"`
+}
+
+func GetDashboradByIds(dashboradIds []int) (list []*BiDashboard, err error) {
+	//_, err = orm.NewOrmUsingDB("rddp").
+	//	QueryTable("ppt_v2").
+	//	Filter("ppt_id__in", pptIds).
+	//	All(&list)
+	err = global.DEFAULT_DmSQL.Table("bi_dashboard").Where("bi_dashboard_id IN ?", dashboradIds).Find(&list).Error
+
+	return
+}
+
+// GetAllGrantList 获取已经有权限的看板列表
+func GetAllGrantList(sysUserId int) (list []*BiDashboard, err error) {
+	sql := `SELECT a.* FROM bi_dashboard a JOIN bi_dashboard_grant b on a.bi_dashboard_id=b.bi_dashboard_id 
+ WHERE b.grant_admin_id=?`
+	err = global.DEFAULT_DmSQL.Raw(sql, sysUserId, sysUserId).Find(&list).Error
+	return
+}

+ 112 - 0
models/bi_dashboard/bi_dashboard_classify.go

@@ -0,0 +1,112 @@
+package bi_dashboard
+
+import (
+	"eta_gn/eta_api/global"
+	"time"
+)
+
+type BiDashboardClassify struct {
+	BiDashboardClassifyId   int       `gorm:"primaryKey;autoIncrement;column:bi_dashboard_classify_id"` // bi看板分类id
+	BiDashboardClassifyName string    `gorm:"column:bi_dashboard_classify_name;size:255;not null" `     // 看板分类名称
+	Sort                    int       `gorm:"column:sort" `                                             // 排序字段
+	CreateTime              time.Time `gorm:"column:create_time" `                                      // 创建时间
+	ModifyTime              time.Time `gorm:"column:modify_time"`                                       // 更新时间
+}
+type BiDashboardClassifyItem struct {
+	BiDashboardClassifyId   int    // bi看板分类id
+	BiDashboardClassifyName string // 看板分类名称
+	Sort                    int    // 排序字段
+	CreateTime              string // 创建时间
+	ModifyTime              string // 更新时间
+}
+
+// tableName
+func (m *BiDashboardClassify) TableName() string {
+	return "bi_dashboard_classify"
+}
+
+// add
+func AddBiDashboardClassify(item *BiDashboardClassify) (lastId int64, err error) {
+	err = global.DEFAULT_DmSQL.Create(item).Error
+	lastId = int64(item.BiDashboardClassifyId)
+	return
+}
+
+// update
+func EditDashboardClassify(item *BiDashboardClassify) (err error) {
+	return global.DEFAULT_DmSQL.Model(item).Updates(item).Error
+}
+
+type RespGroupList struct {
+	MyList    []*BiDashboard
+	OtherList []*RespOtherGroupListItem
+}
+
+type RespMyGroupListItem struct {
+	GroupId       int64  `description:"目录id"`
+	GroupName     string `description:"目录名称"`
+	AdminId       int    `description:"目录创建者账号ID"`
+	DashboardList []*BiDashboard
+}
+
+type RespOtherGroupListItem struct {
+	GroupId       int64  `description:"目录id"`
+	GroupName     string `description:"目录名称"`
+	AdminId       int    `description:"目录创建者账号ID"`
+	DashboardList []*BiDashboard
+}
+
+type RespGroupDashboardListItem struct {
+	GroupPptId    int64  `description:"目录和ppt绑定序号"`
+	PptId         int64  `description:"ppt ID"`
+	Title         string `description:"标题"`
+	AdminId       int    `description:"移动ppt到该目录的系统用户id"`
+	AdminRealName string `description:"系统用户名称"`
+	PptVersion    int8   `description:"是否ppt的旧版本;1:旧的,2:新的"`
+	IsSingleShare int8   `description:"是否是单个共享ppt,0未单个共享,1共享"`
+	PptxUrl       string `description:"pptx下载地址"`
+	ReportId      int    `description:"关联的报告ID"`
+	ReportCode    string `description:"关联的报告code"`
+	PptCreateTime string `description:"ppt创建时间"`
+	PptModifyTime string `description:"ppt修改时间"`
+	PublishTime   string `description:"发布时间"`
+	PptPage       int    `description:"PPT总页数"`
+	IsReceived    int8   `description:"是否收到的共享,0:不是,1:是"`
+	IsGrant       int8   `description:"是否分配了权限,0:不是,1:是"`
+	TitleSetting  string `description:"PPT标题设置"`
+}
+
+func GetBiDashboardClassifyAllList() (list []*BiDashboardClassify, err error) {
+	err = global.DEFAULT_DmSQL.Select("*").Find(&list).Error
+	return
+}
+
+func GetBiDashboardClassifyById(id int) (item *BiDashboardClassify, err error) {
+	err = global.DEFAULT_DmSQL.Where("bi_dashboard_classify_id = ?", id).First(&item).Error
+	return
+}
+
+type AddDashboardClassifyReq struct {
+	ClassifyName string `description:"看板名称"`
+}
+
+type EditDashboardClassifyReq struct {
+	BiDashboardClassifyId int    `description:"看板id"`
+	ClassifyName          string `description:"看板名称"`
+}
+
+type DelDashboardClassifyReq struct {
+	BiDashboardClassifyId int    `description:"看板id"`
+}
+
+// GetBiDashboardClassifyMaxSort 获取看板分类下最大的排序数
+func GetBiDashboardClassifyMaxSort() (sort int, err error) {
+	sql := `SELECT Max(sort) AS sort FROM bi_dashboard_classify `
+	err = global.DEFAULT_DmSQL.Raw(sql).First(&sort).Error
+	return
+}
+
+// del
+func DelBiDashboardClassify(id int) (err error) {
+	return global.DEFAULT_DmSQL.Where("bi_dashboard_classify_id = ?", id).Delete(&BiDashboardClassify{}).Error
+}

+ 66 - 0
models/bi_dashboard/bi_dashboard_detail.go

@@ -0,0 +1,66 @@
+package bi_dashboard
+
+import (
+	"eta_gn/eta_api/global"
+	"time"
+)
+
+type BiDashboardDetail struct {
+	BiDashboardDetailId int       `gorm:"primaryKey;autoIncrement;column:bi_dashboard_detail_id" ` // bi看板id
+	BiDashboardId       int       `gorm:"column:bi_dashboard_id" `                                 // 看板id
+	Type                int       `gorm:"column:type" `                                            // 1图表 2表格
+	UniqueCode          string    `gorm:"column:unique_code;size:32;not null" `                    // 报告唯一编码
+	Sort                int       `gorm:"column:sort" `                                            // 排序字段
+	CreateTime          time.Time `gorm:"column:create_time" `                                     // 创建时间
+	ModifyTime          time.Time `gorm:"column:modify_time" `                                     // 更新时间
+}
+
+// tableName
+func (m *BiDashboardDetail) TableName() string {
+	return "bi_dashboard_detail"
+}
+
+// add
+func AddBiDashboardDetail(item *BiDashboardDetail) (err error) {
+	err = global.DEFAULT_DmSQL.Create(item).Error
+	return
+}
+
+func GetBiDashboardDetailById(id int) (list []*BiDashboardDetail, err error) {
+	err = global.DEFAULT_DmSQL.Table("bi_dashboard_detail").Where("bi_dashboard_id IN ?", id).Find(&list).Error
+
+	return
+}
+
+// multiAdd
+func AddBiDashboardDetailMulti(items []*BiDashboardDetail) (err error) {
+	return global.DEFAULT_DmSQL.CreateInBatches(items, 100).Error
+}
+
+// del
+func DeleteBiDashboardDetail(id int) (err error) {
+	return global.DEFAULT_DmSQL.Where("bi_dashboard_id = ?", id).Delete(&BiDashboardDetail{}).Error
+}
+
+type MoveDashboardDetailReq struct {
+	BiDashboardId       int `description:"看板id"`
+	BiDashboardDetailId int `description:"看板详情id"`
+	Sort                int `description:"排序"`
+	OtherDetailId       int `description:"交换的详情id"`
+	OtherSort           int `description:"交换的排序"`
+}
+
+// update
+func EditBiDashboardDetail(item *BiDashboardDetail) (err error){
+	return global.DEFAULT_DmSQL.Model(item).Where("bi_dashboard_detail_id = ?", item.BiDashboardDetailId).Updates(item).Error
+}
+
+type DelDashboardDetailReq struct {
+	BiDashboardDetailId int `description:"看板详情id"`
+}
+
+
+// del
+func DeleteBiDashboardDetailByDetailId(id int) (err error) {
+	return global.DEFAULT_DmSQL.Where("bi_dashboard_detail_id = ?", id).Delete(&BiDashboardDetail{}).Error
+}

+ 63 - 0
models/bi_dashboard/bi_dashboard_grant.go

@@ -0,0 +1,63 @@
+package bi_dashboard
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+	"time"
+)
+
+type BiDashboardGrant struct {
+	GrantId       int       `gorm:"primaryKey;autoIncrement;column:grant_id"` // 授权id
+	BiDashboardId int       `gorm:"column:bi_dashboard_id" `                  // 看板id
+	GrantAdminId  int       `gorm:"column:grant_admin_id"`                    // 授权的用户id
+	CreateTime    time.Time `gorm:"column:create_time"`                       // 授权时间
+}
+
+// tableName
+func (m *BiDashboardGrant) TableName() string {
+	return "bi_dashboard_grant"
+}
+
+// GrantDashboardReq 分配看板权限
+type GrantDashboardReq struct {
+	BiDashboardId int    `description:"看板id" `
+	AdminIdStr    string `description:"指定成员id,多个成员用英文,隔开"`
+}
+
+// MultiAddDashboardGrant 批量添加授权记录
+func MultiAddDashboardGrant(pptId int, list []*BiDashboardGrant) (err error) {
+
+	to := global.DEFAULT_DmSQL.Begin()
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	sql := "DELETE from bi_dashboard_grant where bi_dashboard_id=?"
+	//_, err = to.Raw(sql, pptId).Exec()
+	err = to.Exec(sql, pptId).Error
+	if err != nil {
+		return
+	}
+
+	// 新增授权记录
+	if len(list) > 0 {
+		//_, tmpErr := to.InsertMulti(len(list), list)
+		tmpErr := to.CreateInBatches(list, utils.MultiAddNum).Error
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+	}
+
+	return
+}
+
+// PublicDashboardReq 设置公共看板权限
+type PublicDashboardReq struct {
+	BiDashboardId int `description:"看板id" `
+	ClassifyId    int `description:"分类id"`
+}

+ 1 - 0
models/business_conf.go

@@ -17,6 +17,7 @@ const (
 	BusinessConfXfVcn                     = "XfVcn"
 	BusinessConfEnPptCoverImgs            = "EnPptCoverImgs"
 	BusinessConfIsReportApprove           = "IsReportApprove"
+	BusinessConfIsBIApprove               = "IsBIApprove"
 	BusinessConfReportApproveType         = "ReportApproveType"
 	BusinessConfCompanyName               = "CompanyName"
 	BusinessConfCompanyWatermark          = "CompanyWatermark"

+ 1 - 1
models/business_conf_operation_record.go

@@ -10,7 +10,7 @@ import (
 
 // BusinessConfOperationRecord 商户配置操作记录表
 type BusinessConfOperationRecord struct {
-	Id          int       //`orm:"column(id);pk" gorm:"primaryKey" `
+	Id          int       `gorm:"primaryKey" `
 	SysUserId   int       //`description:"操作人ID"`
 	SysRealName string    //`description:"操作人姓名"`
 	Content     string    //`description:"操作数据"`

+ 24 - 24
models/chart_permission.go

@@ -13,30 +13,30 @@ const (
 
 // ChartPermission 报告权限表
 type ChartPermission struct {
-	ChartPermissionId     int       `gorm:"column:chart_permission_id"`     //`orm:"column(chart_permission_id);pk" gorm:"primaryKey"  description:"问题ID" json:"chart_permission_id"`
-	ChartPermissionName   string    `gorm:"column:chart_permission_name"`   //`description:"名称" json:"chart_permission_name"`
-	PermissionName        string    `gorm:"column:permission_name"`         //`description:"权限名" json:"permission_name"`
-	Sort                  int       `gorm:"column:sort"`                    //`description:"排序" json:"sort"`
-	Enabled               int       `gorm:"column:enabled"`                 //`description:"是否可用" json:"enabled"`
-	CreatedTime           time.Time `gorm:"column:created_time"`            //`description:"创建时间" json:"created_time"`
-	LastUpdatedTime       time.Time `gorm:"column:last_updated_time"`       //`description:"更新时间" json:"last_updated_time"`
-	TeleconferenceSort    int       `gorm:"column:teleconference_sort"`     //`description:"电话会类型排序" json:"teleconference_sort"`
-	Remark                string    `gorm:"column:remark"`                  //`description:"备注" json:"remark"`
-	ClassifyName          string    `gorm:"column:classify_name"`           //`description:"分类名称" json:"classify_name"`
-	ProductName           string    `gorm:"column:product_name"`            //`description:"产品名称" json:"product_name"`
-	ProductId             int       `gorm:"column:product_id"`              //`description:"产品ID" json:"product_id"`
-	ImageURL              string    `gorm:"column:image_url"`               //`orm:"column(image_url);" description:"图片地址" json:"image_url"`
-	ShowType              int       `gorm:"column:show_type"`               //`description:"1:查研观向小程序展示" json:"show_type"`
-	IsOther               int       `gorm:"column:is_other"`                //`description:"是否是其他,用于查研观向小程序后台展示" json:"is_other"`
-	IsReport              int       `gorm:"column:is_report"`               //`description:"是否是报告,用于查研观向小程序前台报告展示" json:"is_report"`
-	CygxAuth              int       `gorm:"column:cygx_auth"`               //`description:"是否是权限,用于查研观向小程序前台权限校验" json:"cygx_auth"`
-	PermissionType        int       `gorm:"column:permission_type"`         //`description:"1主观,2客观" json:"permission_type"`
-	YbImgUrl              string    `gorm:"column:yb_img_url"`              //`description:"研报小程序报告列表icon" json:"yb_img_url"`
-	ProductPermissionName string    `gorm:"column:product_permission_name"` //`description:"种类权限名称" json:"product_permission_name"`
-	PriceDrivenState      int       `gorm:"column:price_driven_state"`      //`description:"品种价格驱动开启状态 0-关闭 1-开启" json:"price_driven_state"`
-	ImageUrlM             string    `gorm:"column:image_url_m"`             //`description:"图片地址(查研观向移动端)" json:"image_url_m"`
-	ParentId              int       `gorm:"column:parent_id"`               //`description:"父级权限id" json:"parent_id"`
-	IsPublic              int       `gorm:"column:is_public"`               //`description:"是否是公有权限1:公有权限,0私有权限" json:"is_public"`
+	ChartPermissionId     int       `gorm:"column:chart_permission_id;primaryKey"` //`orm:"column(chart_permission_id);pk" gorm:"primaryKey"  description:"问题ID" json:"chart_permission_id"`
+	ChartPermissionName   string    `gorm:"column:chart_permission_name"`          //`description:"名称" json:"chart_permission_name"`
+	PermissionName        string    `gorm:"column:permission_name"`                //`description:"权限名" json:"permission_name"`
+	Sort                  int       `gorm:"column:sort"`                           //`description:"排序" json:"sort"`
+	Enabled               int       `gorm:"column:enabled"`                        //`description:"是否可用" json:"enabled"`
+	CreatedTime           time.Time `gorm:"column:created_time"`                   //`description:"创建时间" json:"created_time"`
+	LastUpdatedTime       time.Time `gorm:"column:last_updated_time"`              //`description:"更新时间" json:"last_updated_time"`
+	TeleconferenceSort    int       `gorm:"column:teleconference_sort"`            //`description:"电话会类型排序" json:"teleconference_sort"`
+	Remark                string    `gorm:"column:remark"`                         //`description:"备注" json:"remark"`
+	ClassifyName          string    `gorm:"column:classify_name"`                  //`description:"分类名称" json:"classify_name"`
+	ProductName           string    `gorm:"column:product_name"`                   //`description:"产品名称" json:"product_name"`
+	ProductId             int       `gorm:"column:product_id"`                     //`description:"产品ID" json:"product_id"`
+	ImageURL              string    `gorm:"column:image_url"`                      //`orm:"column(image_url);" description:"图片地址" json:"image_url"`
+	ShowType              int       `gorm:"column:show_type"`                      //`description:"1:查研观向小程序展示" json:"show_type"`
+	IsOther               int       `gorm:"column:is_other"`                       //`description:"是否是其他,用于查研观向小程序后台展示" json:"is_other"`
+	IsReport              int       `gorm:"column:is_report"`                      //`description:"是否是报告,用于查研观向小程序前台报告展示" json:"is_report"`
+	CygxAuth              int       `gorm:"column:cygx_auth"`                      //`description:"是否是权限,用于查研观向小程序前台权限校验" json:"cygx_auth"`
+	PermissionType        int       `gorm:"column:permission_type"`                //`description:"1主观,2客观" json:"permission_type"`
+	YbImgUrl              string    `gorm:"column:yb_img_url"`                     //`description:"研报小程序报告列表icon" json:"yb_img_url"`
+	ProductPermissionName string    `gorm:"column:product_permission_name"`        //`description:"种类权限名称" json:"product_permission_name"`
+	PriceDrivenState      int       `gorm:"column:price_driven_state"`             //`description:"品种价格驱动开启状态 0-关闭 1-开启" json:"price_driven_state"`
+	ImageUrlM             string    `gorm:"column:image_url_m"`                    //`description:"图片地址(查研观向移动端)" json:"image_url_m"`
+	ParentId              int       `gorm:"column:parent_id"`                      //`description:"父级权限id" json:"parent_id"`
+	IsPublic              int       `gorm:"column:is_public"`                      //`description:"是否是公有权限1:公有权限,0私有权限" json:"is_public"`
 }
 
 type ChartPermissionItem struct {

+ 6 - 6
models/classify_menu.go

@@ -9,12 +9,12 @@ import (
 
 // ClassifyMenu 报告分类-子目录表
 type ClassifyMenu struct {
-	MenuId     int       `gorm:"column:menu_id"`     // `orm:"column(menu_id);pk" gorm:"primaryKey" `
-	MenuName   string    `gorm:"column:mobile"`      //`description:"子目录名称"`
-	ClassifyId int       `gorm:"column:classify_id"` //`description:"一级分类ID"`
-	Sort       int       `gorm:"column:sort"`        //`description:"排序"`
-	CreateTime time.Time `gorm:"column:create_time"` //`description:"创建时间"`
-	ModifyTime time.Time `gorm:"column:modify_time"` //`description:"更新时间"`
+	MenuId     int       `gorm:"column:menu_id;primaryKey"` // `orm:"column(menu_id);pk" gorm:"primaryKey" `
+	MenuName   string    `gorm:"column:mobile"`             //`description:"子目录名称"`
+	ClassifyId int       `gorm:"column:classify_id"`        //`description:"一级分类ID"`
+	Sort       int       `gorm:"column:sort"`               //`description:"排序"`
+	CreateTime time.Time `gorm:"column:create_time"`        //`description:"创建时间"`
+	ModifyTime time.Time `gorm:"column:modify_time"`        //`description:"更新时间"`
 }
 
 func (item *ClassifyMenu) TableName() string {

+ 4 - 4
models/classify_menu_relation.go

@@ -8,10 +8,10 @@ import (
 
 // ClassifyMenuRelation 报告分类-子目录关联表
 type ClassifyMenuRelation struct {
-	Id         int       `gorm:"column:id"`          //`orm:"column(id);pk" gorm:"primaryKey" `
-	MenuId     int       `gorm:"column:menu_id"`     //`description:"子目录ID"`
-	ClassifyId int       `gorm:"column:classify_id"` //`description:"二级分类ID"`
-	CreateTime time.Time `gorm:"column:create_time"` //`description:"创建时间"`
+	Id         int       `gorm:"column:id;primaryKey"` //`orm:"column(id);pk" gorm:"primaryKey" `
+	MenuId     int       `gorm:"column:menu_id"`       //`description:"子目录ID"`
+	ClassifyId int       `gorm:"column:classify_id"`   //`description:"二级分类ID"`
+	CreateTime time.Time `gorm:"column:create_time"`   //`description:"创建时间"`
 }
 
 func (item *ClassifyMenuRelation) TableName() string {

+ 8 - 8
models/cloud_disk_menu.go

@@ -9,14 +9,14 @@ import (
 )
 
 type CloudDiskMenu struct {
-	MenuId     int       `gorm:"column:menu_id"`     // `orm:"column(menu_id);pk" gorm:"primaryKey"  description:"目录ID"`
-	MenuName   string    `gorm:"column:menu_name"`   //`description:"目录名称"`
-	ParentId   int       `gorm:"column:parent_id"`   //`description:"父级ID"`
-	Size       int64     `gorm:"column:size"`        //`description:"目录大小"`
-	AdminId    int       `gorm:"column:admin_id"`    //`description:"创建人ID"`
-	AdminName  string    `gorm:"column:admin_name"`  //`description:"创建人名称"`
-	CreateTime time.Time `grom:"column:create_time"` //`description:"创建时间"`
-	ModifyTime time.Time `gorm:"column:modify_time"` //`description:"修改时间"`
+	MenuId     int       `gorm:"column:menu_id;primaryKey"` // `orm:"column(menu_id);pk" gorm:"primaryKey"  description:"目录ID"`
+	MenuName   string    `gorm:"column:menu_name"`          //`description:"目录名称"`
+	ParentId   int       `gorm:"column:parent_id"`          //`description:"父级ID"`
+	Size       int64     `gorm:"column:size"`               //`description:"目录大小"`
+	AdminId    int       `gorm:"column:admin_id"`           //`description:"创建人ID"`
+	AdminName  string    `gorm:"column:admin_name"`         //`description:"创建人名称"`
+	CreateTime time.Time `grom:"column:create_time"`        //`description:"创建时间"`
+	ModifyTime time.Time `gorm:"column:modify_time"`        //`description:"修改时间"`
 }
 
 func (m *CloudDiskMenu) TableName() string {

+ 1 - 1
models/data_manage/base_from_sci_hq_index.go

@@ -9,7 +9,7 @@ import (
 )
 
 type BaseFromSciHqIndex struct {
-	BaseFromSciHqIndexId int       `orm:"pk" gorm:"primaryKey" `
+	BaseFromSciHqIndexId int       `gorm:"primaryKey" `
 	ClassifyId           int       `description:"指标分类id"`
 	IndexCode            string    `description:"指标编码"`
 	IndexName            string    `description:"指标名称"`

+ 1 - 1
models/data_manage/base_from_smm.go

@@ -9,7 +9,7 @@ import (
 )
 
 type BaseFromSmm struct {
-	BaseFromSmmId int `orm:"column(base_from_smm_id);pk" gorm:"primaryKey" `
+	BaseFromSmmId int `gorm:"primaryKey" `
 	Aid           int
 	Name          string
 	Interface     string

+ 1 - 1
models/data_manage/chart_classify.go

@@ -286,7 +286,7 @@ func (chartClassify *ChartClassify) Update(cols []string) (err error) {
 // GetChartClassifyMaxSort 获取图表分类下最大的排序数
 func GetChartClassifyMaxSort(parentId, source int) (sort int, err error) {
 	o := global.DmSQL["data"]
-	sql := `SELECT Max(sort) AS sort FROM chart_classify WHERE parent_id=? AND source = ? `
+	sql := `SELECT COALESCE(MAX(sort),0) AS sort FROM chart_classify WHERE parent_id=? AND source = ? `
 	err = o.Raw(sql, parentId, source).Scan(&sort).Error
 
 	return

+ 123 - 56
models/data_manage/chart_info.go

@@ -6,11 +6,13 @@ import (
 	"eta_gn/eta_api/models/mgo"
 	"eta_gn/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/paging"
-	"go.mongodb.org/mongo-driver/bson"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"go.mongodb.org/mongo-driver/bson"
+	"gorm.io/gorm"
 )
 
 type ChartInfo struct {
@@ -477,6 +479,15 @@ func GetEdbDataList(source, subSource, edbInfoId int, startDate, endDate string)
 
 }
 
+func (e *EdbDataList) AfterFind(db *gorm.DB) (err error) {
+	tmp, err := time.Parse(utils.FormatDateWallWithLoc, e.DataTime)
+	if err != nil {
+		return
+	}
+	e.DataTime = tmp.Format(utils.FormatDate)
+	return
+}
+
 // getEdbDataListByMysql
 // @Description: 通过mysql查询指标数据
 // @author: Roc
@@ -511,7 +522,7 @@ func getEdbDataListByMysql(source, subSource, edbInfoId int, startDate, endDate
 	sql = fmt.Sprintf(sql, tableName)
 	o := global.DmSQL["data"]
 
-	err = o.Raw(sql, utils.ForwardPars(pars, edbInfoId)...).Scan(&list).Error
+	err = o.Raw(sql, utils.ForwardPars(pars, edbInfoId)...).Find(&list).Error
 	//err = o.Raw(sql, pars...).Scan(&list).Error
 	return
 }
@@ -703,60 +714,116 @@ func getEdbDataListMinAndMaxByMongo(source, subSource, edbInfoId int, startDate,
 	return
 }
 
+// type ChartEdbInfoMapping struct {
+// 	EdbInfoId           int     `description:"指标id"`
+// 	SourceName          string  `description:"来源名称"`
+// 	Source              int     `description:"来源id"`
+// 	SubSource           int     `description:"来源id"`
+// 	EdbCode             string  `description:"指标编码"`
+// 	EdbName             string  `description:"指标名称"`
+// 	EdbAliasName        string  `description:"指标名称(别名)"`
+// 	EdbNameEn           string  `description:"英文指标名称"`
+// 	EdbAliasNameEn      string  `description:"英文指标名称(别名)"`
+// 	EdbType             int     `description:"指标类型:1:基础指标,2:计算指标"`
+// 	Frequency           string  `description:"频率"`
+// 	FrequencyEn         string  `description:"英文频率"`
+// 	Unit                string  `description:"单位"`
+// 	UnitEn              string  `description:"英文单位"`
+// 	StartDate           string  `description:"起始日期"`
+// 	EndDate             string  `description:"终止日期"`
+// 	ModifyTime          string  `description:"指标最后更新时间"`
+// 	ChartEdbMappingId   int     `description:"图表指标id"`
+// 	ChartInfoId         int     `description:"图表id"`
+// 	MaxData             float64 `description:"上限"`
+// 	MinData             float64 `description:"下限"`
+// 	IsOrder             bool    `description:"true:正序,false:逆序"`
+// 	IsAxis              int     `description:"1:左轴,0:右轴"`
+// 	EdbInfoType         int     `description:"1:标准指标,0:领先指标"`
+// 	EdbInfoCategoryType int     `description:"0:普通指标,1:预测指标"`
+// 	LeadValue           int     `description:"领先值"`
+// 	LeadUnit            string  `description:"领先单位"`
+// 	LeadUnitEn          string  `description:"领先英文单位"`
+// 	ChartStyle          string  `description:"图表类型"`
+// 	ChartColor          string  `description:"颜色"`
+// 	PredictChartColor   string  `description:"预测数据的颜色"`
+// 	ChartWidth          float64 `description:"线条大小"`
+// 	ChartType           int     `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图"`
+// 	LatestDate          string  `description:"数据最新日期"`
+// 	LatestValue         float64 `description:"数据最新值"`
+// 	MoveLatestDate      string  `description:"移动后的数据最新日期"`
+// 	UniqueCode          string  `description:"指标唯一编码"`
+// 	MinValue            float64 `json:"-" description:"最小值"`
+// 	MaxValue            float64 `json:"-" description:"最大值"`
+// 	DataList            interface{}
+// 	IsNullData          bool    `json:"-" description:"是否空数据"`
+// 	MappingSource       int     `description:"1:ETA图库;2:商品价格曲线"`
+// 	RegionType          string  `description:"交易所来源,海外还是国内" json:"-"`
+// 	ClassifyId          int     `description:"分类id"`
+// 	SubSourceName       string  `description:"子数据来源名称"`
+// 	IndicatorCode       string  `description:"指标代码"`
+// 	IsConvert           int     `description:"是否数据转换 0不转 1转"`
+// 	ConvertType         int     `description:"数据转换类型 1乘 2除 3对数"`
+// 	ConvertValue        float64 `description:"数据转换值"`
+// 	ConvertUnit         string  `description:"数据转换单位"`
+// 	ConvertEnUnit       string  `description:"数据转换单位"`
+// 	IsJoinPermission    int     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
+// 	HaveOperaAuth       bool    `description:"是否有数据权限,默认:false"`
+// }
+
 type ChartEdbInfoMapping struct {
-	EdbInfoId           int     `description:"指标id"`
-	SourceName          string  `description:"来源名称"`
-	Source              int     `description:"来源id"`
-	SubSource           int     `description:"来源id"`
-	EdbCode             string  `description:"指标编码"`
-	EdbName             string  `description:"指标名称"`
-	EdbAliasName        string  `description:"指标名称(别名)"`
-	EdbNameEn           string  `description:"英文指标名称"`
-	EdbAliasNameEn      string  `description:"英文指标名称(别名)"`
-	EdbType             int     `description:"指标类型:1:基础指标,2:计算指标"`
-	Frequency           string  `description:"频率"`
-	FrequencyEn         string  `description:"英文频率"`
-	Unit                string  `description:"单位"`
-	UnitEn              string  `description:"英文单位"`
-	StartDate           string  `description:"起始日期"`
-	EndDate             string  `description:"终止日期"`
-	ModifyTime          string  `description:"指标最后更新时间"`
-	ChartEdbMappingId   int     `description:"图表指标id"`
-	ChartInfoId         int     `description:"图表id"`
-	MaxData             float64 `description:"上限"`
-	MinData             float64 `description:"下限"`
-	IsOrder             bool    `description:"true:正序,false:逆序"`
-	IsAxis              int     `description:"1:左轴,0:右轴"`
-	EdbInfoType         int     `description:"1:标准指标,0:领先指标"`
-	EdbInfoCategoryType int     `description:"0:普通指标,1:预测指标"`
-	LeadValue           int     `description:"领先值"`
-	LeadUnit            string  `description:"领先单位"`
-	LeadUnitEn          string  `description:"领先英文单位"`
-	ChartStyle          string  `description:"图表类型"`
-	ChartColor          string  `description:"颜色"`
-	PredictChartColor   string  `description:"预测数据的颜色"`
-	ChartWidth          float64 `description:"线条大小"`
-	ChartType           int     `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图"`
-	LatestDate          string  `description:"数据最新日期"`
-	LatestValue         float64 `description:"数据最新值"`
-	MoveLatestDate      string  `description:"移动后的数据最新日期"`
-	UniqueCode          string  `description:"指标唯一编码"`
-	MinValue            float64 `json:"-" description:"最小值"`
-	MaxValue            float64 `json:"-" description:"最大值"`
-	DataList            interface{}
-	IsNullData          bool    `json:"-" description:"是否空数据"`
-	MappingSource       int     `description:"1:ETA图库;2:商品价格曲线"`
-	RegionType          string  `description:"交易所来源,海外还是国内" json:"-"`
-	ClassifyId          int     `description:"分类id"`
-	SubSourceName       string  `description:"子数据来源名称"`
-	IndicatorCode       string  `description:"指标代码"`
-	IsConvert           int     `description:"是否数据转换 0不转 1转"`
-	ConvertType         int     `description:"数据转换类型 1乘 2除 3对数"`
-	ConvertValue        float64 `description:"数据转换值"`
-	ConvertUnit         string  `description:"数据转换单位"`
-	ConvertEnUnit       string  `description:"数据转换单位"`
-	IsJoinPermission    int     `description:"是否加入权限管控,0:不加入;1:加入;默认:0"`
-	HaveOperaAuth       bool    `description:"是否有数据权限,默认:false"`
+	EdbInfoId           int         `description:"指标id" gorm:"column:edb_info_id"`
+	SourceName          string      `description:"来源名称" gorm:"column:source_name"`
+	Source              int         `description:"来源id" gorm:"column:source"`
+	SubSource           int         `description:"来源id" gorm:"column:sub_source"`
+	EdbCode             string      `description:"指标编码" gorm:"column:edb_code"`
+	EdbName             string      `description:"指标名称" gorm:"column:edb_name"`
+	EdbAliasName        string      `description:"指标名称(别名)" gorm:"column:edb_alias_name"`
+	EdbNameEn           string      `description:"英文指标名称" gorm:"column:edb_name_en"`
+	EdbAliasNameEn      string      `description:"英文指标名称(别名)" gorm:"column:edb_alias_name_en"`
+	EdbType             int         `description:"指标类型:1:基础指标,2:计算指标" gorm:"column:edb_type"`
+	Frequency           string      `description:"频率" gorm:"column:frequency"`
+	FrequencyEn         string      `description:"英文频率" gorm:"column:frequency_en"`
+	Unit                string      `description:"单位" gorm:"column:unit"`
+	UnitEn              string      `description:"英文单位" gorm:"column:unit_en"`
+	StartDate           string      `description:"起始日期" gorm:"column:start_date"`
+	EndDate             string      `description:"终止日期" gorm:"column:end_date"`
+	ModifyTime          string      `description:"指标最后更新时间" gorm:"column:modify_time"`
+	ChartEdbMappingId   int         `description:"图表指标id" gorm:"column:chart_edb_mapping_id"`
+	ChartInfoId         int         `description:"图表id" gorm:"column:chart_info_id"`
+	MaxData             float64     `description:"上限" gorm:"column:max_data"`
+	MinData             float64     `description:"下限" gorm:"column:min_data"`
+	IsOrder             bool        `description:"true:正序,false:逆序" gorm:"column:is_order"`
+	IsAxis              int         `description:"1:左轴,0:右轴" gorm:"column:is_axis"`
+	EdbInfoType         int         `description:"1:标准指标,0:领先指标" gorm:"column:edb_info_type"`
+	EdbInfoCategoryType int         `description:"0:普通指标,1:预测指标" gorm:"column:edb_info_category_type"`
+	LeadValue           int         `description:"领先值" gorm:"column:lead_value"`
+	LeadUnit            string      `description:"领先单位" gorm:"column:lead_unit"`
+	LeadUnitEn          string      `description:"领先英文单位" gorm:"column:lead_unit_en"`
+	ChartStyle          string      `description:"图表类型" gorm:"column:chart_style"`
+	ChartColor          string      `description:"颜色" gorm:"column:chart_color"`
+	PredictChartColor   string      `description:"预测数据的颜色" gorm:"column:predict_chart_color"`
+	ChartWidth          float64     `description:"线条大小" gorm:"column:chart_width"`
+	ChartType           int         `description:"生成样式:1:曲线图,2:季节性图,3:面积图,4:柱状图,5:散点图,6:组合图,7:柱方图,8:商品价格曲线图,9:相关性图" gorm:"column:chart_type"`
+	LatestDate          string      `description:"数据最新日期" gorm:"column:latest_date"`
+	LatestValue         float64     `description:"数据最新值" gorm:"column:latest_value"`
+	MoveLatestDate      string      `description:"移动后的数据最新日期" gorm:"column:move_latest_date"`
+	UniqueCode          string      `description:"指标唯一编码" gorm:"column:unique_code"`
+	MinValue            float64     `json:"-" description:"最小值" gorm:"column:min_value"`
+	MaxValue            float64     `json:"-" description:"最大值" gorm:"column:max_value"`
+	DataList            interface{} `gorm:"-"`
+	IsNullData          bool        `json:"-" description:"是否空数据" gorm:"column:is_null_data"`
+	MappingSource       int         `description:"1:ETA图库;2:商品价格曲线" gorm:"column:mapping_source"`
+	RegionType          string      `description:"交易所来源,海外还是国内" json:"-" gorm:"column:region_type"`
+	ClassifyId          int         `description:"分类id" gorm:"column:classify_id"`
+	SubSourceName       string      `description:"子数据来源名称" gorm:"column:sub_source_name"`
+	IndicatorCode       string      `description:"指标代码" gorm:"column:indicator_code"`
+	IsConvert           int         `description:"是否数据转换 0不转 1转" gorm:"column:is_convert"`
+	ConvertType         int         `description:"数据转换类型 1乘 2除 3对数" gorm:"column:convert_type"`
+	ConvertValue        float64     `description:"数据转换值" gorm:"column:convert_value"`
+	ConvertUnit         string      `description:"数据转换单位" gorm:"column:convert_unit"`
+	ConvertEnUnit       string      `description:"数据转换单位" gorm:"column:convert_en_unit"`
+	IsJoinPermission    int         `description:"是否加入权限管控,0:不加入;1:加入;默认:0" gorm:"column:is_join_permission"`
+	HaveOperaAuth       bool        `description:"是否有数据权限,默认:false" gorm:"column:have_opera_auth"`
 }
 
 type QuarterData struct {

+ 1 - 1
models/data_manage/chart_theme/chart_theme.go

@@ -143,7 +143,7 @@ func GetChartThemeItemList(chartThemeTypeId int) (list []*ChartThemeItem, err er
 	sql := `SELECT a.*,b.default_chart_theme_id FROM chart_theme a
 	    JOIN chart_theme_type b on a.chart_theme_type_id =b.chart_theme_type_id
 	    WHERE a.chart_theme_type_id = ? AND a.is_delete=0 ORDER BY a.chart_theme_id ASC `
-	err = global.DmSQL["data"].Raw(sql).Find(&list).Error
+	err = global.DmSQL["data"].Raw(sql, chartThemeTypeId).Find(&list).Error
 	return
 }
 

+ 8 - 8
models/data_manage/chart_theme/chart_theme_type.go

@@ -18,14 +18,14 @@ type ChartThemeType struct {
 }
 
 type ChartThemeTypeList struct {
-	ChartThemeTypeId    int    `description:"图表主题类型ID" `
-	ChartTypeName       string `description:"类型名称"`
-	ChartTypeNameEn     string `description:"类型名称"`
-	ChartType           int    `description:"图表类型"`
-	ChartSource         int    `description:"图表来源"`
-	ParentId            int    `description:"父级ID"`
-	DefaultChartThemeId int    `description:"默认使用的主题id"`
-	Child               []*ChartThemeTypeList
+	ChartThemeTypeId    int                   `description:"图表主题类型ID" `
+	ChartTypeName       string                `description:"类型名称"`
+	ChartTypeNameEn     string                `description:"类型名称"`
+	ChartType           int                   `description:"图表类型"`
+	ChartSource         int                   `description:"图表来源"`
+	ParentId            int                   `description:"父级ID"`
+	DefaultChartThemeId int                   `description:"默认使用的主题id"`
+	Child               []*ChartThemeTypeList `gorm:"-"`
 }
 
 // Update

+ 1 - 1
models/data_manage/edb_classify.go

@@ -9,7 +9,7 @@ import (
 )
 
 type EdbClassify struct {
-	ClassifyId             int       `orm:"column(classify_id);pk" gorm:"primaryKey" `
+	ClassifyId             int       `gorm:"primaryKey" `
 	ClassifyType           uint8     `description:"分类类型,0:普通指标分类,1:预测指标分类"`
 	ClassifyName           string    `description:"分类名称"`
 	ParentId               int       `description:"父级id"`

+ 1 - 1
models/data_manage/edb_data_pb.go

@@ -6,7 +6,7 @@ import (
 )
 
 type EdbDataPb struct {
-	EdbDataId     int `orm:"column(edb_data_id);pk" gorm:"primaryKey" `
+	EdbDataId     int `gorm:"primaryKey" `
 	EdbInfoId     int
 	EdbCode       string
 	DataTime      string

+ 1 - 1
models/data_manage/edb_data_ths.go

@@ -6,7 +6,7 @@ import (
 )
 
 type EdbDataThs struct {
-	EdbDataId     int `orm:"column(edb_data_id);pk" gorm:"primaryKey" `
+	EdbDataId     int `gorm:"primaryKey" `
 	EdbInfoId     int
 	EdbCode       string
 	DataTime      string

+ 1 - 1
models/data_manage/edb_data_wind.go

@@ -7,7 +7,7 @@ import (
 )
 
 type EdbDataWind struct {
-	EdbDataId     int `orm:"column(edb_data_id);pk" gorm:"primaryKey" `
+	EdbDataId     int `gorm:"primaryKey" `
 	EdbInfoId     int
 	EdbCode       string
 	DataTime      string

+ 1 - 1
models/data_manage/edb_info.go

@@ -19,7 +19,7 @@ import (
 )
 
 type EdbInfo struct {
-	EdbInfoId        int    `orm:"column(edb_info_id);pk" gorm:"primaryKey" `
+	EdbInfoId        int    `gorm:"primaryKey" `
 	EdbInfoType      int    `description:"指标类型,0:普通指标,1:预测指标"`
 	SourceName       string `description:"来源名称"`
 	Source           int    `description:"来源id"`

+ 1 - 1
models/data_manage/edb_info_calculate.go

@@ -28,7 +28,7 @@ type EdbInfoFromTag struct {
 }
 
 type EdbInfoCalculate struct {
-	EdbInfoCalculateId int       `orm:"column(edb_info_calculate_id);pk" gorm:"primaryKey" `
+	EdbInfoCalculateId int       `gorm:"primaryKey" `
 	EdbInfoId          int       `description:"指标id"`
 	EdbCode            string    `description:"指标编码"`
 	FromEdbInfoId      int       `description:"计算指标id"`

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

@@ -880,7 +880,7 @@ func GetExcelMaxSortByClassifyId(classifyId int, source int) (sort int, err erro
 	//sql := ` SELECT Max(sort) AS sort FROM excel_info WHERE excel_classify_id=? AND source = ? AND is_delete=0 order by sort desc,excel_info_id desc limit 1`
 	//err = o.Raw(sql, classifyId, source).QueryRow(&sort)
 
-	sql := ` SELECT Max(sort) AS sort FROM excel_info WHERE excel_classify_id=? AND source = ? AND is_delete=0 order by sort desc,excel_info_id desc limit 1`
+	sql := ` SELECT COALESCE(MAX(sort),0) AS sort FROM excel_info WHERE excel_classify_id=? AND source = ? AND is_delete=0 order by sort desc,excel_info_id desc limit 1`
 	err = global.DmSQL["data"].Raw(sql, classifyId, source).Scan(&sort).Error
 	return
 }

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

@@ -68,7 +68,7 @@ type SheetItem struct {
 	CalcChain    string          `description:"计算公式"`
 	ModifyTime   time.Time       `description:"最近修改日期" json:"-"`
 	CreateTime   time.Time       `description:"创建日期"`
-	Data         *ExcelSheetData `description:"excel的数据"`
+	Data         *ExcelSheetData `gorm:"-" description:"excel的数据"`
 }
 
 // GetAllSheetItemList 根据excel_id获取所有的sheet详情

+ 1 - 1
models/data_manage/excel_style.go

@@ -163,7 +163,7 @@ type Rowlen struct {
 }
 
 type ExcelEdbdataMapping struct {
-	MappingId  int `orm:"column(mapping_id);pk" gorm:"primaryKey" `
+	MappingId  int `gorm:"primaryKey" `
 	ExcelId    int64
 	ClassifyId int
 	Frequency  string

+ 1 - 1
models/data_manage/factor_edb_series_calculate_data_qjjs.go

@@ -205,7 +205,7 @@ func (m *FactorEdbSeriesCalculateDataQjjs) GetEdbDataList(seriesId int, edbInfoI
 
 	sql += ` ORDER BY data_time ASC `
 	sql = fmt.Sprintf(sql, m.TableName())
-	err = global.DmSQL["data"].Raw(sql, pars...).Scan(&list).Error
+	err = global.DmSQL["data"].Raw(sql, pars...).Find(&list).Error
 
 	return
 }

+ 1 - 1
models/data_manage/manual_classify.go

@@ -6,7 +6,7 @@ import (
 )
 
 type EdbdataClassify struct {
-	ClassifyId   int       `orm:"column(classify_id);pk" gorm:"primaryKey"  description:"分类id"`
+	ClassifyId   int       `gorm:"primaryKey"  description:"分类id"`
 	ClassifyName string    `description:"分类名称"`
 	ParentId     int       `description:"父级id"`
 	CreateTime   time.Time `description:"创建时间"`

+ 2 - 2
models/data_manage/manual_user.go

@@ -8,7 +8,7 @@ import (
 )
 
 type ManualUser struct {
-	ManualUserId    int       `orm:"column(manual_user_id);pk" gorm:"primaryKey" `
+	ManualUserId    int       `gorm:"primaryKey" `
 	AdminId         int       `description:"用户id"`
 	AdminRealName   string    `description:"用户姓名"`
 	SysUserId       int       `description:"创建人id"`
@@ -73,7 +73,7 @@ type ManualSysUserClassifySaveReq struct {
 }
 
 type ManualUserClassify struct {
-	ManualUserClassifyId int `orm:"column(manual_user_classify_id);pk" gorm:"primaryKey" `
+	ManualUserClassifyId int `gorm:"primaryKey" `
 	AdminId              int
 	ClassifyId           int
 	CreateTime           time.Time

+ 1 - 1
models/data_manage/my_chart.go

@@ -517,7 +517,7 @@ func GetChartClassify(chartClassifyId int) (chart_classify_id string, err error)
 	//			)AS t`
 	//	err = o.Raw(sql, chartClassifyId, chartClassifyId, chartClassifyId).QueryRow(&chart_classify_id)
 
-	sql := `SELECT GROUP_CONCAT(t.chart_classify_id) AS chart_classify_id FROM (
+	sql := `SELECT LISTAGG(t.chart_classify_id, ',') WITHIN GROUP (ORDER BY t.chart_classify_id) AS chart_classify_id FROM (
 				SELECT a.chart_classify_id FROM chart_classify AS a
 				WHERE a.chart_classify_id=?
 				UNION ALL

+ 1 - 1
models/data_manage/search_keyword.go

@@ -6,7 +6,7 @@ import (
 )
 
 type SearchKeyword struct {
-	Id         int `orm:"column(id);pk" gorm:"primaryKey" `
+	Id         int `gorm:"primaryKey" `
 	KeyWord    string
 	CreateTime time.Time
 }

+ 6 - 3
models/data_manage/supply_analysis/variety.go

@@ -126,7 +126,7 @@ type VarietyItem struct {
 	PermissionUserId          string        `description:"有操作权限的用户id"`
 	ModifyTime                string        `description:"修改时间"`
 	CreateTime                string        `description:"创建时间"`
-	Button                    VarietyButton `description:"操作按钮权限"`
+	Button                    VarietyButton `gorm:"-" description:"操作按钮权限"`
 }
 
 type VarietyButton struct {
@@ -137,13 +137,16 @@ type VarietyButton struct {
 
 // GetListBySuperAdminPage 不区分是否有分析权限的获取分页数据
 func (item Variety) GetListBySuperAdminPage(condition string, pars []interface{}, startSize, pageSize int) (total int, items []*VarietyItem, err error) {
-	baseSql := ` FROM ( SELECT a.*, GROUP_CONCAT(DISTINCT b.sys_user_id ORDER BY b.sys_user_id ASC SEPARATOR ',') AS permission_user_id FROM variety a 
+	baseSql := ` FROM ( SELECT a.variety_id,a.variety_name,a.last_update_sys_user_id,
+a.last_update_sys_user_real_name,a.production_day,a.sys_user_id,a.sys_user_real_name,a.modify_time,a.create_time,LISTAGG(b.sys_user_id, ',') WITHIN GROUP (ORDER BY b.sys_user_id ASC) AS permission_user_id 
+				FROM variety a 
 				LEFT JOIN variety_admin_permission b on a.variety_id=b.variety_id 
 				LEFT JOIN variety_edb_info c on a.variety_id=c.variety_id WHERE 1=1 `
 	if condition != "" {
 		baseSql += condition
 	}
-	baseSql += ` GROUP BY a.variety_id ) d `
+	baseSql += ` GROUP BY a.variety_id,a.variety_name,a.last_update_sys_user_id,
+a.last_update_sys_user_real_name,a.production_day,a.sys_user_id,a.sys_user_real_name,a.modify_time,a.create_time ) d `
 	// 数据总数
 	totalSql := `SELECT COUNT(1) total ` + baseSql
 

+ 531 - 0
models/db2.go

@@ -0,0 +1,531 @@
+package models
+
+import (
+	"eta_gn/eta_api/models/ai_summary"
+	"eta_gn/eta_api/models/aimod"
+	"eta_gn/eta_api/models/data_manage"
+	"eta_gn/eta_api/models/data_manage/chart_theme"
+	"eta_gn/eta_api/models/data_manage/cross_variety"
+	"eta_gn/eta_api/models/data_manage/data_manage_permission"
+	"eta_gn/eta_api/models/data_manage/edb_refresh"
+	"eta_gn/eta_api/models/data_manage/excel"
+	future_good2 "eta_gn/eta_api/models/data_manage/future_good"
+	"eta_gn/eta_api/models/data_manage/supply_analysis"
+	"eta_gn/eta_api/models/data_stat"
+	"eta_gn/eta_api/models/fe_calendar"
+	"eta_gn/eta_api/models/ppt_english"
+	"eta_gn/eta_api/models/report"
+	"eta_gn/eta_api/models/report_approve"
+	"eta_gn/eta_api/models/sandbox"
+	"eta_gn/eta_api/models/semantic_analysis"
+	"eta_gn/eta_api/models/smart_report"
+	"eta_gn/eta_api/models/speech_recognition"
+	"eta_gn/eta_api/models/system"
+	_ "github.com/go-sql-driver/mysql"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+func init() {
+
+	//注册对象
+	orm.RegisterModel(
+		new(Classify),
+		new(Resource),
+		new(PptV2),
+		new(PptV2PublishRecord),
+		new(PptV2SaveLog),
+		new(PptV2Group),
+		new(PptV2GroupMapping),
+		new(PptV2Grant),                 //ppt授权操作表
+		new(ResearchVarietyTagRelation), // 研究员标签关系表
+		new(ReportPptImg),               //Ppt转报告的图片记录表
+	)
+
+	// 系统表 数据表
+	initSystem()
+
+	// 联系人相关
+	initWxUser()
+
+	// 报告相关 数据表
+	initReport()
+
+	// 注册Edb沙盘 数据表
+	initSandbox()
+
+	// 上海指标服务 数据表
+	initShEdbData()
+
+	// 指标服务 数据表
+	initEdbData()
+
+	// 图表 数据表
+	initChart()
+	// 英文报告
+	initEnglishReport()
+
+	// 英文ppt
+	initPptEnglish()
+
+	// 期货数据库
+	initFutureGood()
+
+	// 共享网盘
+	initCloudDisk()
+
+	// 语义分析
+	initSemanticAnalysis()
+
+	// 供应分析
+	initSupplyAnalysis()
+
+	//多图配置
+	initMultipleGraphConfig()
+
+	// 商家配置
+	initBusinessConf()
+
+	// 图库框架
+	initChartFramework()
+
+	// 外部链接
+	initOutLink()
+
+	// 智能研报
+	initSmartReport()
+
+	// initDataStat 数据源统计管理相关表
+	initDataStat()
+
+	// 初始化EXCEL的表
+	initExcel()
+
+	// 初始化跨品种分析表
+	initCrossVariety()
+
+	//初始化AI
+	initAi()
+
+	// 报告审批
+	initReportApprove()
+
+	// 初始化图表主题
+	initChartTheme()
+
+	// 初始化指标刷新
+	initEdbRefresh()
+
+	// 语音识别
+	initSpeechRecognition()
+
+	// 初始化数据资产权限的一些表
+	initDataMangePerMission()
+
+	// 初始化外汇日历
+	initFeCalendar()
+
+	// 初始化因子指标系列
+	initFactorEdbSeries()
+}
+
+// initSystem 系统表 数据表
+func initSystem() {
+	orm.RegisterModel(
+		new(system.SysUserLoginRecord),
+		new(system.SysSession),
+		new(system.SysDepartment),
+		new(system.SysGroup),
+		new(system.SysRoleMenu),
+		new(system.Admin),
+		new(system.SysRole),
+		new(system.SysMenuButton),
+		new(system.SysRoleButton),
+		new(system.SysRoleAdmin), //管理员账号和角色映射表
+		new(system.AdminConfig),  //系统用户配置表
+		new(system.AdminOperateRecord),
+		new(system.AdminVerifyCodeRecord), // 用户短信邮箱验证码记录表
+	)
+}
+
+// initWxUser 联系人相关 数据表
+func initWxUser() {
+	orm.RegisterModel(
+		new(WxUser),
+		new(UserSellerRelation),
+	)
+}
+
+// initReport 报告相关 数据表
+func initReport() {
+	orm.RegisterModel(
+		new(Report),
+		new(ReportViewRecord),
+		new(ChartPermissionSearchKeyWordMapping), //报告分类权限表
+		new(ReportChapter),                       // 报告章节表
+		new(ReportChapterTicker),                 // 晨报章节ticker
+		new(ReportChapterTypePermission),         // 晨周报章节类型权限表
+		new(ChartPermission),                     // 权限表
+		new(YbPcSuncode),
+		new(YbSuncodePars),
+		new(ReportAuthor),                          //报告作者
+		new(ClassifyMenu),                          // 报告分类-子目录表
+		new(ClassifyMenuRelation),                  // 报告分类-子目录关联表
+		new(ChartPermissionChapterMapping),         // 权限mapping表
+		new(ReportChapterType),                     // 报告章节类型表
+		new(ReportStateRecord),                     // 研报状态修改记录表
+		new(report.ReportGrant),                    // 报告授权用户表
+		new(report.ReportChapterGrant),             // 报告章节授权用户表
+		new(report.ReportChapterPermissionMapping), // 报告章节的权限关系表
+	)
+}
+
+// initSandbox 注册Edb沙盘 数据表
+func initSandbox() {
+	//注册对象
+	orm.RegisterModel(
+		new(sandbox.Sandbox),         //沙盘主表
+		new(sandbox.SandboxVersion),  //沙盘版本表
+		new(sandbox.SandboxDraft),    //沙盘草稿表
+		new(sandbox.SandboxClassify), //沙盘分类表
+	)
+}
+
+// initShEdbData 上海服务器指标 数据表
+func initShEdbData() {
+	orm.RegisterModel(
+		new(Edbdata),
+		new(EdbdataDeleteRecord),
+		new(EdbdataImportFail),
+		new(EdbImportFail),                   //指标导入失败数据表
+		new(Edbinfo),                         //edb库的edbinfo表
+		new(data_manage.ExcelStyle),          //在线excel样式表
+		new(data_manage.ExcelEdbdataMapping), //excel样式和指标映射表
+		new(EdbinfoOpRecord),                 // 手工数据的操作日志
+	)
+}
+
+// initEdbData 指标服务 数据表
+func initEdbData() {
+	orm.RegisterModel(
+		new(data_manage.EdbClassify),
+		new(data_manage.EdbInfo), //hz_data库的edb_info表
+		new(data_manage.EdbDataThs),
+		new(data_manage.EdbDataWind),
+		new(data_manage.EdbDataPb),
+		new(data_manage.ManualUserClassify),
+		new(data_manage.EdbdataClassify),
+		new(data_manage.ManualUser),
+		new(data_manage.EdbInfoCalculate),
+		new(data_manage.SearchKeyword),
+		new(data_manage.BaseFromSmm), //orm删除到此
+		new(data_manage.BaseFromSmmIndex),
+		new(data_manage.BaseFromSmmData),
+		new(data_manage.BaseFromSmmClassify),
+		new(data_manage.EdbInfoLog),
+		new(data_manage.EdbInfoRecord),
+		new(data_manage.EdbInfoCalculateMapping),
+		new(data_manage.PredictEdbConf),                  //预测指标配置
+		new(data_manage.BaseFromMysteelChemicalClassify), //预测指标配置
+		new(data_manage.BaseFromMysteelChemicalIndex),    //钢联化工
+		new(data_manage.BaseFromEiaSteoClassify),         // Eia steo 报告指标
+		new(data_manage.BaseFromEiaSteoIndex),            // Eia steo 报告指标分类
+		new(data_manage.PredictEdbRuleData),              //预测指标,动态规则的计算数据
+		new(data_manage.ComTradeCountry),                 //联合国商品贸易数据库的国家编码表
+		new(data_manage.ComTradeData),                    //联合国商品贸易数据表
+		new(data_manage.BaseFromSci),
+		new(data_manage.BaseFromSciIndex),
+		new(data_manage.BaseFromSciData),
+		new(data_manage.BaseFromSciClassify),
+		new(data_manage.TradePositionDalianTop),
+		new(data_manage.TradePositionZhengzhouTop),
+		new(data_manage.TradePositionCffexTop),
+		new(data_manage.TradePositionShanghaiTop),
+		new(data_manage.TradePositionIneTop),
+		new(data_manage.BaseFromBaiinfo),
+		new(data_manage.BaseFromBaiinfoIndex),
+		new(data_manage.BaseFromBaiinfoData),
+		new(data_manage.BaseFromBaiinfoClassify),
+		new(data_manage.EdbDataInsertConfig),      // 指标数据插入配置表
+		new(data_manage.EdbInfoNoPermissionAdmin), //指标不可见用户配置表
+		new(data_manage.EdbTerminal),              //指标终端
+		new(data_manage.BaseFromThsHfIndex),
+		new(data_manage.BaseFromThsHfData),
+		new(data_manage.BaseFromThsHfClassify),
+		new(data_manage.BaseFromEdbMapping),
+		new(data_manage.EdbInfoRelation), //指标关系表
+		new(data_manage.BaseFromSciHqClassify),
+		new(data_manage.BaseFromSciHqIndex),
+		new(data_manage.BaseFromSciHqData),
+	)
+}
+
+// initChart 图表 数据表
+func initChart() {
+	orm.RegisterModel(
+		new(data_manage.ChartClassify),
+		new(data_manage.ChartInfo),
+		new(data_manage.ChartEdbMapping),
+		new(data_manage.MyChartClassify),
+		new(data_manage.MyChart),
+		new(data_manage.MyChartLog),
+		new(data_manage.MyChartClassifyMapping),
+		new(data_manage.ChartInfoLog),
+		new(data_manage.ChartInfoCorrelation),
+		new(data_manage.ChartSeries),
+		new(data_manage.ChartSeriesEdbMapping),
+	)
+}
+
+// initEnglishReport 英文报告
+func initEnglishReport() {
+	orm.RegisterModel(
+		new(EnglishReport),
+		new(EnglishPolicyReport),
+		new(EnglishReportEmail),
+		new(EnglishReportEmailPV),
+		new(EnglishReportEmailLog),
+		new(EnglishClassify),
+		new(EnglishCompany),           // 英文客户
+		new(EnglishCompanyLog),        // 英文客户操作日志
+		new(EnglishReportEmailOpLog),  // 英文联系人操作日志
+		new(EnglishCompanyTodo),       // 英文客户TODO任务
+		new(EnglishCompanyTodoPublic), // 英文客户公共TODO任务
+		new(EnglishVideoCover),        // 英文研报线上路演视频封面
+		new(EnglishVideo),             // 英文研报线上路演
+		new(EnPermission),             // 英文品种权限表
+		new(EnCompanyPermission),      // 英文客户品种权限关联表
+		new(EnClassifyPermission),     // 英文分类品种权限关联表
+	)
+}
+
+// initPptEnglish ppt英文
+func initPptEnglish() {
+	orm.RegisterModel(
+		new(ppt_english.PptEnglish),
+		new(ppt_english.PptEnglishPublishRecord),
+		new(ppt_english.PptEnglishSaveLog),
+		new(ppt_english.PptEnglishGroup),
+		new(ppt_english.PptEnglishGroupMapping),
+		new(ppt_english.PptEnglishGrant), //ppt授权操作表
+	)
+}
+
+// initFutureGood 注册期货数据 数据表
+func initFutureGood() {
+	//注册对象
+	orm.RegisterModel(
+		new(future_good2.FutureGoodEdbInfo), //期货指标表
+		new(future_good2.FutureGoodEdbData), //期货指标数据表
+		//new(future_good2.FutureGoodChartClassify), //期货指标分类表
+		new(future_good2.ChartInfoFutureGoodProfit), //期货利润图的扩展表
+	)
+}
+
+// initCloudDisk 共享云盘
+func initCloudDisk() {
+	//注册对象
+	orm.RegisterModel(
+		new(CloudDiskMenu),     // 云盘目录表
+		new(CloudDiskResource), // 云盘资源表
+	)
+}
+
+// initSemanticAnalysis 语义分析
+func initSemanticAnalysis() {
+	orm.RegisterModel(
+		new(semantic_analysis.SaLabel),                // 语义分析-标签表
+		new(semantic_analysis.SaDocClassify),          // 语义分析-文档分类表
+		new(semantic_analysis.SaDoc),                  // 语义分析-文档表
+		new(semantic_analysis.SaDocSection),           // 语义分析-文档段落表
+		new(semantic_analysis.SaCompareClassify),      // 语义分析-比对分类表
+		new(semantic_analysis.SaCompare),              // 语义分析-比对表
+		new(semantic_analysis.SaCompareDoc),           // 语义分析-比对关联文档表
+		new(semantic_analysis.SaCompareLabel),         // 语义分析-比对段落表
+		new(semantic_analysis.SaCompareSearchKeyword), // 语义分析-比对搜索关键词
+	)
+}
+
+// initSupplyAnalysis 供应分析
+func initSupplyAnalysis() {
+	orm.RegisterModel(
+		new(supply_analysis.Variety),
+		new(supply_analysis.VarietyAdminPermission),
+		new(supply_analysis.VarietyEdbInfo),
+		new(supply_analysis.VarietyPlant),
+	)
+}
+
+// initMultipleGraphConfig 多图配置 数据表
+func initMultipleGraphConfig() {
+	//注册对象
+	orm.RegisterModel(
+		new(data_manage.MultipleGraphConfig),             //多图配置表
+		new(data_manage.MultipleGraphConfigChartMapping), //图表与多图配置的关系表
+		new(data_manage.MultipleGraphConfigEdbMapping),   //指标与多图配置的关系表
+	)
+}
+
+// initBusinessConf 商家配置
+func initBusinessConf() {
+	orm.RegisterModel(
+		new(BusinessConf),                // 商家配置表
+		new(BusinessConfOperationRecord), // 商家配置操作记录表
+	)
+}
+
+func initOutLink() {
+	orm.RegisterModel(
+		new(OutLink)) // 外部链接表
+}
+
+// initDataStat 数据源统计管理相关表
+func initDataStat() {
+	orm.RegisterModel(
+		new(data_stat.EdbInfoDeleteLog),  // 指标删除日志表
+		new(data_stat.EdbInfoUpdateStat), // 指标更新/刷新 汇总表(数据源明细表)
+		new(data_stat.EdbInfoUpdateLog),  // 指标更新/刷新日志列表
+		new(data_stat.EdbSourceStat),     // 数据源统计表
+	)
+}
+
+// initChartFramework 图库框架相关表
+func initChartFramework() {
+	orm.RegisterModel(
+		new(data_manage.ChartFramework),     // 图库框架主表
+		new(data_manage.ChartFrameworkNode), // 图库框架节点表
+	)
+}
+
+// initExcel 初始化EXCEL
+func initExcel() {
+	orm.RegisterModel(
+		new(excel.ExcelClassify),        //ETA excel表格分类
+		new(excel.ExcelInfo),            //ETA excel表格
+		new(excel.ExcelDraft),           //ETA excel表格草稿
+		new(excel.ExcelSheet),           //ETA excel sheet
+		new(excel.ExcelSheetData),       //ETA excel sheet data
+		new(excel.ExcelEdbMapping),      //ETA excel 与 指标 的关系表
+		new(excel.ExcelWorker),          // 平衡表协作人表格
+		new(excel.ExcelChartEdb),        // 平衡表做图指标
+		new(excel.ExcelChartData),       // 平衡表作图数据
+		new(excel.ExcelInfoRuleMapping), //表格的管理规则
+	)
+}
+
+// initSmartReport 智能研报相关表
+func initSmartReport() {
+	orm.RegisterModel(
+		new(smart_report.SmartReport),         // 智能研报主表
+		new(smart_report.SmartReportSaveLog),  // 智能研报-保存记录表
+		new(smart_report.SmartReportResource), // 智能研报-资源表
+	)
+}
+
+// initCrossVariety 跨品种分析
+func initCrossVariety() {
+	orm.RegisterModel(
+		new(cross_variety.ChartVariety),          // 品种表
+		new(cross_variety.ChartTag),              // 标签表
+		new(cross_variety.ChartTagVariety),       // 标签、品种、指标关系表
+		new(cross_variety.ChartVarietyMapping),   // 图表与品种的关系表
+		new(cross_variety.ChartInfoCrossVariety), // 跨品种分析配置表
+	)
+}
+
+func initAi() {
+	orm.RegisterModel(
+		new(aimod.AiChatTopic),
+		new(aimod.AiChat),
+		new(aimod.FileUploadRecord),
+		new(ai_summary.AiSummaryClassify),
+		new(ai_summary.AiSummary),
+		new(ai_summary.AiPrompt),
+	)
+}
+
+// initReportApprove 报告审批相关表
+func initReportApprove() {
+	orm.RegisterModel(
+		new(report_approve.ReportApprove),        // 审批表
+		new(report_approve.ReportApproveFlow),    // 审批流表
+		new(report_approve.ReportApproveNode),    // 审批节点表
+		new(report_approve.ReportApproveRecord),  // 审批记录表
+		new(report_approve.ReportApproveMessage), // 审批消息表
+	)
+}
+
+// initChartTheme 初始化图表主题
+func initChartTheme() {
+	orm.RegisterModel(
+		new(chart_theme.ChartTheme),            // 图表主题
+		new(chart_theme.ChartThemeType),        // 图表主题类型
+		new(chart_theme.ChartThemeDefaultData), //默认数据
+	)
+}
+
+// initEdbRefresh 初始化指标刷新
+func initEdbRefresh() {
+	orm.RegisterModel(
+		new(edb_refresh.EdbRefreshSource),        // 刷新的数据源表
+		new(edb_refresh.EdbRefreshDefaultConfig), // 指标的默认刷新时间配置表
+		new(edb_refresh.EdbRefreshConfig),        // 指标的刷新时间配置表
+		new(edb_refresh.EdbRefreshMapping),       // 指标刷新时间配置关系表
+	)
+}
+
+// initSpeechRecognition 语音识别
+func initSpeechRecognition() {
+	orm.RegisterModel(
+		new(speech_recognition.SpeechRecognition),           // 语音识别表
+		new(speech_recognition.SpeechRecognitionApiLog),     // 语音识别-API请求日志
+		new(speech_recognition.SpeechRecognitionContent),    // 语音识别-转换内容表
+		new(speech_recognition.SpeechRecognitionMenu),       // 语音识别-目录表
+		new(speech_recognition.SpeechRecognitionTag),        // 语音识别-标签表
+		new(speech_recognition.SpeechRecognitionTagMenu),    // 语音识别-标签目录表
+		new(speech_recognition.SpeechRecognitionTagMapping), // 语音识别-标签关联表
+	)
+}
+
+// initDataMangePerMission
+// @Description: 初始化数据资产权限的一些表
+// @author: Roc
+// @datetime 2024-03-27 14:03:11
+func initDataMangePerMission() {
+	orm.RegisterModel(
+		new(data_manage_permission.EdbInfoPermission),                       // 指标权限表
+		new(data_manage_permission.EdbClassifyPermission),                   // 指标分类权限表
+		new(data_manage_permission.ChartInfoPermission),                     // 图表权限表
+		new(data_manage_permission.ChartClassifyPermission),                 // 图表分类权限表
+		new(data_manage_permission.ExcelInfoPermission),                     // ETA表格权限表
+		new(data_manage_permission.ExcelClassifyPermission),                 // ETA表格分类权限表
+		new(data_manage_permission.DataPermissionMessage),                   // 数据权限变更消息表
+		new(data_manage_permission.DataPermissionMoveRecord),                // 数据资产转移记录表
+		new(data_manage_permission.EdbInfoPermissionNoAuthRecord),           // 指标资产数据未授权分类记录表
+		new(data_manage_permission.ChartInfoPermissionNoAuthRecord),         // 图表资产数据未授权分类记录表
+		new(data_manage_permission.ExcelInfoPermissionNoAuthRecord),         // ETA表格资产数据未授权分类记录表
+		new(data_manage_permission.EdbInfoClassifyPermissionNoAuthRecord),   // 指标资产分类数据未授权分类记录表
+		new(data_manage_permission.ChartInfoClassifyPermissionNoAuthRecord), // 图表资产分类数据未授权分类记录表
+		new(data_manage_permission.ExcelInfoClassifyPermissionNoAuthRecord), // ETA表格资产分类数据未授权分类记录表
+		new(data_manage_permission.DataPermissionClassifyNoAuthRecord),      // 资产分类数据权限未授权记录表
+		new(data_manage_permission.DataPermissionNoAuthRecord),              // 资产数据权限设置记录表
+	)
+}
+
+// initFeCalendar 初始化外汇日历
+func initFeCalendar() {
+	orm.RegisterModel(
+		new(fe_calendar.FeCalendarMatter), // 事项表
+	)
+}
+
+// initFactorEdbSeries 因子指标系列数据表
+func initFactorEdbSeries() {
+	orm.RegisterModel(
+		new(data_manage.FactorEdbSeries),                  // 因子指标系列
+		new(data_manage.FactorEdbSeriesChartMapping),      // 因子指标系列-图表关联
+		new(data_manage.FactorEdbSeriesMapping),           // 因子指标系列-指标计算数据
+		new(data_manage.FactorEdbSeriesCalculateData),     // 因子指标系列-指标关联
+		new(data_manage.FactorEdbSeriesCalculateDataQjjs), // 因子指标系列-区间计算数据
+	)
+}

+ 1 - 1
models/english_company.go

@@ -14,7 +14,7 @@ const (
 
 // EnglishCompany 英文客户
 type EnglishCompany struct {
-	CompanyId   int       `gorm:"column:company_id;primary_key:true" description:"英文客户ID"`
+	CompanyId   int       `gorm:"column:company_id;primaryKey" description:"英文客户ID"`
 	CompanyName string    `gorm:"column:company_name" description:"客户名称"`
 	CountryCode string    `gorm:"column:country_code" description:"国家Code"`
 	Country     string    `gorm:"column:country" description:"国家"`

+ 1 - 1
models/english_company_log.go

@@ -15,7 +15,7 @@ const (
 
 // EnglishCompanyLog 英文客户操作日志表
 type EnglishCompanyLog struct {
-	Id         int       `gorm:"column:id;primary_key:true" description:"日志ID"`
+	Id         int       `gorm:"column:id;primaryKey" description:"日志ID"`
 	CompanyId  int       `gorm:"column:company_id" description:"英文客户ID"`
 	AdminId    int       `gorm:"column:admin_id" description:"操作人ID"`
 	OptionData string    `gorm:"column:option_data" description:"操作数据-JSON"`

+ 1 - 1
models/english_company_todo.go

@@ -17,7 +17,7 @@ const (
 
 // EnglishCompanyTodo 英文客户TODO任务
 type EnglishCompanyTodo struct {
-	Id                 int       `gorm:"column:id;primary_key:true" description:"任务ID"`
+	Id                 int       `gorm:"column:id;primaryKey" description:"任务ID"`
 	CompanyId          int       `gorm:"column:company_id" description:"客户ID"`
 	Content            string    `gorm:"column:content" description:"任务描述"`
 	SellerId           int       `gorm:"column:seller_id" description:"客户所属销售ID"`

+ 1 - 1
models/english_company_todo_public.go

@@ -8,7 +8,7 @@ import (
 // EnglishCompanyTodoPublic 英文客户公共TODO任务
 
 type EnglishCompanyTodoPublic struct {
-	Id             int       `gorm:"column:id;primary_key:true" description:"任务ID"`
+	Id             int       `gorm:"column:id;primaryKey" description:"任务ID"`
 	Content        string    `gorm:"column:content" description:"任务描述"`
 	CreateUserId   int       `gorm:"column:create_user_id" description:"创建人用户ID"`
 	CreateUserName string    `gorm:"column:create_user_name" description:"创建人用户姓名"`

+ 1 - 1
models/english_policy_report.go

@@ -10,7 +10,7 @@ import (
 
 // 英文策略报告
 type EnglishPolicyReport struct {
-	Id                 int       `gorm:"column:id;primary_key:true;auto_increment:true" description:"策略报告ID"`
+	Id                 int       `gorm:"column:id;primaryKey;auto_increment:true" description:"策略报告ID"`
 	ClassifyIdFirst    int       `gorm:"column:classify_id_first" description:"一级分类ID"`
 	ClassifyNameFirst  string    `gorm:"column:classify_name_first" description:"一级分类名称"`
 	ClassifyIdSecond   int       `gorm:"column:classify_id_second" description:"二级分类ID"`

+ 1 - 1
models/english_report_email.go

@@ -9,7 +9,7 @@ import (
 
 // EnglishReportEmail 英文研报-邮箱/客户联系人
 type EnglishReportEmail struct {
-	Id              int       `gorm:"column:id;primary_key:true" description:"邮箱ID"`
+	Id              int       `gorm:"column:id;primaryKey" description:"邮箱ID"`
 	CompanyId       int       `gorm:"column:company_id" description:"客户ID"`
 	Name            string    `gorm:"column:name" description:"联系人名称"`
 	Email           string    `gorm:"column:email" description:"邮箱地址"`

+ 1 - 1
models/english_report_email_log.go

@@ -18,7 +18,7 @@ const (
 
 // EnglishReportEmailLog 英文研报-邮件推送记录
 type EnglishReportEmailLog struct {
-	Id           int       `gorm:"column:id;primary_key:true;auto_increment:true" description:"邮箱日志ID"`
+	Id           int       `gorm:"column:id;primaryKey;auto_increment:true" description:"邮箱日志ID"`
 	ReportId     int       `gorm:"column:report_id" description:"报告ID或者线上路演ID"`
 	ReportType   int       `gorm:"column:report_type" description:"类型:0英文研报,1英文线上路演"`
 	EmailId      int       `gorm:"column:email_id" description:"邮箱ID"`

+ 1 - 1
models/english_report_email_op_log.go

@@ -17,7 +17,7 @@ const (
 
 // EnglishReportEmailOpLog 英文邮箱/联系人-操作日志表
 type EnglishReportEmailOpLog struct {
-	Id         int       `gorm:"column:id;primary_key:true" description:"日志ID"`
+	Id         int       `gorm:"column:id;primaryKey" description:"日志ID"`
 	CompanyId  int       `gorm:"column:company_id" description:"客户ID"`
 	EmailId    int       `gorm:"column:email_id" description:"联系人ID"`
 	AdminId    int       `gorm:"column:admin_id" description:"操作人ID"`

+ 1 - 1
models/english_report_email_pv.go

@@ -10,7 +10,7 @@ import (
 // EnglishReportEmailPV 英文研报-邮箱pv
 
 type EnglishReportEmailPV struct {
-	Id         int       `gorm:"column:id;primary_key:true;auto_increment:true" description:"日志ID"`
+	Id         int       `gorm:"column:id;primaryKey;auto_increment:true" description:"日志ID"`
 	ReportId   int       `gorm:"column:report_id" description:"英文报告ID"`
 	EmailId    int       `gorm:"column:email_id" description:"邮箱ID"`
 	ReportType int       `gorm:"column:report_type" description:"类型:0英文研报,1英文线上路演"`

+ 1 - 1
models/english_video.go

@@ -10,7 +10,7 @@ import (
 )
 
 type EnglishVideo struct {
-	Id                 int       `gorm:"column:id;primary_key:true;auto_increment:true" description:"路演视频Id"`
+	Id                 int       `gorm:"column:id;primaryKey;auto_increment:true" description:"路演视频Id"`
 	ClassifyIdFirst    int       `gorm:"column:classify_id_first" description:"一级分类id"`
 	ClassifyNameFirst  string    `gorm:"column:classify_name_first" description:"一级分类名称"`
 	ClassifyIdSecond   int       `gorm:"column:classify_id_second" description:"二级分类id"`

+ 7 - 7
models/permission.go

@@ -7,7 +7,7 @@ import (
 
 // ChartPermissionSearchKeyWordMapping 权限相关
 type ChartPermissionSearchKeyWordMapping struct {
-	Id                 int    `gorm:"column:id" json:"id"`                                   //`description:"id" json:"-"`
+	Id                 int    `gorm:"primaryKey" json:"id"`                                  //`description:"id" json:"-"`
 	ChartPermissionId  int    `gorm:"column:chart_permission_id" json:"chart_permission_id"` //`description:"权限id"`
 	KeyWord            string `gorm:"column:key_word" json:"key_word"`                       //`description:"二级分类名称"`
 	From               string `gorm:"column:from" json:"-"`                                  //`description:"类型标识" json:"-"`
@@ -18,7 +18,7 @@ type ChartPermissionSearchKeyWordMapping struct {
 
 func GetPermission(classifyId int) (items []*ChartPermissionSearchKeyWordMapping, err error) {
 	//o := orm.NewOrmUsingDB("rddp")
-	sql := `SELECT * FROM chart_permission_search_key_word_mapping AS a WHERE a.from='rddp' AND a.classify_id = ? `
+	sql := `SELECT * FROM chart_permission_search_key_word_mapping AS a WHERE a.source_from='rddp' AND a.classify_id = ? `
 	//_, err = o.Raw(sql, classifyId).QueryRows(&items)
 	err = global.DmSQL["rddp"].Raw(sql, classifyId).Find(&items).Error
 	return
@@ -26,7 +26,7 @@ func GetPermission(classifyId int) (items []*ChartPermissionSearchKeyWordMapping
 
 func GetAllPermissionMapping() (items []*ChartPermissionSearchKeyWordMapping, err error) {
 	//o := orm.NewOrmUsingDB("rddp")
-	sql := `SELECT * FROM chart_permission_search_key_word_mapping AS a WHERE a.from='rddp'`
+	sql := `SELECT * FROM chart_permission_search_key_word_mapping AS a WHERE a.source_from='rddp'`
 	//_, err = o.Raw(sql).QueryRows(&items)
 	err = global.DmSQL["rddp"].Raw(sql).Find(&items).Error
 	return
@@ -44,7 +44,7 @@ func EditChartPermissionSearchKeyWordMappingMulti(keyword string, permissionIdLi
 			_ = to.Commit()
 		}
 	}()
-	sql := "DELETE FROM chart_permission_search_key_word_mapping WHERE `from` = 'rddp' AND classify_id = ?"
+	sql := "DELETE FROM chart_permission_search_key_word_mapping WHERE source_from= 'rddp' AND classify_id = ?"
 	//_, err = to.Raw(sql, classifyId).Exec()
 	err = to.Exec(sql, classifyId).Error
 	if err != nil {
@@ -94,7 +94,7 @@ type ChartPermissionMappingIdName struct {
 
 func GetChartPermissionNameFromMappingByKeyword(source string, classifyId int) (list []*ChartPermissionMappingIdName, err error) {
 	//o := orm.NewOrmUsingDB("rddp")
-	sql := " SELECT b.chart_permission_id AS permission_id,b.permission_name FROM chart_permission_search_key_word_mapping AS a INNER JOIN chart_permission AS b ON a.chart_permission_id = b.chart_permission_id WHERE a.`from` = ? AND a.classify_id = ? "
+	sql := " SELECT b.chart_permission_id AS permission_id,b.permission_name FROM chart_permission_search_key_word_mapping AS a INNER JOIN chart_permission AS b ON a.chart_permission_id = b.chart_permission_id WHERE a.source_from = ? AND a.classify_id = ? "
 	//_, err = o.Raw(sql, source, classifyId).QueryRows(&list)
 	err = global.DmSQL["rddp"].Raw(sql, source, classifyId).Find(&list).Error
 	return
@@ -103,7 +103,7 @@ func GetChartPermissionNameFromMappingByKeyword(source string, classifyId int) (
 // UpdateChartPermissionNameFromMappingByKeyword 根据关键词及来源更新新关键词
 func UpdateChartPermissionNameFromMappingByKeyword(newKeyword string, classifyId int, source string) (err error) {
 	//o := orm.NewOrmUsingDB("rddp")
-	sql := " UPDATE chart_permission_search_key_word_mapping SET key_word = ? WHERE classify_id = ? AND `from` = ? "
+	sql := " UPDATE chart_permission_search_key_word_mapping SET key_word = ? WHERE classify_id = ? AND source_from = ? "
 	//_, err = o.Raw(sql, newKeyword, classifyId, source).Exec()
 	err = global.DmSQL["rddp"].Exec(sql, newKeyword, classifyId, source).Error
 	return
@@ -129,7 +129,7 @@ type ChartPermissionSearchKeyWordMappingAndPermissionName struct {
 func GetPermissionByClassifyId(classifyId int) (items []*ChartPermissionSearchKeyWordMappingAndPermissionName, err error) {
 	//o := orm.NewOrmUsingDB("rddp")
 	sql := `SELECT a.chart_permission_name,a.permission_name,b.chart_permission_id,b.key_word,b.classify_id FROM chart_permission AS a 
- join chart_permission_search_key_word_mapping AS b ON a.chart_permission_id=b.chart_permission_id WHERE b.from='rddp' AND b.classify_id = ? `
+ join chart_permission_search_key_word_mapping AS b ON a.chart_permission_id=b.chart_permission_id WHERE b.source_from='rddp' AND b.classify_id = ? `
 	//_, err = o.Raw(sql, classifyId).QueryRows(&items)
 	err = global.DmSQL["rddp"].Raw(sql, classifyId).Find(&items).Error
 	return

+ 1 - 1
models/ppt_v2.go

@@ -198,7 +198,7 @@ func EditPptV2Path(pptId int, pptxPath string) (err error) {
 
 // PptV2PublishRecord 发布记录表
 type PptV2PublishRecord struct {
-	Id         int `orm:"column(id);pk" gorm:"primaryKey" `
+	Id         int `gorm:"primaryKey" `
 	PptId      int
 	PptUrl     string
 	CreateTime time.Time

+ 14 - 5
models/report.go

@@ -259,12 +259,21 @@ func GetReportListCountByGrant(condition string, pars []interface{}) (count int,
 func GetReportListByGrant(condition string, pars []interface{}, startSize, pageSize int) (items []*ReportList, err error) {
 	//o := orm.NewOrmUsingDB("rddp")
 
-	sql := `SELECT a.* FROM report as a JOIN report_grant b on a.id = b.report_id  WHERE 1=1  `
+	sql := `SELECT a.add_type,a.classify_id_first,a.classify_name_first,a.classify_id_second,a.classify_name_second,a.title,a.abstract,a.author,a.frequency,a.create_time,a.modify_time,a.state,a.publish_time,a.pre_publish_time,a.stage,a.msg_is_send,a.pre_msg_send,a.content,a.video_url,a.video_name,a.video_play_seconds,a.content_sub,a.report_code,a.video_size,a.report_version,a.ths_msg_is_send,a.has_chapter,a.chapter_type,a.old_report_id,a.msg_send_time,a.admin_id,a.admin_real_name,a.approve_time,a.approve_id,a.detail_img_url,a.detail_pdf_url,a.content_struct,a.last_modify_admin_id,a.last_modify_admin_name,a.content_modify_time,a.pv,a.uv,a.head_img,a.end_img,a.canvas_color,a.need_splice,a.head_resource_id,a.end_resource_id,a.classify_id_third,a.classify_name_third,a.collaborate_type,a.report_layout,a.is_public_publish,a.report_create_time,a.inherit_report_id,a.voice_generate_type FROM report as a JOIN report_grant b on a.id = b.report_id  WHERE 1=1  `
 	if condition != "" {
 		sql += condition
 	}
 	// 排序:1:未发布;2:已发布;3-待提交;4-待审批;5-已驳回;6-已通过
-	sql += ` GROUP BY a.id ORDER BY FIELD(state,3,1,4,5,6,2), a.modify_time DESC LIMIT ?,?`
+	sql += ` GROUP BY a.id,a.add_type,a.classify_id_first,a.classify_name_first,a.classify_id_second,a.classify_name_second,a.title,a.abstract,a.author,a.frequency,a.create_time,a.modify_time,a.state,a.publish_time,a.pre_publish_time,a.stage,a.msg_is_send,a.pre_msg_send,a.content,a.video_url,a.video_name,a.video_play_seconds,a.content_sub,a.report_code,a.video_size,a.report_version,a.ths_msg_is_send,a.has_chapter,a.chapter_type,a.old_report_id,a.msg_send_time,a.admin_id,a.admin_real_name,a.approve_time,a.approve_id,a.detail_img_url,a.detail_pdf_url,a.content_struct,a.last_modify_admin_id,a.last_modify_admin_name,a.content_modify_time,a.pv,a.uv,a.head_img,a.end_img,a.canvas_color,a.need_splice,a.head_resource_id,a.end_resource_id,a.classify_id_third,a.classify_name_third,a.collaborate_type,a.report_layout,a.is_public_publish,a.report_create_time,a.inherit_report_id,a.voice_generate_type
+
+		ORDER BY CASE a."state"   
+        WHEN 3 THEN 1  
+        WHEN 1 THEN 2  
+        WHEN 4 THEN 3  
+        WHEN 5 THEN 4  
+        WHEN 6 THEN 5  
+        ELSE 6  
+    END, a.modify_time DESC LIMIT ?,?`
 	//_, err = o.Raw(sql, pars...).QueryRows(&items)
 	pars = append(pars, startSize)
 	pars = append(pars, pageSize)
@@ -405,7 +414,7 @@ func GetReportStage(classifyIdFirst, classifyIdSecond, classifyIdThird int) (cou
 	}
 	yearStart := time.Date(time.Now().Local().Year(), 1, 1, 0, 0, 0, 0, time.Local)
 
-	sql := `SELECT MAX(stage) AS max_stage FROM report WHERE create_time > ? `
+	sql := `SELECT COALESCE(MAX(stage),0) AS count FROM report WHERE create_time > ? `
 	if classifyIdThird > 0 {
 		sql += " AND classify_id_third = ? "
 	} else if classifyIdSecond > 0 {
@@ -912,7 +921,7 @@ type SunCodeReq struct {
 
 // YbPcSuncode 活动海报表
 type YbPcSuncode struct {
-	SuncodeID  uint32    `gorm:"column:suncode_id" json:"suncodeId"`                             //`orm:"column(suncode_id);pk" gorm:"primaryKey"  `
+	SuncodeID  uint32    `gorm:"column:suncode_id;primaryKey" json:"suncodeId"`                  //`orm:"column(suncode_id);pk" gorm:"primaryKey"  `
 	Scene      string    `gorm:"column:scene;type:varchar(255);not null;default:0" json:"scene"` // 微信scene
 	SceneMd5   string    `gorm:"column:scene_md5;type:varchar(255);not null" json:"sceneMd5"`
 	CodePage   string    `gorm:"column:code_page;type:varchar(255);not null;default:''" json:"codePage"`     // 路径
@@ -938,7 +947,7 @@ func AddYbPcSunCode(item *YbPcSuncode) (err error) {
 
 // YbSuncodePars 小程序太阳码scene参数
 type YbSuncodePars struct {
-	ID         uint32    `gorm:"column:id" json:"id"`                                                    //`orm:"column(id);pk" gorm:"primaryKey"  `
+	ID         uint32    `gorm:"column:id;primaryKey" json:"id"`                                         //`orm:"column(id);pk" gorm:"primaryKey"  `
 	Scene      string    `gorm:"column:scene;type:varchar(255);not null;default:''" json:"scene"`        // scene参数
 	SceneKey   string    `gorm:"column:scene_key;type:varchar(32);not null;default:''" json:"scene_key"` // MD5值
 	CreateTime time.Time `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP" json:"createTime"`

+ 3 - 1
models/report_approve/report_approve.go

@@ -378,7 +378,7 @@ func GetApplyReportApproveCount(cond string, pars []interface{}) (count int, err
 	base := fmt.Sprintf(`SELECT a.* FROM report_approve AS a WHERE 1 = 1 %s`, cond)
 	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
 	//err = o.Raw(sql, pars).QueryRow(&count)
-	err = global.DmSQL["rddp"].Raw(sql, pars).Scan(&count).Error
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
 	return
 }
 
@@ -391,6 +391,8 @@ func GetApplyReportApprovePageList(cond string, pars []interface{}, orderRule st
 	}
 	sql := fmt.Sprintf(`SELECT a.* FROM report_approve AS a WHERE 1 = 1 %s %s LIMIT ?,?`, cond, order)
 	//_, err = o.Raw(sql, pars...).QueryRows(&items)
+	pars = append(pars, startSize)
+	pars = append(pars, pageSize)
 	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
 	return
 }

+ 3 - 1
models/report_approve/report_approve_flow.go

@@ -139,7 +139,7 @@ func (m *ReportApproveFlow) GetCountByCondition(condition string, pars []interfa
 	//o := orm.NewOrmUsingDB("rddp")
 	sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition)
 	//err = o.Raw(sql, pars).QueryRow(&count)
-	err = global.DmSQL["rddp"].Raw(sql, pars).Scan(&count).Error
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
 	return
 }
 
@@ -171,6 +171,8 @@ func (m *ReportApproveFlow) GetPageItemsByCondition(condition string, pars []int
 	}
 	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order)
 	//_, err = o.Raw(sql, pars...).QueryRows(&items)
+	pars = append(pars, startSize)
+	pars = append(pars, pageSize)
 	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
 	return
 }

+ 1 - 1
models/report_author.go

@@ -7,7 +7,7 @@ import (
 )
 
 type ReportAuthor struct {
-	Id           int       `gorm:"column:id"`            //`orm:"column(id)" description:"报告作者ID"`
+	Id           int       `gorm:"column:id;primaryKey"` //`orm:"column(id)" description:"报告作者ID"`
 	ReportAuthor string    `gorm:"column:report_author"` //`description:"报告作者名称"`
 	AuthorType   int       `gorm:"column:author_type"`   //`description:"类型,1:中文;2:英文"`
 	Enable       int       `gorm:"column:enable"`        //`description:"是否启用,0:禁用,1:启用"`

+ 4 - 1
models/report_chapter.go

@@ -319,10 +319,13 @@ func GetReportChapterVideoListByReportIds(reportIds []int) (list []*ReportChapte
 			FROM
 				report_chapter
 			WHERE
-				report_id IN (` + utils.GetOrmInReplace(len(reportIds)) + `) AND publish_state = 2 AND video_url != ""
+				report_id IN (` + utils.GetOrmInReplace(len(reportIds)) + `) AND publish_state = 2 AND video_url != ''
 			ORDER BY
 				report_chapter_id ASC `
 	//_, err = o.Raw(sql, reportIds).QueryRows(&list)
+
+	//report_id IN (` + utils.GetOrmInReplace(len(reportIds)) + `) AND publish_state = 2 AND video_url != ""
+
 	err = global.DmSQL["rddp"].Raw(sql, reportIds).Find(&list).Error
 	return
 }

+ 24 - 24
models/report_chapter_type.go

@@ -8,30 +8,30 @@ import (
 )
 
 type ReportChapterType struct {
-	ReportChapterTypeId        int       `gorm:"column:report_chapter_type_id"`         //`orm:"column(report_chapter_type_id);pk" gorm:"primaryKey"  description:"报告章节类型id"`
-	ReportChapterTypeKey       string    `gorm:"column:report_chapter_type_key"`        //`description:"章节key"`
-	ReportChapterTypeThumb     string    `gorm:"column:report_chapter_type_thumb"`      //`description:"H5展示的图片"`
-	BannerUrl                  string    `gorm:"column:banner_url"`                     //`description:"banner显示图片"`
-	ReportChapterTypeName      string    `gorm:"column:report_chapter_type_name"`       //`description:"报告章节类型名称"`
-	Sort                       int       `gorm:"column:sort"`                           //`description:"排序字段"`
-	Enabled                    int       `gorm:"column:enabled"`                        //`description:"启禁用状态"`
-	CreatedTime                time.Time `gorm:"column:created_time"`                   //`description:"创建时间"`
-	LastUpdatedTime            time.Time `gorm:"column:last_updated_time"`              //`description:"更新时间"`
-	ResearchType               string    `gorm:"column:research_type"`                  //`description:"研报类型"`
-	SelectedImage              string    `gorm:"column:selected_image"`                 //`description:"选中时的图片"`
-	UnselectedImage            string    `gorm:"column:unselected_image"`               //`description:"没选中时的图片"`
-	PcSelectedImage            string    `gorm:"column:pc_selected_image"`              //`description:"PC-选中的图片"`
-	PcUnselectedImage          string    `gorm:"column:pc_unselected_image"`            //`description:"PC-未选中的图片"`
-	EditImgUrl                 string    `gorm:"column:edit_img_url"`                   //`description:"管理后台编辑时选用的图"`
-	TickerTitle                string    `gorm:"column:ticker_title"`                   //`description:"指标列的标题"`
-	IsShow                     int       `gorm:"column:is_show"`                        //`description:"是否显示(研报小程序端根据此字段判断)"`
-	PauseStartTime             string    `gorm:"column:pause_start_time"`               //`description:"暂停开始日期"`
-	PauseEndTime               string    `gorm:"column:pause_end_time"`                 //`description:"暂停结束日期"`
-	IsSet                      int       `gorm:"column:is_set"`                         //`description:"是否设置:0为设置,1已设置"`
-	YbIconUrl                  string    `gorm:"column:yb_icon_url"`                    // `description:"研报小程序icon"`
-	YbBottomIcon               string    `gorm:"column:yb_bottom_icon"`                 // `description:"研报小程序详情底部icon"`
-	ReportClassifyId           int       `gorm:"column:report_classify_id"`             // `description:"所属分类id"`
-	InheritReportChapterTypeId int       `gorm:"column:inherit_report_chapter_type_id"` // `description:"继承的报告章节类型id"`
+	ReportChapterTypeId        int       `gorm:"column:report_chapter_type_id;primaryKey"` //`orm:"column(report_chapter_type_id);pk" gorm:"primaryKey"  description:"报告章节类型id"`
+	ReportChapterTypeKey       string    `gorm:"column:report_chapter_type_key"`           //`description:"章节key"`
+	ReportChapterTypeThumb     string    `gorm:"column:report_chapter_type_thumb"`         //`description:"H5展示的图片"`
+	BannerUrl                  string    `gorm:"column:banner_url"`                        //`description:"banner显示图片"`
+	ReportChapterTypeName      string    `gorm:"column:report_chapter_type_name"`          //`description:"报告章节类型名称"`
+	Sort                       int       `gorm:"column:sort"`                              //`description:"排序字段"`
+	Enabled                    int       `gorm:"column:enabled"`                           //`description:"启禁用状态"`
+	CreatedTime                time.Time `gorm:"column:created_time"`                      //`description:"创建时间"`
+	LastUpdatedTime            time.Time `gorm:"column:last_updated_time"`                 //`description:"更新时间"`
+	ResearchType               string    `gorm:"column:research_type"`                     //`description:"研报类型"`
+	SelectedImage              string    `gorm:"column:selected_image"`                    //`description:"选中时的图片"`
+	UnselectedImage            string    `gorm:"column:unselected_image"`                  //`description:"没选中时的图片"`
+	PcSelectedImage            string    `gorm:"column:pc_selected_image"`                 //`description:"PC-选中的图片"`
+	PcUnselectedImage          string    `gorm:"column:pc_unselected_image"`               //`description:"PC-未选中的图片"`
+	EditImgUrl                 string    `gorm:"column:edit_img_url"`                      //`description:"管理后台编辑时选用的图"`
+	TickerTitle                string    `gorm:"column:ticker_title"`                      //`description:"指标列的标题"`
+	IsShow                     int       `gorm:"column:is_show"`                           //`description:"是否显示(研报小程序端根据此字段判断)"`
+	PauseStartTime             string    `gorm:"column:pause_start_time"`                  //`description:"暂停开始日期"`
+	PauseEndTime               string    `gorm:"column:pause_end_time"`                    //`description:"暂停结束日期"`
+	IsSet                      int       `gorm:"column:is_set"`                            //`description:"是否设置:0为设置,1已设置"`
+	YbIconUrl                  string    `gorm:"column:yb_icon_url"`                       // `description:"研报小程序icon"`
+	YbBottomIcon               string    `gorm:"column:yb_bottom_icon"`                    // `description:"研报小程序详情底部icon"`
+	ReportClassifyId           int       `gorm:"column:report_classify_id"`                // `description:"所属分类id"`
+	InheritReportChapterTypeId int       `gorm:"column:inherit_report_chapter_type_id"`    // `description:"继承的报告章节类型id"`
 }
 
 func (r *ReportChapterType) Create() (err error) {

+ 3 - 2
models/report_v2.go

@@ -384,12 +384,13 @@ func GetReportListCountByAuthorized(condition string, pars []interface{}) (count
 func GetReportListByAuthorized(condition string, pars []interface{}, startSize, pageSize int) (items []*ReportList, err error) {
 	//o := orm.NewOrmUsingDB("rddp")
 
-	sql := `SELECT id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time FROM report as a WHERE 1=1  `
+	sql := `SELECT id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time,report_create_time FROM report as a WHERE 1=1  `
 	if condition != "" {
 		sql += condition
 	}
 	// 排序:1:未发布;2:已发布;3-待提交;4-待审批;5-已驳回;6-已通过
-	sql += ` GROUP BY a.id ORDER BY  report_create_time DESC LIMIT ?,?`
+	sql += ` GROUP BY id,classify_id_first,classify_name_first,classify_id_second,classify_name_second,classify_id_third,classify_name_third,title,stage,create_time,author,report_layout,collaborate_type,is_public_publish,abstract,has_chapter,publish_time,report_create_time
+            ORDER BY  report_create_time DESC LIMIT ?,?`
 	//_, err = o.Raw(sql, pars...).QueryRows(&items)
 	pars = append(pars, startSize)
 	pars = append(pars, pageSize)

+ 1 - 1
models/research_report.go

@@ -1,7 +1,7 @@
 package models
 
 type ChartPermissionChapterMapping struct {
-	Id                  int    `orm:"column(id);pk" gorm:"primaryKey" `
+	Id                  int    `gorm:"primaryKey" `
 	ChartPermissionId   int    `description:"权限ID"`
 	ReportChapterTypeId int    `description:"report_chapter_type表主键id或research_report表主键id或tactic表主键id"`
 	ResearchType        string `description:"报告类型 week;two_week;tactic;month;other;rddp; "`

+ 1 - 1
models/search_key_word.go

@@ -28,7 +28,7 @@ func AddTrendTagKeyWord(trend string) (err error) {
 // GetKeyWordListByFrom 根据来源获取搜索关键词列表
 func GetKeyWordListByFrom(from string) (list []*SearchKeyWord, err error) {
 	//o := orm.NewOrm()
-	sql := " SELECT * FROM search_key_word WHERE `from` = ? ORDER BY created_time ASC "
+	sql := ` SELECT * FROM search_key_word WHERE "from" = ? ORDER BY created_time ASC `
 	//_, err = o.Raw(sql, from).QueryRows(&list)
 	err = global.DEFAULT_DmSQL.Raw(sql, from).Find(&list).Error
 	return

+ 1 - 1
models/system/sys_department.go

@@ -10,7 +10,7 @@ type SysDepartmentAddReq struct {
 }
 
 type SysDepartment struct {
-	DepartmentId   int       `orm:"column(department_id);pk" description:"部门Id"`
+	DepartmentId   int       `gorm:"primaryKey;" description:"部门Id"`
 	DepartmentName string    `description:"部门名称"`
 	Sort           int       `description:"排序"`
 	CreateTime     time.Time `description:"创建时间"`

+ 1 - 1
models/system/sys_group.go

@@ -11,7 +11,7 @@ type SysGroupAddReq struct {
 }
 
 type SysGroup struct {
-	GroupId      int       `orm:"column(group_id);pk" description:"分组ID"`
+	GroupId      int       `gorm:"primaryKey"`
 	DepartmentId int       `description:"部门Id"`
 	ParentId     int       `description:"父级Id"`
 	GroupName    string    `description:"分组名称"`

+ 2 - 2
models/system/sys_menu_button.go

@@ -7,7 +7,7 @@ import (
 )
 
 type SysMenuButton struct {
-	MenuButtonId int `orm:"column(menu_button_id);pk" description:"菜单按钮id"`
+	MenuButtonId int `gorm:"primaryKey" description:"菜单按钮id"`
 	MenuId       int
 	ButtonName   int
 	CreateTime   time.Time
@@ -37,7 +37,7 @@ type MenuButtonsResp struct {
 //}
 
 type SysRoleButton struct {
-	Id           int `orm:"column(id);pk" description:"关联id"`
+	Id           int `gorm:"primaryKey" description:"关联id"`
 	RoleId       int
 	MenuButtonId int
 	CreateTime   time.Time

+ 6 - 6
models/system/sys_role.go

@@ -13,7 +13,7 @@ type SysRoleAddReq struct {
 }
 
 type SysRole struct {
-	RoleId       int       `orm:"column(role_id);pk" description:"角色ID"`
+	RoleId       int       `gorm:"primaryKey"`
 	RoleName     string    `description:"角色名称"`
 	RoleType     string    `description:"角色类型"`
 	RoleTypeCode string    `description:"角色类型编码"`
@@ -133,10 +133,10 @@ type RoleMenu struct {
 }
 
 type RoleMenuList struct {
-	MenuId    int    `description:"导航唯一标识"`
-	Name      string `description:"导航名称"`
-	NameEn    string `description:"导航名称(英文)"`
-	Child     []*RoleMenu
+	MenuId    int         `description:"导航唯一标识"`
+	Name      string      `description:"导航名称"`
+	NameEn    string      `description:"导航名称(英文)"`
+	Child     []*RoleMenu `gorm:"-"`
 	CheckList []int
 }
 
@@ -183,7 +183,7 @@ func DeleteRoleMenuByRoleId(roleId int) (err error) {
 }
 
 type SysRoleMenu struct {
-	RoleMenuId int `orm:"column(role_menu_id);pk" description:"关联id"`
+	RoleMenuId int `gorm:"primaryKey"`
 	RoleId     int
 	MenuId     int
 	Type       int `description:"类型:0-全选;1-半选(此字段仅用于前端的回显)"`

+ 1 - 1
models/system/sys_role_admin.go

@@ -7,7 +7,7 @@ import (
 )
 
 type SysRoleAdmin struct {
-	Id         int       `orm:"column(id);pk" description:"自增ID"`
+	Id         int       `gorm:"primaryKey" description:"自增ID"`
 	AdminId    int       `orm:"column(admin_id);" description:"系统用户id"`
 	RoleId     int       `orm:"column(role_id);" description:"角色ID"`
 	CreateTime time.Time `orm:"column(create_time);" description:"创建时间"`

+ 1 - 1
models/system/sys_session.go

@@ -6,7 +6,7 @@ import (
 )
 
 type SysSession struct {
-	Id              int `orm:"column(id);pk"`
+	Id              int `gorm:"primaryKey"`
 	SysUserId       int
 	UserName        string
 	AccessToken     string

+ 2 - 1
models/system/sys_user.go

@@ -27,7 +27,8 @@ type LoginResp struct {
 }
 
 type Admin struct {
-	AdminId                   int    `orm:"column(admin_id);pk" description:"系统用户id"`
+	//AdminId                   int    `grm:"column:admin_id;identity:true" description:"系统用户id"`
+	AdminId                   int    `gorm:"primaryKey;autoIncrement;column:admin_id"`
 	AdminName                 string `description:"系统用户名称"`
 	AdminAvatar               string `description:"用户头像"`
 	RealName                  string `description:"系统用户姓名"`

+ 1 - 1
models/system/sys_user_login_record.go

@@ -6,7 +6,7 @@ import (
 )
 
 type SysUserLoginRecord struct {
-	Id         int `orm:"column(id);pk"`
+	Id         int `gorm:"primaryKey"`
 	Uid        int
 	UserName   string
 	Ip         string

+ 1 - 1
models/target.go

@@ -118,7 +118,7 @@ func EditEdbdata(item *Edbdata) (err error) {
 }
 
 type EdbdataDeleteRecord struct {
-	Id         int       `orm:"column(id);pk" gorm:"primaryKey" `
+	Id         int       `gorm:"primaryKey" `
 	TradeCode  string    `orm:"column(TRADE_CODE)" description:"指标编码"`
 	Dt         string    `orm:"column(DT)" description:"日期"`
 	Close      string    `orm:"column(CLOSE)" description:"值"`

+ 1 - 1
models/variety_tag.go

@@ -142,7 +142,7 @@ package models
 
 // ResearchVarietyTagRelation 研究员标签关系表
 type ResearchVarietyTagRelation struct {
-	Id           int `orm:"column(id);pk" gorm:"primaryKey" `
+	Id           int `gorm:"primaryKey" `
 	VarietyTagId int `json:"variety_tag_id" description:"标签ID"`
 	AdminId      int `json:"admin_id" description:"研究员ID"`
 }

+ 1 - 1
models/wechat_send_msg.go

@@ -31,7 +31,7 @@ func GetOpenIdArrByClassifyId(classifyId int) (items []string, err error) {
 			INNER JOIN chart_permission AS f ON e.chart_permission_id=f.chart_permission_id
 			INNER JOIN chart_permission_search_key_word_mapping AS g ON f.chart_permission_id=g.chart_permission_id
 			WHERE ur.open_id != "" AND ur.subscribe=1 AND ur.create_platform=1 AND  d.status IN('正式','试用','永续') AND  e.status IN('正式','试用','永续') 
-			AND g.from='rddp'
+			AND g.source_from='rddp'
 			AND g.classify_id=?
 			ORDER BY FIELD(c.company_id, 16) DESC, ur.user_record_id ASC  `
 	//o := orm.NewOrmUsingDB("weekly")

+ 252 - 0
routers/commentsRouter.go

@@ -241,6 +241,132 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Approve",
+            Router: `/approve`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "CheckApproveOpen",
+            Router: `/classify/check_open`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "ClassifyList",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "MessageList",
+            Router: `/message/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "MessageRead",
+            Router: `/message/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Refuse",
+            Router: `/refuse`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/flow/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/flow/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/flow/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/flow/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Remove",
+            Router: `/flow/remove`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/correlation:CorrelationChartClassifyController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/data_manage/correlation:CorrelationChartClassifyController"],
         beego.ControllerComments{
             Method: "AddChartClassify",
@@ -8098,6 +8224,132 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "AddDashboard",
+            Router: `/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "AddDashboardClassify",
+            Router: `/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "DelDashboardClassify",
+            Router: `/classify/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "EditDashboardClassify",
+            Router: `/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "DeleteDashboard",
+            Router: `/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "DetailDashboard",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "DeleteDashboardDetail",
+            Router: `/detail/delete`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "MoveDashboard",
+            Router: `/detail/move`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "EditDashboard",
+            Router: `/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "Grant",
+            Router: `/grant`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "MyList",
+            Router: `/my_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "Public",
+            Router: `/public`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "PublicList",
+            Router: `/public_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "ShareList",
+            Router: `/share_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BannerController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BannerController"],
         beego.ControllerComments{
             Method: "Upload",

+ 12 - 0
routers/router.go

@@ -10,6 +10,7 @@ package routers
 import (
 	"eta_gn/eta_api/controllers"
 	"eta_gn/eta_api/controllers/ai"
+	biapprove "eta_gn/eta_api/controllers/bi_approve"
 	"eta_gn/eta_api/controllers/data_manage"
 	"eta_gn/eta_api/controllers/data_manage/correlation"
 	"eta_gn/eta_api/controllers/data_manage/cross_variety"
@@ -352,6 +353,12 @@ func init() {
 				&report_approve.ReportApproveFlowController{},
 			),
 		),
+		web.NSNamespace("/bi_approve",
+			web.NSInclude(
+				&biapprove.BiApproveFlowController{},
+				&biapprove.BiApproveController{},
+			),
+		),
 		web.NSNamespace("/data_source",
 			web.NSInclude(
 				&data_source.DataSourceController{},
@@ -394,6 +401,11 @@ func init() {
 				&controllers.KnowledgeTagController{},
 			),
 		),
+		web.NSNamespace("/bi_dashborad",
+			web.NSInclude(
+				&controllers.BIDaShboardController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 1181 - 0
services/bi_approve/bi_approve.go

@@ -0,0 +1,1181 @@
+package biapprove
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models"
+	biapprove "eta_gn/eta_api/models/bi_approve"
+	"eta_gn/eta_api/models/bi_approve/response"
+	"eta_gn/eta_api/models/bi_dashboard"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strings"
+	"time"
+)
+
+var (
+	timeField   = map[int]string{1: fmt.Sprintf("a.%s", biapprove.BiApproveCols.CreateTime), 2: fmt.Sprintf("a.%s", biapprove.BiApproveCols.ApproveTime), 3: fmt.Sprintf("b.%s", biapprove.BiApproveCols.ApproveTime)}
+	myTimeField = map[int]string{1: biapprove.BiApproveCols.CreateTime, 3: biapprove.BiApproveCols.ApproveTime}
+	orderRules  = map[int]string{1: "ASC", 2: "DESC"}
+)
+
+func GetPulicBiClassifyList() (res []*bi_dashboard.BiDashboardClassifyItem, msg string, err error) {
+	classifyList, err := bi_dashboard.GetBiDashboardClassifyAllList()
+	if err != nil {
+		msg = "获取公共分类列表失败"
+		return
+	}
+	res = toClassifyItem(classifyList)
+	return
+}
+
+func PassBiApprove(approveId int, adminId int) (msg string, err error) {
+	approveItem, e := biapprove.GetBiApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	if approveItem.State != BiApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	var ApprovePars []interface{}
+	Approveconds := ` AND bi_approve_id =? AND approve_user_id =? AND state =? `
+	ApprovePars = append(ApprovePars, approveId, adminId, BiApproveStateApproving)
+
+	recordItem, er := biapprove.GetBiApproveRecordByCondition(Approveconds, ApprovePars)
+	if er != nil {
+		if utils.IsErrNoRow(er) {
+			msg = "无权审批"
+			err = er
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	// 查询审批流和审批流节点
+	flowItem, e := biapprove.GetBiApproveFlowById(approveItem.FlowId)
+	if e != nil {
+		err = fmt.Errorf("获取审批流失败, Err: %s", e.Error())
+		return
+	}
+	nodePars := make([]interface{}, 0)
+	nodeCond := ` AND bi_approve_flow_id =? AND curr_version =? `
+	nodePars = append(nodePars, flowItem.BiApproveFlowId, flowItem.CurrVersion)
+	nodeItems, e := biapprove.GetBiApproveNodeByCondition(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]*biapprove.BiApproveNode)
+	for _, v := range nodeItems {
+		nodeMap[v.BiApproveNodeId] = v
+	}
+
+	// 取出审批记录的节点
+	currNodeItem := nodeMap[recordItem.NodeId]
+	if currNodeItem == nil {
+		err = fmt.Errorf("当前节点信息有误")
+		return
+	}
+	currNode, e := FormatBiApproveNode2Item(currNodeItem)
+	if e != nil {
+		err = fmt.Errorf("当前节点信息有误, Err: %s", e.Error())
+		return
+	}
+	now := time.Now().Local()
+	recordItem.State = BiApproveStatePass
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+	recordItem.NodeState = BiApproveStatePass
+	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.BiApproveNodeUser) // 下一个审批人, 为nil则表示当前审批人即为最后
+		for k, v := range currNode.Users {
+			// 当前审批人
+			if v.UserId == adminId && recordItem.ApproveUserSort == v.Sort {
+				//if k == (userLen - 1) {
+				//	lastRoll = true
+				//	break
+				//}
+				if (k + 1) < userLen {
+					nextUser = currNode.Users[k+1]
+				}
+			}
+		}
+		//if lastRoll && currNode.NextNodeId == 0 {
+		//	lastApprove = true
+		//}
+
+		// 当前节点下一个审批人, 生成下一个审批记录且return
+		if nextUser.UserId > 0 {
+			newRecord := new(biapprove.BiApproveRecord)
+			newRecord.BiApproveId = recordItem.BiApproveId
+			newRecord.State = BiApproveStateApproving
+			newRecord.NodeId = currNode.BiApproveNodeId
+			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 = BiApproveStateApproving
+			if e = newRecord.Create(); e != nil {
+				err = fmt.Errorf("生成审批记录失败, Err: %s", e.Error())
+				return
+			}
+
+			// 推送审批消息
+			go func() {
+				messageItem := new(biapprove.BiApproveMessage)
+				messageItem.SendUserId = approveItem.ApplyUserId
+				messageItem.ReceiveUserId = nextUser.UserId
+				messageItem.Content = "您有新的待办任务"
+				messageItem.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", approveItem.ApplyUserName, approveItem.BiTitle)
+				messageItem.BiApproveId = approveItem.BiApproveId
+				messageItem.ApproveState = BiApproveStateApproving
+				messageItem.CreateTime = now
+				messageItem.ModifyTime = now
+				if e = messageItem.Create(); e != nil {
+					utils.FileLog.Info(fmt.Sprintf("PassBiApprove 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.BiApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName)
+			return
+		} else {
+			// 最后一个节点
+			lastApprove = true
+		}
+	}
+
+	// 会签
+	if currNode.ApproveType == NodeApproveTypeAll {
+		// 查询其他审批人是否已审批
+		otherCond := ` AND bi_approve_id =? AND node_id =? AND approve_user_id <> ? `
+		otherPars := make([]interface{}, 0)
+		otherPars = append(otherPars, approveItem.BiApproveId, recordItem.NodeId, adminId)
+		otherRecords, e := biapprove.GetBiApproveRecordItemsByCondition(otherCond, otherPars)
+		if e != nil {
+			err = fmt.Errorf("获取节点审批记录失败, Err: %s", e.Error())
+			return
+		}
+		otherPass := true
+		for _, v := range otherRecords {
+			if v.State != BiApproveStatePass {
+				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.BiApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName)
+			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.BiApproveId, 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.BiApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName)
+			return
+		}
+	}
+
+	// 最后一个审批, 更新审批记录、审批、报告状态、推送消息给申请人
+	if lastApprove {
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+		approveItem.State = BiApproveStatePass
+		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 = updateBiApproveState(approveItem.BiId, approveItem.BiApproveId, BiStatePass); e != nil {
+			err = fmt.Errorf("更新报告审批状态失败, Err: %s", e.Error())
+			return
+		}
+
+		go func() {
+			messageItem := new(biapprove.BiApproveMessage)
+			messageItem.SendUserId = adminId
+			messageItem.ReceiveUserId = approveItem.ApplyUserId
+			messageItem.Content = "您提交的审批已通过"
+			messageItem.Remark = fmt.Sprintf("您提交的【%s】已通过", approveItem.BiTitle)
+			messageItem.BiApproveId = approveItem.BiApproveId
+			messageItem.ApproveState = BiApproveStatePass
+			messageItem.CreateTime = now
+			messageItem.ModifyTime = now
+			if e = messageItem.Create(); e != nil {
+				utils.FileLog.Info(fmt.Sprintf("PassBiApprove message err: %s", e.Error()))
+				return
+			}
+		}()
+	}
+	return
+
+}
+
+func toClassifyItem(src []*bi_dashboard.BiDashboardClassify) (dst []*bi_dashboard.BiDashboardClassifyItem) {
+	for _, item := range src {
+		dst = append(dst, &bi_dashboard.BiDashboardClassifyItem{
+			BiDashboardClassifyId:   item.BiDashboardClassifyId,
+			BiDashboardClassifyName: item.BiDashboardClassifyName,
+		})
+	}
+	return
+}
+
+// BuildNextNodeRecordAndMsg 生成下一个节点的审批记录并推送消息
+func BuildNextNodeRecordAndMsg(approveNodeItem *biapprove.BiApproveNode, approveId, sysAdminId int, sysAdminName string) (err error) {
+	if approveNodeItem == nil {
+		err = fmt.Errorf("approve node nil")
+		return
+	}
+
+	// 根据节点审批方式生成审批记录
+	now := time.Now().Local()
+	approveNode, e := FormatBiApproveNode2Item(approveNodeItem)
+	if e != nil {
+		err = fmt.Errorf("FormatBiApproveNode2Item err: %s", e.Error())
+		return
+	}
+	if len(approveNode.Users) == 0 {
+		err = fmt.Errorf("审批节点用户有误")
+		return
+	}
+	newRecords := make([]*biapprove.BiApproveRecord, 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(biapprove.BiApproveRecord)
+		r.BiApproveId = approveId
+		r.State = BiApproveStateApproving
+		r.NodeId = approveNode.BiApproveNodeId
+		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 = BiApproveStateApproving // 当前节点审批状态
+		newRecords = append(newRecords, r)
+		// 依次审批仅生成一条记录
+		if approveNode.ApproveType == NodeApproveTypeRoll {
+			break
+		}
+	}
+
+	recordOb := new(biapprove.BiApproveRecord)
+	if e = recordOb.CreateMulti(newRecords); e != nil {
+		err = fmt.Errorf("生成节点审批记录失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送审批消息
+	go func() {
+		messageOb := new(biapprove.BiApproveMessage)
+		messages := make([]*biapprove.BiApproveMessage, 0)
+		for _, v := range newRecords {
+			m := new(biapprove.BiApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = "您有新的待办任务"
+			m.Remark = fmt.Sprintf("%s提交的【看板审批】需要您审批,请及时处理", sysAdminName)
+			m.BiApproveId = approveId
+			m.ApproveState = BiApproveStateApproving
+			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
+}
+
+// updateBiApproveState 更新Bi看板审批状态
+func updateBiApproveState(biId, approveId, state int) (err error) {
+	// updateCols := []string{"ApproveId", "State", "ModifyTime"}
+	updateCols := []string{"State", "ModifyTime"}
+	BiItem, e := bi_dashboard.GetDashboardById(biId)
+	if e != nil && !utils.IsErrNoRow(e) {
+		err = fmt.Errorf("获取智能看板失败, Err: %s", e.Error())
+		return
+	}
+	if BiItem != nil && BiItem.BiDashboardId > 0 {
+		// BiItem.ApproveId = approveId
+		BiItem.State = state
+		BiItem.ModifyTime = time.Now().Local()
+
+		// if state == models.BiStatePass || state == models.BiStateRefused {
+		// 	updateCols = append(updateCols, "ApproveTime")
+		// 	// BiItem.ApproveTime = time.Now().Local()
+		// }
+		// if state == models.BiStatePass {
+		// 	updateCols = append(updateCols, "PublishTime")
+		// 	// BiItem.PublishTime = time.Now().Local()
+		// }
+		if e = BiItem.Update(updateCols); e != nil {
+			err = fmt.Errorf("更新Bi看板审批状态失败, Err: %s", e.Error())
+			return
+		}
+	}
+	return
+}
+
+func ProcessingBiApprove(adminId, classifyId, timeType, sortField, sortRule, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.BiApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND b.%s = ? AND a.%s = ?`, biapprove.BiApproveRecordCols.State, biapprove.BiApproveCols.State, biapprove.BiApproveRecordCols.ApproveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, BiApproveStateApproving, BiApproveStateApproving, adminId)
+	order := ""
+
+	// 筛选条件
+	if classifyId > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, biapprove.BiApproveCols.ClassifyId)
+		pars = append(pars, classifyId)
+	}
+	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 ?)`, biapprove.BiApproveCols.CreateTime)
+		pars = append(pars, startTime, tmpEndTime)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND b.%s LIKE ?`, biapprove.BiApproveCols.BiTitle)
+		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 := biapprove.GetApprovingBiApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingBiApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := biapprove.GetApprovingBiApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingBiApprovePageList err: %s", e.Error())
+		return
+	}
+
+	respList = toBiApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+// SolvedBiApprove 已处理的审批
+func SolvedBiApprove(adminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.BiApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND a.%s IN (?)`, biapprove.BiApproveRecordCols.ApproveUserId, biapprove.BiApproveRecordCols.NodeState)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId, []int{BiApproveStatePass, BiApproveStateRefuse})
+	order := ""
+
+	// 筛选条件
+	if classifyId > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, biapprove.BiApproveCols.ClassifyId)
+		pars = append(pars, classifyId)
+	}
+	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 ?`, biapprove.BiApproveCols.BiTitle)
+		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 = ?`, biapprove.BiApproveRecordCols.State)
+		pars = append(pars, approveState)
+	}
+	total, e := biapprove.GetApprovedBiApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedBiApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := biapprove.GetApprovedBiApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedBiApprovePageList err: %s", e.Error())
+		return
+	}
+
+	for _, v := range list {
+		// 这个时候的状态,用审批状态
+		v.RecordState = v.NodeState
+		v.ApproveTime = v.NodeApproveTime
+	}
+	respList = toBiApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+func MyApplyBiApproves(adminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.BiApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ?`, biapprove.BiApproveCols.ApplyUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := ""
+
+	// 筛选条件
+	if classifyId > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, biapprove.BiApproveCols.ClassifyId)
+		pars = append(pars, classifyId)
+	}
+	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 a.%s LIKE ?`, biapprove.BiApproveCols.BiTitle)
+		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 = ?`, biapprove.BiApproveRecordCols.State)
+		pars = append(pars, approveState)
+	}
+	total, e := biapprove.GetApplyBiApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyBiApproveCount err: %s", e.Error())
+		return
+	}
+	respTotal = total
+	list, e := biapprove.GetApplyBiApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyBiApprovePageList err: %s", e.Error())
+		return
+	}
+	respList = toBiApproveItemOrmResp(list)
+	return
+}
+
+func GetApproveDetail(approveId int) (resp *response.BiApproveDetail, msg string, err error) {
+	approveItem, e := biapprove.GetBiApproveById(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.BiApproveDetail)
+	detail.Approve = new(response.BiApproveDetailItem)
+	detail.Approve.BiApproveId = approveItem.BiApproveId
+	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(biapprove.BiApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, biapprove.BiApproveNodeCols.BiApproveFlowId, biapprove.BiApproveNodeCols.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(biapprove.BiApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveRecordCols.BiApproveId)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.BiApproveId)
+	recordItems, e := recordOb.GetItemsByCondition(recordCond, recordPars, []string{}, fmt.Sprintf("%s DESC", biapprove.BiApproveRecordCols.ApproveTime))
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	recordMap := make(map[string]*biapprove.BiApproveRecord)
+	for _, v := range recordItems {
+		k := fmt.Sprintf("%d-%d", v.NodeId, v.ApproveUserId)
+		recordMap[k] = v
+	}
+
+	// 审批流节点详情
+	detail.ApproveFlowNodes = make([]*response.BiApproveDetailNodes, 0)
+	for _, v := range nodeItems {
+		t := new(response.BiApproveDetailNodes)
+		t.BiApproveNodeId = v.BiApproveNodeId
+		t.BiApproveFlowId = v.BiApproveFlowId
+		t.PrevNodeId = v.PrevNodeId
+		t.NextNodeId = v.NextNodeId
+		t.NodeType = v.NodeType
+		t.ApproveType = v.ApproveType
+		t.Users = make([]*response.BiApproveDetailNodeUser, 0)
+		us := make([]*response.BiApproveNodeUserReq, 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.BiApproveDetailNodeUser)
+			u.UserType = vu.UserType
+			u.UserId = vu.UserId
+			u.UserName = vu.UserName
+			u.Sort = vu.Sort
+			// 审批记录
+			k := fmt.Sprintf("%d-%d", v.BiApproveNodeId, vu.UserId)
+			r := recordMap[k]
+			if r != nil {
+				u.ApproveRecord = new(response.BiApproveDetailNodeUserRecord)
+				u.ApproveRecord.BiApproveRecordId = r.BiApproveRecordId
+				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)
+	}
+
+	// 看板信息
+	cnClassifyIdName := make(map[int]string)
+	cnClassify, e := bi_dashboard.GetBiDashboardClassifyAllList()
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetBiDashboardClassifyAllList err: %s", e.Error())
+		return
+	}
+	for _, v := range cnClassify {
+		cnClassifyIdName[v.BiDashboardClassifyId] = v.BiDashboardClassifyName
+	}
+	detail.Bi = new(response.BiApproveDetailBi)
+	detail.Bi.BiId = approveItem.BiId
+	detail.Bi.BiTitle = approveItem.BiTitle
+	detail.Bi.BiClassify = cnClassifyIdName[approveItem.ClassifyId]
+	resp = detail
+	return
+}
+
+func BiApproveRefuse(biApproveId, adminId int, approveRemark string) (msg string, err error) {
+	approveItem, e := biapprove.GetBiApproveById(biApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetBiApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.State != BiApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	// 校验审批记录和审批
+	recordOb := new(biapprove.BiApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?`, biapprove.BiApproveRecordCols.BiApproveId, biapprove.BiApproveRecordCols.ApproveUserId, biapprove.BiApproveRecordCols.State)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.BiApproveId, adminId, BiApproveStateApproving)
+	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 = RefuseBiApprove(approveItem, recordItem, approveRemark, adminId); e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("RefuseBiApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// RefuseBiApprove 驳回审批
+func RefuseBiApprove(approveItem *biapprove.BiApprove, recordItem *biapprove.BiApproveRecord, 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 = BiApproveStateRefuse
+	recordItem.ApproveRemark = approveRemark
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+
+	recordItem.NodeState = BiApproveStateRefuse
+	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.BiApproveId, recordItem.NodeId, recordItem.NodeState, recordItem.NodeApproveUserId, recordItem.NodeApproveUserName, recordItem.NodeApproveTime); e != nil {
+		err = fmt.Errorf("更新同一节点的其他审批记录状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 驳回-更新审批, 报告状态, 推送消息
+	approveItem.State = BiApproveStateRefuse
+	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 := updateBiApproveState(approveItem.BiId, approveItem.BiApproveId, BiStateRefused); e != nil {
+		err = fmt.Errorf("更新报告状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送驳回消息给申请人
+	go func() {
+		messageItem := new(biapprove.BiApproveMessage)
+		messageItem.SendUserId = sysAdminId
+		messageItem.ReceiveUserId = approveItem.ApplyUserId
+		messageItem.Content = "您提交的审批被驳回"
+		messageItem.Remark = "您提交的【看板审批】已被驳回"
+		messageItem.BiApproveId = approveItem.BiApproveId
+		messageItem.ApproveState = BiApproveStateRefuse
+		messageItem.CreateTime = now
+		messageItem.ModifyTime = now
+		if e := messageItem.Create(); e != nil {
+			utils.FileLog.Info(fmt.Sprintf("ApproveBi message err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+func BiApproveCancel(biApproveId, adminId int, adminName string) (msg string, err error) {
+	approveItem, e := biapprove.GetBiApproveById(biApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批已被删除, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetBiApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.ApplyUserId != adminId {
+		msg = "非申请人不可撤销"
+		err = fmt.Errorf("非申请人不可撤销")
+		return
+	}
+
+	// 撤销审批
+	e = cancelBiApprove(approveItem.BiId, approveItem.BiApproveId, adminId, adminName)
+	if e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("cancelBiApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// cancelBiApprove 撤回审批
+func cancelBiApprove(biId, approveId, sysAdminId int, sysAdminName string) (err error) {
+	// 默认内部审批, 如果是走的第三方审批, 那么仅修改状态
+	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.BusinessConfIsBIApprove]]
+	if !openApprove {
+		//err = fmt.Errorf("未开启审批")
+		return
+	}
+
+	// 修改审批信息状态
+	approveItem, e := biapprove.GetBiApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			err = e
+			return
+		}
+		err = fmt.Errorf("approve GetItemById err: %s", e.Error())
+		return
+	}
+	if approveItem.State == BiApproveStateCancel {
+		return
+	}
+	approveItem.State = BiApproveStateCancel
+	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 = updateBiApproveState(biId, 0, BiStateWaitSubmit)
+	if e != nil {
+		err = fmt.Errorf("更新报告审批撤回失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送撤回消息
+	go func() {
+		recordOb := new(biapprove.BiApproveRecord)
+		recordCond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveRecordCols.BiApproveId)
+		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(biapprove.BiApproveMessage)
+		messages := make([]*biapprove.BiApproveMessage, 0)
+		for _, v := range recordItems {
+			m := new(biapprove.BiApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = fmt.Sprintf("%s提交的【看板审批】已撤回", sysAdminName)
+			m.BiApproveId = approveId
+			m.ApproveState = BiApproveStateCancel
+			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("CancelBiApprove messages err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+// CheckBiOpenApprove 校验报告是否开启了审批流
+func CheckBiOpenApprove(classifyId int) (opening bool, err error) {
+	// 获取审批配置
+	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.BusinessConfIsBIApprove]]
+
+	// 查询对应分类是否有审批流
+	flowOb := new(biapprove.BiApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveFlowCols.ClassifyId)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, classifyId)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil && !utils.IsErrNoRow(e) {
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+	if utils.IsErrNoRow(e) {
+		return
+	}
+
+	// 开启审批/有审批流
+	if openApprove && (flowItem != nil) {
+		opening = true
+		return
+	}
+	return
+}
+
+// CheckBiCurrState 校验报告当前应有的状态
+func CheckBiCurrState(classifyId, operate int) (state int, err error) {
+	// 获取审批配置
+	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.BusinessConfIsBIApprove]]
+
+	// 查询对应分类是否有审批流
+	flowOb := new(biapprove.BiApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveFlowCols.ClassifyId)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, classifyId)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil && !utils.IsErrNoRow(e) {
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 开启审批/有审批流
+	if openApprove && (flowItem != nil) {
+		// 操作为无审批的操作时, 会转为有审批的初始状态-待提交
+		stateMap := map[int]int{
+			BiOperateAdd:           BiStateWaitSubmit,  // 新增
+			BiOperateEdit:          BiStateWaitSubmit,  // 编辑
+			BiOperatePublish:       BiStateWaitSubmit,  // 发布
+			BiOperateCancelPublish: BiStateWaitSubmit,  // 取消发布
+			BiOperateSubmitApprove: BiStateWaitApprove, // 提审
+			BiOperateCancelApprove: BiStateWaitSubmit,  // 撤回
+		}
+		state = stateMap[operate]
+		return
+	}
+
+	// 关闭审批/分类无审批
+	// 操作为有审批的操作时, 会转为无审批的初始状态-未发布
+	stateMap := map[int]int{
+		BiOperateAdd:           BiStateUnpublished, // 新增
+		BiOperateEdit:          BiStateUnpublished, // 编辑
+		BiOperatePublish:       BiStatePublished,   // 发布
+		BiOperateCancelPublish: BiStateUnpublished, // 取消发布
+		BiOperateSubmitApprove: BiStateUnpublished, // 提审
+		BiOperateCancelApprove: BiStateUnpublished, // 撤回
+	}
+	state = stateMap[operate]
+	return
+}
+
+// SubmitBiApprove 提交审批
+func SubmitBiApprove(biId int, biTitle string, classifyId int, sysAdminId int, sysAdminName string) (approveId int, err error) {
+	// 默认内部审批, 如果是走的第三方审批, 那么仅修改状态
+	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.BusinessConfIsBIApprove]]
+	if !openApprove {
+		err = fmt.Errorf("未开启审批")
+		return
+	}
+
+	// 查询审批流
+	flowOb := new(biapprove.BiApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveFlowCols.ClassifyId)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, classifyId)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 查询审批节点
+	nodeOb := new(biapprove.BiApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, biapprove.BiApproveNodeCols.BiApproveFlowId, biapprove.BiApproveNodeCols.CurrVersion)
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, flowItem.BiApproveFlowId, 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(biapprove.BiApproveNode)
+	for _, v := range nodeItems {
+		if v.PrevNodeId == 0 {
+			firstNodeItem = v
+			continue
+		}
+	}
+	if firstNodeItem == nil {
+		err = fmt.Errorf("首个审批节点有误")
+		return
+	}
+
+	// 审批信息
+	now := time.Now().Local()
+	newApprove := new(biapprove.BiApprove)
+	newApprove.BiId = biId
+	newApprove.BiTitle = biTitle
+	newApprove.ClassifyId = classifyId
+	newApprove.State = BiApproveStateApproving
+	newApprove.FlowId = flowItem.BiApproveFlowId
+	newApprove.FlowVersion = flowItem.CurrVersion
+	newApprove.StartNodeId = firstNodeItem.BiApproveNodeId
+	newApprove.CurrNodeId = firstNodeItem.BiApproveNodeId
+	newApprove.ApplyUserId = sysAdminId
+	newApprove.ApplyUserName = sysAdminName
+	newApprove.CreateTime = now
+	newApprove.ModifyTime = now
+	if e = newApprove.Create(); e != nil {
+		err = fmt.Errorf("生成审批信息失败, Err: %s", e.Error())
+		return
+	}
+	approveId = newApprove.BiApproveId
+
+	// 生成节点审批记录
+	err = BuildNextNodeRecordAndMsg(firstNodeItem, newApprove.BiApproveId, sysAdminId, sysAdminName)
+	return
+}
+
+func toBiApproveItemOrmResp(src []*biapprove.BiApproveItemOrm) (res []*response.BiApproveItemOrmResp) {
+	for _, v := range src {
+		r := new(response.BiApproveItemOrmResp)
+		r.BiApproveId = v.BiApproveId
+		r.BiApproveRecordId = v.BiApproveRecordId
+		r.BiId = v.BiId
+		r.BiTitle = v.BiTitle
+		r.ClassifyId = v.ClassifyId
+		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 = v.ApproveTime.Format(utils.FormatDateTime)
+		r.HandleTime = v.HandleTime.Format(utils.FormatDateTime)
+		r.CreateTime = v.CreateTime.Format(utils.FormatDateTime)
+		r.ModifyTime = v.ModifyTime.Format(utils.FormatDateTime)
+		r.NodeState = v.NodeState
+		res = append(res, r)
+	}
+	return
+}
+
+func GetBiClassifyAll() (list []*bi_dashboard.BiDashboardClassify, msg string, err error) {
+	ClassifyList, e := bi_dashboard.GetBiDashboardClassifyAllList()
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetBiDashboardClassifyAllList err: %s", e.Error())
+		return
+	}
+	list = ClassifyList
+	return
+}

+ 243 - 0
services/bi_approve/bi_approve_flow.go

@@ -0,0 +1,243 @@
+package biapprove
+
+import (
+	"encoding/json"
+	biapprove "eta_gn/eta_api/models/bi_approve"
+	"eta_gn/eta_api/models/bi_approve/request"
+	"eta_gn/eta_api/models/bi_approve/response"
+	"eta_gn/eta_api/models/bi_dashboard"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+// GetBiApproveFlowList 获取BI审批流列表
+func GetBiApproveFlowList(condition string, pars []interface{}, startSize, pageSize int) (items []*response.BiApproveFlowItem, total int, msg string, err error) {
+	total, err = biapprove.GetBiApproveFlowCountByCondition(condition, pars)
+	if err != nil {
+		msg = "获取审批流程列表失败"
+		return
+	}
+	if total == 0 {
+		items = make([]*response.BiApproveFlowItem, 0)
+		return
+	}
+	flowList, err := biapprove.GetBiApproveFlowByCondition(condition, pars, startSize, pageSize)
+	if err != nil {
+		msg = "获取审批流程列表失败"
+		return
+	}
+	items = toBiApproveFlowItem(flowList)
+	return
+}
+
+// SaveBiApproveFlow 保存审批流
+func SaveBiApproveFlow(flow *request.BiApproveFlowSaveReq) (ok bool, msg string, err error) {
+	classifyInfo, err := bi_dashboard.GetBiDashboardClassifyById(flow.ClassifyId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			msg = "保存审批流失败, 分类不存在"
+			return
+		}
+		msg = "保存审批流失败"
+		return
+	}
+	if flow.BiApproveFlowId == 0 {
+		tmp, er := biapprove.GetBiApproveFlowByClassifyId(flow.ClassifyId)
+		if er != nil && !utils.IsErrNoRow(er) {
+			msg = "保存审批流失败"
+			err = er
+			return
+		}
+		if tmp != nil && tmp.BiApproveFlowId > 0 {
+			msg = "保存审批流失败, 分类下已存在审批流"
+			err = fmt.Errorf("分类下已存在审批流")
+			return
+		}
+
+		t := &biapprove.BiApproveFlow{
+			FlowName:     flow.FlowName,
+			ClassifyId:   flow.ClassifyId,
+			ClassifyName: classifyInfo.BiDashboardClassifyName,
+			CurrVersion:  1,
+			CreateTime:   time.Now(),
+			ModifyTime:   time.Now(),
+		}
+		biFlowNodeItems := make([]*biapprove.BiApproveNode, 0)
+		for _, node := range flow.Nodes {
+			biFlowNode := new(biapprove.BiApproveNode)
+			biFlowNode.ApproveType = node.ApproveType
+			biFlowNode.CurrVersion = t.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			biFlowNode.Users = string(userBytes)
+			biFlowNode.CreatedTime = time.Now()
+			biFlowNodeItems = append(biFlowNodeItems, biFlowNode)
+		}
+		err = t.Add(biFlowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	} else {
+		resFlow, er := biapprove.GetBiApproveFlowById(flow.BiApproveFlowId)
+		if er != nil {
+			msg = "保存审批流失败"
+			err = er
+			return
+		}
+		ok, err = CheckDeleteBiApproveFlow(resFlow.BiApproveFlowId)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		if !ok {
+			msg = "保存审批流失败, 存在还未审批的报告"
+			return
+		}
+		var updateCols []string
+		if resFlow.FlowName != flow.FlowName {
+			resFlow.FlowName = flow.FlowName
+			updateCols = append(updateCols, "flow_name")
+		}
+		resFlow.CurrVersion += 1
+		resFlow.ModifyTime = time.Now()
+		updateCols = append(updateCols, "modify_time", "curr_version")
+
+		biFlowNodeItems := make([]*biapprove.BiApproveNode, 0)
+		for _, node := range flow.Nodes {
+			biFlowNode := new(biapprove.BiApproveNode)
+			biFlowNode.ApproveType = node.ApproveType
+			biFlowNode.CurrVersion = resFlow.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			biFlowNode.Users = string(userBytes)
+			biFlowNode.CreatedTime = time.Now()
+			biFlowNodeItems = append(biFlowNodeItems, biFlowNode)
+		}
+
+		err = resFlow.Update(updateCols, biFlowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	}
+	return
+}
+
+// GetBiApproveFlowDetail 获取审批流详情
+func GetBiApproveFlowDetail(flowId int) (detail *response.BiApproveFlowDetailResp, msg string, err error) {
+	flowInfo, err := biapprove.GetBiApproveFlowById(flowId)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	flowNodes, err := biapprove.GetBiApproveNodeByFlowIdAndVersionId(flowId, flowInfo.CurrVersion)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	detail, err = FormatFlowAndNodesItem2Detail(flowInfo, flowNodes)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	return
+}
+
+// DeleteBiApproveFlow 删除审批流
+func DeleteBiApproveFlow(flowId int) (ok bool, msg string, err error) {
+	ok, err = CheckDeleteBiApproveFlow(flowId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			msg = "删除审批流失败, 审批流不存在"
+			return
+		}
+		msg = "删除审批流失败"
+		return
+	}
+	if !ok {
+		msg = "删除审批流失败, 存在还未审批的报告"
+		return
+	}
+
+	t := &biapprove.BiApproveFlow{
+		BiApproveFlowId: flowId,
+	}
+	err = t.Delete()
+	if err != nil {
+		msg = "删除审批流失败"
+		return
+	}
+	ok = true
+	return
+}
+
+// CheckDeleteBiApproveFlow 检查是否可以删除审批流
+func CheckDeleteBiApproveFlow(flowId int) (ok bool, err error) {
+	flowInfo, err := biapprove.GetBiApproveFlowById(flowId)
+	if err != nil {
+		return
+	}
+	// 检查是否存在还未审批的Bi看报
+	approveList, err := biapprove.GetBiApproveByFlowIdAndVersionId(flowInfo.BiApproveFlowId, flowInfo.CurrVersion)
+	if err != nil {
+		return
+	}
+	for _, v := range approveList {
+		if v.State == BiApproveStateApproving {
+			return false, nil
+		}
+	}
+
+	ok = true
+	return
+}
+
+func toBiApproveFlowItem(src []*biapprove.BiApproveFlow) (res []*response.BiApproveFlowItem) {
+	res = make([]*response.BiApproveFlowItem, 0, len(src))
+	for _, item := range src {
+		res = append(res, &response.BiApproveFlowItem{
+			BiApproveFlowId: item.BiApproveFlowId,
+			FlowName:        item.FlowName,
+			ClassifyId:      item.ClassifyId,
+			ClassifyName:    item.ClassifyName,
+			CurrVersion:     item.CurrVersion,
+			CreateTime:      item.CreateTime.Format(utils.FormatDateTime),
+			ModifyTime:      item.ModifyTime.Format(utils.FormatDateTime),
+		})
+	}
+	return
+}
+
+func FormatFlowAndNodesItem2Detail(flowItem *biapprove.BiApproveFlow, nodeItems []*biapprove.BiApproveNode) (detail *response.BiApproveFlowDetailResp, err error) {
+	if flowItem == nil {
+		return
+	}
+	detail = new(response.BiApproveFlowDetailResp)
+	detail.BiApproveFlowId = flowItem.BiApproveFlowId
+	detail.FlowName = flowItem.FlowName
+	detail.ClassifyId = flowItem.ClassifyId
+	detail.CreateTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.CreateTime)
+	detail.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.ModifyTime)
+	detail.Nodes = make([]*response.BiApproveNodeItem, 0)
+	for _, v := range nodeItems {
+		t, e := FormatBiApproveNode2Item(v)
+		if e != nil {
+			err = fmt.Errorf("format node err: %s", e.Error())
+			return
+		}
+		detail.Nodes = append(detail.Nodes, t)
+	}
+	return
+}

+ 89 - 0
services/bi_approve/bi_approve_message.go

@@ -0,0 +1,89 @@
+package biapprove
+
+import (
+	biapprove "eta_gn/eta_api/models/bi_approve"
+	"eta_gn/eta_api/models/bi_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+func GetBiApproveMessage(adminId, startSize, pageSize int) (list []*response.BiApproveMessageItem, total, unread int, msg string, err error) {
+	cond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveMessageCols.ReceiveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := fmt.Sprintf(`%s ASC, %s DESC`, biapprove.BiApproveMessageCols.IsRead, biapprove.BiApproveMessageCols.CreateTime)
+
+	messageOb := new(biapprove.BiApproveMessage)
+	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 := FormatBiApproveMessage2Item(v)
+		list = append(list, t)
+	}
+
+	// 未读消息数
+	cond += fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveMessageCols.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(biapprove.BiApproveMessage)
+	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
+}
+
+// FormatBiApproveMessage2Item 格式化报告审批消息
+func FormatBiApproveMessage2Item(origin *biapprove.BiApproveMessage) (item *response.BiApproveMessageItem) {
+	item = new(response.BiApproveMessageItem)
+	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.BiApproveId = origin.BiApproveId
+	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/bi_approve/bi_approve_node.go

@@ -0,0 +1,31 @@
+package biapprove
+
+import (
+	"encoding/json"
+	biapprove "eta_gn/eta_api/models/bi_approve"
+	"eta_gn/eta_api/models/bi_approve/response"
+	"fmt"
+)
+
+// FormatBiApproveNode2Item 格式化报告审批节点信息
+func FormatBiApproveNode2Item(origin *biapprove.BiApproveNode) (item *response.BiApproveNodeItem, err error) {
+	if origin == nil {
+		return
+	}
+	item = new(response.BiApproveNodeItem)
+	item.BiApproveNodeId = origin.BiApproveNodeId
+	item.BiApproveFlowId = origin.BiApproveFlowId
+	item.PrevNodeId = origin.PrevNodeId
+	item.NextNodeId = origin.NextNodeId
+	item.NodeType = origin.NodeType
+	item.ApproveType = origin.ApproveType
+	item.Users = make([]*response.BiApproveNodeUser, 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
+}

+ 42 - 0
services/bi_approve/constant.go

@@ -0,0 +1,42 @@
+package biapprove
+
+// 看板状态
+const (
+	BiStateUnpublished = 1 // 未发布
+	BiStatePublished   = 2 // 已发布
+	BiStateWaitSubmit  = 3 // 待提交
+	BiStateWaitApprove = 4 // 审批中
+	BiStateRefused     = 5 // 已驳回
+	BiStatePass        = 6 // 已通过
+)
+
+// 看板操作
+const (
+	BiOperateAdd           = 1 // 新增报告
+	BiOperateEdit          = 2 // 编辑报告
+	BiOperatePublish       = 3 // 发布报告
+	BiOperateCancelPublish = 4 // 取消发布报告
+	BiOperateSubmitApprove = 5 // 提交审批
+	BiOperateCancelApprove = 6 // 撤回审批
+)
+
+// 节点审批方式
+const (
+	NodeApproveTypeRoll = 1 // 依次审批
+	NodeApproveTypeAll  = 2 // 会签
+	NodeApproveTypeAny  = 3 // 或签
+)
+
+// 节点审批人类型
+const (
+	NodeUserTypeNormal = "user" // 用户
+	NodeUserTypeRole   = "role" // 角色
+)
+
+// 报告审批状态
+const (
+	BiApproveStateApproving = 1 // 待审批
+	BiApproveStatePass      = 2 // 已审批
+	BiApproveStateRefuse    = 3 // 已驳回
+	BiApproveStateCancel    = 4 // 已撤销
+)

+ 22 - 95
services/classify.go

@@ -203,7 +203,7 @@ func AddReportClassify(classifyName string, parentId int, chartPermissionIdList
 		}
 		return
 	}
-	if item != nil {
+	if item != nil && item.Id > 0 {
 		errMsg = "分类名称:" + classifyName + "已存在"
 		isSendEmail = false
 		err = errors.New(errMsg)
@@ -269,85 +269,12 @@ func AddReportClassify(classifyName string, parentId int, chartPermissionIdList
 	classify.ReportDetailShowType = 1 //默认列表格式
 	classify.IsShow = 1
 	classify.Level = level
-	/*classify.Abstract = req.Abstract
-	classify.Descript = req.Descript
-	classify.Abstract = req.Abstract
-	classify.Descript = req.Descript
-	classify.ReportAuthor = req.ReportAuthor
-	classify.AuthorDescript = req.AuthorDescript
-	classify.ColumnImgUrl = req.ColumnImgUrl
-	classify.ReportImgUrl = req.ReportImgUrl
-	classify.HeadImgUrl = req.HeadImgUrl
-	classify.AvatarImgUrl = req.AvatarImgUrl
-	classify.HomeImgUrl = req.HomeImgUrl
-	classify.ClassifyLabel = req.ClassifyLabel
-	classify.ShowType = req.ShowType
-	classify.HasTeleconference = req.HasTeleconference
-	classify.VipTitle = req.VipTitle
-
-	classify.IsShow = req.IsShow
-	classify.YbFiccSort = req.YbFiccSort
-	classify.YbFiccIcon = req.YbFiccIcon
-	classify.YbFiccPcIcon = req.YbFiccPcIcon
-	classify.YbIconUrl = req.YbIconUrl
-	classify.YbBgUrl = req.YbBgUrl
-	classify.YbListImg = req.YbListImg
-	classify.YbShareBgImg = req.YbShareBgImg
-	classify.YbRightBanner = req.YbRightBanner
-	classify.RelateTel = req.RelateTel
-	classify.RelateVideo = req.RelateVideo
-	if req.ParentId > 0 {
-		parentClassify := new(models.Classify)
-		if parentClassify, err = models.GetClassifyById(req.ParentId); err != nil {
-			br.Msg = "获取父级分类信息失败"
-			br.ErrMsg = "获取父级分类信息失败, Err:" + err.Error()
-			return
-		}
-		updateParent := false
-		updateCols := make([]string, 0)
-		updateCols = append(updateCols, "HasTeleconference")
-		if req.HasTeleconference == 1 {
-			// 二级分类包含电话会,则一级分类也默认包含电话会
-			if parentClassify.HasTeleconference == 0 {
-				parentClassify.HasTeleconference = 1
-				updateParent = true
-			}
-		} else {
-			// 二级分类均无电话会,则一级分类也无电话会
-			if parentClassify.HasTeleconference == 1 {
-				child, err := models.GetClassifyChild(parentClassify.Id, "")
-				if err != nil {
-					br.Msg = "获取子分类失败"
-					br.ErrMsg = "获取子分类失败,Err:" + err.Error()
-					return
-				}
-				// 存在同一级分类下的二级分类有电话会则不变动
-				hasTel := false
-				for i := 0; i < len(child); i++ {
-					if child[i].HasTeleconference == 1 {
-						hasTel = true
-						break
-					}
-				}
-				if !hasTel {
-					parentClassify.HasTeleconference = 0
-					updateParent = true
-				}
-			}
-		}
-		if updateParent {
-			if err = parentClassify.UpdateClassify(updateCols); err != nil {
-				br.Msg = "更新父级分类失败"
-				br.ErrMsg = "更新父级分类失败, Err:" + err.Error()
-				return
-			}
-		}
-	}*/
+
 	err = models.AddClassify(classify)
 	if err != nil {
 		return
 	}
-
+	/* 国能补充需求调整
 	//获取报告分类权限列表
 	err = models.EditChartPermissionSearchKeyWordMappingMulti(classifyName, chartPermissionIdList, classify.Id)
 	if err != nil {
@@ -358,7 +285,7 @@ func AddReportClassify(classifyName string, parentId int, chartPermissionIdList
 	// 修改CRM权限
 	go func() {
 		_ = EditClassifyChartPermissionSync(classifyName, classify.Id)
-	}()
+	}()*/
 
 	// 如果父级分类不为空的话,那么就标记有子级分类,同时
 	if parentClassifyItem != nil {
@@ -704,7 +631,7 @@ func EditReportClassify(classifyId int, classifyName string, chartPermissionIdLi
 		}
 		return
 	}
-	originName := item.ClassifyName
+	//originName := item.ClassifyName
 
 	// 重名校验
 	existName, e := models.GetClassifyByName(classifyName, item.ParentId)
@@ -730,23 +657,23 @@ func EditReportClassify(classifyId int, classifyName string, chartPermissionIdLi
 	if err != nil {
 		return
 	}
-
-	err = models.EditChartPermissionSearchKeyWordMappingMulti(item.ClassifyName, chartPermissionIdList, item.Id)
-	if err != nil {
-		errMsg = "修改分类权限失败"
-		return
-	}
-
-	// 修改CRM权限
-	go func() {
-		_ = EditClassifyChartPermissionSync(item.ClassifyName, item.Id)
-	}()
-
-	// TODO 修改分类的关联品种时,历史报告中关联的品种怎么处理?
-	// 更新报告分类名称/父级分类后
-	go func() {
-		_ = AfterUpdateClassifyNameOrParent(item.Id, item.ParentId, item.ParentId, originName, item.ClassifyName, item.Level)
-	}()
+	/* 	国能补充需求调整
+	   	err = models.EditChartPermissionSearchKeyWordMappingMulti(item.ClassifyName, chartPermissionIdList, item.Id)
+	   	if err != nil {
+	   		errMsg = "修改分类权限失败"
+	   		return
+	   	}
+
+	   	// 修改CRM权限
+	   	go func() {
+	   		_ = EditClassifyChartPermissionSync(item.ClassifyName, item.Id)
+	   	}()
+
+	   	// TODO 修改分类的关联品种时,历史报告中关联的品种怎么处理?
+	   	// 更新报告分类名称/父级分类后
+	   	go func() {
+	   		_ = AfterUpdateClassifyNameOrParent(item.Id, item.ParentId, item.ParentId, originName, item.ClassifyName, item.Level)
+	   	}()*/
 
 	return
 }

+ 1 - 1
services/data/chart_classify.go

@@ -475,7 +475,7 @@ func MoveChartClassify(req data_manage.MoveChartClassifyReq, sysUser *system.Adm
 			err = fmt.Errorf("获取父级分类下的同名分类失败, Err: %s", e.Error())
 			return
 		}
-		if exists != nil {
+		if exists != nil && exists.ChartClassifyId > 0 {
 			errMsg = "移动失败,分类名称已存在"
 			return
 		}

+ 20 - 18
services/report_v2.go

@@ -798,26 +798,28 @@ func EditChapterBaseInfoAndPermission(reportInfo *models.Report, reportChapterIn
 			delChapterPermissionMap[v.ChartPermissionId] = v
 		}
 
-		for _, permissionId := range permissionIdList {
-			_, ok := currChapterPermissionMap[permissionId]
-			// 如果存在,那么从 “需要删除的报告章节品种权限配置” 的map中移除
-			if ok {
-				delete(delChapterPermissionMap, permissionId)
-				continue
+		// 国能补充需求调整
+		/*
+			for _, permissionId := range permissionIdList {
+				_, ok := currChapterPermissionMap[permissionId]
+				// 如果存在,那么从 “需要删除的报告章节品种权限配置” 的map中移除
+				if ok {
+					delete(delChapterPermissionMap, permissionId)
+					continue
+				}
+				// 如果不存在,那么就新增品种权限配置
+				addChapterPermissionList = append(addChapterPermissionList, &report.ReportChapterPermissionMapping{
+					//ReportChapterPermissionMappingId:         0,
+					ReportChapterId:   reportChapterInfo.ReportChapterId,
+					ChartPermissionId: permissionId,
+					CreateTime:        time.Now(),
+				})
 			}
-			// 如果不存在,那么就新增品种权限配置
-			addChapterPermissionList = append(addChapterPermissionList, &report.ReportChapterPermissionMapping{
-				//ReportChapterPermissionMappingId:         0,
-				ReportChapterId:   reportChapterInfo.ReportChapterId,
-				ChartPermissionId: permissionId,
-				CreateTime:        time.Now(),
-			})
-		}
 
-		// 查出需要移除的品种权限配置
-		for _, v := range delChapterPermissionMap {
-			delChapterPermissionMappingIdList = append(delChapterPermissionMappingIdList, v.ReportChapterPermissionMappingId)
-		}
+			// 查出需要移除的品种权限配置
+			for _, v := range delChapterPermissionMap {
+				delChapterPermissionMappingIdList = append(delChapterPermissionMappingIdList, v.ReportChapterPermissionMappingId)
+			}*/
 	}
 
 	err = models.EditChapterBaseInfoAndPermission(reportInfo, reportChapterInfo, updateCols, addChapterAdminList, addChapterPermissionList, delReportChapterGrantIdList, delChapterPermissionMappingIdList)

+ 6 - 5
utils/common.go

@@ -1382,11 +1382,12 @@ func GetReportContentTextSub(content string) (contentSub string, err error) {
 
 // GetOrmInReplace 获取orm的in查询替换?的方法
 func GetOrmInReplace(num int) string {
-	template := make([]string, num)
-	for i := 0; i < num; i++ {
-		template[i] = "?"
-	}
-	return strings.Join(template, ",")
+	//template := make([]string, num)
+	//for i := 0; i < num; i++ {
+	//	template[i] = "?"
+	//}
+	//return strings.Join(template, ",")
+	return "?"
 }
 
 // RevSlice 反转切片

+ 16 - 15
utils/constants.go

@@ -6,21 +6,22 @@ import (
 
 // 常量定义
 const (
-	FormatTime                 = "15:04:05"                //时间格式
-	FormatTimeHm               = "15:04"                   //时间格式
-	FormatDate                 = "2006-01-02"              //日期格式
-	FormatDateUnSpace          = "20060102"                //日期格式
-	FormatDateTime             = "2006-01-02 15:04:05"     //完整时间格式
-	HlbFormatDateTime          = "2006-01-02_15:04:05.999" //完整时间格式
-	FormatDateTimeUnSpace      = "20060102150405"          //完整时间格式
-	FormatShortDateTimeUnSpace = "060102150405"            //省去开头两位年份的时间格式
-	EmptyDateTimeStr           = "0000-00-00 00:00:00"     //DateTime零值字符串
-	EmptyDateStr               = "0000-00-00"              //Date零值字符串
-	FormatMonthDayUnSpace      = "0102"                    //日期格式
-	FormatMonthDay             = "01-02"                   //日期格式
-	FormatYearMonthDate        = "2006-01"                 //日期格式
-	FormatYearDate             = "2006"                    //日期格式
-	PageSize15                 = 15                        //列表页每页数据量
+	FormatTime                 = "15:04:05"                  //时间格式
+	FormatTimeHm               = "15:04"                     //时间格式
+	FormatDate                 = "2006-01-02"                //日期格式
+	FormatDateWallWithLoc      = "2006-01-02T15:04:05-07:00" //日期格式
+	FormatDateUnSpace          = "20060102"                  //日期格式
+	FormatDateTime             = "2006-01-02 15:04:05"       //完整时间格式
+	HlbFormatDateTime          = "2006-01-02_15:04:05.999"   //完整时间格式
+	FormatDateTimeUnSpace      = "20060102150405"            //完整时间格式
+	FormatShortDateTimeUnSpace = "060102150405"              //省去开头两位年份的时间格式
+	EmptyDateTimeStr           = "0000-00-00 00:00:00"       //DateTime零值字符串
+	EmptyDateStr               = "0000-00-00"                //Date零值字符串
+	FormatMonthDayUnSpace      = "0102"                      //日期格式
+	FormatMonthDay             = "01-02"                     //日期格式
+	FormatYearMonthDate        = "2006-01"                   //日期格式
+	FormatYearDate             = "2006"                      //日期格式
+	PageSize15                 = 15                          //列表页每页数据量
 	PageSize5                  = 5
 	PageSize10                 = 10
 	PageSize20                 = 20