Преглед изворни кода

Merge branch 'BI_Dashboard' into dm

zwxi пре 6 месеци
родитељ
комит
28acae6b7a

+ 401 - 47
controllers/bi_approve/bi_approve.go

@@ -1,11 +1,16 @@
 package biapprove
 
 import (
+	"encoding/json"
 	"eta_gn/eta_api/controllers"
 	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/bi_approve/request"
+	"eta_gn/eta_api/models/bi_approve/response"
 	biapprove "eta_gn/eta_api/services/bi_approve"
 	"eta_gn/eta_api/utils"
-	"time"
+	"fmt"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 type BiApproveController struct {
@@ -26,7 +31,7 @@ type BiApproveController struct {
 // @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.ReportApproveListResp
+// @Success 200 {object} report_approve.BiApproveListResp
 // @router /list [get]
 func (this *BiApproveController) List() {
 	br := new(models.BaseResponse).Init()
@@ -38,6 +43,7 @@ func (this *BiApproveController) List() {
 		this.ServeJSON()
 	}()
 
+	sysUser := this.SysUser
 	pageSize, _ := this.GetInt("PageSize")
 	currentIndex, _ := this.GetInt("CurrentIndex")
 	listType, _ := this.GetInt("ListType")
@@ -45,78 +51,78 @@ func (this *BiApproveController) List() {
 	timeType, _ := this.GetInt("TimeType")
 	startTime := this.GetString("StartTime")
 	endTime := this.GetString("EndTime")
-	// sortField, _ := this.GetInt("SortField")
-	// sortRule, _ := this.GetInt("SortRule")
+	sortField, _ := this.GetInt("SortField")
+	sortRule, _ := this.GetInt("SortRule")
 	classifyId, _ := this.GetInt("ClassifyId")
 	keyword := this.GetString("Keyword")
 
-	var pars []interface{}
-	var condition string
-
 	if pageSize <= 0 {
 		pageSize = utils.PageSize10
 	}
 	if currentIndex <= 0 {
 		currentIndex = 1
 	}
+	startSize := paging.StartIndex(currentIndex, pageSize)
 
-	if classifyId > 0 {
-		condition += ` AND classify_id = ? `
-		pars = append(pars, classifyId)
-	}
-	if keyword != "" {
-		condition += ` AND bi_title LIKE ? `
-		pars = utils.GetLikeKeywordPars(pars, keyword, 1)
-	}
-	if approveState > 0 {
-		condition += ` AND a.state = ? `
-		pars = append(pars, approveState)
-	}
-	if startTime != "" && endTime != "" {
-		_, err := time.Parse(utils.FormatDate, startTime)
-		if err != nil {
-			br.Msg = "开始时间格式错误"
-			return
-		}
-		endTime, err := time.Parse(utils.FormatDate, endTime)
-		endTime = endTime.AddDate(0, 0, 1)
-		switch timeType {
-		case 1:
-			condition += ` AND create_time BETWEEN ? AND ? `
-			pars = append(pars, startTime, endTime)
-		case 2:
-			condition += ` AND approve_time BETWEEN ? AND ? `
-			pars = append(pars, startTime, endTime)
-		case 3:
-			condition += ` AND approve_time BETWEEN ? AND ? `
-			pars = append(pars, startTime, endTime)
-		default:
-			br.Msg = "时间类型错误"
-			return
+	var list []*response.BiApproveItemOrmResp
+	var total int
+	var msg string
+	var err error
+
+	classifyList, msg, err := biapprove.GetBiClassifyAll()
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批列表成功"
 		}
+		br.ErrMsg = "获取分类列表失败, Err: " + err.Error()
+		return
+	}
+	classifyMap := make(map[int]string)
+	for _, v := range classifyList {
+		classifyMap[v.BiDashboardClassifyId] = v.BiDashboardClassifyName
 	}
 
 	switch listType {
 	case 1:
-		condition += ` AND a.state = 1 AND a.approve_user_id = ?`
-		pars = append(pars, this.SysUser.AdminId)
+		list, total, msg, err = biapprove.ProcessingBiApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
 	case 2:
-		condition += ` AND a.state IN (2,3) AND a.approve_user_id = ?`
-		pars = append(pars, this.SysUser.AdminId)
+		list, total, msg, err = biapprove.SolvedBiApprove(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
 	case 3:
-		condition += ` AND a.state = ? `
-		pars = append(pars, this.GetSession("username"))
+		list, total, msg, err = biapprove.MyApplyBiApproves(sysUser.AdminId, classifyId, timeType, sortField, sortRule, approveState, startSize, pageSize, sysUser.RealName, startTime, endTime, keyword)
 	default:
 		br.Msg = "列表类型错误"
 		return
 	}
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批列表失败"
+		}
+		br.ErrMsg = "获取审批列表失败, Err: " + err.Error()
+		return
+	}
+	for _, v := range list {
+		v.ClassifyName = classifyMap[v.ClassifyId]
+	}
 
+	resp := new(response.BiApproveListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+
+	br.Msg = "获取审批列表成功"
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
 }
 
 // list
 // @Title 公共看板分类列表
 // @Description 公共看板分类列表
-// @Success 200 {object} report_approve.ReportApproveFlowDetailItem
+// @Success 200 {object} report_approve.BiApproveFlowDetailItem
 // @router /classify/list [get]
 func (this *BiApproveController) ClassifyList() {
 	br := new(models.BaseResponse).Init()
@@ -143,3 +149,351 @@ func (this *BiApproveController) ClassifyList() {
 	br.Ret = 200
 	br.Success = true
 }
+
+// Approve
+// @Title 通过审批
+// @Description 通过审批
+// @Param	request	body report_approve.BiApprovePassReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /approve [post]
+func (this *BiApproveController) Approve() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.BiApprovePassReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.BiApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", req.BiApproveId)
+		return
+	}
+
+	// 通过审批
+	msg, err := biapprove.PassBiApprove(req.BiApproveId, sysUser.AdminId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "通过审批失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 审批详情
+// @Description 审批详情
+// @Param   BiApproveId  query  int  true  "审批ID"
+// @Success 200 {object} report_approve.BiApproveDetail
+// @router /detail [get]
+func (this *BiApproveController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	approveId, _ := this.GetInt("BiApproveId")
+	if approveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", approveId)
+		return
+	}
+
+	resp, msg, err := biapprove.GetApproveDetail(approveId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批详情失败"
+		}
+		br.ErrMsg = "获取审批详情失败, Err: " + err.Error()
+		return
+	}
+
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// Refuse
+// @Title 驳回审批
+// @Description 驳回审批
+// @Param	request	body request.BiApproveRefuseReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /refuse [post]
+func (this *BiApproveController) Refuse() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.BiApproveRefuseReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.BiApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", req.BiApproveId)
+		return
+	}
+	msg, err := biapprove.BiApproveRefuse(req.BiApproveId, sysUser.AdminId, req.ApproveRemark)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "驳回审批失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Cancel
+// @Title 撤销审批
+// @Description 撤销审批
+// @Param	request	body report_approve.BiApproveCancelReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /cancel [post]
+func (this *BiApproveController) Cancel() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.BiApproveCancelReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.BiApproveId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiApproveId: %d", req.BiApproveId)
+		return
+	}
+
+	// 撤销审批
+	msg, e := biapprove.BiApproveCancel(req.BiApproveId, sysUser.AdminId, sysUser.RealName)
+	if e != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "撤销审批失败, Err: " + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// MessageList
+// @Title 审批消息列表
+// @Description 审批消息列表
+// @Param   PageSize			query	int		true	"每页数据条数"
+// @Param   CurrentIndex		query	int		true	"当前页页码"
+// @Success 200 {object} report_approve.BiApproveMessageListResp
+// @router /message/list [get]
+func (this *BiApproveController) MessageList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	currentIndex, _ := this.GetInt("currentIndex")
+	pageSize, _ := this.GetInt("pageSize")
+	// 分页
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	resp := new(response.BiApproveMessageListResp)
+	resp.List = make([]*response.BiApproveMessageItem, 0)
+	list, total, unRead, msg, err := biapprove.GetBiApproveMessage(sysUser.AdminId, startSize, pageSize)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "获取审批消息失败"
+		}
+		br.ErrMsg = "获取审批消息失败, Err: " + err.Error()
+		return
+	}
+	resp.List = list
+	resp.UnreadTotal = unRead
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.Paging = page
+	br.Data = resp
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+}
+
+// MessageRead
+// @Title 消息已读
+// @Description 消息已读
+// @Param	request	body report_approve.BiApproveMessageReadReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /message/read [post]
+func (this *BiApproveController) MessageRead() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.BiApproveMessageReadReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+	if req.MessageId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, MessageId: %d", req.MessageId)
+		return
+	}
+
+	msg, err := biapprove.ReadBiMessage(req.MessageId, sysUser.AdminId)
+	if err != nil {
+		if msg != "" {
+			br.Msg = msg
+		} else {
+			br.Msg = "操作失败"
+		}
+		br.ErrMsg = "消息已读失败, Err: " + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// CheckApproveOpen
+// @Title 校验分类是否开启审批
+// @Description 校验分类是否开启审批
+// @Param	request	body report_approve.BiApproveCheckApproveOpenReq true "type json string"
+// @Success 200 string "操作成功"
+// @router /classify/check_open [post]
+func (this *BiApproveController) CheckApproveOpen() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req request.BiApproveCheckApproveOpenReq
+	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
+		br.Msg = "参数有误"
+		br.ErrMsg = "参数解析失败, Err: " + e.Error()
+		return
+	}
+
+	// 校验是否开启了审批流
+	opening, e := biapprove.CheckBiOpenApprove(req.ClassifyId)
+	if e != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "校验报告是否开启审批流失败, Err: " + e.Error()
+		return
+	}
+
+	br.Data = opening
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 264 - 10
controllers/bi_dashboard.go

@@ -7,6 +7,9 @@ import (
 	"eta_gn/eta_api/models/bi_dashboard"
 	"eta_gn/eta_api/models/system"
 	"eta_gn/eta_api/utils"
+	"fmt"
+	"strconv"
+	"strings"
 	"time"
 )
 
@@ -84,12 +87,12 @@ func (this *BIDaShboardController) AddDashboard() {
 		return
 	}
 	detailList := make([]*bi_dashboard.BiDashboardDetail, 0)
-	for _, v := range req.List {
+	for i, v := range req.List {
 		item := &bi_dashboard.BiDashboardDetail{
 			BiDashboardId: int(id),
 			Type:          v.Type,
 			UniqueCode:    v.UniqueCode,
-			Sort:          v.Sort,
+			Sort:          i + 1,
 			CreateTime:    time.Now(),
 			ModifyTime:    time.Now(),
 		}
@@ -370,7 +373,6 @@ func (this *BIDaShboardController) ShareList() {
 	//myPptList := make([]*bi_dashboard.BiDashboard, 0)
 	//otherPptList := make([]*bi_dashboard.BiDashboard, 0)
 	grantList := bi_dashboard.RespGroupList{}
-	dashboradIds := make([]int, 0)
 
 	// 获取我的看板列表
 	ShareCond := ` AND sys_admin_id = ? AND state IN (1,6) `
@@ -398,7 +400,6 @@ func (this *BIDaShboardController) ShareList() {
 	publicAdminIdList := make([]int, 0)
 	publicDashboardListMap := make(map[int][]*bi_dashboard.BiDashboard)
 	for _, v := range grantDashboardList {
-		dashboradIds = append(dashboradIds, v.BiDashboardId)
 		publicDashboardList, ok := publicDashboardListMap[v.SysAdminId]
 		if !ok {
 			publicDashboardList = make([]*bi_dashboard.BiDashboard, 0)
@@ -485,19 +486,272 @@ func (this *BIDaShboardController) PublicList() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
-
-	// 获取我的看板列表
-	privateCond := ` AND sys_admin_id = ? AND state IN (1,6) `
-	privatePars := []interface{}{this.SysUser.AdminId}
-	privateList, err := bi_dashboard.GetBiDashboardList(privateCond, privatePars)
+	grantList := bi_dashboard.RespGroupList{}
+	// 获取公共看板列表
+	publicCond := ` AND state = 6 `
+	publicPars := []interface{}{this.SysUser.AdminId}
+	publicList, err := bi_dashboard.GetBiDashboardList(publicCond, publicPars)
 	if err != nil {
 		err = errors.New("我的看板列表查询出错:" + err.Error())
 		return
 	}
 
+	//dashboardMap := make(map[int]*bi_dashboard.BiDashboard)
+	adminIdList := make([]int, 0)   //需要查询的创建人admin_id列表集合
+	adminIdMap := make(map[int]int) //需要查询的创建人admin_id集合,用来去重的,避免重复id
+
+	publicAdminIdList := make([]int, 0)
+	publicDashboardListMap := make(map[int][]*bi_dashboard.BiDashboard)
+	for _, v := range publicList {
+		publicDashboardList, ok := publicDashboardListMap[v.SysAdminId]
+		if !ok {
+			publicDashboardList = make([]*bi_dashboard.BiDashboard, 0)
+			publicAdminIdList = append(publicAdminIdList, v.SysAdminId)
+			if _, ok := adminIdMap[v.SysAdminId]; !ok {
+				adminIdList = append(adminIdList, v.SysAdminId) //需要查询的创建人admin_id列表集合
+				adminIdMap[v.SysAdminId] = v.SysAdminId         //需要查询的创建人admin_id集合,用来去重的,避免重复id
+			}
+		}
+
+		tmp := &bi_dashboard.BiDashboard{
+			BiDashboardId:   v.BiDashboardId,
+			BiDashboardName: v.BiDashboardName,
+			CreateTime:      v.CreateTime,
+			ModifyTime:      v.ModifyTime,
+			Sort:            v.Sort,
+			State:           v.State,
+			SysAdminId:      v.SysAdminId,
+			SysAdminName:    v.SysAdminName,
+		}
+		publicDashboardList = append(publicDashboardList, tmp)
+		publicDashboardListMap[v.SysAdminId] = publicDashboardList
+	}
+	// 创建人信息
+	systemAdminMap := make(map[int]*system.Admin)
+	systemAdminList, err := system.GetAdminListByIdList(adminIdList)
+	if err != nil {
+		return
+	}
+	for _, v := range systemAdminList {
+		systemAdminMap[v.AdminId] = v
+	}
+
+	for _, v := range publicAdminIdList {
+		systemAdmin, ok := systemAdminMap[v]
+		if !ok {
+			continue
+		}
+
+		// 看板 列表信息
+		respGroupNameListItemList, ok := publicDashboardListMap[v]
+		if !ok {
+			respGroupNameListItemList = make([]*bi_dashboard.BiDashboard, 0)
+		}
+
+		// ppt 分组信息
+		tmpRespGroupListItem := &bi_dashboard.RespOtherGroupListItem{
+			GroupId:       int64(systemAdmin.AdminId),
+			GroupName:     systemAdmin.RealName,
+			AdminId:       systemAdmin.AdminId,
+			DashboardList: respGroupNameListItemList,
+		}
+		grantList.OtherList = append(grantList.OtherList, tmpRespGroupListItem)
+	}
+
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "查询成功"
-	br.Data = privateList
+	br.Data = publicList
 	return
 }
+
+// AddDashboardClassify
+// @Title 新增看板分类
+// @Description 新增看板分类接口
+// @Param	request	body bi_dashboard.AddDashboardClassifyReq true "type json string"
+// @Success 200 Ret=200 新增成功
+// @router /classify/add [post]
+func (this *BIDaShboardController) AddDashboardClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.AddDashboardClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "名称不能为空"
+		return
+	}
+	maxSort, err := bi_dashboard.GetBiDashboardClassifyMaxSort()
+	if err != nil {
+		br.Msg = "获取最大排序值失败"
+		br.ErrMsg = "获取最大排序值失败,Err:" + err.Error()
+		return
+	}
+
+	item := &bi_dashboard.BiDashboardClassify{
+		BiDashboardClassifyName: req.ClassifyName,
+		Sort:                    maxSort + 1,
+		CreateTime:              time.Now(),
+		ModifyTime:              time.Now(),
+	}
+	_, e := bi_dashboard.AddBiDashboardClassify(item)
+	if e != nil {
+		err = e
+		br.Msg = "新增失败"
+		br.ErrMsg = "新增失败,Err:" + e.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "新增成功"
+	//br.Data =
+}
+
+// EditDashboardClassify
+// @Title 编辑看板分类
+// @Description 编辑看板分类接口
+// @Param	request	body bi_dashboard.EditDashboardReq true "type json string"
+// @Success 200 Ret=200 编辑成功
+// @router /classify/edit [post]
+func (this *BIDaShboardController) EditDashboardClassify() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.EditDashboardClassifyReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.ClassifyName == "" {
+		br.Msg = "标题不能为空"
+		return
+	}
+	if req.BiDashboardClassifyId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, BiDashboardClassifyId: %d", req.BiDashboardClassifyId)
+		return
+	}
+	item, err := bi_dashboard.GetBiDashboardClassifyById(req.BiDashboardClassifyId)
+	if err != nil && !utils.IsErrNoRow(err) {
+		br.Msg = "获取数据异常!"
+		br.ErrMsg = "获取数据异常,Err:" + err.Error()
+		return
+	}
+
+	// 修改
+	item.BiDashboardClassifyName = req.ClassifyName
+	item.ModifyTime = time.Now()
+
+	err = bi_dashboard.EditDashboardClassify(item)
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "编辑成功"
+	br.IsAddLog = true
+}
+
+// Grant
+// @Title 分配ppt权限
+// @Description 分配ppt权限接口
+// @Param	request	body models.GrantPptReq true "type json string"
+// @Success 200 Ret=200 分配成功
+// @router /grant [post]
+func (this *BIDaShboardController) Grant() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req bi_dashboard.GrantDashboardReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.AdminIdStr == "" {
+		br.Msg = "参数错误"
+		return
+	}
+	if req.BiDashboardId <= 0 {
+		br.Msg = "参数错误"
+		return
+	}
+
+	dashboardItem, err := bi_dashboard.GetDashboardById(req.BiDashboardId)
+	if err != nil {
+		err = errors.New("我的看板列表查询出错:" + err.Error())
+		br.Msg = "我的看板列表查询出错"
+		br.ErrMsg = err.Error()
+		return
+	}
+	if dashboardItem.SysAdminId != this.SysUser.AdminId {
+		br.Msg = "无权配置"
+		return
+	}
+
+	list := make([]*bi_dashboard.BiDashboardGrant, 0)
+
+
+	grantAdminIdStrList := strings.Split(req.AdminIdStr, ",")
+	lenGrantAdminIdStrList := len(grantAdminIdStrList) //指定用户的人数
+	for _, v := range grantAdminIdStrList {
+		grantAdminId, tmpErr := strconv.Atoi(v)
+		if tmpErr != nil {
+			br.Msg = "参数有误"
+			br.ErrMsg = fmt.Sprintf("参数有误,Err:%s", tmpErr.Error())
+			return
+		}
+
+		//如果只选择了自己作为指定的人,那么就提示他报错。如果多人,那么就过滤自己
+		if grantAdminId == this.SysUser.AdminId {
+			if lenGrantAdminIdStrList == 1 {
+				br.Msg = "不能指定自己为权限用户"
+				br.ErrMsg = fmt.Sprintf("参数有误,Err:%s", tmpErr.Error())
+				return
+			}
+			continue
+		}
+		tmpV := &bi_dashboard.BiDashboardGrant{
+			BiDashboardId: req.BiDashboardId,
+			GrantAdminId:  grantAdminId,
+			CreateTime:    time.Time{},
+		}
+		list = append(list, tmpV)
+	}
+
+	if len(list) <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误,Err:%s", "指定用户为空")
+		return
+	}
+
+	err = bi_dashboard.MultiAddDashboardGrant(req.BiDashboardId, list)
+	if err != nil {
+		br.Msg = "分配失败"
+		br.ErrMsg = fmt.Sprintf("分配失败,Err:%s", err.Error())
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.IsAddLog = true
+	br.Msg = "分配成功"
+}

+ 150 - 1
models/bi_approve/bi_approve.go

@@ -2,6 +2,7 @@ package biapprove
 
 import (
 	"eta_gn/eta_api/global"
+	"fmt"
 	"time"
 )
 
@@ -14,7 +15,7 @@ type BiApprove struct {
 	FlowId        int       `gorm:"column:flow_id"`
 	FlowVersion   int       `gorm:"column:flow_version"`
 	StartNodeId   int       `gorm:"column:start_node_id"`
-	CurrentNodeId int       `gorm:"column:current_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"`
@@ -23,12 +24,160 @@ type BiApprove struct {
 	ModifyTime    time.Time `gorm:"column:update_time"`
 }
 
+var BiApproveCols = struct {
+	BiApproveId   string
+	BiId          string
+	BiTitle       string
+	ClassifyId    string
+	State         string //  '审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回'
+	FlowId        string
+	FlowVersion   string
+	StartNodeId   string
+	CurrNodeId    string
+	ApplyUserId   string
+	ApplyUserName string
+	ApproveRemark string
+	ApproveTime   string
+	CreateTime    string
+	ModifyTime    string
+}{
+	BiApproveId:   "bi_approve_id",
+	BiId:          "bi_id",
+	BiTitle:       "bi_title",
+	ClassifyId:    "classify_id",
+	State:         "state",
+	FlowId:        "flow_id",
+	FlowVersion:   "flow_version",
+	StartNodeId:   "start_node_id",
+	CurrNodeId:    "curr_node_id",
+	ApplyUserId:   "apply_user_id",
+	ApplyUserName: "apply_user_name",
+	ApproveRemark: "approve_remark",
+	ApproveTime:   "approve_time",
+	CreateTime:    "create_time",
+	ModifyTime:    "modify_time",
+}
+
+type BiApproveItemOrm struct {
+	BiApproveId       int       `description:"审批ID"`
+	BiApproveRecordId int       `description:"审批记录ID"`
+	BiId              int       `description:"报告ID"`
+	BiTitle           string    `description:"报告标题"`
+	ClassifyId        int       `description:"分类ID"`
+	State             int       `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	RecordState       int       `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
+	FlowId            int       `description:"审批流ID"`
+	FlowVersion       int       `description:"审批流版本"`
+	StartNodeId       int       `description:"开始节点ID"`
+	CurrNodeId        int       `description:"当前节点ID"`
+	ApplyUserId       int       `description:"申请人ID"`
+	ApplyUserName     string    `description:"申请人姓名"`
+	ApproveRemark     string    `description:"审批备注"`
+	ApproveTime       time.Time `description:"审批时间"`
+	HandleTime        time.Time `description:"处理时间"`
+	CreateTime        time.Time `description:"创建时间"`
+	ModifyTime        time.Time `description:"修改时间"`
+	NodeState         int       `description:"当前节点审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回" json:"-"`
+	NodeApproveTime   time.Time `description:"当前节点审批时间" json:"-"`
+}
+
 func (b *BiApprove) TableName() string {
 	return "bi_approve"
 }
 
+func (b *BiApprove) Update(cols []string) (err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Model(b).Select(cols).Updates(b).Error
+	return
+}
+
+func (b *BiApprove) Create() (err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Create(b).Error
+	return
+}
+
 func GetBiApproveByFlowIdAndVersionId(biFlowId int, flowVersion int) (item []*BiApprove, err error) {
 	db := global.DmSQL["rddp"]
 	err = db.Where("flow_id = ? AND flow_version = ?", biFlowId, flowVersion).Find(&item).Error
 	return
 }
+
+func GetBiApproveById(biApproveId int) (item *BiApprove, err error) {
+	db := global.DmSQL["rddp"]
+	err = db.Where("bi_approve_id = ?", biApproveId).First(&item).Error
+	return
+}
+
+// GetApprovingBiApproveCount 获取待处理的审批分页列表总数
+func GetApprovingBiApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.bi_approve_record_id
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_approve_id AND a.node_id = b.curr_node_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovingBiApprovePageList 获取待处理的审批列表-分页
+func GetApprovingBiApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*BiApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.bi_approve_record_id, a.state AS record_state, b.*
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_approve_id AND a.node_id = b.curr_node_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApprovedBiApproveCount 获取已处理的审批分页列表总数
+func GetApprovedBiApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.bi_approve_record_id
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_approve_id
+		WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApprovedBiApprovePageList 获取已处理的审批列表-分页
+func GetApprovedBiApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*BiApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.bi_approve_record_id, a.node_state AS record_state,a.node_state,a.node_approve_time, a.node_approve_time AS handle_time, b.*
+		FROM bi_approve_record AS a
+		JOIN bi_approve AS b ON a.bi_approve_id = b.bi_approve_id
+		WHERE 1 = 1 %s %s
+		LIMIT ?,?`, cond, order)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
+// GetApplyBiApproveCount 获取我发起的审批分页列表总数
+func GetApplyBiApproveCount(cond string, pars []interface{}) (count int, err error) {
+	base := fmt.Sprintf(`SELECT a.* FROM Bi_approve AS a WHERE 1 = 1 %s`, cond)
+	sql := fmt.Sprintf(`SELECT COUNT(1) FROM (%s) t`, base)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// GetApplyBiApprovePageList 获取我发起的审批列表-分页
+func GetApplyBiApprovePageList(cond string, pars []interface{}, orderRule string, startSize, pageSize int) (items []*BiApproveItemOrm, err error) {
+	order := `ORDER BY a.create_time DESC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT a.* FROM bi_approve AS a WHERE 1 = 1 %s %s LIMIT ?,?`, cond, order)
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}

+ 26 - 0
models/bi_approve/bi_approve_flow.go

@@ -16,6 +16,22 @@ type BiApproveFlow struct {
 	ModifyTime      time.Time `gorm:"column:modify_time"`
 }
 
+var BiApproveFlowCols = struct {
+	BiApproveFlowId string
+	FlowName        string
+	ClassifyId      string
+	CurrVersion     string
+	CreateTime      string
+	ModifyTime      string
+}{
+	BiApproveFlowId: "bi_approve_flow_id",
+	FlowName:        "flow_name",
+	ClassifyId:      "classify_id",
+	CurrVersion:     "curr_version",
+	CreateTime:      "create_time",
+	ModifyTime:      "modify_time",
+}
+
 func (b *BiApproveFlow) TableName() string {
 	return "bi_approve_flow"
 }
@@ -120,6 +136,16 @@ func (b *BiApproveFlow) Delete() error {
 	return global.DmSQL["rddp"].Delete(b).Error
 }
 
+func (m *BiApproveFlow) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *BiApproveFlow, err error) {
+	order := ``
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s `, m.TableName(), condition, order)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).First(&item).Error
+	return
+}
+
 func GetBiApproveFlowById(biApproveFlowId int) (item *BiApproveFlow, err error) {
 	err = global.DmSQL["rddp"].Where("bi_approve_flow_id = ?", biApproveFlowId).First(&item).Error
 	return

+ 108 - 14
models/bi_approve/bi_approve_message.go

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

+ 47 - 0
models/bi_approve/bi_approve_node.go

@@ -3,6 +3,7 @@ package biapprove
 import (
 	"eta_gn/eta_api/global"
 	"fmt"
+	"strings"
 	"time"
 )
 
@@ -18,10 +19,46 @@ type BiApproveNode struct {
 	CreatedTime     time.Time `gorm:"column:created_time"`
 }
 
+var BiApproveNodeCols = struct {
+	BiApproveNodeId string
+	BiApproveFlowId string
+	PrevNodeId      string
+	NextNodeId      string
+	NodeType        string
+	ApproveType     string
+	Users           string
+	CurrVersion     string
+	CreatedTime     string
+}{
+	BiApproveNodeId: "bi_approve_node_id",
+	BiApproveFlowId: "bi_approve_flow_id",
+	PrevNodeId:      "prev_node_id",
+	NextNodeId:      "next_node_id",
+	NodeType:        "node_type",
+	ApproveType:     "approve_type",
+	Users:           "users",
+	CurrVersion:     "curr_version",
+	CreatedTime:     "created_time",
+}
+
 func (b *BiApproveNode) TableName() string {
 	return "bi_approve_node"
 }
 
+func (m *BiApproveNode) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*BiApproveNode, err error) {
+	fields := strings.Join(fieldArr, ",")
+	if len(fieldArr) == 0 {
+		fields = `*`
+	}
+	order := `ORDER BY created_time DESC, bi_approve_node_id ASC`
+	if orderRule != "" {
+		order = ` ORDER BY ` + orderRule
+	}
+	sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Find(&items).Error
+	return
+}
+
 func UpdateNextNodes(nodes []*BiApproveNode) (err error) {
 	if len(nodes) == 0 {
 		return
@@ -37,6 +74,16 @@ func UpdateNextNodes(nodes []*BiApproveNode) (err error) {
 	return
 }
 
+func GetBiApproveNodeByCondition(condition string, pars []interface{}) (node []*BiApproveNode, err error) {
+	o := global.DmSQL["rddp"]
+	sql := "SELECT * FROM bi_approve_node WHERE 1=1 "
+	if condition != "" {
+		sql += " AND " + condition
+	}
+	err = o.Raw(sql, pars...).Find(&node).Error
+	return
+}
+
 func GetBiApproveNodeByFlowIdAndVersionId(flowId int, versionId int) (node []*BiApproveNode, err error) {
 	err = global.DmSQL["rddp"].Model(&BiApproveNode{}).Where("bi_approve_flow_id =? AND curr_version =?", flowId, versionId).Scan(&node).Error
 	return

+ 124 - 1
models/bi_approve/bi_approve_record.go

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

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

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

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

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

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

@@ -0,0 +1,90 @@
+package response
+
+// BiApproveDetail 审批详情信息
+type BiApproveDetail struct {
+	Bi               *BiApproveDetailBi      `description:"报告信息"`
+	Approve          *BiApproveDetailItem    `description:"审批信息"`
+	ApproveFlowNodes []*BiApproveDetailNodes `description:"审批节点信息"`
+}
+
+// BiApproveDetailBi 审批详情-报告信息
+type BiApproveDetailBi struct {
+	BiId       int    `description:"看板ID"`
+	BiTitle    string `description:"看板标题"`
+	BiCode     string `description:"看板code"`
+	BiClassify string `description:"看板分类"`
+}
+
+// BiApproveDetailItem 审批详情-审批信息
+type BiApproveDetailItem struct {
+	BiApproveId   int    `description:"审批ID"`
+	State         int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	FlowId        int    `description:"审批流ID"`
+	FlowVersion   int    `description:"审批流版本"`
+	StartNodeId   int    `description:"开始节点ID"`
+	CurrNodeId    int    `description:"当前节点ID"`
+	ApplyUserId   int    `description:"申请人ID"`
+	ApplyUserName string `description:"申请人姓名"`
+	ApproveTime   string `description:"审批时间"`
+	CreateTime    string `description:"创建时间"`
+	ModifyTime    string `description:"修改时间"`
+}
+
+// BiApproveDetailNodes 审批详情-节点信息
+type BiApproveDetailNodes struct {
+	BiApproveNodeId int                        `description:"看板审批节点ID"`
+	BiApproveFlowId int                        `description:"看板审批流ID"`
+	PrevNodeId      int                        `description:"上一个节点ID(0为开始节点)"`
+	NextNodeId      int                        `description:"下一个节点ID(0为结束节点)"`
+	NodeType        int                        `description:"节点类型:0-审批;1-抄送"`
+	ApproveType     int                        `description:"审批类型:1-依次审批;2-会签;3-或签"`
+	Users           []*BiApproveDetailNodeUser `description:"审批人信息"`
+}
+
+// BiApproveDetailNodeUser 审批详情-节点用户信息
+type BiApproveDetailNodeUser struct {
+	BiApproveNodeUserReq
+	ApproveRecord *BiApproveDetailNodeUserRecord `description:"用户审批记录"`
+}
+
+// BiApproveNodeUserReq 报告审批节点用户请求体
+type BiApproveNodeUserReq struct {
+	UserType string `description:"审批人类型: user-用户; role-角色"`
+	UserId   int    `description:"用户/角色ID"`
+	UserName string `description:"用户/角色姓名"`
+	Sort     int    `description:"排序"`
+}
+
+// BiApproveDetailNodeUserRecord 审批详情-节点用户审批记录
+type BiApproveDetailNodeUserRecord struct {
+	BiApproveRecordId int    `description:"审批记录ID"`
+	State             int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	ApproveUserId     int    `description:"审批人ID"`
+	ApproveUserName   string `description:"审批人姓名"`
+	ApproveRemark     string `description:"审批备注"`
+	ApproveTime       string `description:"审批时间"`
+}
+
+type BiApproveItemOrmResp struct {
+	BiApproveId       int    `description:"审批ID"`
+	BiApproveRecordId int    `description:"审批记录ID"`
+	BiId              int    `description:"报告ID"`
+	BiTitle           string `description:"报告标题"`
+	ClassifyId        int    `description:"分类ID"`
+	ClassifyName      string `description:"分类名称"`
+	State             int    `description:"审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回"`
+	RecordState       int    `description:"审批记录状态:1-待审批;2-已通过;3-已驳回"`
+	FlowId            int    `description:"审批流ID"`
+	FlowVersion       int    `description:"审批流版本"`
+	StartNodeId       int    `description:"开始节点ID"`
+	CurrNodeId        int    `description:"当前节点ID"`
+	ApplyUserId       int    `description:"申请人ID"`
+	ApplyUserName     string `description:"申请人姓名"`
+	ApproveRemark     string `description:"审批备注"`
+	ApproveTime       string `description:"审批时间"`
+	HandleTime        string `description:"处理时间"`
+	CreateTime        string `description:"创建时间"`
+	ModifyTime        string `description:"修改时间"`
+	NodeState         int    `description:"当前节点审批状态:1-待审批;2-已审批;3-已驳回;4-已撤回" json:"-"`
+	NodeApproveTime   string `description:"当前节点审批时间" json:"-"`
+}

+ 8 - 1
models/bi_approve/response/bi_approve_flow.go

@@ -1,6 +1,8 @@
 package response
 
-import "github.com/rdlucklib/rdluck_tools/paging"
+import (
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
 
 type BiApproveFlowItem struct {
 	BiApproveFlowId int    `description:"主键"`
@@ -37,3 +39,8 @@ type BiApproveNodeItem struct {
 	ApproveType     int                  `description:"审批类型:1-依次审批;2-会签;3-或签"`
 	Users           []*BiApproveNodeUser `description:"审批人信息"`
 }
+
+type BiApproveListResp struct {
+	List   []*BiApproveItemOrmResp
+	Paging *paging.PagingItem
+}

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

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

+ 7 - 2
models/bi_dashboard/bi_dashboard.go

@@ -22,6 +22,11 @@ func (m *BiDashboard) TableName() string {
 	return "bi_dashboard"
 }
 
+func (m *BiDashboard) Update(cols []string) (err error) {
+	err = global.DEFAULT_DmSQL.Model(m).Select(cols).Updates(m).Error
+	return
+}
+
 // AddBiDashboard 新增看板
 func AddBiDashboard(item *BiDashboard) (lastId int64, err error) {
 	err = global.DEFAULT_DmSQL.Create(item).Error
@@ -99,7 +104,7 @@ func EditDashboard(item *BiDashboard) (err error) {
 }
 
 type DelDashboardReq struct {
-	BiDashboardId   int    `description:"看板id"`
+	BiDashboardId int `description:"看板id"`
 }
 
 func GetDashboradByIds(dashboradIds []int) (list []*BiDashboard, err error) {
@@ -118,4 +123,4 @@ func GetAllGrantList(sysUserId int) (list []*BiDashboard, err error) {
  WHERE b.grant_admin_id=?`
 	err = global.DEFAULT_DmSQL.Raw(sql, sysUserId, sysUserId).Find(&list).Error
 	return
-}
+}

+ 23 - 2
models/bi_dashboard/bi_dashboard_classify.go

@@ -32,9 +32,14 @@ func AddBiDashboardClassify(item *BiDashboardClassify) (lastId int64, err error)
 	return
 }
 
+// update
+func EditDashboardClassify(item *BiDashboardClassify) (err error) {
+	return global.DEFAULT_DmSQL.Model(item).Updates(item).Error
+}
+
 type RespGroupList struct {
-	MyList  []*BiDashboard
-	OtherList   []*RespOtherGroupListItem
+	MyList    []*BiDashboard
+	OtherList []*RespOtherGroupListItem
 }
 
 type RespMyGroupListItem struct {
@@ -80,3 +85,19 @@ func GetBiDashboardClassifyById(id int) (item *BiDashboardClassify, err error) {
 	err = global.DEFAULT_DmSQL.Where("bi_dashboard_classify_id = ?", id).First(&item).Error
 	return
 }
+
+type AddDashboardClassifyReq struct {
+	ClassifyName string `description:"看板名称"`
+}
+
+type EditDashboardClassifyReq struct {
+	BiDashboardClassifyId int    `description:"看板id"`
+	ClassifyName          string `description:"看板名称"`
+}
+
+// GetBiDashboardClassifyMaxSort 获取看板分类下最大的排序数
+func GetBiDashboardClassifyMaxSort() (sort int, err error) {
+	sql := `SELECT Max(sort) AS sort FROM bi_dashboard_classify `
+	err = global.DEFAULT_DmSQL.Raw(sql).First(&sort).Error
+	return
+}

+ 40 - 0
models/bi_dashboard/bi_dashboard_grant.go

@@ -1,6 +1,8 @@
 package bi_dashboard
 
 import (
+	"eta_gn/eta_api/global"
+	"eta_gn/eta_api/utils"
 	"time"
 )
 
@@ -15,3 +17,41 @@ type BiDashboardGrant struct {
 func (m *BiDashboardGrant) TableName() string {
 	return "bi_dashboard_grant"
 }
+
+// GrantDashboardReq 分配看板权限
+type GrantDashboardReq struct {
+	BiDashboardId int    `description:"看板id" `
+	AdminIdStr    string `description:"指定成员id,多个成员用英文,隔开"`
+}
+
+// MultiAddDashboardGrant 批量添加授权记录
+func MultiAddDashboardGrant(pptId int, list []*BiDashboardGrant) (err error) {
+
+	to := global.DEFAULT_DmSQL.Begin()
+	defer func() {
+		if err != nil {
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	sql := "DELETE from bi_dashboard_grant where bi_dashboard_id=?"
+	//_, err = to.Raw(sql, pptId).Exec()
+	err = to.Exec(sql, pptId).Error
+	if err != nil {
+		return
+	}
+
+	// 新增授权记录
+	if len(list) > 0 {
+		//_, tmpErr := to.InsertMulti(len(list), list)
+		tmpErr := to.CreateInBatches(list, utils.MultiAddNum).Error
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+	}
+
+	return
+}

+ 1 - 0
models/business_conf.go

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

+ 90 - 0
routers/commentsRouter.go

@@ -241,6 +241,33 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Approve",
+            Router: `/approve`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Cancel",
+            Router: `/cancel`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "CheckApproveOpen",
+            Router: `/classify/check_open`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
         beego.ControllerComments{
             Method: "ClassifyList",
@@ -250,6 +277,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
         beego.ControllerComments{
             Method: "List",
@@ -259,6 +295,33 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "MessageList",
+            Router: `/message/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "MessageRead",
+            Router: `/message/read`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveController"],
+        beego.ControllerComments{
+            Method: "Refuse",
+            Router: `/refuse`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers/bi_approve:BiApproveFlowController"],
         beego.ControllerComments{
             Method: "Add",
@@ -8170,6 +8233,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "AddDashboardClassify",
+            Router: `/classify/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "EditDashboardClassify",
+            Router: `/classify/edit`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
         beego.ControllerComments{
             Method: "DeleteDashboard",
@@ -8206,6 +8287,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
+        beego.ControllerComments{
+            Method: "Grant",
+            Router: `/grant`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:BIDaShboardController"],
         beego.ControllerComments{
             Method: "MyList",

+ 1159 - 1
services/bi_approve/bi_approve.go

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

+ 4 - 3
services/bi_approve/bi_approve_flow.go

@@ -44,13 +44,14 @@ func SaveBiApproveFlow(flow *request.BiApproveFlowSaveReq) (ok bool, msg string,
 	}
 	if flow.BiApproveFlowId == 0 {
 		tmp, er := biapprove.GetBiApproveFlowByClassifyId(flow.ClassifyId)
-		if er != nil {
+		if er != nil && !utils.IsErrNoRow(er) {
 			msg = "保存审批流失败"
 			err = er
 			return
 		}
 		if tmp != nil && tmp.BiApproveFlowId > 0 {
 			msg = "保存审批流失败, 分类下已存在审批流"
+			err = fmt.Errorf("分类下已存在审批流")
 			return
 		}
 
@@ -194,7 +195,7 @@ func CheckDeleteBiApproveFlow(flowId int) (ok bool, err error) {
 		return
 	}
 	for _, v := range approveList {
-		if v.State == BiApproveApproveStateApproving {
+		if v.State == BiApproveStateApproving {
 			return false, nil
 		}
 	}
@@ -231,7 +232,7 @@ func FormatFlowAndNodesItem2Detail(flowItem *biapprove.BiApproveFlow, nodeItems
 	detail.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, flowItem.ModifyTime)
 	detail.Nodes = make([]*response.BiApproveNodeItem, 0)
 	for _, v := range nodeItems {
-		t, e := FormatReportApproveNode2Item(v)
+		t, e := FormatBiApproveNode2Item(v)
 		if e != nil {
 			err = fmt.Errorf("format node err: %s", e.Error())
 			return

+ 89 - 0
services/bi_approve/bi_approve_message.go

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

+ 2 - 2
services/bi_approve/bi_approve_node.go

@@ -7,8 +7,8 @@ import (
 	"fmt"
 )
 
-// FormatReportApproveNode2Item 格式化报告审批节点信息
-func FormatReportApproveNode2Item(origin *biapprove.BiApproveNode) (item *response.BiApproveNodeItem, err error) {
+// FormatBiApproveNode2Item 格式化报告审批节点信息
+func FormatBiApproveNode2Item(origin *biapprove.BiApproveNode) (item *response.BiApproveNodeItem, err error) {
 	if origin == nil {
 		return
 	}

+ 24 - 4
services/bi_approve/constant.go

@@ -1,5 +1,25 @@
 package biapprove
 
+// 看板状态
+const (
+	BiStateUnpublished = 1 // 未发布
+	BiStatePublished   = 2 // 已发布
+	BiStateWaitSubmit  = 3 // 待提交
+	BiStateWaitApprove = 4 // 审批中
+	BiStateRefused     = 5 // 已驳回
+	BiStatePass        = 6 // 已通过
+)
+
+// 看板操作
+const (
+	BiOperateAdd           = 1 // 新增报告
+	BiOperateEdit          = 2 // 编辑报告
+	BiOperatePublish       = 3 // 发布报告
+	BiOperateCancelPublish = 4 // 取消发布报告
+	BiOperateSubmitApprove = 5 // 提交审批
+	BiOperateCancelApprove = 6 // 撤回审批
+)
+
 // 节点审批方式
 const (
 	NodeApproveTypeRoll = 1 // 依次审批
@@ -15,8 +35,8 @@ const (
 
 // 报告审批状态
 const (
-	BiApproveApproveStateApproving = 1 // 待审批
-	BiApproveApproveStatePass      = 2 // 已审批
-	BiApproveApproveStateRefuse    = 3 // 已驳回
-	BiApproveApproveStateCancel    = 4 // 已撤销
+	BiApproveStateApproving = 1 // 待审批
+	BiApproveStatePass      = 2 // 已审批
+	BiApproveStateRefuse    = 3 // 已驳回
+	BiApproveStateCancel    = 4 // 已撤销
 )