package biapprove import ( "encoding/json" "eta_gn/eta_api/models" biapprove "eta_gn/eta_api/models/bi_approve" "eta_gn/eta_api/models/bi_approve/response" "eta_gn/eta_api/models/bi_dashboard" "eta_gn/eta_api/utils" "fmt" "sort" "strings" "time" ) var ( timeField = map[int]string{1: fmt.Sprintf("a.%s", biapprove.BiApproveRecordCols.CreateTime), 2: fmt.Sprintf("a.%s", biapprove.BiApproveRecordCols.NodeApproveTime), 3: fmt.Sprintf("b.%s", biapprove.BiApproveCols.ApproveTime)} myTimeField = map[int]string{1: biapprove.BiApproveCols.CreateTime, 3: biapprove.BiApproveCols.ApproveTime} orderRules = map[int]string{1: "ASC", 2: "DESC"} ) func GetPulicBiClassifyList() (res []*bi_dashboard.BiDashboardClassifyItem, msg string, err error) { classifyList, err := bi_dashboard.GetBiDashboardClassifyAllList() if err != nil { msg = "获取公共分类列表失败" return } res = toClassifyItem(classifyList) return } func PassBiApprove(approveId int, adminId int) (msg string, err error) { approveItem, e := biapprove.GetBiApproveById(approveId) if e != nil { if utils.IsErrNoRow(e) { msg = "审批不存在, 请刷新页面" err = e return } msg = "操作失败" return } if approveItem.State != BiApproveStateApproving { msg = "审批状态有误, 请刷新页面" err = fmt.Errorf("审批状态有误, State: %d", approveItem.State) return } var ApprovePars []interface{} Approveconds := ` AND bi_approve_id =? AND approve_user_id =? AND state =? ` ApprovePars = append(ApprovePars, approveId, adminId, BiApproveStateApproving) recordItem, er := biapprove.GetBiApproveRecordByCondition(Approveconds, ApprovePars) if er != nil { if utils.IsErrNoRow(er) { msg = "无权审批" err = er return } msg = "操作失败" return } // 查询审批流和审批流节点 flowItem, e := biapprove.GetBiApproveFlowById(approveItem.FlowId) if e != nil { err = fmt.Errorf("获取审批流失败, Err: %s", e.Error()) return } nodePars := make([]interface{}, 0) nodeCond := ` AND bi_approve_flow_id =? AND curr_version =? ` nodePars = append(nodePars, flowItem.BiApproveFlowId, flowItem.CurrVersion) nodeItems, e := biapprove.GetBiApproveNodeByCondition(nodeCond, nodePars) if e != nil { err = fmt.Errorf("ApproveNodes GetItemsByCondition err: %s", e.Error()) return } if len(nodeItems) == 0 { err = fmt.Errorf("无审批节点") return } nodeMap := make(map[int]*biapprove.BiApproveNode) for _, v := range nodeItems { nodeMap[v.BiApproveNodeId] = v } // 取出审批记录的节点 currNodeItem := nodeMap[recordItem.NodeId] if currNodeItem == nil { err = fmt.Errorf("当前节点信息有误") return } currNode, e := FormatBiApproveNode2Item(currNodeItem) if e != nil { err = fmt.Errorf("当前节点信息有误, Err: %s", e.Error()) return } now := time.Now().Local() recordItem.State = BiApproveStatePass recordItem.ApproveTime = now recordItem.ModifyTime = now recordItem.NodeState = BiApproveStatePass recordItem.NodeApproveUserId = recordItem.ApproveUserId recordItem.NodeApproveUserName = recordItem.ApproveUserName recordItem.NodeApproveTime = now recordCols := []string{"State", "ApproveTime", "ModifyTime", "NodeState", "NodeApproveUserId", "NodeApproveUserName", "NodeApproveTime"} lastApprove := false // 依次审批 if currNode.ApproveType == NodeApproveTypeRoll { if e = recordItem.Update(recordCols); e != nil { err = fmt.Errorf("更新审批记录状态失败, Err: %s", e.Error()) return } // 检查依次审批情况 sort.Slice(currNode.Users, func(k, j int) bool { return currNode.Users[k].Sort < currNode.Users[j].Sort }) userLen := len(currNode.Users) //lastRoll := false nextUser := new(response.BiApproveNodeUser) // 下一个审批人, 为nil则表示当前审批人即为最后 for k, v := range currNode.Users { // 当前审批人 if v.UserId == adminId && recordItem.ApproveUserSort == v.Sort { if (k + 1) < userLen { nextUser = currNode.Users[k+1] } } } // 当前节点下一个审批人, 生成下一个审批记录且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, approveItem.BiTitle) 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, approveItem.BiTitle) 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, approveItem.BiTitle) 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, BiStatePass); e != nil { err = fmt.Errorf("更新报告审批状态失败, Err: %s", e.Error()) return } go func() { messageItem := new(biapprove.BiApproveMessage) messageItem.SendUserId = adminId messageItem.ReceiveUserId = approveItem.ApplyUserId messageItem.Content = "您提交的审批已通过" messageItem.Remark = fmt.Sprintf("您提交的【%s】已通过", approveItem.BiTitle) messageItem.BiApproveId = approveItem.BiApproveId messageItem.ApproveState = BiApproveStatePass messageItem.CreateTime = now messageItem.ModifyTime = now if e = messageItem.Create(); e != nil { utils.FileLog.Info(fmt.Sprintf("PassBiApprove message err: %s", e.Error())) return } }() } return } func toClassifyItem(src []*bi_dashboard.BiDashboardClassify) (dst []*bi_dashboard.BiDashboardClassifyItem) { for _, item := range src { dst = append(dst, &bi_dashboard.BiDashboardClassifyItem{ BiDashboardClassifyId: item.BiDashboardClassifyId, BiDashboardClassifyName: item.BiDashboardClassifyName, }) } return } // BuildNextNodeRecordAndMsg 生成下一个节点的审批记录并推送消息 func BuildNextNodeRecordAndMsg(approveNodeItem *biapprove.BiApproveNode, approveId, sysAdminId int, sysAdminName, biTitle 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提交的【%s】需要您审批,请及时处理", sysAdminName, biTitle) 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, 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("获取Bi看板失败, 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.NodeState) 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 } tmpEndTimeStr := tmpEndTime.AddDate(0, 0, 1).Format(utils.FormatDate) cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, myTimeField[timeType]) pars = append(pars, startTime, tmpEndTimeStr) } keyword = strings.TrimSpace(keyword) if keyword != "" { kw := fmt.Sprint("%", keyword, "%") cond += fmt.Sprintf(` AND a.%s LIKE ?`, 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, 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 = fmt.Sprintf("您提交的【%s】已被驳回", approveItem.BiTitle) 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, BiStateUnpublished) 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提交的【%s】已撤回", sysAdminName, approveItem.BiTitle) 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 { err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error()) return } // 开启审批/有审批流 if openApprove && (flowItem != nil) { opening = true return } return } // SubmitBiApprove 提交审批 func SubmitBiApprove(biId int, biTitle string, classifyId int, sysAdminId int, sysAdminName string) (approveId int, err error) { // 默认内部审批, 如果是走的第三方审批, 那么仅修改状态 confMap, e := models.GetBusinessConf() if e != nil { err = fmt.Errorf("GetBusinessConf err: %s", e.Error()) return } openMap := map[string]bool{"false": false, "true": true} openApprove := openMap[confMap[models.BusinessConfIsBIApprove]] if !openApprove { err = fmt.Errorf("未开启审批") return } // 查询审批流 flowOb := new(biapprove.BiApproveFlow) flowCond := fmt.Sprintf(` AND %s = ?`, biapprove.BiApproveFlowCols.ClassifyId) flowPars := make([]interface{}, 0) flowPars = append(flowPars, classifyId) flowItem, e := flowOb.GetItemByCondition(flowCond, flowPars, "") if e != nil { err = fmt.Errorf("ApproveFlow GetItemByCondition err: %s", e.Error()) return } // 查询审批节点 nodeOb := new(biapprove.BiApproveNode) nodeCond := fmt.Sprintf(` AND %s = ? AND %s = ?`, biapprove.BiApproveNodeCols.BiApproveFlowId, biapprove.BiApproveNodeCols.CurrVersion) nodePars := make([]interface{}, 0) nodePars = append(nodePars, flowItem.BiApproveFlowId, flowItem.CurrVersion) nodeItems, e := nodeOb.GetItemsByCondition(nodeCond, nodePars, []string{}, "") if e != nil { err = fmt.Errorf("ApproveNodes GetItemsByCondition err: %s", e.Error()) return } if len(nodeItems) == 0 { err = fmt.Errorf("无审批节点") return } // 取出首个节点 firstNodeItem := new(biapprove.BiApproveNode) for _, v := range nodeItems { if v.PrevNodeId == 0 { firstNodeItem = v continue } } if firstNodeItem == nil { err = fmt.Errorf("首个审批节点有误") return } // 审批信息 now := time.Now().Local() newApprove := new(biapprove.BiApprove) newApprove.BiId = biId newApprove.BiTitle = biTitle newApprove.ClassifyId = classifyId newApprove.State = BiApproveStateApproving newApprove.FlowId = flowItem.BiApproveFlowId newApprove.FlowVersion = flowItem.CurrVersion newApprove.StartNodeId = firstNodeItem.BiApproveNodeId newApprove.CurrNodeId = firstNodeItem.BiApproveNodeId newApprove.ApplyUserId = sysAdminId newApprove.ApplyUserName = sysAdminName newApprove.CreateTime = now newApprove.ModifyTime = now if e = newApprove.Create(); e != nil { err = fmt.Errorf("生成审批信息失败, Err: %s", e.Error()) return } approveId = newApprove.BiApproveId // 生成节点审批记录 err = BuildNextNodeRecordAndMsg(firstNodeItem, newApprove.BiApproveId, sysAdminId, sysAdminName, newApprove.BiTitle) 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 = utils.TimeTransferString(utils.FormatDateTime, v.ApproveTime) r.HandleTime = utils.TimeTransferString(utils.FormatDateTime, v.HandleTime) r.CreateTime = utils.TimeTransferString(utils.FormatDateTime, v.CreateTime) r.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, v.ModifyTime) r.NodeState = v.NodeState res = append(res, r) } return } func 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 } func CheckHasApprovingBi() (ok bool, err error) { count, err := biapprove.GetBiApproveCountByState(BiApproveStateApproving) if err != nil { return } if count > 0 { ok = true } return }