package seal import ( "errors" "fmt" "github.com/beego/beego/v2/client/orm" "hongze/hz_crm_api/models/company" "hongze/hz_crm_api/models/contract" "hongze/hz_crm_api/models/seal" "hongze/hz_crm_api/models/seal/request" "hongze/hz_crm_api/models/seal/response" "hongze/hz_crm_api/models/system" "hongze/hz_crm_api/services" "hongze/hz_crm_api/utils" "mime/multipart" "reflect" "strconv" "strings" "time" ) // UploadCheckBackFile 上传签回用印附件(实际操作) func UploadCheckBackFile(sealId int, fileUrl string, opUser *system.Admin) (sealInfo *seal.Seal, err error) { //查询当前用印信息 sealInfo, err = seal.GetSealInfoByContractId(sealId) if err != nil { return } //用印状态判断 if sealInfo.Status != "已审批" && sealInfo.Status != "已签回" { err = errors.New("用印状态异常,不允许上传签回用印附件,当前用印状态:" + sealInfo.Status) return } sealInfo.CheckBackFileUrl = fileUrl sealInfo.Status = "已签回" sealInfo.ModifyTime = time.Now() sealInfo.CheckBackFileTime = time.Now() err = sealInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"}) if err != nil { return } // 给销售发送模版消息 sellerInfo, tErr := system.GetSysAdminById(sealInfo.UserId) if tErr == nil { if sellerInfo.Mobile != "" { go services.SendSealFinishedWxTemplateMsg(sellerInfo.Mobile, sealInfo.CompanyName, sealInfo.SealId) } } return } // UploadCheckBackFileFromSeal 用印上传签回用印附件 func UploadCheckBackFileFromSeal(sealId int, ext string, fileMulti multipart.File, opUser *system.Admin) (sealInfo *seal.Seal, err error) { //查询当前用印信息 sealInfo, err = seal.GetSealInfoById(sealId) if err != nil { return } //用印状态判断 if sealInfo.Status != "已审批" && sealInfo.Status != "已签回" { err = errors.New("用印状态异常,不允许上传签回用印附件,当前用印状态:" + sealInfo.Status) return } fileName := `` //保存的文件名 fileName = sealInfo.CompanyName + "_" + sealInfo.Code + "(签回)" if sealInfo.ContractId > 0 { //获取合同信息 contractInfo, tmpErr := contract.GetContractById(sealInfo.ContractId) if tmpErr != nil { err = tmpErr return } //保存的文件名 fileName = contractInfo.CompanyName + "_" + contractInfo.ContractCode + "(签回)" } //非正式环境下,文件名上面还是加上随机数 if utils.RunMode != "release" { fileName += "_" + utils.GetRandStringNoSpecialChar(10) } fileName += ext //上传到阿里云 resourceUrl, err := services.UploadToOssAndFileName(fileMulti, fileName) if err != nil { err = errors.New("文件保存失败,Err:" + err.Error()) return } sealInfo.CheckBackFileUrl = resourceUrl sealInfo.Status = "已签回" sealInfo.ModifyTime = time.Now() sealInfo.CheckBackFileTime = time.Now() err = sealInfo.Update([]string{"CheckBackFileUrl", "Status", "ModifyTime", "CheckBackFileTime"}) if err != nil { return } // 给销售发送模版消息 sellerInfo, tErr := system.GetSysAdminById(sealInfo.UserId) if tErr == nil { if sellerInfo.Mobile != "" { go services.SendSealFinishedWxTemplateMsg(sellerInfo.Mobile, sealInfo.CompanyName, sealInfo.SealId) } } return } // ApplySeal 申请用印 func ApplySeal(sysUser *system.Admin, req request.SealApprovalApplyReq) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() // 添加用印 sealInfo, err := addSeal(sysUser.AdminId, req.ContractId, req.FileNum, sysUser.RealName, req.Use, req.CompanyName, req.UseCompanyName, req.CreditCode, req.ServiceType, req.SealType, req.Remark, req.FileUrls, req.AffiliatedCompany) if err != nil { return } // 添加操作日志 err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "apply", sysUser.RealName, "提交审批", "") if err != nil { return } // 用印审批 err = SubmitApproval(sealInfo) return } // addSeal 新增用印 func addSeal(userId, contractId, fileNum int, userName, use, companyName, useCompanyName, creditCode, serviceType, sealType, remark string, fileUrls []string, affiliatedCompany string) (sealInfo *seal.Seal, err error) { if !strings.Contains(strings.Join(seal.EnumUse, ","), use) { err = errors.New("用印用途异常") return } if !strings.Contains(strings.Join(seal.EnumServiceType, ","), serviceType) { err = errors.New("业务类型异常") return } sealCode, err := seal.GetSealCode() if err != nil { return } fileUrl := "" now := time.Now() attachments := make([]*seal.Attachment, 0) if len(fileUrls) == 1 { fileUrl = fileUrls[0] } sealInfo = &seal.Seal{ Code: sealCode, UserId: userId, UserName: userName, Use: use, CompanyName: companyName, UseCompanyName: useCompanyName, CreditCode: creditCode, ServiceType: serviceType, SealType: sealType, Status: "待提交", Remark: remark, FileUrl: fileUrl, FileNum: fileNum, ContractId: contractId, ModifyTime: now, CreateTime: now, AffiliatedCompany: affiliatedCompany, } err = seal.AddSeal(sealInfo) if err != nil { return } if len(fileUrls) > 1 { for _, v := range fileUrls { tmp := &seal.Attachment{ SealId: sealInfo.SealId, FileUrl: v, ModifyTime: now, CreateTime: now, } attachments = append(attachments, tmp) } err = seal.AddAttachments(attachments) } return } // EditApply 编辑用印审批 func EditApply(sysUser *system.Admin, req request.SealApprovalEditReq) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() // 编辑用印 sealInfo, err := editSeal(req.SealId, sysUser.AdminId, req.ContractId, req.FileNum, req.Use, req.CompanyName, req.UseCompanyName, req.CreditCode, req.ServiceType, req.SealType, req.Remark, req.FileUrls, req.AffiliatedCompany) if err != nil { return } // 添加操作日志 err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "edit", sysUser.RealName, "重提审批", "") if err != nil { return } // 用印审批 err = SubmitApproval(sealInfo) return } // editSeal 编辑用印申请 func editSeal(sealId, userId, contractId, fileNum int, use, companyName, userCompanyName, creditCode, serviceType, sealType, remark string, fileUrls []string, affiliatedCompany string) (sealInfo *seal.Seal, err error) { if !strings.Contains(strings.Join(seal.EnumUse, ","), use) { err = errors.New("用印用途异常") return } if !strings.Contains(strings.Join(seal.EnumServiceType, ","), serviceType) { err = errors.New("业务类型异常") return } sealInfo, err = seal.GetSealInfoById(sealId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New("获取用印申请失败") } return } if sealInfo.UserId != userId { err = errors.New("当前账号无操作权限") return } ignoreStatus := []string{"待提交", "已撤回", "已驳回"} if !strings.Contains(strings.Join(ignoreStatus, ","), sealInfo.Status) { err = errors.New("用印状态异常,不允许修改,当前用印状态:" + sealInfo.Status) return } fileUrl := "" now := time.Now() attachments := make([]*seal.Attachment, 0) if len(fileUrls) == 1 { fileUrl = fileUrls[0] } sealInfo.Use = use sealInfo.CompanyName = companyName sealInfo.UseCompanyName = userCompanyName sealInfo.CreditCode = creditCode sealInfo.ServiceType = serviceType sealInfo.SealType = sealType sealInfo.Remark = remark sealInfo.FileUrl = fileUrl sealInfo.FileNum = fileNum sealInfo.ContractId = contractId sealInfo.ModifyTime = now sealInfo.CreateTime = now // 更新提交时间 sealInfo.Status = "待提交" sealInfo.AffiliatedCompany = affiliatedCompany err = sealInfo.Update([]string{"Use", "CompanyName", "UseCompanyName", "CreditCode", "ServiceType", "SealType", "Remark", "FileUrl", "FileNum", "ContractId", "ModifyTime", "CreateTime", "Status", "AffiliatedCompany"}) if err != nil { return } //删除原有的附件,新增最新的附件 err = seal.DelAttachmentBySealId(sealId) if err != nil { return } if len(fileUrls) > 1 { for _, v := range fileUrls { tmp := &seal.Attachment{ SealId: sealInfo.SealId, FileUrl: v, ModifyTime: now, CreateTime: now, } attachments = append(attachments, tmp) } err = seal.AddAttachments(attachments) } return } // VerifierEditApply 合规编辑用印申请 func VerifierEditApply(sysUser *system.Admin, req request.SealApprovalEditReq) (err error) { // 审批权限校验 sealInfo, approvalInfo, approvalRecord, err := CheckApprovalAuth(req.SealId, sysUser) if err != nil { return } // 数据状态校验 if sysUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE { err = errors.New("当前账号无修改权限") return } if sealInfo.Status != "待审批" { err = errors.New("用印状态异常,不允许修改,当前用印状态:" + sealInfo.Status) return } if !strings.Contains(strings.Join(seal.EnumUse, ","), req.Use) { err = errors.New("用印用途异常") return } if !strings.Contains(strings.Join(seal.EnumServiceType, ","), req.ServiceType) { err = errors.New("业务类型异常") return } // 变更字段判断 updateCol := make([]string, 0) updateContent := make([]string, 0) if sealInfo.Use != req.Use { updateCol = append(updateCol, "Use") updateContent = append(updateContent, "用印用途") } if sealInfo.SealType != req.SealType { updateCol = append(updateCol, "SealType") updateContent = append(updateContent, "加盖何种印章") } if sealInfo.Remark != req.Remark { updateCol = append(updateCol, "Remark") updateContent = append(updateContent, "备注") } if sealInfo.FileNum != req.FileNum { updateCol = append(updateCol, "FileNum") updateContent = append(updateContent, "文件份数") } //判断附件地址是否相等: sealAttachements, err := seal.GetAttachmentBySealId(sealInfo.SealId) if err != nil { err = errors.New(fmt.Sprint("获取用印附件失败,Err:"+err.Error(), err)) return } oldFileUrls := make([]string, 0) if sealInfo.FileUrl != "" { oldFileUrls = append(oldFileUrls, sealInfo.FileUrl) } if len(sealAttachements) > 0 { for _, v := range sealAttachements { oldFileUrls = append(oldFileUrls, v.FileUrl) } } attachmentFlag := false if !reflect.DeepEqual(oldFileUrls, req.FileUrls) { updateCol = append(updateCol, "FileUrl") updateContent = append(updateContent, "文件附件") attachmentFlag = true } if sealInfo.AffiliatedCompany != req.AffiliatedCompany { updateCol = append(updateCol, "AffiliatedCompany") updateContent = append(updateContent, "归属公司") } if len(updateCol) <= 0 { err = errors.New("没有变更信息") return } content := "用印修改:" + sysUser.RealName + "修改了" + strings.Join(updateContent, "、") // 通过盖章类型判断是否需要变更审批流程 originFlowType := GetFlowTypeBySealType(sealInfo.SealType) reqFlowType := GetFlowTypeBySealType(req.SealType) //如果变更了盖章类型(涉及到审批流程变更),那么需要变更审批流 //变更审批流:先驳回用印申请,再修改用印,再发消息给申请人,再替申请人重新发起申请, //然后遍历审批流程,当前操作人节点之前的全部审核通过,最后通过当前操作人的节点(改成如果一级审批人如果是自己,那么直接通过这一级审批,否则不通过,让审批单重走流程) newFileUrl := "" if len(req.FileUrls) == 1 { newFileUrl = req.FileUrls[0] } if originFlowType != reqFlowType { // 先驳回 err = reject(sealInfo, approvalInfo, approvalRecord, sysUser, "") if err != nil { return } //修改用印申请,给申请人发消息 sealInfo.Use = req.Use sealInfo.SealType = req.SealType sealInfo.Remark = req.Remark sealInfo.FileNum = req.FileNum sealInfo.FileUrl = newFileUrl sealInfo.ModifyTime = time.Now() sealInfo.AffiliatedCompany = req.AffiliatedCompany verifierEdit(sealInfo, updateCol, approvalRecord.ContractApprovalRecordId, content, sysUser, attachmentFlag, req.FileUrls) // 重新获取最新的用印单 sealInfo, tmpErr := seal.GetSealInfoById(sealInfo.SealId) if tmpErr != nil { err = tmpErr return } err = reapply(sealInfo, sysUser) if err != nil { return } // 重新发起申请 } else { // 修改用印申请,给申请人发消息 sealInfo.Use = req.Use sealInfo.SealType = req.SealType sealInfo.Remark = req.Remark sealInfo.FileNum = req.FileNum sealInfo.FileUrl = newFileUrl sealInfo.ModifyTime = time.Now() sealInfo.AffiliatedCompany = req.AffiliatedCompany verifierEdit(sealInfo, updateCol, approvalRecord.ContractApprovalRecordId, content, sysUser, attachmentFlag, req.FileUrls) // 审核通过 err = ApprovedApproval(sealInfo.SealId, sysUser, "") } // 操作日志 err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, approvalRecord.ContractApprovalRecordId, "edit", sysUser.RealName, "审批人修改信息", "") if err != nil { return } return } // verifierEdit 审批人修改用印信息 func verifierEdit(sealInfo *seal.Seal, updateCol []string, approvalRecordId int, content string, opUser *system.Admin, attachmentFlag bool, fileUrls []string) { if attachmentFlag { // 同时更新用印申请和附件 _ = updateSealAndAttachment(sealInfo, updateCol, fileUrls) } else { _ = sealInfo.Update(updateCol) } //给用印人,发送修改消息 sysUserMobile := "" sysUser, _ := system.GetSysAdminById(opUser.AdminId) if sysUser != nil { sysUserMobile = sysUser.Mobile } go services.AddCompanyApprovalMessage(opUser.AdminId, sealInfo.UserId, 0, approvalRecordId, 3, sourceType, 2, sealInfo.CompanyName, content, content, sysUserMobile) return } // reapply 重新提交审批单 func reapply(sealInfo *seal.Seal, opUser *system.Admin) (err error) { // 发起审批 approvalInfo, contractApprovalRecordList, err := addApproval(sealInfo) if err != nil { return } // 校验一级审批人是否与当前提交人一致,如果一致的话,那么审批通过且不发送消息给一级审批人 var contractApprovalRecord *contract.ContractApprovalRecord for _, tmpContractApprovalRecord := range contractApprovalRecordList { if tmpContractApprovalRecord.NodeId == approvalInfo.CurrNodeId && tmpContractApprovalRecord.ApproveUserId == opUser.AdminId { contractApprovalRecord = tmpContractApprovalRecord } } // 如果一级审批人和当前提交人一致,那么审批通过,且不发送消息给一级审批人 if contractApprovalRecord != nil { err = ApprovedApproval(sealInfo.SealId, opUser, "") } else { //如果一级审批人和当前提交人不一致,那么发送消息给一级审批人,重走审批流程 //待办通知 { //发送消息下级审批人 go MessageToNodeUser(contractApprovalRecordList[0].NodeId, approvalInfo.ApplyUserId, approvalInfo.ContractApprovalId, 1, 1, sealInfo.CompanyName, sealInfo.Use) } } return } // GetSealApprovalPageList 获取用印审批分页列表 func GetSealApprovalPageList(condition, joinCondition string, pars []interface{}, startSize, pageSize int, sysUser *system.Admin) (newList []*response.SealApprovalList, total int, err error) { // 1.列表数据 list, total, err := seal.GetSealApprovalListByWhere(condition, joinCondition, pars, startSize, pageSize) if err != nil { err = errors.New(fmt.Sprint("获取用印审批列表失败,Err:"+err.Error(), err)) return } // 2.操作权限 if len(list) > 0 { // 取出所有列表最新的审批IDs approvalIdSlice := make([]string, 0) // 取出所有列表的关联合同id contractIdSlice := make([]string, 0) for i := 0; i < len(list); i++ { approvalIdSlice = append(approvalIdSlice, strconv.Itoa(list[i].ContractApprovalId)) contractIdSlice = append(contractIdSlice, strconv.Itoa(list[i].ContractId)) } approvalIdStr := strings.Join(approvalIdSlice, ",") // 通过审批IDs获取所有的审批流 approvalRecordList, tempErr := contract.GetContractApprovalRecordListByContractApprovalIds(approvalIdStr) //approvalRecordList, tempErr := contract.GetContractApprovalRecordList(approvalIdStr, sysUser.AdminId) if tempErr != nil { err = errors.New(fmt.Sprint("获取审批流失败,Err:"+tempErr.Error(), err)) return } // 获取自己的审批流列表数据 selfContractApprovalRecordList, tempErr := contract.GetSelfContractApprovalRecordList(approvalIdStr, sysUser.AdminId) if tempErr != nil { err = errors.New(fmt.Sprint("获取审批列表失败,Err:"+tempErr.Error(), err)) return } selfContractApprovalRecordMap := make(map[int]*contract.ContractApprovalRecord) for i := 0; i < len(selfContractApprovalRecordList); i++ { selfContractApprovalRecordMap[selfContractApprovalRecordList[i].ContractApprovalId] = selfContractApprovalRecordList[i] } // 获取所有关联的合同列表 selfContractMap := make(map[int]*contract.ContractList) { if len(contractIdSlice) > 0 { contractIdStr := strings.Join(contractIdSlice, ",") contractList, tempErr := contract.GetContractListByContractIds(contractIdStr) if tempErr != nil { err = errors.New(fmt.Sprint("获取合同失败,Err:"+tempErr.Error(), err)) return } for i := 0; i < len(contractList); i++ { selfContractMap[contractList[i].ContractId] = contractList[i] } } } for i := 0; i < len(list); i++ { item := list[i] list[i].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime) list[i].ModifyTimeStr = item.ModifyTime.Format(utils.FormatDateTime) list[i].ApproveTimeStr = item.ApproveTime.Format(utils.FormatDateTime) list[i].InvalidTimeStr = item.InvalidTime.Format(utils.FormatDateTime) list[i].CheckBackFileTimeStr = item.CheckBackFileTime.Format(utils.FormatDateTime) if item.ApproveStatus == "已审批" || item.ApproveStatus == "已驳回" { list[i].ApproveTime = item.ModifyTime list[i].ApproveTimeStr = item.ModifyTime.Format(utils.FormatDateTime) } // 如果当前状态是待审批的话,那么校验自己的审批流数据,然后去返回对应的状态 if item.Status == "待审批" { // 如果是自己发起的审批单,同时已经经过了一轮审批,那么标记为处理中 if item.ApplyUserId == sysUser.AdminId && item.CurrNodeId > item.StartNodeId { list[i].Status = "处理中" } else if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_ADMIN && item.CurrNodeId > item.StartNodeId { // 如果是超管角色,同时已经经过了一轮审批,那么标记为处理中 list[i].Status = "处理中" } else { // 此处可能出现同一审批人同时有权限处理一级二级的情况 maxNodeId := 0 tempStatus := "待审批" for _, selfRecord := range selfContractApprovalRecordList { if item.ContractApprovalId == selfRecord.ContractApprovalId { if selfRecord.NodeId > maxNodeId { maxNodeId = selfRecord.NodeId } if maxNodeId < item.CurrNodeId && selfRecord.NodeType != "cc" { tempStatus = "处理中" } else if maxNodeId == item.CurrNodeId && selfRecord.NodeType != "cc" { tempStatus = "待审批" } } } list[i].Status = tempStatus /*if contractApprovalRecord, has := selfContractApprovalRecordMap[item.ContractApprovalId]; has { if contractApprovalRecord.NodeId < item.CurrNodeId && contractApprovalRecord.NodeType != "cc" { list[i].Status = "处理中" } }*/ } } // 合同编码 if selfContract, has := selfContractMap[item.ContractId]; has { list[i].ContractCode = selfContract.ContractCode } // 取出item对应approval_id的审批流 var tempApprovalRecordMap []*contract.ContractApprovalRecord for _, recordItem := range approvalRecordList { if item.ContractApprovalId == recordItem.ContractApprovalId { tempApprovalRecordMap = append(tempApprovalRecordMap, recordItem) } } // 获取对该条数据的操作权限 opButton, tempErr := handleListOpButton(item, tempApprovalRecordMap, sysUser) if tempErr != nil { err = errors.New(fmt.Sprint("获取操作权限失败,Err:"+tempErr.Error(), err)) return } tempNewList := &response.SealApprovalList{ SealApprovalItem: item, OpButton: opButton, } newList = append(newList, tempNewList) } } return } // handleOpButton 列表数据操作权限 func handleListOpButton(approvalItem *seal.SealApprovalItem, recordList []*contract.ContractApprovalRecord, sysUser *system.Admin) (opButton response.SealApprovalOpButton, err error) { // 待审批状态下,如果是自己发起的审批单,同时已经经过了一轮审批,那么标记为处理中 if approvalItem.Status == "待审批" { if approvalItem.ApplyUserId == sysUser.AdminId && approvalItem.CurrNodeId > approvalItem.StartNodeId { approvalItem.Status = "处理中" } } flowNodeMap := make(map[int][]contract.ContractApprovalRecord, 0) keySort := make([]int, 0) for _, approvalRecord := range recordList { // 如果当前节点正好是该节点,同时审批单状态是待审批状态,然后当前账号又有权限,该账号也正是审批人,那么允许审批操作 if approvalItem.CurrNodeId == approvalRecord.NodeId && approvalItem.Status == "待审批" { if sysUser.AdminId == approvalRecord.ApproveUserId && approvalRecord.NodeType == "check" { opButton.Approval = true } // 合规在审批过程中具有 部分修改权限 if sysUser.AdminId == approvalRecord.ApproveUserId && sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && approvalRecord.NodeType == "check" { opButton.CheckEdit = true } } // 如果当前节点正好是该节点,同时审批单状态又是第一层节点 if approvalItem.CurrNodeId == approvalRecord.NodeId && approvalRecord.PrevNodeId == 0 && approvalItem.Status == "待审批" { // 发起人具有撤回审批单权限 if sysUser.AdminId == approvalItem.ApplyUserId { opButton.Cancel = true } } if tmpFlowNodeList, ok := flowNodeMap[approvalRecord.NodeId]; ok { flowNodeMap[approvalRecord.NodeId] = append(tmpFlowNodeList, *approvalRecord) } else { tmpFlowNodeList := make([]contract.ContractApprovalRecord, 1) tmpFlowNodeList[0] = *approvalRecord flowNodeMap[approvalRecord.NodeId] = tmpFlowNodeList keySort = append(keySort, approvalRecord.NodeId) } // 待审批状态下,如果当前审批节点就是操作人,审批节点超过当前审批节点,且节点类型是抄送人,,那么标记为处理中 if approvalItem.Status == "待审批" { if approvalRecord.ApproveUserId == sysUser.AdminId && approvalRecord.NodeId < approvalItem.CurrNodeId && approvalRecord.NodeType == "cc" { approvalItem.Status = "处理中" } } } // 作废权限 if sysUser.AdminId == approvalItem.ApplyUserId && approvalItem.Status == "已审批" { opButton.Invalid = true } // 是否具有签回合同用印权限 uploadStatus := []string{"已审批", "已签回"} if sysUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && strings.Contains(strings.Join(uploadStatus, ","), approvalItem.Status) { opButton.UploadFile = true } // 编辑权限 editStatus := []string{"已驳回", "待提交", "已撤回"} if sysUser.AdminId == approvalItem.ApplyUserId && strings.Contains(strings.Join(editStatus, ","), approvalItem.Status) { opButton.Edit = true } return } // GetSealApprovalDetail 获取审批详情 func GetSealApprovalDetail(sealId int, sysUser *system.Admin) (sealMore *response.SealMoreResp, flowNodeListResp [][]contract.ContractApprovalRecord, opButton response.SealApprovalOpButton, err error) { sealInfo, err := seal.GetSealInfoById(sealId) if err != nil { err = errors.New(fmt.Sprint("获取用印详情失败,Err:"+err.Error(), err)) return } sealAttachements, err := seal.GetAttachmentBySealId(sealId) if err != nil { err = errors.New(fmt.Sprint("获取用印附件失败,Err:"+err.Error(), err)) return } fileUrls := make([]string, 0) if sealInfo.FileUrl != "" { fileUrls = append(fileUrls, sealInfo.FileUrl) } for _, v := range sealAttachements { fileUrls = append(fileUrls, v.FileUrl) } sealMore = &response.SealMoreResp{ Seal: sealInfo, FileUrls: fileUrls, } // 查询最近一次审批单信息 lastApprovalInfo, err := contract.GetLastContractApprovalByContractId(sealInfo.SealId, "seal") if err != nil { if err.Error() != utils.ErrNoRow() { err = errors.New("获取最近一次审批单信息失败,ERR:" + err.Error()) } err = nil return } if lastApprovalInfo != nil { // 获取审批操作和审批流数据 tmpSealOpButton, tmpFlowNodeListResp, tmpErr := GetSealOpButton(sealInfo, lastApprovalInfo, sysUser) if tmpErr != nil { err = errors.New("获取用印按钮权限、审批流程失败,Err:" + tmpErr.Error()) return } opButton = tmpSealOpButton flowNodeListResp = tmpFlowNodeListResp } return } // GetSealOpButton 获取用印审批操作权限 func GetSealOpButton(sealInfo *seal.Seal, contractApprovalInfo *contract.ContractApproval, opUser *system.Admin) (sealOpButton response.SealApprovalOpButton, flowNodeListResp [][]contract.ContractApprovalRecord, err error) { // 审批流 approvalRecordList, err := contract.GetApprovalRecordListByApprovalId(contractApprovalInfo.ContractApprovalId) if err != nil { err = errors.New("获取审批失败,Err:" + err.Error()) return } // 待审批状态下,如果是自己发起的审批单,同时已经经过了一轮审批,那么标记为处理中 if contractApprovalInfo.Status == "待审批" { if contractApprovalInfo.ApplyUserId == opUser.AdminId && contractApprovalInfo.CurrNodeId > contractApprovalInfo.StartNodeId { sealInfo.Status = "处理中" } } flowNodeMap := make(map[int][]contract.ContractApprovalRecord, 0) keySort := make([]int, 0) for _, approvalRecord := range approvalRecordList { // 如果当前节点正好是该节点,同时审批单状态是待审批状态,然后当前账号又有权限,该账号也正是审批人,那么允许审批操作 if contractApprovalInfo.CurrNodeId == approvalRecord.NodeId && contractApprovalInfo.Status == "待审批" { if opUser.AdminId == approvalRecord.ApproveUserId && approvalRecord.NodeType == "check" { sealOpButton.Approval = true } // 合规在审批过程中具有 部分修改权限 if opUser.AdminId == approvalRecord.ApproveUserId && opUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && approvalRecord.NodeType == "check" { sealOpButton.CheckEdit = true } } // 如果当前节点正好是该节点,同时审批单状态又是第一层节点 if contractApprovalInfo.CurrNodeId == approvalRecord.NodeId && approvalRecord.PrevNodeId == 0 && contractApprovalInfo.Status == "待审批" { // 发起人具有撤回审批单权限 if opUser.AdminId == sealInfo.UserId { sealOpButton.Cancel = true } } if tmpFlowNodeList, ok := flowNodeMap[approvalRecord.NodeId]; ok { flowNodeMap[approvalRecord.NodeId] = append(tmpFlowNodeList, *approvalRecord) } else { tmpFlowNodeList := make([]contract.ContractApprovalRecord, 1) tmpFlowNodeList[0] = *approvalRecord flowNodeMap[approvalRecord.NodeId] = tmpFlowNodeList keySort = append(keySort, approvalRecord.NodeId) } // 待审批状态下,如果当前审批节点就是操作人,审批节点超过当前审批节点,且节点类型是抄送人,,那么标记为处理中 if contractApprovalInfo.Status == "待审批" { if approvalRecord.ApproveUserId == opUser.AdminId && approvalRecord.NodeId < contractApprovalInfo.CurrNodeId && approvalRecord.NodeType == "cc" { sealInfo.Status = "处理中" } } } for _, key := range keySort { flowNodeListResp = append(flowNodeListResp, flowNodeMap[key]) } // 作废权限 if opUser.AdminId == sealInfo.UserId && sealInfo.Status == "已审批" { sealOpButton.Invalid = true } // 是否具有签回合同用印权限 uploadStatus := []string{"已审批", "已签回"} if opUser.RoleTypeCode == utils.ROLE_TYPE_CODE_COMPLIANCE && strings.Contains(strings.Join(uploadStatus, ","), sealInfo.Status) { sealOpButton.UploadFile = true } // 编辑权限 editStatus := []string{"已驳回", "待提交", "已撤回"} if opUser.AdminId == sealInfo.UserId && strings.Contains(strings.Join(editStatus, ","), sealInfo.Status) { sealOpButton.Edit = true } return } // CancelSealApproval 撤回用印审批 func CancelSealApproval(sealId int, sysUser *system.Admin) (err error) { // 审批信息 sealInfo, err := seal.GetSealInfoById(sealId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New("用印审批信息有误,Err:" + err.Error()) } return } // 审批状态判断 if sealInfo.Status != "待审批" { err = errors.New("用印状态异常,不允许撤回申请,当前用印状态:" + sealInfo.Status) return } // 操作人与申请人是否一致 if sealInfo.UserId != sysUser.AdminId { err = errors.New("不允许撤回非本人提交的申请:" + strconv.Itoa(sealInfo.UserId)) return } // 获取最近一次待审批的审批单信息 approvalInfo, err := contract.GetLastContractApprovalByContractId(sealInfo.SealId, "seal") if err != nil { return } if approvalInfo.Status != "待审批" { err = errors.New("审批单状态异常,审批单状态:" + approvalInfo.Status) return } //获取当前审批单的审批流信息 approvalRecordList, err := contract.GetContractApprovalRecordListByContractApprovalIdAndNodeId(approvalInfo.ContractApprovalId, approvalInfo.CurrNodeId) if err != nil { err = errors.New("获取审批流失败,Err:" + err.Error()) return } if len(approvalRecordList) <= 0 { err = errors.New("找不到对应的审批流") return } for _, tmpApprovalRecord := range approvalRecordList { // 判断当前节点是否存在上级节点,如果存在,那么说明 if tmpApprovalRecord.PrevNodeId > 0 { err = errors.New("合同已存在审批操作,不允许撤回申请") return } } // 获取当前审批单中所有待审批的流程流 contractApprovalRecordList, err := contract.GetPendingContractApprovalRecordListByContractId(approvalInfo.ContractApprovalId, approvalInfo.CurrNodeId) if err != nil { return } // 撤回审批流 err = approvalInfo.Cancel(approvalInfo, contractApprovalRecordList) if err != nil { return } // 添加操作日志 err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "cancel", sysUser.RealName, "撤回申请", "") if err != nil { return } // 作废原有消息 for _, contractApprovalRecord := range contractApprovalRecordList { go company.CancelCompanyApprovalMessage(contractApprovalRecord.ContractApprovalRecordId, 3) } return } // DelSealApproval 删除用印审批 func DelSealApproval(sealId int, sysUser *system.Admin) (err error) { // 审批信息 sealInfo, err := seal.GetSealInfoById(sealId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New("用印审批信息有误,Err:" + err.Error()) } return } // 审批状态判断 if sealInfo.Status != "已撤回" { err = errors.New("用印状态异常,不允许删除,当前用印状态:" + sealInfo.Status) return } // 操作人与申请人是否一致 if sealInfo.UserId != sysUser.AdminId { err = errors.New("不允许删除非本人提交的申请:" + strconv.Itoa(sealInfo.UserId)) return } // 删除用印审批 err = seal.DeleteSeal(sealInfo) if err != nil { err = errors.New("删除用印申请失败:" + strconv.Itoa(sealInfo.UserId)) return } // 添加操作日志 err = seal.AddSealOperationRecord(sealInfo.SealId, sysUser.AdminId, 0, "del", sysUser.RealName, "删除申请", "") if err != nil { return } return } // InvalidSealApproval 作废用印审批 func InvalidSealApproval(sealId int, opUser *system.Admin) (err error) { //查询当前用印信息 sealInfo, err := seal.GetSealInfoById(sealId) if err != nil { if err.Error() == utils.ErrNoRow() { err = errors.New(fmt.Sprint("根据用印编号:", sealId, " 找不到初始用印")) } return } if sealInfo.UserId != opUser.AdminId && opUser.RoleTypeCode != utils.ROLE_TYPE_CODE_COMPLIANCE { err = errors.New("当前账号无操作权限") return } if sealInfo.Status != "已审批" { err = errors.New("用印状态异常,不允许作废,当前用印状态:" + sealInfo.Status) return } //如果删除状态 >0,那么代表已经被删除了 if sealInfo.IsDelete > 0 { err = errors.New("该用印已删除") return } //用印作废 err = seal.Invalid(sealInfo) if err != nil { return } // 操作日志 err = seal.AddSealOperationRecord(sealInfo.SealId, opUser.AdminId, 0, "invalid", opUser.RealName, "作废审批", "") if err != nil { return } //获取最近一次提交的审批单信息 contractApproval, err := contract.GetLastContractApprovalByContractId(sealInfo.SealId, "seal") if err != nil { err = nil return } //如果有提测信息,那么需要给对应的审批人发送消息 if contractApproval != nil { //作废后需要给审批者发送消息 contractApprovalRecordList, tmpErr := contract.GetContractApprovalRecordListByContractApprovalId(contractApproval.ContractApprovalId) if tmpErr != nil { return } content := fmt.Sprint("作废", sealInfo.CompanyName, "用印申请") for _, contractApprovalRecord := range contractApprovalRecordList { if contractApprovalRecord.NodeType == "check" { //如果是审批人,那么需要发送消息给对方 //操作人信息 sysUserMobile := "" sysUser, _ := system.GetSysAdminById(contractApprovalRecord.ApproveUserId) if sysUser != nil { sysUserMobile = sysUser.Mobile } go services.AddCompanyApprovalMessage(opUser.AdminId, contractApprovalRecord.ApproveUserId, 0, contractApprovalRecord.ContractApprovalRecordId, 3, sourceType, 2, sealInfo.CompanyName, content, content, sysUserMobile) } } } return } // GetSealOperationRecordList 获取用印操作日志列表 func GetSealOperationRecordList(sealId int) (list []*seal.SealOperationRecordList, err error) { list, err = seal.GetSealOperationListBySealId(sealId) if len(list) > 0 { for k, item := range list { list[k].CreateTimeStr = item.CreateTime.Format(utils.FormatDateTime) } } return } // updateSealAndAttachment 更新用印申请,并更新附件 func updateSealAndAttachment(sealInfo *seal.Seal, updateCol []string, fileUrls []string) (err error) { o := orm.NewOrm() to, err := o.Begin() if err != nil { return } defer func() { if err != nil { _ = to.Rollback() } else { _ = to.Commit() } }() err = sealInfo.Update(updateCol) if err != nil { return } now := time.Now() //删除原有的附件,新增最新的附件 err = seal.DelAttachmentBySealId(sealInfo.SealId) if err != nil { return } attachments := make([]*seal.Attachment, 0) if len(fileUrls) > 1 { for _, v := range fileUrls { tmp := &seal.Attachment{ SealId: sealInfo.SealId, FileUrl: v, ModifyTime: now, CreateTime: now, } attachments = append(attachments, tmp) } err = seal.AddAttachments(attachments) } return }