Browse Source

Merge branch 'bzq/knowledge_add_viewpoint'

hsun 1 month ago
parent
commit
60e17845c2
34 changed files with 4185 additions and 116 deletions
  1. 199 19
      controllers/knowledge/resource.go
  2. 11 5
      controllers/knowledge/tag.go
  3. 505 0
      controllers/knowledge_approve/knowledge_approve.go
  4. 305 0
      controllers/knowledge_approve/knowledge_approve_flow.go
  5. 18 2
      controllers/message.go
  6. 1 0
      controllers/ppt_report.go
  7. 32 6
      controllers/ppt_v2.go
  8. 145 17
      models/knowledge/knowledge_resource.go
  9. 33 0
      models/knowledge/knowledge_resource_file.go
  10. 3 3
      models/knowledge/knowledge_tag.go
  11. 203 0
      models/knowledge_approve/knowledge_approve.go
  12. 184 0
      models/knowledge_approve/knowledge_approve_flow.go
  13. 115 0
      models/knowledge_approve/knowledge_approve_message.go
  14. 90 0
      models/knowledge_approve/knowledge_approve_node.go
  15. 152 0
      models/knowledge_approve/knowledge_approve_record.go
  16. 21 0
      models/knowledge_approve/request/knowledge_approve.go
  17. 23 0
      models/knowledge_approve/request/knowledge_approve_flow.go
  18. 5 0
      models/knowledge_approve/request/knowledge_approve_message.go
  19. 90 0
      models/knowledge_approve/response/knowledge_approve.go
  20. 46 0
      models/knowledge_approve/response/knowledge_approve_flow.go
  21. 24 0
      models/knowledge_approve/response/knowledge_approve_message.go
  22. 17 6
      models/ppt_v2.go
  23. 31 31
      models/system/sys_user.go
  24. 144 0
      routers/commentsRouter.go
  25. 7 0
      routers/router.go
  26. 61 2
      services/knowledge/es.go
  27. 80 12
      services/knowledge/resource.go
  28. 30 0
      services/knowledge_approve/constant.go
  29. 1171 0
      services/knowledge_approve/knowledge_approve.go
  30. 300 0
      services/knowledge_approve/knowledge_approve_flow.go
  31. 90 0
      services/knowledge_approve/knowledge_approve_message.go
  32. 31 0
      services/knowledge_approve/knowledge_approve_node.go
  33. 3 1
      services/report_outer.go
  34. 15 12
      services/report_v2.go

+ 199 - 19
controllers/knowledge/resource.go

@@ -6,7 +6,8 @@ import (
 	"eta_gn/eta_api/models"
 	"eta_gn/eta_api/models/knowledge"
 	"eta_gn/eta_api/services"
-	knowledgeServ "eta_gn/eta_api/services/knowledge"
+	knowledgeSrv "eta_gn/eta_api/services/knowledge"
+	"eta_gn/eta_api/services/knowledge_approve"
 	"eta_gn/eta_api/utils"
 	"fmt"
 	"html"
@@ -37,13 +38,14 @@ type ResourceController struct {
 // @Param   EndDate   query   string  true       "结束时间"
 // @Param   Frequency   query   string  true       "频度"
 // @Param   ClassifyIds   query   int  true       "分类id, 多选, 英文逗号分隔"
-// @Param   State   query   int  true       "状态"
+// @Param   State   query   string  true       "状态, 多选, 英文逗号分隔"
 // @Param   KeyWord   query   string  true       "搜索关键词"
 // @Param   PublishSort   query   string  true       "desc:降序,asc 升序(预留)"
 // @Param   FilterReportType   query   string  true       "筛选事件类型,1:公共研报,2:共享研报,3:我的研报"
 // @Param   IncludeFile   query   string  true       "是否包含文件, no:不包含"
 // @Param   SourceFrom   query   string  true       "来源, 用英文逗号分隔"
 // @Param   IsShowMe   query   string  true       "只看我, false:全部, true:只看我"
+// @Param   IsShowPublic   query   string  true       "只看我, false:全部, true:只看发布"
 // @Success 200 {object} knowledge.KnowledgeResourceListResp
 // @router /resource/list [get]
 func (this *ResourceController) List() {
@@ -56,6 +58,9 @@ func (this *ResourceController) List() {
 	currentIndex, _ := this.GetInt("CurrentIndex")
 
 	classifyIds := this.GetString("ClassifyIds")
+
+	state := this.GetString("State")
+
 	// 添加人
 	addUserIds, _ := this.GetInt("SysUserIds")
 	// 标签
@@ -70,6 +75,18 @@ func (this *ResourceController) List() {
 
 	IsShowMe, _ := this.GetBool("IsShowMe")
 
+	isShowPublic, _ := this.GetBool("IsShowPublic")
+	publishSort := this.GetString("PublishSort")
+
+	var sortCond string
+
+	switch publishSort {
+	case "desc":
+		sortCond = ` ORDER BY start_time DESC `
+	case "asc":
+		sortCond = ` ORDER BY start_time ASC `
+	}
+
 	var startSize int
 	if pageSize <= 0 {
 		pageSize = utils.PageSize20
@@ -93,6 +110,16 @@ func (this *ResourceController) List() {
 		condition += ` AND admin_id = ? `
 		pars = append(pars, this.SysUser.AdminId)
 	}
+	if state != "" {
+		stateArr := strings.Split(state, ",")
+		condition += ` AND state in (?) `
+		pars = append(pars, stateArr)
+	}
+
+	if isShowPublic {
+		condition += ` AND state = ? `
+		pars = append(pars, knowledge.KnowledgeResourceStatePassed)
+	}
 
 	if keyWord != "" {
 		//按照空格划分为关键词数组
@@ -165,7 +192,7 @@ func (this *ResourceController) List() {
 		br.ErrMsg = "获取失败,Err:" + err.Error()
 		return
 	}
-	listTmp, err := knowledge.GetKnowledgeResourcePageList(condition, pars, startSize, pageSize)
+	listTmp, err := knowledge.GetKnowledgeResourcePageList(condition, pars, sortCond, startSize, pageSize)
 	if err != nil {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取失败,Err:" + err.Error()
@@ -216,13 +243,13 @@ func (this *ResourceController) List() {
 		var startTime, endTime string
 		if v.StartTime != nil && !v.StartTime.IsZero() {
 			startTime = v.StartTime.In(time.Local).Format(utils.FormatDateTime)
-			if resourceType == knowledge.KnowledgeResourceTypeOpinion || resourceType == knowledge.KnowledgeResourceTypeKnow {
+			if resourceType == knowledge.KnowledgeResourceTypeReport || resourceType == knowledge.KnowledgeResourceTypeKnow || resourceType == knowledge.KnowledgeResourceTypeOpinion {
 				startTime = v.StartTime.In(time.Local).Format(utils.FormatDate)
 			}
 		}
 		if v.EndTime != nil && !v.EndTime.IsZero() {
 			endTime = v.EndTime.In(time.Local).Format(utils.FormatDateTime)
-			if resourceType == knowledge.KnowledgeResourceTypeOpinion || resourceType == knowledge.KnowledgeResourceTypeKnow {
+			if resourceType == knowledge.KnowledgeResourceTypeReport || resourceType == knowledge.KnowledgeResourceTypeKnow {
 				endTime = v.EndTime.In(time.Local).Format(utils.FormatDate)
 			}
 		}
@@ -243,6 +270,7 @@ func (this *ResourceController) List() {
 			TagId:               v.TagId,
 			StartTime:           startTime,
 			EndTime:             endTime,
+			OutSource:           v.OutSource,
 		}
 
 		// todo 编辑状态
@@ -296,6 +324,7 @@ func (this *ResourceController) List() {
 // @Param   IncludeFile   query   string  true       "是否包含文件, no:不包含"
 // @Param   SourceFrom   query   string  true       "来源, 用英文逗号分隔"
 // @Param   IsShowMe   query   string  true       "只看我, false:全部, true:只看我"
+// @Param   IsQueryRef   query   string  true       "是否查询引用, false:否, true: 是"
 // @Success 200 {object} knowledge.KnowledgeResourceListResp
 // @router /resource/search_by_es [get]
 func (this *ResourceController) Search() {
@@ -320,7 +349,9 @@ func (this *ResourceController) Search() {
 
 	includeFile := this.GetString("IncludeFile")
 
-	IsShowMe, _ := this.GetBool("IsShowMe")
+	isShowMe, _ := this.GetBool("IsShowMe")
+
+	isQueryRef, _ := this.GetBool("IsQueryRef")
 
 	var startSize int
 	if pageSize <= 0 {
@@ -346,7 +377,11 @@ func (this *ResourceController) Search() {
 		}
 	}
 	var myId int
-	if IsShowMe {
+	if isShowMe {
+		myId = this.SysUser.AdminId
+	}
+
+	if isQueryRef {
 		myId = this.SysUser.AdminId
 	}
 
@@ -372,7 +407,7 @@ func (this *ResourceController) Search() {
 			tagIdsInt = append(tagIdsInt, tagId)
 		}
 	}
-	listTmp, total, err := knowledgeServ.SearchKnowledgeResourceByEs(
+	listTmp, total, err := knowledgeSrv.SearchKnowledgeResourceByEs(
 		resourceType,
 		keyWord,
 		searchUserIds,
@@ -380,7 +415,9 @@ func (this *ResourceController) Search() {
 		classifyIdsInt,
 		sourceFromArr,
 		tagIdsInt,
+		isShowMe,
 		isIncludeFile,
+		isQueryRef,
 		startSize,
 		pageSize,
 	)
@@ -560,14 +597,14 @@ func (this *ResourceController) Add() {
 			br.IsSendEmail = false
 			return
 		}
-		if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy {
+		if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy || req.ResourceType == knowledge.KnowledgeResourceTypeOpinion {
 			if req.StartTime == "" {
 				br.Msg = "开始时间必填"
 				br.ErrMsg = "开始时间必填"
 				return
 			}
 		}
-		_, err, errMsg := knowledgeServ.AddResource(&req, sysUser)
+		_, err, errMsg := knowledgeSrv.AddResource(&req, sysUser)
 		if err != nil {
 			br.Msg = "保存失败"
 			if errMsg != "" {
@@ -637,7 +674,7 @@ func (this *ResourceController) Edit() {
 		return
 	}
 
-	if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy {
+	if req.ResourceType == knowledge.KnowledgeResourceTypeEvent || req.ResourceType == knowledge.KnowledgeResourceTypePolicy || req.ResourceType == knowledge.KnowledgeResourceTypeOpinion {
 		if req.StartTime == "" {
 			br.Msg = "开始时间必填"
 			br.ErrMsg = "开始时间必填"
@@ -673,7 +710,7 @@ func (this *ResourceController) Edit() {
 	}
 
 	// 编辑事件信息
-	err, errMsg := knowledgeServ.EditResource(resourceInfo, req, sysUser)
+	err, errMsg := knowledgeSrv.EditResource(resourceInfo, req, sysUser)
 	if err != nil {
 		br.Msg = "保存失败"
 		if errMsg != "" {
@@ -742,10 +779,45 @@ func (this *ResourceController) Detail() {
 		br.Msg = "事件类型错误"
 		return
 	}
+	knowledgeItem := new(knowledge.KnowledgeResourceDetail)
+	var urls []string
+	if item.IsFile == 1 {
+		if item.FileUrl == "" {
+			fileObj := new(knowledge.KnowledgeResourceFile)
+			fileItem, err := fileObj.GetByResourceId(item.KnowledgeResourceId)
+			if err != nil {
+				br.Msg = "获取失败"
+				br.ErrMsg = "获取失败,Err:" + err.Error()
+				return
+			}
+			for _, v := range fileItem {
+				urls = append(urls, v.FileUrl)
+			}
+		} else {
+			urls = append(urls, item.FileUrl)
+		}
+	}
 	item.Content = html.UnescapeString(item.Content)
+	knowledgeItem.KnowledgeResourceId = item.KnowledgeResourceId
+	knowledgeItem.ResourceType = item.ResourceType
+	knowledgeItem.ClassifyId = item.ClassifyId
+	knowledgeItem.Title = item.Title
+	knowledgeItem.CreateTime = item.CreateTime
+	knowledgeItem.ModifyTime = item.ModifyTime
+	knowledgeItem.State = item.State
+	knowledgeItem.Content = item.Content
+	knowledgeItem.ResourceCode = item.ResourceCode
+	knowledgeItem.AdminId = item.AdminId
+	knowledgeItem.AdminRealName = item.AdminRealName
+	knowledgeItem.SourceFrom = item.SourceFrom
+	knowledgeItem.TagId = item.TagId
+	knowledgeItem.StartTime = item.StartTime
+	knowledgeItem.EndTime = item.EndTime
+	knowledgeItem.IsFile = item.IsFile
+	knowledgeItem.FileUrl = urls
 
 	resp := &knowledge.KnowledgeResourceDetailView{
-		KnowledgeResource: item,
+		KnowledgeResourceDetail: knowledgeItem,
 	}
 	br.Ret = 200
 	br.Success = true
@@ -1054,7 +1126,7 @@ func (this *ResourceController) Delete() {
 	}
 	go func() {
 		item.IsDelete = 1
-		er := knowledgeServ.EsAddOrEditKnowledgeResource(item)
+		er := knowledgeSrv.EsAddOrEditKnowledgeResource(item)
 		if er != nil {
 			utils.FileLog.Info("知识资源id:" + strconv.Itoa(req.KnowledgeResourceId) + ",删除事件同步es失败, Err: " + er.Error())
 		}
@@ -1101,7 +1173,7 @@ func (c *ResourceController) ImportData() {
 	defer os.Remove(path)
 	//}
 
-	successCount, failCount, err, errMsg := knowledgeServ.ImportResourceData(path, resourceType, sysUser)
+	successCount, failCount, err, errMsg := knowledgeSrv.ImportResourceData(path, resourceType, sysUser)
 	if err != nil {
 		br.Msg = errMsg
 		br.ErrMsg = err.Error()
@@ -1421,12 +1493,12 @@ func (this *ResourceController) TemplateDownload() {
 	case 1:
 		downUrl = "./static/template/政策库上传模板.xlsx"
 		fileName = "政策库上传模板.xlsx"
-	case 2:
-		downUrl = "./static/template/观点库上传模板.xlsx"
-		fileName = "观点库上传模板.xlsx"
 	case 3:
 		downUrl = "./static/template/知识库上传模板.xlsx"
 		fileName = "知识库上传模板.xlsx"
+	case 4:
+		downUrl = "./static/template/观点库上传模板.xlsx"
+		fileName = "观点库上传模板.xlsx"
 	default:
 		downUrl = "./static/template/事件库上传模板.xlsx"
 		fileName = "事件库上传模板.xlsx"
@@ -1445,6 +1517,114 @@ func (this *ResourceController) TemplateDownload() {
 	br.Msg = "下载成功"
 }
 
+// cancel
+// @Title 设置知识库事件公开接口
+// @Description 设置知识库事件公开接口
+// @Param	request	body knowledge.AddReq true "type json string"
+// @Success 200 {object} knowledge.AddResp
+// @router /resource/cancel [post]
+func (this *ResourceController) Cancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+	var req knowledge.PublicReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+
+	approveId, err := knowledge_approve.GetKnowledgeApproveIdByKnowledgeResourceId(req.KnowledgeResourceId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			br.Msg = "该知识库事件未发起审批"
+			return
+		}
+		br.Msg = "获取审批记录失败"
+		br.ErrMsg = "获取审批记录失败,Err:" + err.Error()
+		return
+	}
+
+	msg, err := knowledge_approve.KnowledgeResourceApproveCancel(approveId, sysUser.AdminId, sysUser.RealName)
+	if err != nil {
+		if msg == "" {
+			msg = "设置失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = "设置失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "设置成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// Public
+// @Title 设置知识库事件公开接口
+// @Description 设置知识库事件公开接口
+// @Param	request	body knowledge.AddReq true "type json string"
+// @Success 200 {object} knowledge.AddResp
+// @router /resource/public [post]
+func (this *ResourceController) Public() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请重新登录"
+		return
+	}
+	var req knowledge.PublicReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败,Err:" + e.Error()
+		return
+	}
+	obj := new(knowledge.KnowledgeResource)
+	obj, err := obj.GetById(req.KnowledgeResourceId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			br.Msg = "该知识库事件不存在"
+			return
+		}
+		br.Msg = "获取知识库事件失败"
+		br.ErrMsg = "获取知识库事件失败,Err:" + err.Error()
+		return
+	}
+	_, msg, err := knowledge_approve.SubmitKnowledgeResourceApprove(obj.KnowledgeResourceId, obj.Title, obj.ClassifyId, sysUser.AdminId, sysUser.RealName)
+	if err != nil {
+		if msg == "" {
+			msg = "设置公共失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = "设置公共失败,Err:" + err.Error()
+		return
+	}
+	msg, err = knowledgeSrv.SetKnowledgeResourcePublic(req.KnowledgeResourceId)
+	if err != nil {
+		if msg == "" {
+			msg = "设置公共失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = "设置失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "设置成功"
+	br.Ret = 200
+	br.Success = true
+}
+
 // BiDashboardTmpResourceList
 // @Title 获取bi看报中的知识资源列表
 // @Description 获取bi看报中的知识资源列表
@@ -1460,7 +1640,7 @@ func (this *ResourceController) BiDashboardCacheResourceList() {
 
 	biDashboardDetailId, _ := this.GetInt("BiDashboardDetailId")
 
-	resp, msg, err := knowledgeServ.GetKnowledgeResourceTmpList(biDashboardDetailId, this.SysUser.AdminId)
+	resp, msg, err := knowledgeSrv.GetKnowledgeResourceTmpList(biDashboardDetailId, this.SysUser.AdminId)
 	if err != nil {
 		if msg == "" {
 			msg = "获取数据失败"

+ 11 - 5
controllers/knowledge/tag.go

@@ -7,6 +7,7 @@ import (
 	"eta_gn/eta_api/models/knowledge"
 	knowledgeServ "eta_gn/eta_api/services/knowledge"
 	"eta_gn/eta_api/utils"
+	"fmt"
 )
 
 // 标签
@@ -77,10 +78,7 @@ func (this *TagController) Delete() {
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
-	//todo 删除标签时,是否需要检测,标签下是否有事件
-	/*br.Msg = "报告标签不允许删除"
-	br.IsSendEmail = false
-	return*/
+
 	knowledgeObj := new(knowledge.KnowledgeTag)
 	item, err := knowledgeObj.GetTagById(req.TagId)
 	if err != nil {
@@ -99,6 +97,14 @@ func (this *TagController) Delete() {
 		return
 	}
 
+	// 取消标签的关联
+	resourceOb := new(knowledge.KnowledgeResource)
+	if e := resourceOb.RemoveTagRelateByTagId(req.TagId); e != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = fmt.Sprintf("移除事件标签关联失败, %v", e)
+		return
+	}
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "删除成功"
@@ -133,7 +139,7 @@ func (this *TagController) Edit() {
 	}
 
 	// 修改标签
-	err, errMsg, isSentEmail := knowledgeServ.EditKnowledgeTag(req.TagId, req.ParentId, req.TagName)
+	err, errMsg, isSentEmail := knowledgeServ.EditKnowledgeTag(req.TagId, req.ResourceType, req.TagName)
 	if err != nil {
 		br.Msg = "修改失败"
 		if errMsg != "" {

+ 505 - 0
controllers/knowledge_approve/knowledge_approve.go

@@ -0,0 +1,505 @@
+package knowledge_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/knowledge"
+	"eta_gn/eta_api/models/knowledge_approve/request"
+	"eta_gn/eta_api/models/knowledge_approve/response"
+	"eta_gn/eta_api/services/knowledge_approve"
+	"eta_gn/eta_api/utils"
+	"fmt"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type KnowledgeApproveController 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.KnowledgeResourceApproveListResp
+// @router /list [get]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApproveItemOrmResp
+	var total int
+	var msg string
+	var err error
+
+	classifyList, msg, err := knowledge_approve.GetKnowledgeClassifyAll()
+	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.ClassifyId] = v.ClassifyName
+	}
+
+	switch listType {
+	case 1:
+		list, total, msg, err = knowledge_approve.ProcessingKnowledgeResourceApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 2:
+		list, total, msg, err = knowledge_approve.SolvedKnowledgeResourceApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
+	case 3:
+		list, total, msg, err = knowledge_approve.MyApplyKnowledgeResourceApproves(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.KnowledgeResourceApproveListResp)
+	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} []*knowledge.KnowledgeClassifyItem
+// @router /classify/list [get]
+func (this *KnowledgeApproveController) ClassifyList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	res, msg, err := knowledge_approve.GetPulicKnowledgeClassifyList(knowledge.KnowledgeResourceTypeOpinion)
+	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 request.KnowledgeResourceApprovePassReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /approve [post]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApprovePassReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.KnowledgeResourceApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, KnowledgeResourceApproveId: %d", req.KnowledgeResourceApproveId)
+		return
+	}
+
+	// 通过审批
+	msg, err := knowledge_approve.PassKnowledgeResourceApprove(req.KnowledgeResourceApproveId, 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   KnowledgeResourceApproveId  query  int  true  "审批ID"
+// @Success 200 {object} report_approve.KnowledgeResourceApproveDetail
+// @router /detail [get]
+func (this *KnowledgeApproveController) 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("KnowledgeResourceApproveId")
+	if approveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, KnowledgeResourceApproveId: %d", approveId)
+		return
+	}
+
+	resp, msg, err := knowledge_approve.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.KnowledgeResourceApproveRefuseReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /refuse [post]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApproveRefuseReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.KnowledgeResourceApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, KnowledgeResourceApproveId: %d", req.KnowledgeResourceApproveId)
+		return
+	}
+	maxStrLen := 500
+	approvelen := len([]rune(req.ApproveRemark))
+	if approvelen > maxStrLen {
+		br.Msg = fmt.Sprintf("审批驳回原因不能超过%d字", maxStrLen)
+		return
+	}
+	msg, err := knowledge_approve.KnowledgeResourceApproveRefuse(req.KnowledgeResourceApproveId, 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.KnowledgeResourceApproveCancelReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /cancel [post]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApproveCancelReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.KnowledgeResourceApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, KnowledgeResourceApproveId: %d", req.KnowledgeResourceApproveId)
+		return
+	}
+
+	// 撤销审批
+	msg, e := knowledge_approve.KnowledgeResourceApproveCancel(req.KnowledgeResourceApproveId, 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.KnowledgeResourceApproveMessageListResp
+// @router /message/list [get]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApproveMessageListResp)
+	list, total, unRead, msg, err := knowledge_approve.GetKnowledgeResourceApproveMessage(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.KnowledgeResourceApproveMessageReadReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /message/read [post]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApproveMessageReadReq
+	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 := knowledge_approve.ReadKnowledgeMessage(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.KnowledgeResourceApproveCheckApproveOpenReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /classify/check_open [post]
+func (this *KnowledgeApproveController) 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.KnowledgeResourceApproveCheckApproveOpenReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	// 校验是否开启了审批流
+	opening, e := knowledge_approve.CheckKnowledgeOpenApprove(req.ClassifyId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验报告是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	br.Data = opening
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 305 - 0
controllers/knowledge_approve/knowledge_approve_flow.go

@@ -0,0 +1,305 @@
+package knowledge_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/controllers"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/knowledge_approve/request"
+	"eta_gn/eta_api/models/knowledge_approve/response"
+	"eta_gn/eta_api/services/knowledge_approve"
+	"eta_gn/eta_api/utils"
+	"strings"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type KnowledgeApproveFlowController 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 *KnowledgeApproveFlowController) 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"}
+	if sortRule == 0 {
+		sortRule = 2
+	}
+	condition += " ORDER BY create_time " + orderMap[sortRule]
+
+	res, total, msg, err := knowledge_approve.GetKnowledgeResourceApproveFlowList(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.KnowledgeResourceApproveFlowListResp)
+	resp.List = res
+	resp.Paging = page
+
+	br.Data = resp
+	br.Msg = "获取审批流列表成功"
+	br.Success = true
+	br.Ret = 200
+}
+
+// Add
+// @Title 新增审批流
+// @Description 新增审批流
+// @Param	request	body request.KnowledgeResourceApproveFlowSaveReq true "type json string"
+// @Success 200
+// @router /flow/add [post]
+func (c *KnowledgeApproveFlowController) Add() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.KnowledgeResourceApproveFlowSaveReq
+	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.KnowledgeResourceApproveFlowId > 0 {
+		br.Msg = "审批流已存在"
+		return
+	}
+
+	_, msg, err := knowledge_approve.SaveKnowledgeResourceApproveFlow(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.KnowledgeResourceApproveFlowSaveReq true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/edit [post]
+func (c *KnowledgeApproveFlowController) Edit() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.KnowledgeResourceApproveFlowSaveReq
+	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.KnowledgeResourceApproveFlowId == 0 {
+		br.Msg = "审批流不存在, 请刷新重试"
+		return
+	}
+
+	ok, msg, err := knowledge_approve.SaveKnowledgeResourceApproveFlow(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.KnowledgeResourceApproveFlowRemoveReq true "type json string"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/remove [post]
+func (c *KnowledgeApproveFlowController) Remove() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+	var req *request.KnowledgeResourceApproveFlowRemoveReq
+	if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil {
+		br.Msg = "参数解析失败"
+		br.ErrMsg = "参数解析失败, err:" + err.Error()
+		return
+	}
+	if req.KnowledgeResourceApproveFlowId <= 0 {
+		br.Msg = "审批流不存在, 请刷新重试"
+		return
+	}
+	ok, msg, err := knowledge_approve.DeleteKnowledgeResourceApproveFlow(req.KnowledgeResourceApproveFlowId)
+	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	KnowledgeResourceApproveFlowId   query	int   true "看板审批流ID"
+// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @router /flow/detail [get]
+func (c *KnowledgeApproveFlowController) 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("KnowledgeResourceApproveFlowId")
+	if flowId <= 0 {
+		br.Msg = "审批流不存在"
+		return
+	}
+	detail, msg, err := knowledge_approve.GetKnowledgeResourceApproveFlowDetail(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 = "获取审批流详情成功"
+}

+ 18 - 2
controllers/message.go

@@ -4,6 +4,7 @@ import (
 	"eta_gn/eta_api/models"
 	biapprove "eta_gn/eta_api/models/bi_approve"
 	"eta_gn/eta_api/models/data_manage/data_manage_permission"
+	"eta_gn/eta_api/models/knowledge_approve"
 	"fmt"
 )
 
@@ -35,7 +36,7 @@ func (c *MessageController) UnReadMessageNum() {
 		return
 	}
 
-	var unReadReportNum, unReadDataPermissionNum, unReadBiNum int
+	var unReadReportNum, unReadDataPermissionNum, unReadBiNum, unReadKnowledgeNum int
 
 	// 获取报告审批消息(废弃)
 	//{
@@ -107,9 +108,24 @@ func (c *MessageController) UnReadMessageNum() {
 		}
 		unReadBiNum = unreadTotal
 	}
+	// 观点库审批
+	{
+		messageOb := new(knowledge_approve.KnowledgeResourceApproveMessage)
+		pars := make([]interface{}, 0)
+		cond := fmt.Sprintf(` AND %s = ? AND %s = ?`, knowledge_approve.KnowledgeResourceApproveMessageCols.ReceiveUserId, knowledge_approve.KnowledgeResourceApproveMessageCols.IsRead)
+		pars = append(pars, sysUser.AdminId, 0)
+		// 未读消息数
+		unreadTotal, e := messageOb.GetCountByCondition(cond, pars)
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取看板消息列表总数失败, Err: " + e.Error()
+			return
+		}
+		unReadKnowledgeNum = unreadTotal
+	}
 
 	// 汇总数
-	num := unReadReportNum + unReadDataPermissionNum + unReadBiNum
+	num := unReadReportNum + unReadDataPermissionNum + unReadBiNum + unReadKnowledgeNum
 
 	br.Data = num
 	br.Ret = 200

+ 1 - 0
controllers/ppt_report.go

@@ -382,6 +382,7 @@ func (this *PptV2Controller) CreateReport() {
 	// 新报告
 	newItem := new(models.PptV2)
 	newItem.Title = req.Title
+	newItem.Abstract = req.Abstract
 	newItem.AddType = req.AddType
 	newItem.ClassifyId = req.ClassifyId
 	newItem.CollaborateType = req.CollaborateType

+ 32 - 6
controllers/ppt_v2.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"eta_gn/eta_api/models"
 	"eta_gn/eta_api/models/company"
+	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/services"
 	"eta_gn/eta_api/services/ppt"
 	"eta_gn/eta_api/utils"
@@ -154,6 +155,7 @@ func (this *PptV2Controller) AddPpt() {
 			CurrentBackgroundImg:   req.FirstPage.CurrentBackgroundImg,
 			CurrentBackgroundImgId: req.FirstPage.CurrentBackgroundImgId,
 			Title:                  req.FirstPage.Title,
+			Abstract:               req.Abstract,
 			ReportType:             req.FirstPage.ReportType,
 			PptDate:                req.FirstPage.PptDate,
 			Content:                req.Content,
@@ -193,6 +195,7 @@ func (this *PptV2Controller) AddPpt() {
 		pptInfo.BackCoverImg = req.FirstPage.BackCoverImg
 		pptInfo.BackCoverImgId = req.FirstPage.BackCoverImgId
 		pptInfo.CurrentBackgroundImg = req.FirstPage.CurrentBackgroundImg
+		pptInfo.Abstract = req.Abstract
 		pptInfo.CurrentBackgroundImgId = req.FirstPage.CurrentBackgroundImgId
 		pptInfo.Title = req.FirstPage.Title
 		pptInfo.ReportType = req.FirstPage.ReportType
@@ -201,7 +204,7 @@ func (this *PptV2Controller) AddPpt() {
 		pptInfo.CoverContent = req.CoverContent
 		pptInfo.ModifyTime = time.Now()
 		pptInfo.TitleSetting = req.TitleSetting
-		err = pptInfo.Update([]string{"TemplateType", "BackgroundImg", "BackgroundImgId", "BackCoverImg", "BackCoverImgId", "CurrentBackgroundImg", "CurrentBackgroundImgId", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "CoverContent", "TitleSetting"})
+		err = pptInfo.Update([]string{"Abstract", "TemplateType", "BackgroundImg", "BackgroundImgId", "BackCoverImg", "BackCoverImgId", "CurrentBackgroundImg", "CurrentBackgroundImgId", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "CoverContent", "TitleSetting"})
 
 		msg = "保存成功"
 	}
@@ -263,6 +266,8 @@ func (this *PptV2Controller) EditPpt() {
 	}
 
 	// 修改
+	pptInfo.Abstract = req.Abstract
+	pptInfo.CollaborateUsers = req.CollaborateUsers
 	pptInfo.TemplateType = req.FirstPage.TemplateType
 	pptInfo.BackgroundImg = req.FirstPage.ImgUrl
 	pptInfo.CurrentBackgroundImg = req.FirstPage.CurrentBackgroundImg
@@ -277,7 +282,7 @@ func (this *PptV2Controller) EditPpt() {
 	pptInfo.CoverContent = req.CoverContent
 	pptInfo.ModifyTime = time.Now()
 	pptInfo.TitleSetting = req.TitleSetting
-	err = pptInfo.Update([]string{"TemplateType", "BackgroundImg", "CurrentBackgroundImg", "BackCoverImg", "CurrentBackgroundImgId", "BackCoverImgId", "BackgroundImgId", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "CoverContent", "TitleSetting"})
+	err = pptInfo.Update([]string{"Abstract", "CollaborateUsers", "TemplateType", "BackgroundImg", "CurrentBackgroundImg", "BackCoverImg", "CurrentBackgroundImgId", "BackCoverImgId", "BackgroundImgId", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "CoverContent", "TitleSetting"})
 	if err != nil {
 		br.Msg = "编辑失败"
 		br.ErrMsg = "编辑失败,Err:" + err.Error()
@@ -454,19 +459,38 @@ func (this *PptV2Controller) DetailPpt() {
 		br.ErrMsg = "信息获取失败,Err:" + err.Error()
 		return
 	}
+	pptInfo2 := new(models.PptV2Detail)
+	pptInfo2.PptV2 = pptInfo
 
 	// 权限
 	var hasAuth bool
 	if pptInfo.AdminId == sysUser.AdminId {
 		hasAuth = true
 	}
-	if hasAuth == false && pptInfo.CollaborateUsers != "" {
+
+	if !hasAuth && pptInfo.CollaborateUsers != "" {
 		authorArr := strings.Split(pptInfo.CollaborateUsers, ",")
 		strId := strconv.Itoa(sysUser.AdminId)
 		if utils.InArrayByStr(authorArr, strId) {
 			hasAuth = true
 		}
 	}
+	if pptInfo.CollaborateUsers != "" {
+		authorArr := strings.Split(pptInfo.CollaborateUsers, ",")
+		cond := ` AND enabled = 1 AND admin_id IN (?) `
+		pars := make([]interface{}, 0)
+		pars = append(pars, authorArr)
+		sysAdmin, e := system.GetSysAdminList(cond, pars, []string{"admin_id", "real_name"}, "")
+		if e != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取用户失败,Err:" + e.Error()
+			return
+		}
+		for _, v := range sysAdmin {
+			pptInfo2.CollaborateUserNames = append(pptInfo2.CollaborateUserNames, map[int]string{v.AdminId: v.RealName})
+		}
+
+	}
 
 	// 维护背景图
 	if pptInfo.CurrentBackgroundImg == "" {
@@ -517,7 +541,7 @@ func (this *PptV2Controller) DetailPpt() {
 		return
 	}
 	resp := new(models.PPTDetailResp)
-	resp.PptV2 = pptInfo
+	resp.PptV2Detail = pptInfo2
 	resp.Editor = editor
 	resp.HasAuth = hasAuth
 
@@ -664,7 +688,7 @@ func (this *PptV2Controller) Publish() {
 		}
 		outId, _ := strconv.Atoi(pptItem.OutReportId)
 		// 若回调失败, 则恢复提交前状态(先这么处理吧,允许再次提交)
-		e = services.OuterReportCallBack(outId, pptItem.Title, req.PptxUrl, ".pptx")
+		e = services.OuterReportCallBack(outId, pptItem.Title, pptItem.Abstract, req.PptxUrl, ".pptx")
 		if e != nil {
 			pptItem.State = stateOrigin
 			_ = pptItem.Update([]string{"State"})
@@ -842,6 +866,8 @@ func (this *PptV2Controller) SaveLog() {
 			return
 		}
 	}
+	pptItem.Abstract = req.Abstract
+	pptItem.CollaborateUsers = req.CollaborateUsers
 	pptItem.TemplateType = req.FirstPage.TemplateType
 	pptItem.BackgroundImg = req.FirstPage.ImgUrl
 	pptItem.CurrentBackgroundImg = req.FirstPage.CurrentBackgroundImg
@@ -856,7 +882,7 @@ func (this *PptV2Controller) SaveLog() {
 	pptItem.ModifyTime = time.Now()
 	pptItem.TitleSetting = req.TitleSetting
 	pptItem.PptPage = len(pptContent)
-	err = pptItem.Update([]string{"TemplateType", "BackgroundImg", "CurrentBackgroundImg", "BackCoverImg", "CurrentBackgroundImgId", "BackCoverImgId", "BackgroundImgId", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "TitleSetting", "ppt_page"})
+	err = pptItem.Update([]string{"CollaborateUsers", "Abstract", "TemplateType", "BackgroundImg", "CurrentBackgroundImg", "BackCoverImg", "CurrentBackgroundImgId", "BackCoverImgId", "BackgroundImgId", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "TitleSetting", "ppt_page"})
 	if err != nil {
 		br.Msg = "自动保存失败"
 		br.ErrMsg = fmt.Sprintf("自动保存PPT失败, ID: %d, Err: %v", pptItem.PptId, err)

+ 145 - 17
models/knowledge/knowledge_resource.go

@@ -14,12 +14,47 @@ const (
 	KnowledgeResourceTypeEvent = 0
 	// 事件-政策库
 	KnowledgeResourceTypePolicy = 1
-	// 事件-观点
-	KnowledgeResourceTypeOpinion = 2
+	// 事件-报告
+	KnowledgeResourceTypeReport = 2
 	// 事件类型-知识库
 	KnowledgeResourceTypeKnow = 3
+	// 事件-观点库
+	KnowledgeResourceTypeOpinion = 4
+)
+
+const (
+	// 未发布
+	KnowledgeResourceStateUnpublished = iota
+	// 已发布 暂未使用
+	KnowledgeResourceStatePublished
+	// 待审核
+	KnowledgeResourceStatePending
+	// 已驳回
+	KnowledgeResourceStateRejected
+	// 已通过
+	KnowledgeResourceStatePassed
 )
 
+type KnowledgeResourceDetail struct {
+	KnowledgeResourceId int        `gorm:"column:knowledge_resource_id;;primaryKey;autoIncrement"`
+	ResourceType        int        `gorm:"column:resource_type;"`
+	ClassifyId          int        `gorm:"column:classify_id"`
+	Title               string     `gorm:"column:title;"`
+	CreateTime          time.Time  `gorm:"column:create_time" description:"创建时间"`
+	ModifyTime          time.Time  `gorm:"column:modify_time;autoUpdateTime" description:"修改时间"`
+	State               int        `gorm:"column:state" description:"状态:0:未发布;1:已发布;2:待审核;3:已驳回;4:已通过"`
+	Content             string     `gorm:"column:content"`
+	ResourceCode        string     `gorm:"column:resource_code"`
+	AdminId             int        `gorm:"column:admin_id" description:"创建者账号"`
+	AdminRealName       string     `gorm:"column:admin_real_name" description:"创建者姓名"`
+	SourceFrom          string     `gorm:"column:source_from"`
+	TagId               int        `gorm:"column:tag_id;default:0;NOT NULL"`
+	StartTime           *time.Time `gorm:"column:start_time"`
+	EndTime             *time.Time `gorm:"column:end_time"`
+	IsFile              int        `gorm:"column:is_file;default:0;NOT NULL"`
+	FileUrl             []string   `gorm:"column:file_url"`
+}
+
 type KnowledgeResource struct {
 	KnowledgeResourceId int        `gorm:"column:knowledge_resource_id;;primaryKey;autoIncrement"`
 	ResourceType        int        `gorm:"column:resource_type;"`
@@ -27,7 +62,7 @@ type KnowledgeResource struct {
 	Title               string     `gorm:"column:title;"`
 	CreateTime          time.Time  `gorm:"column:create_time" description:"创建时间"`
 	ModifyTime          time.Time  `gorm:"column:modify_time;autoUpdateTime" description:"修改时间"`
-	State               int        `gorm:"column:state" description:"0:未发布;1:已发布;"`
+	State               int        `gorm:"column:state" description:"状态:0:未发布;1:已发布;2:待审核;3:已驳回;4:已通过"`
 	Content             string     `gorm:"column:content"`
 	ResourceCode        string     `gorm:"column:resource_code"`
 	AdminId             int        `gorm:"column:admin_id" description:"创建者账号"`
@@ -39,6 +74,7 @@ type KnowledgeResource struct {
 	IsFile              int        `gorm:"column:is_file;default:0;NOT NULL"`
 	FileUrl             string     `gorm:"column:file_url"`
 	IsDelete            int        `gorm:"column:is_delete;default:0;NOT NULL"`
+	OutSource           int        `gorm:"column:out_source" description:"外部来源:0:内部 1:智力共享 2:数据节点"`
 }
 
 func (m *KnowledgeResource) TableName() string {
@@ -66,6 +102,7 @@ type KnowledgeResourceList struct {
 	StartTime           string `gorm:"column:start_time"`
 	EndTime             string `gorm:"column:end_time"`
 	Content             string `gorm:"-"`
+	OutSource           int    `gorm:"column:out_source" description:"外部来源:0:内部 1:智力共享 2:数据节点"`
 	ClassifyFullName    string
 	TagName             string
 }
@@ -82,12 +119,28 @@ func GetBatchKnowledgeResource(batchSize int, id int) (items []*KnowledgeResourc
 	return
 }
 
-func GetKnowledgeResourcePageList(condition string, pars []interface{}, startSize, pageSize int) (items []*KnowledgeResource, err error) {
+func GetBatchKnowledgeResourceByCondition(condition string, pars []interface{}, batchSize int) (items []*KnowledgeResource, err error) {
+	sql := `SELECT * FROM knowledge_resource WHERE is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+	pars = append(pars, batchSize)
+	sql += `ORDER BY knowledge_resource_id ASC LIMIT ?`
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+func GetKnowledgeResourcePageList(condition string, pars []interface{}, sortCond string, startSize, pageSize int) (items []*KnowledgeResource, err error) {
 	sql := `SELECT * FROM knowledge_resource WHERE 1=1  AND is_delete=0 `
 	if condition != "" {
 		sql += condition
 	}
-	sql += `ORDER BY modify_time DESC LIMIT ?,?`
+	if sortCond != "" {
+		sql += sortCond
+	} else {
+		sql += `ORDER BY modify_time DESC `
+	}
+	sql += ` LIMIT ?,?`
 	pars = append(pars, startSize)
 	pars = append(pars, pageSize)
 	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
@@ -154,16 +207,16 @@ type DeleteReq struct {
 }
 
 type AddReq struct {
-	ResourceType int    `gorm:"column:resource_type;"`
-	ClassifyId   int    `gorm:"column:classify_id"`
-	Title        string `gorm:"column:title;"`
-	State        int    `gorm:"column:state" description:"0:未发布;1:已发布"`
-	Content      string `gorm:"column:content"`
-	SourceFrom   string `gorm:"column:source_from"`
-	TagId        int    `gorm:"column:tag_id;default:0;NOT NULL"`
-	StartTime    string `gorm:"column:start_time"`
-	EndTime      string `gorm:"column:end_time"`
-	FileUrl      string `gorm:"column:file_url"`
+	ResourceType int      `gorm:"column:resource_type;"`
+	ClassifyId   int      `gorm:"column:classify_id"`
+	Title        string   `gorm:"column:title;"`
+	State        int      `gorm:"column:state" description:"0:未发布;1:已发布"`
+	Content      string   `gorm:"column:content"`
+	SourceFrom   string   `gorm:"column:source_from"`
+	TagId        int      `gorm:"column:tag_id;default:0;NOT NULL"`
+	StartTime    string   `gorm:"column:start_time"`
+	EndTime      string   `gorm:"column:end_time"`
+	FileUrl      []string `gorm:"column:file_url"`
 }
 
 type AddResp struct {
@@ -171,11 +224,44 @@ type AddResp struct {
 	ResourceCode        string `description:"事件code"`
 }
 
+type PublicReq struct {
+	KnowledgeResourceId int `description:"事件id"`
+}
+
 func (m *KnowledgeResource) Add(item *KnowledgeResource) (err error) {
 	err = global.DmSQL["rddp"].Create(item).Error
 	return
 }
 
+func (m *KnowledgeResource) AddWithFile(file []string) (err error) {
+	tx := global.DmSQL["rddp"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	err = tx.Create(m).Error
+	if err != nil {
+		return
+	}
+	if len(file) > 0 {
+		fileList := make([]*KnowledgeResourceFile, len(file))
+		for i, v := range file {
+			fileList[i] = &KnowledgeResourceFile{
+				KnowledgeResourceId: m.KnowledgeResourceId,
+				FileUrl:             v,
+			}
+		}
+		err = tx.CreateInBatches(fileList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
 func (m *KnowledgeResource) AddBatch(item []*KnowledgeResource) (err error) {
 	err = global.DmSQL["rddp"].CreateInBatches(item, 50).Error
 	return
@@ -224,6 +310,41 @@ func (m *KnowledgeResource) Update(cols []string) (err error) {
 	return
 }
 
+func (m *KnowledgeResource) UpdateWithFile(cols, file []string) (err error) {
+	tx := global.DmSQL["rddp"].Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	err = tx.Select(cols).Updates(m).Error
+	if err != nil {
+		return
+	}
+	if len(file) > 0 {
+		sql := `DELETE FROM knowledge_resource_file WHERE knowledge_resource_id =?`
+		err = tx.Exec(sql, m.KnowledgeResourceId).Error
+		if err != nil {
+			return
+		}
+
+		fileList := make([]*KnowledgeResourceFile, len(file))
+		for i, v := range file {
+			fileList[i] = &KnowledgeResourceFile{
+				KnowledgeResourceId: m.KnowledgeResourceId,
+				FileUrl:             v,
+			}
+		}
+		err = tx.CreateInBatches(fileList, utils.MultiAddNum).Error
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
 // MarkEditReport 标记编辑英文研报的请求数据
 type MarkEditReport struct {
 	KnowledgeResourceId int `description:"研报id"`
@@ -258,7 +379,7 @@ func (m *KnowledgeResource) GetSourceFrom(keyword string, resourceType int) (ite
 }
 
 type KnowledgeResourceDetailView struct {
-	*KnowledgeResource
+	*KnowledgeResourceDetail
 }
 
 type ResourceImportData struct {
@@ -291,7 +412,7 @@ type GetAdminsRespItem struct {
 }
 
 func (m *KnowledgeResource) GetAdmins(keyword string, resourceType int) (items []*GetAdminsRespItem, err error) {
-	sql := fmt.Sprintf(`SELECT distinct admin_id, admin_real_name FROM %s WHERE 1=1 and resource_type=? `, m.TableName())
+	sql := fmt.Sprintf(`SELECT distinct admin_id, admin_real_name FROM %s WHERE 1=1 AND admin_id > 0 and resource_type=? `, m.TableName())
 	if keyword != `` {
 		sql += ` AND admin_real_name LIKE '%` + keyword + `%'`
 	}
@@ -322,3 +443,10 @@ type KnowledgeResourceMapItem struct {
 	KnowledgeResourceId int
 	ResourceType        int
 }
+
+// RemoveTagRelateByTagId 移除标签关联
+func (m *KnowledgeResource) RemoveTagRelateByTagId(tagId int) (err error) {
+	sql := fmt.Sprintf(`UPDATE %s SET tag_id = 0 WHERE tag_id = ?`, m.TableName())
+	err = global.DmSQL["rddp"].Exec(sql, tagId).Error
+	return
+}

+ 33 - 0
models/knowledge/knowledge_resource_file.go

@@ -0,0 +1,33 @@
+package knowledge
+
+import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
+)
+
+type KnowledgeResourceFile struct {
+	KnowledgeResourceFileId int    `gorm:"column:knowledge_resource_file_id;primaryKey;autoIncrement"`
+	KnowledgeResourceId     int    `gorm:"column:knowledge_resource_id"`
+	FileUrl                 string `gorm:"column:file_url"`
+}
+
+func (k KnowledgeResourceFile) TableName() string {
+	return "knowledge_resource_file"
+}
+
+func (k *KnowledgeResourceFile) BatchAdd(items []*KnowledgeResourceFile) (err error) {
+	err = global.DmSQL["rddp"].CreateInBatches(items, utils.MultiAddNum).Error
+	return
+}
+
+func (k *KnowledgeResourceFile) DeleteByResourceId(id int) (err error) {
+	sql := "DELETE FROM knowledge_resource_file WHERE knowledge_resource_id =?"
+	err = global.DmSQL["rddp"].Exec(sql, id).Error
+	return
+}
+
+func (k *KnowledgeResourceFile) GetByResourceId(id int) (item []*KnowledgeResourceFile, err error) {
+	sql := "SELECT * FROM knowledge_resource_file WHERE knowledge_resource_id =?"
+	err = global.DmSQL["rddp"].Raw(sql, id).Find(&item).Error
+	return
+}

+ 3 - 3
models/knowledge/knowledge_tag.go

@@ -63,12 +63,12 @@ type KnowledgeTagListResp struct {
 type TagAddReq struct {
 	TagName      string `description:"分类名称"`
 	ParentId     int    `description:"父级分类id,没有父级分类传0"`
-	ResourceType int    `description:"分类类型:0事件库,1政策库,2观点库,3知识库"`
+	ResourceType int    `description:"分类类型:0事件库,1政策库,2报告库,3知识库,4观点库"`
 }
 
 type DeleteTagReq struct {
 	TagId        int `description:"分类ID"`
-	ResourceType int `description:"分类类型:0事件库,1政策库,2观点库,3知识库"`
+	ResourceType int `description:"分类类型:0事件库,1政策库,2报告库,3知识库,4观点库"`
 }
 
 type EditTagReq struct {
@@ -157,7 +157,7 @@ type TagMoveReq struct {
 	TagId        int `description:"分类ID"`
 	PrevTagId    int `description:"上一个兄弟节点分类id"`
 	NextTagId    int `description:"下一个兄弟节点分类id"`
-	ResourceType int `description:"分类类型:0事件库,1政策库,2观点库,3知识库"`
+	ResourceType int `description:"分类类型:0事件库,1政策库,2报告库,3知识库,4观点库"`
 }
 
 func (m *KnowledgeTag) GetTagListByKeyword(keyWord string, resourceType int) (items []*KnowledgeTagItem, err error) {

+ 203 - 0
models/knowledge_approve/knowledge_approve.go

@@ -0,0 +1,203 @@
+package knowledge_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"time"
+)
+
+type KnowledgeResourceApprove struct {
+	KnowledgeResourceApproveId int       `gorm:"column:knowledge_resource_approve_id;primary_key"`
+	KnowledgeResourceId        int       `gorm:"column:knowledge_resource_id"`
+	KnowledgeResourceTitle     string    `gorm:"column:knowledge_resource_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 KnowledgeResourceApproveCols = struct {
+	KnowledgeResourceApproveId string
+	KnowledgeResourceId        string
+	KnowledgeResourceTitle     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
+}{
+	KnowledgeResourceApproveId: "knowledge_resource_approve_id",
+	KnowledgeResourceId:        "knowledge_resource_id",
+	KnowledgeResourceTitle:     "knowledge_resource_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 KnowledgeResourceApproveItemOrm struct {
+	KnowledgeResourceApproveId       int       `description:"审批ID"`
+	KnowledgeResourceApproveRecordId int       `description:"审批记录ID"`
+	KnowledgeResourceId              int       `description:"报告ID"`
+	KnowledgeResourceTitle           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 *KnowledgeResourceApprove) TableName() string {
+	return "knowledge_resource_approve"
+}
+
+func (b *KnowledgeResourceApprove) Update(cols []string) (err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *KnowledgeResourceApprove) Create() (err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Create(b).Error
+	return
+}
+
+func GetKnowledgeResourceApproveByFlowIdAndVersionId(knowledgeFlowId int, flowVersion int) (item []*KnowledgeResourceApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("flow_id = ? AND flow_version = ?", knowledgeFlowId, flowVersion).Find(&item).Error
+	return
+}
+
+func GetKnowledgeResourceApproveById(KnowledgeResourceApproveId int) (item *KnowledgeResourceApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("knowledge_resource_approve_id = ?", KnowledgeResourceApproveId).First(&item).Error
+	return
+}
+
+// GetApprovingKnowledgeResourceApproveCount 获取待处理的审批分页列表总数
+func GetApprovingKnowledgeResourceApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.knowledge_resource_approve_record_id
+		FROM knowledge_resource_approve_record AS a
+		JOIN knowledge_resource_approve AS b ON a.knowledge_resource_approve_id = b.knowledge_resource_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
+}
+
+// GetApprovingKnowledgeResourceApprovePageList 获取待处理的审批列表-分页
+func GetApprovingKnowledgeResourceApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*KnowledgeResourceApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.knowledge_resource_approve_record_id, a.state AS record_state, b.*
+		FROM knowledge_resource_approve_record AS a
+		JOIN knowledge_resource_approve AS b ON a.knowledge_resource_approve_id = b.knowledge_resource_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
+}
+
+// GetApprovedKnowledgeResourceApproveCount 获取已处理的审批分页列表总数
+func GetApprovedKnowledgeResourceApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.knowledge_resource_approve_record_id
+		FROM knowledge_resource_approve_record AS a
+		JOIN knowledge_resource_approve AS b ON a.knowledge_resource_approve_id = b.knowledge_resource_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
+}
+
+// GetApprovedKnowledgeResourceApprovePageList 获取已处理的审批列表-分页
+func GetApprovedKnowledgeResourceApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*KnowledgeResourceApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.knowledge_resource_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 knowledge_resource_approve_record AS a
+		JOIN knowledge_resource_approve AS b ON a.knowledge_resource_approve_id = b.knowledge_resource_approve_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
+}
+
+// GetApplyKnowledgeResourceApproveCount 获取我发起的审批分页列表总数
+func GetApplyKnowledgeResourceApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.* FROM knowledge_resource_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
+}
+
+// GetApplyKnowledgeResourceApprovePageList 获取我发起的审批列表-分页
+func GetApplyKnowledgeResourceApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*KnowledgeResourceApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.* FROM knowledge_resource_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
+}
+
+func GetKnowledgeResourceApproveByBoardId(KnowledgeResourceApproveId int) (item *KnowledgeResourceApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("knowledge_resource_id = ?", KnowledgeResourceApproveId).Order("create_time DESC").First(&item).Error
+	return
+}
+
+func GetKnowledgeResourceApproveCountByState(state int) (count int, err error) {
+	db := global.DmSQL["rddp"]
+	sql := `SELECT COUNT(*) FROM knowledge_resource_approve WHERE state = ?`
+	err = db.Raw(sql, state).Scan(&count).Error
+	return
+}
+
+func GetKnowledgeApproveByKnowledgeId(knowledgeId int) (item *KnowledgeResourceApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("knowledge_resource_id = ?", knowledgeId).Order("create_time DESC").First(&item).Error
+	return
+}

+ 184 - 0
models/knowledge_approve/knowledge_approve_flow.go

@@ -0,0 +1,184 @@
+package knowledge_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"time"
+)
+
+type KnowledgeResourceApproveFlow struct {
+	KnowledgeResourceApproveFlowId int       `gorm:"column:knowledge_resource_approve_flow_id;primaryKey"`
+	FlowName                       string    `gorm:"column:flow_name"`
+	ClassifyId                     int       `gorm:"column:classify_id"`
+	CurrVersion                    int       `gorm:"column:curr_version"`
+	CreateTime                     time.Time `gorm:"column:create_time"`
+	ModifyTime                     time.Time `gorm:"column:modify_time"`
+}
+
+var KnowledgeResourceApproveFlowCols = struct {
+	KnowledgeResourceApproveFlowId string
+	FlowName                       string
+	ClassifyId                     string
+	CurrVersion                    string
+	CreateTime                     string
+	ModifyTime                     string
+}{
+	KnowledgeResourceApproveFlowId: "knowledge_resource_approve_flow_id",
+	FlowName:                       "flow_name",
+	ClassifyId:                     "classify_id",
+	CurrVersion:                    "curr_version",
+	CreateTime:                     "create_time",
+	ModifyTime:                     "modify_time",
+}
+
+func (b *KnowledgeResourceApproveFlow) TableName() string {
+	return "knowledge_resource_approve_flow"
+}
+
+func (b *KnowledgeResourceApproveFlow) Add(node []*KnowledgeResourceApproveNode) (err error) {
+	prevNodes := make([]*KnowledgeResourceApproveNode, 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(KnowledgeResourceApproveNode)
+	for k, v := range node {
+		v.KnowledgeResourceApproveFlowId = b.KnowledgeResourceApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.KnowledgeResourceApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.KnowledgeResourceApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	return
+}
+
+func (b *KnowledgeResourceApproveFlow) Update(cols []string, node []*KnowledgeResourceApproveNode) (err error) {
+	prevNodes := make([]*KnowledgeResourceApproveNode, 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(KnowledgeResourceApproveNode)
+	for k, v := range node {
+		v.KnowledgeResourceApproveFlowId = b.KnowledgeResourceApproveFlowId
+		v.PrevNodeId = prevId
+		err = o.Create(v).Error
+		if err != nil {
+			err = fmt.Errorf("insert node err: %v", err)
+			return
+		}
+		prevId = v.KnowledgeResourceApproveNodeId
+
+		// 下一个节点
+		if prevNode != nil && k > 0 && k < nodesLen {
+			prevNode.NextNodeId = v.KnowledgeResourceApproveNodeId
+			prevNodes = append(prevNodes, prevNode)
+		}
+		prevNode = v
+	}
+	return
+}
+
+func (b *KnowledgeResourceApproveFlow) Delete() error {
+	return global.DmSQL["rddp"].Delete(b).Error
+}
+
+func (m *KnowledgeResourceApproveFlow) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *KnowledgeResourceApproveFlow, 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 GetKnowledgeResourceApproveFlowById(KnowledgeResourceApproveFlowId int) (item *KnowledgeResourceApproveFlow, err error) {
+	err = global.DmSQL["rddp"].Where("knowledge_resource_approve_flow_id = ?", KnowledgeResourceApproveFlowId).First(&item).Error
+	return
+}
+
+func GetKnowledgeResourceApproveFlowByClassifyId(classifyId int) (item *KnowledgeResourceApproveFlow, err error) {
+	err = global.DmSQL["rddp"].Where("classify_id = ?", classifyId).First(&item).Error
+	return
+}
+
+func GetKnowledgeResourceApproveFlowByCondition(condition string, pars []interface{}, startSize, pageSize int) (items []*KnowledgeResourceApproveFlow, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT * FROM knowledge_resource_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 GetKnowledgeResourceApproveFlowCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT COUNT(*) AS count FROM knowledge_resource_approve_flow WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+func UpdateFlowClassifyName(classifyId int, classifyName string) (err error) {
+	o := global.DmSQL["rddp"]
+	err = o.Model(&KnowledgeResourceApproveFlow{}).Where("classify_id = ?", classifyId).Update("classify_name", classifyName).Error
+	return
+}

+ 115 - 0
models/knowledge_approve/knowledge_approve_message.go

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

+ 90 - 0
models/knowledge_approve/knowledge_approve_node.go

@@ -0,0 +1,90 @@
+package knowledge_approve
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"strings"
+	"time"
+)
+
+type KnowledgeResourceApproveNode struct {
+	KnowledgeResourceApproveNodeId int       `gorm:"column:knowledge_resource_approve_node_id;primaryKey"`
+	KnowledgeResourceApproveFlowId int       `gorm:"column:knowledge_resource_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 KnowledgeResourceApproveNodeCols = struct {
+	KnowledgeResourceApproveNodeId string
+	KnowledgeResourceApproveFlowId string
+	PrevNodeId                     string
+	NextNodeId                     string
+	NodeType                       string
+	ApproveType                    string
+	Users                          string
+	CurrVersion                    string
+	CreatedTime                    string
+}{
+	KnowledgeResourceApproveNodeId: "knowledge_resource_approve_node_id",
+	KnowledgeResourceApproveFlowId: "knowledge_resource_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 *KnowledgeResourceApproveNode) TableName() string {
+	return "knowledge_resource_approve_node"
+}
+
+func (m *KnowledgeResourceApproveNode) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*KnowledgeResourceApproveNode, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY created_time DESC, knowledge_resource_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 []*KnowledgeResourceApproveNode) (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 GetKnowledgeResourceApproveNodeByCondition(condition string, pars []interface{}) (node []*KnowledgeResourceApproveNode, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT * FROM knowledge_resource_approve_node WHERE 1=1 "
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars...).Find(&node).Error
+	return
+}
+
+func GetKnowledgeResourceApproveNodeByFlowIdAndVersionId(flowId int, versionId int) (node []*KnowledgeResourceApproveNode, err error) {
+	err = global.DmSQL["rddp"].Model(&KnowledgeResourceApproveNode{}).Where("knowledge_resource_approve_flow_id =? AND curr_version =?", flowId, versionId).Scan(&node).Error
+	return
+}

+ 152 - 0
models/knowledge_approve/knowledge_approve_record.go

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

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

+ 23 - 0
models/knowledge_approve/request/knowledge_approve_flow.go

@@ -0,0 +1,23 @@
+package request
+
+type KnowledgeResourceApproveFlowSaveReq struct {
+	KnowledgeResourceApproveFlowId 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 KnowledgeResourceApproveFlowRemoveReq struct {
+	KnowledgeResourceApproveFlowId int
+}

+ 5 - 0
models/knowledge_approve/request/knowledge_approve_message.go

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

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

@@ -0,0 +1,90 @@
+package response
+
+// KnowledgeResourceApproveDetail 审批详情信息
+type KnowledgeResourceApproveDetail struct {
+	Knowledge        *KnowledgeResourceApproveDetailKnowledge `description:"报告信息"`
+	Approve          *KnowledgeResourceApproveDetailItem      `description:"审批信息"`
+	ApproveFlowNodes []*KnowledgeResourceApproveDetailNodes   `description:"审批节点信息"`
+}
+
+// KnowledgeResourceApproveDetailKnowledge 审批详情-报告信息
+type KnowledgeResourceApproveDetailKnowledge struct {
+	KnowledgeResourceId    int    `description:"知识资源ID"`
+	KnowledgeResourceTitle string `description:"知识资源标题"`
+	KnowledgeCode          string `description:"知识资源code"`
+	KnowledgeClassify      string `description:"知识资源分类"`
+}
+
+// KnowledgeResourceApproveDetailItem 审批详情-审批信息
+type KnowledgeResourceApproveDetailItem struct {
+	KnowledgeResourceApproveId 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:"修改时间"`
+}
+
+// KnowledgeResourceApproveDetailNodes 审批详情-节点信息
+type KnowledgeResourceApproveDetailNodes struct {
+	KnowledgeResourceApproveNodeId int                                       `description:"知识资源审批节点ID"`
+	KnowledgeResourceApproveFlowId 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                          []*KnowledgeResourceApproveDetailNodeUser `description:"审批人信息"`
+}
+
+// KnowledgeResourceApproveDetailNodeUser 审批详情-节点用户信息
+type KnowledgeResourceApproveDetailNodeUser struct {
+	KnowledgeResourceApproveNodeUserReq
+	ApproveRecord *KnowledgeResourceApproveDetailNodeUserRecord `description:"用户审批记录"`
+}
+
+// KnowledgeResourceApproveNodeUserReq 报告审批节点用户请求体
+type KnowledgeResourceApproveNodeUserReq struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+
+// KnowledgeResourceApproveDetailNodeUserRecord 审批详情-节点用户审批记录
+type KnowledgeResourceApproveDetailNodeUserRecord struct {
+	KnowledgeResourceApproveRecordId int    `description:"审批记录ID"`
+	State                            int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	ApproveUserId                    int    `description:"审批人ID"`
+	ApproveUserName                  string `description:"审批人姓名"`
+	ApproveRemark                    string `description:"审批备注"`
+	ApproveTime                      string `description:"审批时间"`
+}
+
+type KnowledgeResourceApproveItemOrmResp struct {
+	KnowledgeResourceApproveId       int    `description:"审批ID"`
+	KnowledgeResourceApproveRecordId int    `description:"审批记录ID"`
+	KnowledgeResourceId              int    `description:"报告ID"`
+	KnowledgeResourceTitle           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/knowledge_approve/response/knowledge_approve_flow.go

@@ -0,0 +1,46 @@
+package response
+
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type KnowledgeResourceApproveFlowItem struct {
+	KnowledgeResourceApproveFlowId int    `description:"主键"`
+	FlowName                       string `description:"知识资源审批流程名称"`
+	ClassifyId                     int    `description:"分类ID"`
+	ClassifyName                   string `description:"分类名称"`
+	CurrVersion                    int    `description:"当前版本"`
+	CreateTime                     string `description:"创建时间"`
+	ModifyTime                     string `description:"修改时间"`
+}
+
+type KnowledgeResourceApproveFlowListResp struct {
+	List   []*KnowledgeResourceApproveFlowItem
+	Paging *paging.PagingItem
+}
+
+type KnowledgeResourceApproveFlowDetailResp struct {
+	KnowledgeResourceApproveFlowItem `description:"审批流信息"`
+	Nodes                            []*KnowledgeResourceApproveNodeItem `description:"节点信息"`
+}
+
+type KnowledgeResourceApproveNodeUser struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+type KnowledgeResourceApproveNodeItem struct {
+	KnowledgeResourceApproveNodeId int                                 `description:"知识资源审批节点ID"`
+	KnowledgeResourceApproveFlowId 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                          []*KnowledgeResourceApproveNodeUser `description:"审批人信息"`
+}
+
+type KnowledgeResourceApproveListResp struct {
+	List   []*KnowledgeResourceApproveItemOrmResp
+	Paging *paging.PagingItem
+}

+ 24 - 0
models/knowledge_approve/response/knowledge_approve_message.go

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

+ 17 - 6
models/ppt_v2.go

@@ -16,6 +16,7 @@ type PptV2 struct {
 	TemplateType           int       `gorm:"column:template_type" description:"模版类型"`
 	BackgroundImg          string    `gorm:"column:background_img" description:"现在实际存的封面图(前端改动太大,不知道该字段之前谁定义的)"`
 	Title                  string    `gorm:"column:title" description:"标题"`
+	Abstract               string    `gorm:"column:abstract" description:"摘要"`
 	ReportType             string    `gorm:"column:report_type" description:"报告类型"`
 	PptDate                string    `gorm:"column:ppt_date" description:"选择日期"`
 	Content                string    `gorm:"column:content" description:"ppt内容"`
@@ -52,6 +53,11 @@ type PptV2 struct {
 	BackgroundImgId        int       `gorm:"column:background_img_id" description:"封面图id"`
 }
 
+type PptV2Detail struct {
+	*PptV2
+	CollaborateUserNames []map[int]string
+}
+
 type PptV2Item struct {
 	PptId         int       `gorm:"column:ppt_id;primaryKey" description:"ppt的Id"`
 	TemplateType  int       `gorm:"column:template_type" description:"模版类型"`
@@ -144,10 +150,12 @@ type AddPptV2Req struct {
 		BackIndex              int    `description:"背景图片下标"`
 		TemplateType           int    `description:"模版id"`
 	} `description:"首页"`
-	Content      string `description:"ppt的json数据"`
-	GroupId      int64  `description:"目录id"`
-	CoverContent string `description:"封面图内容-JSON数据"`
-	TitleSetting string `description:"PPT标题设置"`
+	Abstract         string `description:"摘要"`
+	CollaborateUsers string `description:"协作人IDs, 英文逗号分隔"`
+	Content          string `description:"ppt的json数据"`
+	GroupId          int64  `description:"目录id"`
+	CoverContent     string `description:"封面图内容-JSON数据"`
+	TitleSetting     string `description:"PPT标题设置"`
 }
 
 type AddPptResp struct {
@@ -314,7 +322,7 @@ type PPTEditingReq struct {
 
 // PPTDetailResp PPT详情响应体
 type PPTDetailResp struct {
-	*PptV2
+	*PptV2Detail
 	Editor  PPTEditingCache `description:"编辑人信息"`
 	HasAuth bool            `description:"是否有权限"`
 }
@@ -403,7 +411,7 @@ func (m *PptV2) GetCountByConditionWithAdminId(condition string, pars []interfac
 
 // PptReportQueryFields 除富文本的常用查询字段
 var PptReportQueryFields = []string{
-	"ppt_id", "title", "classify_id", "ppt_version", "pptx_url", "ppt_page", "title_setting", "state", "report_source", "publish_time", "submit_time", "approve_time", "create_time", "modify_time", "admin_id", "admin_real_name", "collaborate_type", "collaborate_users",
+	"ppt_id", "title", "abstract", "classify_id", "ppt_version", "pptx_url", "ppt_page", "title_setting", "state", "report_source", "publish_time", "submit_time", "approve_time", "create_time", "modify_time", "admin_id", "admin_real_name", "collaborate_type", "collaborate_users",
 }
 
 type PptReportItem struct {
@@ -413,6 +421,7 @@ type PptReportItem struct {
 	PptVersion int    `description:"是否ppt的旧版本;1:旧的,2:新的"`
 	PptxUrl    string `description:"pptx下载地址"`
 	PptPage    int    `description:"PPT总页数"`
+	Abstract   string `description:"摘要"`
 	//Content      string `description:"内容"`
 	TitleSetting     string                     `description:"PPT标题设置"`
 	State            int                        `description:"报告状态:1-未发布;2-已发布;3-待提交;4-待审批;5-已驳回;6-已通过"`
@@ -444,6 +453,7 @@ func (m *PptV2) Format2ReportItem(origin *PptV2) (item *PptReportItem) {
 	item.PptId = origin.PptId
 	item.Title = origin.Title
 	item.ClassifyId = origin.ClassifyId
+	item.Abstract = origin.Abstract
 	item.PptVersion = int(origin.PptVersion)
 	item.PptxUrl = origin.PptxUrl
 	item.PptPage = origin.PptPage
@@ -484,6 +494,7 @@ type PptPageReportResp struct {
 type PptReportCreateReq struct {
 	Title              string `description:"标题"`
 	ClassifyId         int    `description:"分类ID"`
+	Abstract           string `description:"摘要"`
 	AddType            int    `description:"新增方式:1:新增报告,2:继承报告"`
 	InheritPptId       int    `description:"待继承的报告ID"`
 	CollaborateType    int    `description:"协作方式,1:个人,2:多人协作。默认:1"`

+ 31 - 31
models/system/sys_user.go

@@ -29,42 +29,42 @@ type LoginResp struct {
 type Admin struct {
 	//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:"系统用户姓名"`
+	AdminName                 string `gorm:"column:admin_name" description:"系统用户名称"`
+	AdminAvatar               string `grom:"admin_avatar" description:"用户头像"`
+	RealName                  string `grom:"real_name" description:"系统用户姓名"`
 	Password                  string `json:"-"`
 	LastUpdatedPasswordTime   string `json:"-"`
-	Enabled                   int
-	Email                     string `description:"系统用户邮箱"`
+	Enabled                   int    `gorm:"column:enabled"`
+	Email                     string `gorm:"column:email" description:"系统用户邮箱"`
 	LastLoginTime             string
 	CreatedTime               time.Time
 	LastUpdatedTime           string
-	Role                      string    `description:"系统用户角色"`
-	Mobile                    string    `description:"手机号"`
-	RoleType                  int       `description:"角色类型:1需要录入指标,0:不需要"`
-	RoleId                    int       `description:"角色ID"`
-	RoleName                  string    `description:"角色名称"`
-	RoleTypeCode              string    `description:"角色类型编码"`
-	DepartmentId              int       `description:"部门id"`
-	DepartmentName            string    `description:"部门名称"`
-	GroupId                   int       `description:"分组id"`
-	GroupName                 string    `description:"分组名称"`
-	Authority                 int       `description:"管理权限,0:无,1:部门负责人,2:小组负责人,或者ficc销售主管,3:超级管理员,4:ficc销售组长"`
-	Position                  string    `description:"职位"`
-	DisableTime               time.Time `description:"禁用时间"`
-	ChartPermission           int8      `description:"图表权限id"`
-	OpenId                    string    `description:"国能部门公众号的openid"`
-	UnionId                   string    `description:"微信公众平台唯一标识"`
-	EdbPermission             int8      `description:"指标库操作权限,0:只能操作 自己的,1:所有指标可操作"`
-	MysteelChemicalPermission int8      `description:"钢联化工指标操作权限,0:只能操作 自己的,1:所有指标可操作"`
-	PredictEdbPermission      int8      `description:"预测指标库操作权限,0:只能操作 自己的,1:所有预测指标可操作"`
-	Province                  string    `description:"省"`
-	ProvinceCode              string    `description:"省编码"`
-	City                      string    `description:"市"`
-	CityCode                  string    `description:"市编码"`
-	EmployeeId                string    `description:"员工工号(钉钉/每刻报销)"`
-	TelAreaCode               string    `description:"手机区号"`
-	IsLdap                    int       `description:"是否为域用户:0-系统账户;1-域用户"`
+	Role                      string    `gorm:"column:role" description:"系统用户角色"`
+	Mobile                    string    `gorm:"column:mobile" description:"手机号"`
+	RoleType                  int       `gorm:"role_type" description:"角色类型:1需要录入指标,0:不需要"`
+	RoleId                    int       `gorm:"role_id" description:"角色ID"`
+	RoleName                  string    `gorm:"column:role_name" description:"角色名称"`
+	RoleTypeCode              string    `gorm:"column:role_type_code" description:"角色类型编码"`
+	DepartmentId              int       `gorm:"column:department_id" description:"部门id"`
+	DepartmentName            string    `gorm:"column:department_name" description:"部门名称"`
+	GroupId                   int       `gorm:"column:group_id" description:"分组id"`
+	GroupName                 string    `gorm:"column:group_name" description:"分组名称"`
+	Authority                 int       `gorm:"column:authority" description:"管理权限,0:无,1:部门负责人,2:小组负责人,或者ficc销售主管,3:超级管理员,4:ficc销售组长"`
+	Position                  string    `gorm:"column:position" description:"职位"`
+	DisableTime               time.Time `gorm:"column:disable_time" description:"禁用时间"`
+	ChartPermission           int8      `gorm:"column:chart_permission" description:"图表权限id"`
+	OpenId                    string    `gorm:"column:open_id" description:"国能部门公众号的openid"`
+	UnionId                   string    `gorm:"column:union_id" description:"微信公众平台唯一标识"`
+	EdbPermission             int8      `gorm:"column:edb_permission" description:"指标库操作权限,0:只能操作 自己的,1:所有指标可操作"`
+	MysteelChemicalPermission int8      `gorm:"column:mysteel_chemical_permission" description:"钢联化工指标操作权限,0:只能操作 自己的,1:所有指标可操作"`
+	PredictEdbPermission      int8      `gorm:"column:predict_edb_permission" description:"预测指标库操作权限,0:只能操作 自己的,1:所有预测指标可操作"`
+	Province                  string    `gorm:"column:province" description:"省"`
+	ProvinceCode              string    `gorm:"column:province_code" description:"省编码"`
+	City                      string    `gorm:"column:city" description:"市"`
+	CityCode                  string    `gorm:"column:city_code" description:"市编码"`
+	EmployeeId                string    `gorm:"column:employee_id" description:"员工工号(钉钉/每刻报销)"`
+	TelAreaCode               string    `gorm:"column:tel_area_code" description:"手机区号"`
+	IsLdap                    int       `gorm:"column:is_ldap" description:"是否为域用户:0-系统账户;1-域用户"`
 }
 
 // Update 更新用户基础信息

+ 144 - 0
routers/commentsRouter.go

@@ -5578,6 +5578,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/resource/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
         beego.ControllerComments{
             Method: "Delete",
@@ -5641,6 +5650,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
+        beego.ControllerComments{
+            Method: "Public",
+            Router: `/resource/public`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge:ResourceController"],
         beego.ControllerComments{
             Method: "SaveReportContent",
@@ -5731,6 +5749,132 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "Approve",
+            Router: `/approve`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        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/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "ClassifyList",
+            Router: `/classify/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "MessageList",
+            Router: `/message/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "MessageRead",
+            Router: `/message/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveController"],
+        beego.ControllerComments{
+            Method: "Refuse",
+            Router: `/refuse`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Add",
+            Router: `/flow/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/flow/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Edit",
+            Router: `/flow/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/flow/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/knowledge_approve:KnowledgeApproveFlowController"],
+        beego.ControllerComments{
+            Method: "Remove",
+            Router: `/flow/remove`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/report_approve:ReportApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/report_approve:ReportApproveController"],
         beego.ControllerComments{
             Method: "Approve",

+ 7 - 0
routers/router.go

@@ -25,6 +25,7 @@ import (
 	"eta_gn/eta_api/controllers/data_stat"
 	"eta_gn/eta_api/controllers/fe_calendar"
 	"eta_gn/eta_api/controllers/knowledge"
+	"eta_gn/eta_api/controllers/knowledge_approve"
 	"eta_gn/eta_api/controllers/report_approve"
 	"eta_gn/eta_api/controllers/sandbox"
 	"eta_gn/eta_api/controllers/semantic_analysis"
@@ -374,6 +375,12 @@ func init() {
 				&controllers.ImageConfController{},
 			),
 		),
+		web.NSNamespace("/knowledge_approve",
+			web.NSInclude(
+				&knowledge_approve.KnowledgeApproveController{},
+				&knowledge_approve.KnowledgeApproveFlowController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 61 - 2
services/knowledge/es.go

@@ -11,10 +11,48 @@ import (
 	"strings"
 
 	"github.com/PuerkitoBio/goquery"
+	"github.com/olivere/elastic/v7"
 )
 
+func EsBatchAddOrEditKnowledgeResource(list []*knowledge.KnowledgeResource) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println("EsBatchAddOrEditData Err:", err.Error())
+			utils.FileLog.Info("EsBatchAddOrEditKnowledgeResource err:", err)
+		}
+	}()
+	indexName := utils.EsKnowledgeResourceIndexName
+	client := utils.EsClient
+
+	actions := make([]elastic.BulkableRequest, len(list))
+	for i, item := range list {
+		request := elastic.NewBulkIndexRequest().Index(indexName).Id(strconv.Itoa(item.KnowledgeResourceId)).Doc(item)
+		actions[i] = request
+	}
+	response, err := client.Bulk().Add(actions...).Do(context.Background())
+	if err != nil {
+		jsonBytes, _ := json.Marshal(list)
+		fmt.Println("add json:", string(jsonBytes))
+		fmt.Println("EsBatchAddOrEditKnowledgeResource err:", err)
+		return
+	}
+	if response.Errors {
+		for i, item := range response.Items {
+			for _, op := range item {
+				if op.Error != nil {
+					utils.FileLog.Warning("EsBatchAddOrEditKnowledgeResource Insert failed: %v", list[i])
+				}
+			}
+		}
+		fmt.Println("EsBatchAddOrEditKnowledgeResource:", response.Errors)
+	} else {
+		fmt.Printf("EsBatchAddOrEditKnowledgeResource:%+v\n", response)
+	}
+	return
+}
+
 // SearchChartInfoData 查询es中的图表数据
-func SearchKnowledgeResourceByEs(resourceType int, keywordStr string, showSysIds []int, myId int, classifyIds []int, sourceList []string, tagIds []int, isIncludeFile bool, from, size int) (list []*knowledge.KnowledgeResource, total int64, err error) {
+func SearchKnowledgeResourceByEs(resourceType int, keywordStr string, showSysIds []int, myId int, classifyIds []int, sourceList []string, tagIds []int, isShowMe, isIncludeFile, isQueryRef bool, from, size int) (list []*knowledge.KnowledgeResource, total int64, err error) {
 	indexName := utils.EsKnowledgeResourceIndexName
 	list = make([]*knowledge.KnowledgeResource, 0)
 	defer func() {
@@ -41,7 +79,7 @@ func SearchKnowledgeResourceByEs(resourceType int, keywordStr string, showSysIds
 			},
 		})
 	}
-	if myId > 0 {
+	if myId > 0 && isShowMe {
 		mustMap = append(mustMap, map[string]interface{}{
 			"term": map[string]interface{}{
 				"AdminId": myId,
@@ -83,6 +121,27 @@ func SearchKnowledgeResourceByEs(resourceType int, keywordStr string, showSysIds
 		})
 	}
 
+	if isQueryRef && resourceType == knowledge.KnowledgeResourceTypeOpinion {
+		shouldMap := map[string]interface{}{
+			"should": []interface{}{
+				map[string]interface{}{
+					"term": map[string]interface{}{
+						"State": knowledge.KnowledgeResourceStatePassed,
+					},
+				},
+				map[string]interface{}{
+					"term": map[string]interface{}{
+						"AdminId": myId,
+					},
+				},
+			},
+			"minimum_should_match": 1,
+		}
+		mustMap = append(mustMap, map[string]interface{}{
+			"bool": shouldMap,
+		})
+	}
+
 	if keywordStr != "" {
 		shouldMap := map[string]interface{}{
 			"should": []interface{}{

+ 80 - 12
services/knowledge/resource.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"errors"
 	"eta_gn/eta_api/models/knowledge"
+	"eta_gn/eta_api/models/knowledge_approve"
 	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/services"
 	"eta_gn/eta_api/services/alarm_msg"
@@ -73,7 +74,7 @@ func AddResource(req *knowledge.AddReq, sysUser *system.Admin) (item *knowledge.
 			return
 		}*/
 	} else {
-		if req.FileUrl == "" {
+		if len(req.FileUrl) == 0 {
 			errMsg = "内容或文件不能为空"
 			err = fmt.Errorf("内容或文件不能为空")
 			return
@@ -120,12 +121,11 @@ func AddResource(req *knowledge.AddReq, sysUser *system.Admin) (item *knowledge.
 	item.SourceFrom = req.SourceFrom
 	item.ResourceType = req.ResourceType
 	item.Title = req.Title
-	item.State = 1
+	item.State = knowledge.KnowledgeResourceStateUnpublished
 	item.Content = html.EscapeString(req.Content)
 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
 	item.ResourceCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
 	item.IsFile = isFile
-	item.FileUrl = req.FileUrl
 	//todo 内容前5行
 	//item.ContentSub = html.EscapeString(contentSub)
 	if !startTime.IsZero() {
@@ -146,7 +146,7 @@ func AddResource(req *knowledge.AddReq, sysUser *system.Admin) (item *knowledge.
 	item.ModifyTime = time.Now()
 	item.CreateTime = time.Now()
 
-	err = item.Add(item)
+	err = item.AddWithFile(req.FileUrl)
 	if err != nil {
 		errMsg = "保存失败"
 		err = fmt.Errorf("保存失败,Err:" + err.Error())
@@ -196,7 +196,7 @@ func EditResource(resourceInfo *knowledge.KnowledgeResource, req knowledge.EditR
 			return
 		}
 	} else if resourceInfo.IsFile == 1 {
-		if req.FileUrl == "" {
+		if len(req.FileUrl) == 0 {
 			errMsg = "文件地址不能为空"
 			err = fmt.Errorf("文件地址不能为空")
 			return
@@ -268,15 +268,14 @@ func EditResource(resourceInfo *knowledge.KnowledgeResource, req knowledge.EditR
 	if !endTime.IsZero() {
 		resourceInfo.EndTime = &endTime
 	}
-	resourceInfo.FileUrl = req.FileUrl
 	//resourceInfo.LastModifyAdminId = sysUser.AdminId
 	//resourceInfo.LastModifyAdminName = sysUser.RealName
 	resourceInfo.ModifyTime = time.Now()
 
-	updateCols := []string{"ClassifyId", "SourceFrom", "TagId", "Title", "Content", "StartTime", "EndTime", "ModifyTime", "FileUrl"}
+	updateCols := []string{"ClassifyId", "SourceFrom", "TagId", "Title", "Content", "StartTime", "EndTime", "ModifyTime"}
 
 	// 修改报告的基本信息,以及报告的授权用户
-	err = resourceInfo.Update(updateCols)
+	err = resourceInfo.UpdateWithFile(updateCols, req.FileUrl)
 	if err != nil {
 		return
 	}
@@ -413,6 +412,7 @@ func ImportResourceData(path string, resourceType int, sysUser *system.Admin) (s
 		tagNameMap[v.TagName] = v.TagId
 	}
 
+	var addlist []*knowledge.KnowledgeResource
 	for _, v := range indexDataList {
 		errTip := ""
 		classifyId := 0
@@ -486,7 +486,7 @@ func ImportResourceData(path string, resourceType int, sysUser *system.Admin) (s
 				req.EndTime = fmt.Sprintf("%s %s", v.EndDate, v.EndTime)
 			}
 		}
-		tmpErr, msg := addExcelResource(req, sysUser)
+		item, tmpErr, msg := addExcelResource(req, sysUser)
 		if tmpErr != nil {
 			failItem := &knowledge.KnowledgeImportFail{
 				Title:          v.Title,
@@ -508,9 +508,17 @@ func ImportResourceData(path string, resourceType int, sysUser *system.Admin) (s
 			continue
 		} else {
 			successCount++
+			addlist = append(addlist, item)
 		}
 	}
 
+	go func() {
+		err = EsBatchAddOrEditKnowledgeResource(addlist)
+		if err != nil {
+			utils.FileLog.Info("知识资源EsBatchAddOrEditKnowledgeResource失败,err:%s, err", err.Error())
+		}
+	}()
+
 	// 失败数量
 	failCount = len(failDataList)
 	//fmt.Println("failDataList:", len(failDataList))
@@ -993,7 +1001,7 @@ func getExcelDate(createDate string) (newCreateDate string, err error) {
 	return
 }
 
-func addExcelResource(req *knowledge.AddReq, sysUser *system.Admin) (err error, errMsg string) {
+func addExcelResource(req *knowledge.AddReq, sysUser *system.Admin) (item *knowledge.KnowledgeResource, err error, errMsg string) {
 	var startTime time.Time
 	var endTime time.Time
 	if req.StartTime != "" {
@@ -1024,13 +1032,13 @@ func addExcelResource(req *knowledge.AddReq, sysUser *system.Admin) (err error,
 			}
 		}
 	}
-	item := new(knowledge.KnowledgeResource)
+	item = new(knowledge.KnowledgeResource)
 	item.ClassifyId = req.ClassifyId
 	item.TagId = req.TagId
 	item.SourceFrom = req.SourceFrom
 	item.ResourceType = req.ResourceType
 	item.Title = req.Title
-	item.State = 1
+	item.State = knowledge.KnowledgeResourceStateUnpublished
 	item.Content = html.EscapeString(req.Content)
 	timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
 	item.ResourceCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
@@ -1061,6 +1069,66 @@ func addExcelResource(req *knowledge.AddReq, sysUser *system.Admin) (err error,
 	return
 }
 
+func SetKnowledgeResourcePublic(knowledgeId int) (errMsg string, err error) {
+	obj := new(knowledge.KnowledgeResource)
+	obj, err = obj.GetById(knowledgeId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			errMsg = "资源不存在"
+			return
+		}
+		errMsg = "获取资源失败"
+		err = fmt.Errorf("获取资源失败,Err:%v", err.Error())
+		return
+	}
+	if !(obj.State == knowledge.KnowledgeResourceStateUnpublished || obj.State == knowledge.KnowledgeResourceStateRejected) {
+		errMsg = "不能重复设置公共"
+		err = fmt.Errorf("不能重复设置公共")
+		return
+	}
+	if obj.ResourceType != knowledge.KnowledgeResourceTypeOpinion {
+		errMsg = "非法操作"
+		err = fmt.Errorf("非法操作")
+		return
+	}
+
+	flowOb := new(knowledge_approve.KnowledgeResourceApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveFlowCols.ClassifyId)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, obj.ClassifyId)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	var opening bool
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			opening = false
+			errMsg = "分类未开启审批流"
+			err = fmt.Errorf("分类未开启审批流")
+			return
+		}
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+	if flowItem != nil && flowItem.KnowledgeResourceApproveFlowId > 0 {
+		opening = true
+	}
+
+	if !opening {
+		errMsg = "分类未开启审批流"
+		err = fmt.Errorf("分类未开启审批流")
+		return
+	}
+
+	obj.State = knowledge.KnowledgeResourceStatePending
+	obj.ModifyTime = time.Now()
+	err = obj.Update([]string{"state", "modify_time"})
+	if err != nil {
+		errMsg = "设置失败"
+		err = fmt.Errorf("设置失败,Err:%s", err.Error())
+		return
+	}
+	return
+}
+
 func GetKnowledgeResourceTmpList(dashboardDetailId, adminId int) (resp *knowledge.BiDashboardResourceAddResp, msg string, err error) {
 	if dashboardDetailId <= 0 {
 		data, er := utils.Rc.RedisBytes(utils.CACHE_KEY_BI_DASHBOARD_PREPARE_RESOURCE + strconv.Itoa(adminId))

+ 30 - 0
services/knowledge_approve/constant.go

@@ -0,0 +1,30 @@
+package knowledge_approve
+
+// 看板状态
+const (
+	KnowledgeStateUnpublished = 0 // 未公开
+	KnowledgeStateWaitApprove = 2 // 待审批
+	KnowledgeStateRefused     = 3 // 已驳回
+	KnowledgeStatePass        = 4 // 已通过
+)
+
+// 节点审批方式
+const (
+	NodeApproveTypeRoll = 1 // 依次审批
+	NodeApproveTypeAll  = 2 // 会签
+	NodeApproveTypeAny  = 3 // 或签
+)
+
+// 节点审批人类型
+const (
+	NodeUserTypeNormal = "user" // 用户
+	NodeUserTypeRole   = "role" // 角色
+)
+
+// 报告审批状态
+const (
+	KnowledgeResourceApproveStateApproving = 1 // 待审批
+	KnowledgeResourceApproveStatePass      = 2 // 已审批
+	KnowledgeResourceApproveStateRefuse    = 3 // 已驳回
+	KnowledgeResourceApproveStateCancel    = 4 // 已撤销
+)

+ 1171 - 0
services/knowledge_approve/knowledge_approve.go

@@ -0,0 +1,1171 @@
+package knowledge_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models/knowledge"
+	"eta_gn/eta_api/models/knowledge_approve"
+	"eta_gn/eta_api/models/knowledge_approve/response"
+	knowledgeSrv "eta_gn/eta_api/services/knowledge"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strings"
+	"time"
+)
+
+var (
+	timeField   = map[int]string{1: fmt.Sprintf("a.%s", knowledge_approve.KnowledgeResourceApproveRecordCols.CreateTime), 2: fmt.Sprintf("a.%s", knowledge_approve.KnowledgeResourceApproveRecordCols.NodeApproveTime), 3: fmt.Sprintf("b.%s", knowledge_approve.KnowledgeResourceApproveCols.ApproveTime)}
+	myTimeField = map[int]string{1: knowledge_approve.KnowledgeResourceApproveCols.CreateTime, 3: knowledge_approve.KnowledgeResourceApproveCols.ApproveTime}
+	orderRules  = map[int]string{1: "ASC", 2: "DESC"}
+)
+
+func GetPulicKnowledgeClassifyList(resourceType int) (res []*knowledge.KnowledgeClassifyItem, msg string, err error) {
+	obj := new(knowledge.KnowledgeClassify)
+	classifyList, err := obj.GetAllClassify(resourceType)
+	if err != nil {
+		msg = "获取公共分类列表失败"
+		return
+	}
+	res = toClassifyTree(classifyList, 0)
+	return
+}
+
+func PassKnowledgeResourceApprove(approveId int, adminId int) (msg string, err error) {
+	approveItem, e := knowledge_approve.GetKnowledgeResourceApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	if approveItem.State != KnowledgeResourceApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	var ApprovePars []interface{}
+	Approveconds := ` AND knowledge_resource_approve_id =? AND approve_user_id =? AND state =? `
+	ApprovePars = append(ApprovePars, approveId, adminId, KnowledgeResourceApproveStateApproving)
+
+	recordItem, er := knowledge_approve.GetKnowledgeResourceApproveRecordByCondition(Approveconds, ApprovePars)
+	if er != nil {
+		if utils.IsErrNoRow(er) {
+			msg = "无权审批"
+			err = er
+			return
+		}
+		msg = "操作失败"
+		return
+	}
+
+	// 查询审批流和审批流节点
+	flowItem, e := knowledge_approve.GetKnowledgeResourceApproveFlowById(approveItem.FlowId)
+	if e != nil {
+		err = fmt.Errorf("获取审批流失败, Err: %s", e.Error())
+		return
+	}
+	nodePars := make([]interface{}, 0)
+	nodeCond := ` AND knowledge_resource_approve_flow_id =? AND curr_version =? `
+	nodePars = append(nodePars, flowItem.KnowledgeResourceApproveFlowId, flowItem.CurrVersion)
+	nodeItems, e := knowledge_approve.GetKnowledgeResourceApproveNodeByCondition(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]*knowledge_approve.KnowledgeResourceApproveNode)
+	for _, v := range nodeItems {
+		nodeMap[v.KnowledgeResourceApproveNodeId] = v
+	}
+
+	// 取出审批记录的节点
+	currNodeItem := nodeMap[recordItem.NodeId]
+	if currNodeItem == nil {
+		err = fmt.Errorf("当前节点信息有误")
+		return
+	}
+	currNode, e := FormatKnowledgeResourceApproveNode2Item(currNodeItem)
+	if e != nil {
+		err = fmt.Errorf("当前节点信息有误, Err: %s", e.Error())
+		return
+	}
+	now := time.Now().Local()
+	recordItem.State = KnowledgeResourceApproveStatePass
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+	recordItem.NodeState = KnowledgeResourceApproveStatePass
+	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.KnowledgeResourceApproveNodeUser) // 下一个审批人, 为nil则表示当前审批人即为最后
+		for k, v := range currNode.Users {
+			// 当前审批人
+			if v.UserId == adminId && recordItem.ApproveUserSort == v.Sort {
+				if (k + 1) < userLen {
+					nextUser = currNode.Users[k+1]
+				}
+			}
+		}
+		// 当前节点下一个审批人, 生成下一个审批记录且return
+		if nextUser.UserId > 0 {
+			newRecord := new(knowledge_approve.KnowledgeResourceApproveRecord)
+			newRecord.KnowledgeResourceApproveId = recordItem.KnowledgeResourceApproveId
+			newRecord.State = KnowledgeResourceApproveStateApproving
+			newRecord.NodeId = currNode.KnowledgeResourceApproveNodeId
+			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 = KnowledgeResourceApproveStateApproving
+			if e = newRecord.Create(); e != nil {
+				err = fmt.Errorf("生成审批记录失败, Err: %s", e.Error())
+				return
+			}
+
+			// 推送审批消息
+			go func() {
+				messageItem := new(knowledge_approve.KnowledgeResourceApproveMessage)
+				messageItem.SendUserId = approveItem.ApplyUserId
+				messageItem.ReceiveUserId = nextUser.UserId
+				messageItem.Content = "您有新的待办任务"
+				messageItem.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", approveItem.ApplyUserName, approveItem.KnowledgeResourceTitle)
+				messageItem.KnowledgeResourceApproveId = approveItem.KnowledgeResourceApproveId
+				messageItem.ApproveState = KnowledgeResourceApproveStateApproving
+				messageItem.CreateTime = now
+				messageItem.ModifyTime = now
+				if e = messageItem.Create(); e != nil {
+					utils.FileLog.Info(fmt.Sprintf("PassKnowledgeResourceApprove 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.KnowledgeResourceApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.KnowledgeResourceTitle)
+			return
+		} else {
+			// 最后一个节点
+			lastApprove = true
+		}
+	}
+
+	// 会签
+	if currNode.ApproveType == NodeApproveTypeAll {
+		// 查询其他审批人是否已审批
+		otherCond := ` AND knowledge_resource_approve_id =? AND node_id =? AND approve_user_id <> ? `
+		otherPars := make([]interface{}, 0)
+		otherPars = append(otherPars, approveItem.KnowledgeResourceApproveId, recordItem.NodeId, adminId)
+		otherRecords, e := knowledge_approve.GetKnowledgeResourceApproveRecordItemsByCondition(otherCond, otherPars)
+		if e != nil {
+			err = fmt.Errorf("获取节点审批记录失败, Err: %s", e.Error())
+			return
+		}
+		otherPass := true
+		for _, v := range otherRecords {
+			if v.State != KnowledgeResourceApproveStatePass {
+				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.KnowledgeResourceApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.KnowledgeResourceTitle)
+			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.KnowledgeResourceApproveId, 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.KnowledgeResourceApproveId, approveItem.ApplyUserId, approveItem.ApplyUserName, approveItem.KnowledgeResourceTitle)
+			return
+		}
+	}
+
+	// 最后一个审批, 更新审批记录、审批、报告状态、推送消息给申请人
+	if lastApprove {
+		if e = recordItem.Update(recordCols); e != nil {
+			err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error())
+			return
+		}
+		approveItem.State = KnowledgeResourceApproveStatePass
+		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 = updateKnowledgeResourceApproveState(approveItem.KnowledgeResourceId, KnowledgeStatePass); e != nil {
+			err = fmt.Errorf("更新报告审批状态失败, Err: %s", e.Error())
+			return
+		}
+		go func() {
+			obj := new(knowledge.KnowledgeResource)
+			KnowledgeItem, e := obj.GetById(approveItem.KnowledgeResourceId)
+			if e != nil && !utils.IsErrNoRow(e) {
+				utils.FileLog.Info(fmt.Sprintf("PassKnowledgeResourceApprove update knowledge resource state err: %s", e.Error()))
+				return
+			}
+			e = knowledgeSrv.EsAddOrEditKnowledgeResource(KnowledgeItem)
+			if e != nil {
+				utils.FileLog.Info(fmt.Sprintf("PassKnowledgeResourceApprove update es err: %s", e.Error()))
+				return
+			}
+		}()
+
+		go func() {
+			messageItem := new(knowledge_approve.KnowledgeResourceApproveMessage)
+			messageItem.SendUserId = adminId
+			messageItem.ReceiveUserId = approveItem.ApplyUserId
+			messageItem.Content = "您提交的审批已通过"
+			messageItem.Remark = fmt.Sprintf("您提交的【%s】已通过", approveItem.KnowledgeResourceTitle)
+			messageItem.KnowledgeResourceApproveId = approveItem.KnowledgeResourceApproveId
+			messageItem.ApproveState = KnowledgeResourceApproveStatePass
+			messageItem.CreateTime = now
+			messageItem.ModifyTime = now
+			if e = messageItem.Create(); e != nil {
+				utils.FileLog.Info(fmt.Sprintf("PassKnowledgeResourceApprove message err: %s", e.Error()))
+				return
+			}
+		}()
+	}
+	return
+
+}
+
+func toClassifyTree(src []*knowledge.KnowledgeClassify, parentId int) (dst []*knowledge.KnowledgeClassifyItem) {
+	for _, item := range src {
+		if item.ParentId == parentId {
+			tmp := new(knowledge.KnowledgeClassifyItem)
+			tmp.KnowledgeClassify = *item
+			tmp.Child = toClassifyTree(src, item.ClassifyId)
+			dst = append(dst, tmp)
+		}
+	}
+	return
+}
+
+// BuildNextNodeRecordAndMsg 生成下一个节点的审批记录并推送消息
+func BuildNextNodeRecordAndMsg(approveNodeItem *knowledge_approve.KnowledgeResourceApproveNode, approveId, sysAdminId int, sysAdminName, knowledgeTitle string) (err error) {
+	if approveNodeItem == nil {
+		err = fmt.Errorf("approve node nil")
+		return
+	}
+
+	// 根据节点审批方式生成审批记录
+	now := time.Now().Local()
+	approveNode, e := FormatKnowledgeResourceApproveNode2Item(approveNodeItem)
+	if e != nil {
+		err = fmt.Errorf("FormatKnowledgeResourceApproveNode2Item err: %s", e.Error())
+		return
+	}
+	if len(approveNode.Users) == 0 {
+		err = fmt.Errorf("审批节点用户有误")
+		return
+	}
+	newRecords := make([]*knowledge_approve.KnowledgeResourceApproveRecord, 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(knowledge_approve.KnowledgeResourceApproveRecord)
+		r.KnowledgeResourceApproveId = approveId
+		r.State = KnowledgeResourceApproveStateApproving
+		r.NodeId = approveNode.KnowledgeResourceApproveNodeId
+		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 = KnowledgeResourceApproveStateApproving // 当前节点审批状态
+		newRecords = append(newRecords, r)
+		// 依次审批仅生成一条记录
+		if approveNode.ApproveType == NodeApproveTypeRoll {
+			break
+		}
+	}
+
+	recordOb := new(knowledge_approve.KnowledgeResourceApproveRecord)
+	if e = recordOb.CreateMulti(newRecords); e != nil {
+		err = fmt.Errorf("生成节点审批记录失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送审批消息
+	go func() {
+		messageOb := new(knowledge_approve.KnowledgeResourceApproveMessage)
+		messages := make([]*knowledge_approve.KnowledgeResourceApproveMessage, 0)
+		for _, v := range newRecords {
+			m := new(knowledge_approve.KnowledgeResourceApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = "您有新的待办任务"
+			m.Remark = fmt.Sprintf("%s提交的【%s】需要您审批,请及时处理", sysAdminName, knowledgeTitle)
+			m.KnowledgeResourceApproveId = approveId
+			m.ApproveState = KnowledgeResourceApproveStateApproving
+			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
+}
+
+// updateKnowledgeResourceApproveState 更新知识资源审批状态
+func updateKnowledgeResourceApproveState(KnowledgeResourceId, state int) (err error) {
+	// updateCols := []string{"ApproveId", "State", "ModifyTime"}
+	updateCols := []string{"State", "ModifyTime"}
+	obj := new(knowledge.KnowledgeResource)
+	KnowledgeItem, e := obj.GetById(KnowledgeResourceId)
+	if e != nil && !utils.IsErrNoRow(e) {
+		err = fmt.Errorf("获取知识资源失败, Err: %s", e.Error())
+		return
+	}
+	if KnowledgeItem != nil && KnowledgeItem.KnowledgeResourceId > 0 {
+		KnowledgeItem.State = state
+		KnowledgeItem.ModifyTime = time.Now().Local()
+
+		if e = KnowledgeItem.Update(updateCols); e != nil {
+			err = fmt.Errorf("更新知识资源审批状态失败, Err: %s", e.Error())
+			return
+		}
+	}
+	return
+}
+
+func ProcessingKnowledgeResourceApprove(adminId, classifyId, timeType, sortField, sortRule, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.KnowledgeResourceApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND b.%s = ? AND a.%s = ?`, knowledge_approve.KnowledgeResourceApproveRecordCols.State, knowledge_approve.KnowledgeResourceApproveCols.State, knowledge_approve.KnowledgeResourceApproveRecordCols.ApproveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, KnowledgeResourceApproveStateApproving, KnowledgeResourceApproveStateApproving, adminId)
+	order := ""
+
+	// 筛选条件
+	if classifyId > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, knowledge_approve.KnowledgeResourceApproveCols.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 ?)`, knowledge_approve.KnowledgeResourceApproveCols.CreateTime)
+		pars = append(pars, startTime, tmpEndTime)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND b.%s LIKE ?`, knowledge_approve.KnowledgeResourceApproveCols.KnowledgeResourceTitle)
+		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 := knowledge_approve.GetApprovingKnowledgeResourceApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingKnowledgeResourceApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := knowledge_approve.GetApprovingKnowledgeResourceApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovingKnowledgeResourceApprovePageList err: %s", e.Error())
+		return
+	}
+
+	respList = toKnowledgeResourceApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+// SolvedKnowledgeResourceApprove 已处理的审批
+func SolvedKnowledgeResourceApprove(adminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.KnowledgeResourceApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ? AND a.%s IN (?)`, knowledge_approve.KnowledgeResourceApproveRecordCols.ApproveUserId, knowledge_approve.KnowledgeResourceApproveRecordCols.NodeState)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId, []int{KnowledgeResourceApproveStatePass, KnowledgeResourceApproveStateRefuse})
+	order := ""
+
+	// 筛选条件
+	if classifyId > 0 {
+		cond += fmt.Sprintf(` AND b.%s = ?`, knowledge_approve.KnowledgeResourceApproveCols.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 ?`, knowledge_approve.KnowledgeResourceApproveCols.KnowledgeResourceTitle)
+		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 = ?`, knowledge_approve.KnowledgeResourceApproveRecordCols.NodeState)
+		pars = append(pars, approveState)
+	}
+	total, e := knowledge_approve.GetApprovedKnowledgeResourceApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedKnowledgeResourceApproveCount err: %s", e.Error())
+		return
+	}
+	list, e := knowledge_approve.GetApprovedKnowledgeResourceApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApprovedKnowledgeResourceApprovePageList err: %s", e.Error())
+		return
+	}
+
+	for _, v := range list {
+		// 这个时候的状态,用审批状态
+		v.RecordState = v.NodeState
+		v.ApproveTime = v.NodeApproveTime
+	}
+	respList = toKnowledgeResourceApproveItemOrmResp(list)
+	respTotal = total
+	return
+}
+
+func MyApplyKnowledgeResourceApproves(adminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize int, adminName, startTime, endTime, keyword string) (respList []*response.KnowledgeResourceApproveItemOrmResp, respTotal int, msg string, err error) {
+	cond := fmt.Sprintf(` AND a.%s = ?`, knowledge_approve.KnowledgeResourceApproveCols.ApplyUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := ""
+
+	// 筛选条件
+	if classifyId > 0 {
+		cond += fmt.Sprintf(` AND a.%s = ?`, knowledge_approve.KnowledgeResourceApproveCols.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
+		}
+		tmpEndTimeStr := tmpEndTime.AddDate(0, 0, 1).Format(utils.FormatDate)
+		cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, myTimeField[timeType])
+		pars = append(pars, startTime, tmpEndTimeStr)
+	}
+	keyword = strings.TrimSpace(keyword)
+	if keyword != "" {
+		kw := fmt.Sprint("%", keyword, "%")
+		cond += fmt.Sprintf(` AND a.%s LIKE ?`, knowledge_approve.KnowledgeResourceApproveCols.KnowledgeResourceTitle)
+		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 = ?`, knowledge_approve.KnowledgeResourceApproveRecordCols.State)
+		pars = append(pars, approveState)
+	}
+	total, e := knowledge_approve.GetApplyKnowledgeResourceApproveCount(cond, pars)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyKnowledgeResourceApproveCount err: %s", e.Error())
+		return
+	}
+	respTotal = total
+	list, e := knowledge_approve.GetApplyKnowledgeResourceApprovePageList(cond, pars, order, startSize, pageSize)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetApplyKnowledgeResourceApprovePageList err: %s", e.Error())
+		return
+	}
+	respList = toKnowledgeResourceApproveItemOrmResp(list)
+	return
+}
+
+func GetApproveDetail(approveId int) (resp *response.KnowledgeResourceApproveDetail, msg string, err error) {
+	approveItem, e := knowledge_approve.GetKnowledgeResourceApproveById(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.KnowledgeResourceApproveDetail)
+	detail.Approve = new(response.KnowledgeResourceApproveDetailItem)
+	detail.Approve.KnowledgeResourceApproveId = approveItem.KnowledgeResourceApproveId
+	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(knowledge_approve.KnowledgeResourceApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, knowledge_approve.KnowledgeResourceApproveNodeCols.KnowledgeResourceApproveFlowId, knowledge_approve.KnowledgeResourceApproveNodeCols.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(knowledge_approve.KnowledgeResourceApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveRecordCols.KnowledgeResourceApproveId)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.KnowledgeResourceApproveId)
+	recordItems, e := recordOb.GetItemsByCondition(recordCond, recordPars, []string{}, fmt.Sprintf("%s DESC", knowledge_approve.KnowledgeResourceApproveRecordCols.ApproveTime))
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetItemsByCondition err: %s", e.Error())
+		return
+	}
+	recordMap := make(map[string]*knowledge_approve.KnowledgeResourceApproveRecord)
+	for _, v := range recordItems {
+		k := fmt.Sprintf("%d-%d", v.NodeId, v.ApproveUserId)
+		recordMap[k] = v
+	}
+
+	// 审批流节点详情
+	detail.ApproveFlowNodes = make([]*response.KnowledgeResourceApproveDetailNodes, 0)
+	for _, v := range nodeItems {
+		t := new(response.KnowledgeResourceApproveDetailNodes)
+		t.KnowledgeResourceApproveNodeId = v.KnowledgeResourceApproveNodeId
+		t.KnowledgeResourceApproveFlowId = v.KnowledgeResourceApproveFlowId
+		t.PrevNodeId = v.PrevNodeId
+		t.NextNodeId = v.NextNodeId
+		t.NodeType = v.NodeType
+		t.ApproveType = v.ApproveType
+		t.Users = make([]*response.KnowledgeResourceApproveDetailNodeUser, 0)
+		us := make([]*response.KnowledgeResourceApproveNodeUserReq, 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.KnowledgeResourceApproveDetailNodeUser)
+			u.UserType = vu.UserType
+			u.UserId = vu.UserId
+			u.UserName = vu.UserName
+			u.Sort = vu.Sort
+			// 审批记录
+			k := fmt.Sprintf("%d-%d", v.KnowledgeResourceApproveNodeId, vu.UserId)
+			r := recordMap[k]
+			if r != nil {
+				u.ApproveRecord = new(response.KnowledgeResourceApproveDetailNodeUserRecord)
+				u.ApproveRecord.KnowledgeResourceApproveRecordId = r.KnowledgeResourceApproveRecordId
+				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)
+	obj := new(knowledge.KnowledgeClassify)
+	cnClassify, e := obj.GetAllClassify(knowledge.KnowledgeResourceTypeOpinion)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetKnowledgeDashboardClassifyAllList err: %s", e.Error())
+		return
+	}
+	for _, v := range cnClassify {
+		cnClassifyIdName[v.ClassifyId] = v.ClassifyName
+	}
+	detail.Knowledge = new(response.KnowledgeResourceApproveDetailKnowledge)
+	detail.Knowledge.KnowledgeResourceId = approveItem.KnowledgeResourceId
+	detail.Knowledge.KnowledgeResourceTitle = approveItem.KnowledgeResourceTitle
+	detail.Knowledge.KnowledgeClassify = cnClassifyIdName[approveItem.ClassifyId]
+	resp = detail
+	return
+}
+
+func KnowledgeResourceApproveRefuse(KnowledgeResourceApproveId, adminId int, approveRemark string) (msg string, err error) {
+	approveItem, e := knowledge_approve.GetKnowledgeResourceApproveById(KnowledgeResourceApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批不存在, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetKnowledgeResourceApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.State != KnowledgeResourceApproveStateApproving {
+		msg = "审批状态有误, 请刷新页面"
+		err = fmt.Errorf("审批状态有误, State: %d", approveItem.State)
+		return
+	}
+
+	// 校验审批记录和审批
+	recordOb := new(knowledge_approve.KnowledgeResourceApproveRecord)
+	recordCond := fmt.Sprintf(` AND %s = ? AND %s = ? AND %s = ?`, knowledge_approve.KnowledgeResourceApproveRecordCols.KnowledgeResourceApproveId, knowledge_approve.KnowledgeResourceApproveRecordCols.ApproveUserId, knowledge_approve.KnowledgeResourceApproveRecordCols.State)
+	recordPars := make([]interface{}, 0)
+	recordPars = append(recordPars, approveItem.KnowledgeResourceApproveId, adminId, KnowledgeResourceApproveStateApproving)
+	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 = refuseKnowledgeResourceApprove(approveItem, recordItem, approveRemark, adminId); e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("RefuseKnowledgeResourceApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// refuseKnowledgeResourceApprove 驳回审批
+func refuseKnowledgeResourceApprove(approveItem *knowledge_approve.KnowledgeResourceApprove, recordItem *knowledge_approve.KnowledgeResourceApproveRecord, 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 = KnowledgeResourceApproveStateRefuse
+	recordItem.ApproveRemark = approveRemark
+	recordItem.ApproveTime = now
+	recordItem.ModifyTime = now
+
+	recordItem.NodeState = KnowledgeResourceApproveStateRefuse
+	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.KnowledgeResourceApproveId, recordItem.NodeId, recordItem.NodeState, recordItem.NodeApproveUserId, recordItem.NodeApproveUserName, recordItem.NodeApproveTime); e != nil {
+		err = fmt.Errorf("更新同一节点的其他审批记录状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 驳回-更新审批, 报告状态, 推送消息
+	approveItem.State = KnowledgeResourceApproveStateRefuse
+	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 := updateKnowledgeResourceApproveState(approveItem.KnowledgeResourceId, KnowledgeStateRefused); e != nil {
+		err = fmt.Errorf("更新报告状态失败, Err: %s", e.Error())
+		return
+	}
+
+	// 推送驳回消息给申请人
+	go func() {
+		messageItem := new(knowledge_approve.KnowledgeResourceApproveMessage)
+		messageItem.SendUserId = sysAdminId
+		messageItem.ReceiveUserId = approveItem.ApplyUserId
+		messageItem.Content = "您提交的审批被驳回"
+		messageItem.Remark = fmt.Sprintf("您提交的【%s】已被驳回", approveItem.KnowledgeResourceTitle)
+		messageItem.KnowledgeResourceApproveId = approveItem.KnowledgeResourceApproveId
+		messageItem.ApproveState = KnowledgeResourceApproveStateRefuse
+		messageItem.CreateTime = now
+		messageItem.ModifyTime = now
+		if e := messageItem.Create(); e != nil {
+			utils.FileLog.Info(fmt.Sprintf("ApproveKnowledge message err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+func KnowledgeResourceApproveCancel(KnowledgeResourceApproveId, adminId int, adminName string) (msg string, err error) {
+	approveItem, e := knowledge_approve.GetKnowledgeResourceApproveById(KnowledgeResourceApproveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "审批已被删除, 请刷新页面"
+			err = e
+			return
+		}
+		msg = "操作失败"
+		err = fmt.Errorf("GetKnowledgeResourceApproveById err: %s", e.Error())
+		return
+	}
+	if approveItem.ApplyUserId != adminId {
+		msg = "非申请人不可撤销"
+		err = fmt.Errorf("非申请人不可撤销")
+		return
+	}
+
+	// 撤销审批
+	e = cancelKnowledgeResourceApprove(approveItem.KnowledgeResourceId, approveItem.KnowledgeResourceApproveId, adminId, adminName)
+	if e != nil {
+		msg = "操作失败"
+		err = fmt.Errorf("cancelKnowledgeResourceApprove err: %s", e.Error())
+		return
+	}
+	return
+}
+
+// cancelKnowledgeResourceApprove 撤回审批
+func cancelKnowledgeResourceApprove(knowledgeId, approveId, sysAdminId int, sysAdminName string) (err error) {
+	// 默认内部审批, 如果是走的第三方审批, 那么仅修改状态
+	// confMap, e := models.GetBusinessConf()
+	// if e != nil {
+	// 	err = fmt.Errorf("GetBusinessConf err: %s", e.Error())
+	// 	return
+	// }
+	// openApprove := t
+	// if !openApprove {
+	// 	//err = fmt.Errorf("未开启审批")
+	// 	return
+	// }
+
+	// 修改审批信息状态
+	approveItem, e := knowledge_approve.GetKnowledgeResourceApproveById(approveId)
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			err = e
+			return
+		}
+		err = fmt.Errorf("approve GetItemById err: %s", e.Error())
+		return
+	}
+	if approveItem.State == KnowledgeResourceApproveStateCancel {
+		return
+	}
+	approveItem.State = KnowledgeResourceApproveStateCancel
+	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 = updateKnowledgeResourceApproveState(knowledgeId, KnowledgeStateUnpublished)
+	if e != nil {
+		err = fmt.Errorf("更新报告审批撤回失败, Err: %s", e.Error())
+		return
+	}
+	// 推送到Es
+	go func() {
+		obj := new(knowledge.KnowledgeResource)
+		KnowledgeItem, e := obj.GetById(approveItem.KnowledgeResourceId)
+		if e != nil && !utils.IsErrNoRow(e) {
+			utils.FileLog.Info(fmt.Sprintf("PassKnowledgeResourceApprove update knowledge resource state err: %s", e.Error()))
+			return
+		}
+		e = knowledgeSrv.EsAddOrEditKnowledgeResource(KnowledgeItem)
+		if e != nil {
+			utils.FileLog.Info(fmt.Sprintf("PassKnowledgeResourceApprove update es err: %s", e.Error()))
+			return
+		}
+	}()
+	// 推送撤回消息
+	go func() {
+		recordOb := new(knowledge_approve.KnowledgeResourceApproveRecord)
+		recordCond := fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveRecordCols.KnowledgeResourceApproveId)
+		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(knowledge_approve.KnowledgeResourceApproveMessage)
+		messages := make([]*knowledge_approve.KnowledgeResourceApproveMessage, 0)
+		for _, v := range recordItems {
+			m := new(knowledge_approve.KnowledgeResourceApproveMessage)
+			m.SendUserId = sysAdminId
+			m.ReceiveUserId = v.ApproveUserId
+			m.Content = fmt.Sprintf("%s提交的【%s】已撤回", sysAdminName, approveItem.KnowledgeResourceTitle)
+			m.KnowledgeResourceApproveId = approveId
+			m.ApproveState = KnowledgeResourceApproveStateCancel
+			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("CancelKnowledgeResourceApprove messages err: %s", e.Error()))
+			return
+		}
+	}()
+	return
+}
+
+// CheckKnowledgeOpenApprove 校验报告是否开启了审批流
+func CheckKnowledgeOpenApprove(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(knowledge_approve.KnowledgeResourceApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveFlowCols.ClassifyId)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, classifyId)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			opening = false
+			return
+		}
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 开启审批/有审批流
+	if flowItem != nil {
+		opening = true
+		return
+	}
+	return
+}
+
+// SubmitKnowledgeResourceApprove 提交审批
+func SubmitKnowledgeResourceApprove(KnowledgeResourceId int, KnowledgeResourceTitle string, classifyId int, sysAdminId int, sysAdminName string) (approveId int, msg 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
+	// }
+
+	// 查询审批流
+	flowOb := new(knowledge_approve.KnowledgeResourceApproveFlow)
+	flowCond := fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveFlowCols.ClassifyId)
+	flowPars := make([]interface{}, 0)
+	flowPars = append(flowPars, classifyId)
+	flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "")
+	if e != nil {
+		if utils.IsErrNoRow(e) {
+			msg = "该分类未设置审批流"
+			return
+		}
+		err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error())
+		return
+	}
+
+	// 查询审批节点
+	nodeOb := new(knowledge_approve.KnowledgeResourceApproveNode)
+	nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, knowledge_approve.KnowledgeResourceApproveNodeCols.KnowledgeResourceApproveFlowId, knowledge_approve.KnowledgeResourceApproveNodeCols.CurrVersion)
+	nodePars := make([]interface{}, 0)
+	nodePars = append(nodePars, flowItem.KnowledgeResourceApproveFlowId, 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 {
+		msg = "无审批节点"
+		err = fmt.Errorf("无审批节点")
+		return
+	}
+
+	// 取出首个节点
+	firstNodeItem := new(knowledge_approve.KnowledgeResourceApproveNode)
+	for _, v := range nodeItems {
+		if v.PrevNodeId == 0 {
+			firstNodeItem = v
+			continue
+		}
+	}
+	if firstNodeItem == nil {
+		err = fmt.Errorf("首个审批节点有误")
+		return
+	}
+
+	// 审批信息
+	now := time.Now().Local()
+	newApprove := new(knowledge_approve.KnowledgeResourceApprove)
+	newApprove.KnowledgeResourceId = KnowledgeResourceId
+	newApprove.KnowledgeResourceTitle = KnowledgeResourceTitle
+	newApprove.ClassifyId = classifyId
+	newApprove.State = KnowledgeResourceApproveStateApproving
+	newApprove.FlowId = flowItem.KnowledgeResourceApproveFlowId
+	newApprove.FlowVersion = flowItem.CurrVersion
+	newApprove.StartNodeId = firstNodeItem.KnowledgeResourceApproveNodeId
+	newApprove.CurrNodeId = firstNodeItem.KnowledgeResourceApproveNodeId
+	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.KnowledgeResourceApproveId
+
+	// 生成节点审批记录
+	err = BuildNextNodeRecordAndMsg(firstNodeItem, newApprove.KnowledgeResourceApproveId, sysAdminId, sysAdminName, newApprove.KnowledgeResourceTitle)
+	return
+}
+
+func toKnowledgeResourceApproveItemOrmResp(src []*knowledge_approve.KnowledgeResourceApproveItemOrm) (res []*response.KnowledgeResourceApproveItemOrmResp) {
+	res = make([]*response.KnowledgeResourceApproveItemOrmResp, 0)
+	for _, v := range src {
+		r := new(response.KnowledgeResourceApproveItemOrmResp)
+		r.KnowledgeResourceApproveId = v.KnowledgeResourceApproveId
+		r.KnowledgeResourceApproveRecordId = v.KnowledgeResourceApproveRecordId
+		r.KnowledgeResourceId = v.KnowledgeResourceId
+		r.KnowledgeResourceTitle = v.KnowledgeResourceTitle
+		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 = utils.TimeTransferString(utils.FormatDateTime, v.ApproveTime)
+		r.HandleTime = utils.TimeTransferString(utils.FormatDateTime, v.HandleTime)
+		r.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime)
+		r.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime)
+		r.NodeState = v.NodeState
+		res = append(res, r)
+	}
+	return
+}
+
+func GetKnowledgeClassifyAll() (list []*knowledge.KnowledgeClassify, msg string, err error) {
+	obj := new(knowledge.KnowledgeClassify)
+	ClassifyList, e := obj.GetAllClassify(knowledge.KnowledgeResourceTypeOpinion)
+	if e != nil {
+		msg = "获取失败"
+		err = fmt.Errorf("GetKnowledgeDashboardClassifyAllList err: %s", e.Error())
+		return
+	}
+	list = ClassifyList
+	return
+}
+
+func CheckHasApprovingKnowledge() (ok bool, err error) {
+	count, err := knowledge_approve.GetKnowledgeResourceApproveCountByState(KnowledgeResourceApproveStateApproving)
+	if err != nil {
+		return
+	}
+	if count > 0 {
+		ok = true
+	}
+	return
+}
+
+func GetKnowledgeApproveIdByKnowledgeResourceId(knowledgeResourceId int) (approveId int, err error) {
+	approveItem, err := knowledge_approve.GetKnowledgeApproveByKnowledgeId(knowledgeResourceId)
+	if err != nil {
+		return
+	}
+	approveId = approveItem.KnowledgeResourceApproveId
+	return
+}

+ 300 - 0
services/knowledge_approve/knowledge_approve_flow.go

@@ -0,0 +1,300 @@
+package knowledge_approve
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models/knowledge"
+	knowledge_approve "eta_gn/eta_api/models/knowledge_approve"
+	"eta_gn/eta_api/models/knowledge_approve/request"
+	"eta_gn/eta_api/models/knowledge_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"sort"
+	"strings"
+	"time"
+)
+
+// GetKnowledgeResourceApproveFlowList 获取知识资源审批流列表
+func GetKnowledgeResourceApproveFlowList(condition string, pars []interface{}, startSize, pageSize int) (items []*response.KnowledgeResourceApproveFlowItem, total int, msg string, err error) {
+	total, err = knowledge_approve.GetKnowledgeResourceApproveFlowCountByCondition(condition, pars)
+	if err != nil {
+		msg = "获取审批流程列表失败"
+		return
+	}
+	if total == 0 {
+		items = make([]*response.KnowledgeResourceApproveFlowItem, 0)
+		return
+	}
+	flowList, err := knowledge_approve.GetKnowledgeResourceApproveFlowByCondition(condition, pars, startSize, pageSize)
+	if err != nil {
+		msg = "获取审批流程列表失败"
+		return
+	}
+	obj := new(knowledge.KnowledgeClassify)
+	classifyList, err := obj.GetAllClassify(knowledge.KnowledgeResourceTypeOpinion)
+	if err != nil {
+		msg = "获取审批流程列表失败"
+		err = fmt.Errorf("获取分类列表失败,%+v", err)
+		return
+	}
+	sort.Slice(classifyList, func(i, j int) bool {
+		if classifyList[i].Level != classifyList[j].Level {
+			return classifyList[i].Level < classifyList[j].Level
+		}
+		return classifyList[i].ClassifyId < classifyList[j].ClassifyId
+	})
+	classifyMap := make(map[int]*knowledge.KnowledgeClassify)
+	for _, classify := range classifyList {
+		classifyMap[classify.ClassifyId] = classify
+	}
+	classifyPathMap := make(map[int]map[int]string)
+	for _, classify := range classifyList {
+		if _, ok := classifyPathMap[classify.ClassifyId]; !ok {
+			classifyPathMap[classify.ClassifyId] = make(map[int]string)
+		}
+
+		currClassifyMap := classifyPathMap[classify.ClassifyId]
+		currClassify := classify
+		for i := classify.Level; i > 0; i-- {
+			currClassifyMap[currClassify.Level] = currClassify.ClassifyName
+			if currClassify.ParentId == 0 {
+				break
+			}
+			currClassify = classifyMap[currClassify.ParentId]
+		}
+	}
+
+	items = toKnowledgeResourceApproveFlowItem(flowList, classifyPathMap)
+	return
+}
+
+// SaveKnowledgeResourceApproveFlow 保存审批流
+func SaveKnowledgeResourceApproveFlow(flow *request.KnowledgeResourceApproveFlowSaveReq) (ok bool, msg string, err error) {
+	obj := new(knowledge.KnowledgeClassify)
+	_, err = obj.GetClassifyById(flow.ClassifyId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			msg = "保存审批流失败, 分类不存在"
+			return
+		}
+		msg = "保存审批流失败"
+		return
+	}
+	if flow.KnowledgeResourceApproveFlowId == 0 {
+		tmp, er := knowledge_approve.GetKnowledgeResourceApproveFlowByClassifyId(flow.ClassifyId)
+		if er != nil && !utils.IsErrNoRow(er) {
+			msg = "保存审批流失败"
+			err = er
+			return
+		}
+		if tmp != nil && tmp.KnowledgeResourceApproveFlowId > 0 {
+			msg = "保存审批流失败, 分类下已存在审批流"
+			err = fmt.Errorf("分类下已存在审批流")
+			return
+		}
+
+		t := &knowledge_approve.KnowledgeResourceApproveFlow{
+			FlowName:    flow.FlowName,
+			ClassifyId:  flow.ClassifyId,
+			CurrVersion: 1,
+			CreateTime:  time.Now(),
+			ModifyTime:  time.Now(),
+		}
+		knowledgeFlowNodeItems := make([]*knowledge_approve.KnowledgeResourceApproveNode, 0)
+		for _, node := range flow.Nodes {
+			knowledgeFlowNode := new(knowledge_approve.KnowledgeResourceApproveNode)
+			knowledgeFlowNode.ApproveType = node.ApproveType
+			knowledgeFlowNode.CurrVersion = t.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			knowledgeFlowNode.Users = string(userBytes)
+			knowledgeFlowNode.CreatedTime = time.Now()
+			knowledgeFlowNodeItems = append(knowledgeFlowNodeItems, knowledgeFlowNode)
+		}
+		err = t.Add(knowledgeFlowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	} else {
+		resFlow, er := knowledge_approve.GetKnowledgeResourceApproveFlowById(flow.KnowledgeResourceApproveFlowId)
+		if er != nil {
+			msg = "保存审批流失败"
+			err = er
+			return
+		}
+		ok, err = CheckDeleteKnowledgeResourceApproveFlow(resFlow.KnowledgeResourceApproveFlowId)
+		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")
+
+		knowledgeFlowNodeItems := make([]*knowledge_approve.KnowledgeResourceApproveNode, 0)
+		for _, node := range flow.Nodes {
+			knowledgeFlowNode := new(knowledge_approve.KnowledgeResourceApproveNode)
+			knowledgeFlowNode.ApproveType = node.ApproveType
+			knowledgeFlowNode.CurrVersion = resFlow.CurrVersion
+			userBytes, er := json.Marshal(node.Users)
+			if er != nil {
+				err = er
+				msg = "保存审批流失败"
+				return
+			}
+			knowledgeFlowNode.Users = string(userBytes)
+			knowledgeFlowNode.CreatedTime = time.Now()
+			knowledgeFlowNodeItems = append(knowledgeFlowNodeItems, knowledgeFlowNode)
+		}
+
+		err = resFlow.Update(updateCols, knowledgeFlowNodeItems)
+		if err != nil {
+			msg = "保存审批流失败"
+			return
+		}
+		ok = true
+	}
+	return
+}
+
+// GetKnowledgeResourceApproveFlowDetail 获取审批流详情
+func GetKnowledgeResourceApproveFlowDetail(flowId int) (detail *response.KnowledgeResourceApproveFlowDetailResp, msg string, err error) {
+	flowInfo, err := knowledge_approve.GetKnowledgeResourceApproveFlowById(flowId)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	flowNodes, err := knowledge_approve.GetKnowledgeResourceApproveNodeByFlowIdAndVersionId(flowId, flowInfo.CurrVersion)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	detail, err = FormatFlowAndNodesItem2Detail(flowInfo, flowNodes)
+	if err != nil {
+		msg = "获取审批流详情失败"
+		return
+	}
+	return
+}
+
+// DeleteKnowledgeResourceApproveFlow 删除审批流
+func DeleteKnowledgeResourceApproveFlow(flowId int) (ok bool, msg string, err error) {
+	ok, err = CheckDeleteKnowledgeResourceApproveFlow(flowId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			msg = "删除审批流失败, 审批流不存在"
+			return
+		}
+		msg = "删除审批流失败"
+		return
+	}
+	if !ok {
+		msg = "删除审批流失败, 存在还未审批的报告"
+		return
+	}
+
+	t := &knowledge_approve.KnowledgeResourceApproveFlow{
+		KnowledgeResourceApproveFlowId: flowId,
+	}
+	err = t.Delete()
+	if err != nil {
+		msg = "删除审批流失败"
+		return
+	}
+	ok = true
+	return
+}
+
+// CheckDeleteKnowledgeResourceApproveFlow 检查是否可以删除审批流
+func CheckDeleteKnowledgeResourceApproveFlow(flowId int) (ok bool, err error) {
+	flowInfo, err := knowledge_approve.GetKnowledgeResourceApproveFlowById(flowId)
+	if err != nil {
+		return
+	}
+	// 检查是否存在还未审批的知识资源
+	approveList, err := knowledge_approve.GetKnowledgeResourceApproveByFlowIdAndVersionId(flowInfo.KnowledgeResourceApproveFlowId, flowInfo.CurrVersion)
+	if err != nil {
+		return
+	}
+	for _, v := range approveList {
+		if v.State == KnowledgeResourceApproveStateApproving {
+			return false, nil
+		}
+	}
+
+	ok = true
+	return
+}
+
+func toKnowledgeResourceApproveFlowItem(src []*knowledge_approve.KnowledgeResourceApproveFlow, classifyPathMap map[int]map[int]string) (res []*response.KnowledgeResourceApproveFlowItem) {
+	res = make([]*response.KnowledgeResourceApproveFlowItem, 0, len(src))
+	for _, item := range src {
+		classifyArr := make([]string, 0)
+		for i := 1; i <= 3; i++ {
+			if v, ok := classifyPathMap[item.ClassifyId][i]; ok {
+				classifyArr = append(classifyArr, v)
+			}
+		}
+		res = append(res, &response.KnowledgeResourceApproveFlowItem{
+			KnowledgeResourceApproveFlowId: item.KnowledgeResourceApproveFlowId,
+			FlowName:                       item.FlowName,
+			ClassifyId:                     item.ClassifyId,
+			ClassifyName:                   strings.Join(classifyArr, "/"),
+			CurrVersion:                    item.CurrVersion,
+			CreateTime:                     item.CreateTime.Format(utils.FormatDateTime),
+			ModifyTime:                     item.ModifyTime.Format(utils.FormatDateTime),
+		})
+	}
+	return
+}
+
+func FormatFlowAndNodesItem2Detail(flowItem *knowledge_approve.KnowledgeResourceApproveFlow, nodeItems []*knowledge_approve.KnowledgeResourceApproveNode) (detail *response.KnowledgeResourceApproveFlowDetailResp, err error) {
+	if flowItem == nil {
+		return
+	}
+	detail = new(response.KnowledgeResourceApproveFlowDetailResp)
+	detail.KnowledgeResourceApproveFlowId = flowItem.KnowledgeResourceApproveFlowId
+	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.KnowledgeResourceApproveNodeItem, 0)
+	for _, v := range nodeItems {
+		t, e := FormatKnowledgeResourceApproveNode2Item(v)
+		if e != nil {
+			err = fmt.Errorf("format node err: %s", e.Error())
+			return
+		}
+		detail.Nodes = append(detail.Nodes, t)
+	}
+	return
+}
+
+// func ModifyKnowledgeResourceApproveFlowClassify(classifyId int, classifyName string) (err error) {
+// 	flow, err := knowledge_approve.GetKnowledgeResourceApproveFlowByClassifyId(classifyId)
+// 	if err != nil && !utils.IsErrNoRow(err) {
+// 		return
+// 	}
+// 	if utils.IsErrNoRow(err) {
+// 		err = nil
+// 		return
+// 	}
+// 	if classifyName != "" && flow.ClassifyName != classifyName {
+// 		err = knowledge_approve.UpdateFlowClassifyName(classifyId, classifyName)
+// 	}
+// 	return
+// }

+ 90 - 0
services/knowledge_approve/knowledge_approve_message.go

@@ -0,0 +1,90 @@
+package knowledge_approve
+
+import (
+	"eta_gn/eta_api/models/knowledge_approve"
+	"eta_gn/eta_api/models/knowledge_approve/response"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"time"
+)
+
+func GetKnowledgeResourceApproveMessage(adminId, startSize, pageSize int) (list []*response.KnowledgeResourceApproveMessageItem, total, unread int, msg string, err error) {
+	list = make([]*response.KnowledgeResourceApproveMessageItem, 0)
+	cond := fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveMessageCols.ReceiveUserId)
+	pars := make([]interface{}, 0)
+	pars = append(pars, adminId)
+	order := fmt.Sprintf(`%s ASC, %s DESC`, knowledge_approve.KnowledgeResourceApproveMessageCols.IsRead, knowledge_approve.KnowledgeResourceApproveMessageCols.CreateTime)
+
+	messageOb := new(knowledge_approve.KnowledgeResourceApproveMessage)
+	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 := FormatKnowledgeResourceApproveMessage2Item(v)
+		list = append(list, t)
+	}
+
+	// 未读消息数
+	cond += fmt.Sprintf(` AND %s = ?`, knowledge_approve.KnowledgeResourceApproveMessageCols.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 ReadKnowledgeMessage(msgId int, adminId int) (msg string, err error) {
+	messageOb := new(knowledge_approve.KnowledgeResourceApproveMessage)
+	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
+}
+
+// FormatKnowledgeResourceApproveMessage2Item 格式化报告审批消息
+func FormatKnowledgeResourceApproveMessage2Item(origin *knowledge_approve.KnowledgeResourceApproveMessage) (item *response.KnowledgeResourceApproveMessageItem) {
+	item = new(response.KnowledgeResourceApproveMessageItem)
+	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.KnowledgeResourceApproveId = origin.KnowledgeResourceApproveId
+	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/knowledge_approve/knowledge_approve_node.go

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

+ 3 - 1
services/report_outer.go

@@ -17,6 +17,7 @@ const OuterReportCallBackApiUrl = "/subject/report/writingCallback"
 type OuterReportCallBackRequest struct {
 	Name     string `json:"name"`
 	ReportId int    `json:"reportId"`
+	Abstract string `json:"abstracts"`
 	Url      string `json:"url"`
 	FileType string `json:"fileType"`
 	FileSize int    `json:"fileSize"`
@@ -30,7 +31,7 @@ type OuterReportCallBackResp struct {
 }
 
 // OuterReportCallBack 外部报告回调(提交审批)
-func OuterReportCallBack(outReportId int, title, fileUrl, fileType string) (err error) {
+func OuterReportCallBack(outReportId int, title, abstract, fileUrl, fileType string) (err error) {
 	var requestUrl, params, respBody string
 	defer func() {
 		if err != nil {
@@ -46,6 +47,7 @@ func OuterReportCallBack(outReportId int, title, fileUrl, fileType string) (err
 	var req OuterReportCallBackRequest
 	req.Name = fmt.Sprintf("%s%s", title, fileType)
 	req.ReportId = outReportId
+	req.Abstract = abstract
 	req.Url = fileUrl
 	req.FileType = fileType
 	b, e := json.Marshal(req)

+ 15 - 12
services/report_v2.go

@@ -9,14 +9,15 @@ import (
 	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/utils"
 	"fmt"
-	"github.com/rdlucklib/rdluck_tools/file"
-	"github.com/rdlucklib/rdluck_tools/http"
 	"html"
 	"os"
 	"path"
 	"strconv"
 	"strings"
 	"time"
+
+	"github.com/rdlucklib/rdluck_tools/file"
+	"github.com/rdlucklib/rdluck_tools/http"
 )
 
 // AddReportAndChapter
@@ -184,18 +185,20 @@ func EditReport(reportInfo *models.Report, req models.EditReq, sysUser *system.A
 	reportInfo.LastModifyAdminId = sysUser.AdminId
 	reportInfo.LastModifyAdminName = sysUser.RealName
 	reportInfo.ModifyTime = time.Now()
-
-	state, e := CheckReportCurrState(report_approve.FlowReportTypeChinese, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird, models.ReportOperateEdit)
-	if e != nil {
-		//errMsg = "操作失败"
-		err = errors.New("校验报告当前状态失败, Err: " + e.Error())
-		return
+	updateCols := []string{"Title", "Abstract", "Author", "Frequency", "CreateTime", "IsPublicPublish", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime"}
+	if reportInfo.ReportSource != utils.ReportSourceOuter {
+		state, e := CheckReportCurrState(report_approve.FlowReportTypeChinese, reportInfo.ClassifyIdFirst, reportInfo.ClassifyIdSecond, reportInfo.ClassifyIdThird, models.ReportOperateEdit)
+		if e != nil {
+			//errMsg = "操作失败"
+			err = errors.New("校验报告当前状态失败, Err: " + e.Error())
+			return
+		}
+		// 报告状态
+		reportInfo.State = state
+		updateCols = append(updateCols, "State")
 	}
-	// 报告状态
-	reportInfo.State = state
 
 	//updateCols := []string{"ClassifyIdFirst", "ClassifyNameFirst", "ClassifyIdSecond", "ClassifyNameSecond", "ClassifyIdThird", "ClassifyNameThird", "Title", "Abstract", "Author", "Frequency", "Stage", "CreateTime", "IsPublicPublish", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime"}
-	updateCols := []string{"Title", "Abstract", "Author", "Frequency", "CreateTime", "IsPublicPublish", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime", "State"}
 
 	if req.HeadResourceId > 0 {
 		reportInfo.HeadResourceId = req.HeadResourceId
@@ -1617,7 +1620,7 @@ func PublishReportV2(reportId int, sysUser *system.Admin) (tips string, err erro
 
 		// 回调智力共享审批, 若请求失败则恢复提交前状态(先这么处理吧,允许再次提交)
 		outId, _ := strconv.Atoi(reportInfo.OutReportId)
-		e := OuterReportCallBack(outId, reportInfo.Title, pdfUrl, ".pdf")
+		e := OuterReportCallBack(outId, reportInfo.Title, reportInfo.Abstract, pdfUrl, ".pdf")
 		if e != nil {
 			reportInfo.State = stateOrigin
 			_ = reportInfo.Update([]string{"State"})