package taskflow import ( "appPlatform/models/modelAppPlatform" "appPlatform/models/modelshr" "appPlatform/overall" "appPlatform/overall/publicmethod" "encoding/json" "regexp" "sort" "strconv" "strings" "time" "github.com/gin-gonic/gin" ) /* * @ 作者: 秦东 @ 时间: 2023-11-01 10:28:48 @ 功能: 生成步进工作流 @ 参数 # @ 返回值 # @ 方法原型 # */ func (a *ApiMethod) GenerateFlow(c *gin.Context) { var requestData CreatFlowView err := c.ShouldBindJSON(&requestData) if err != nil { publicmethod.Result(10001, err, c) return } if requestData.Step == 0 { requestData.Step = 1 } var flowInfo modelAppPlatform.FlowVersion err = flowInfo.GetCont(map[string]interface{}{"`key`": requestData.Id, "`state`": 1}) if err != nil && flowInfo.Content == "" { publicmethod.Result(107, err, c) return } var flowVersionCont FlowMainBody err = json.Unmarshal([]byte(flowInfo.Content), &flowVersionCont) if err != nil { publicmethod.Result(104, err, c) return } context, _ := c.Get(overall.MyContJwt) var userCont modelshr.ManCont userCont.GetLoginCont(context) workFlowInfo := flowVersionCont.NodeConfig.CircularParsing(1, userCont, 349, requestData.ConditionList, requestData.NodelPeople) var sendInfo SendFlowInfo sendInfo.Step = requestData.Step sendInfo.NodeKey, sendInfo.NextStep, sendInfo.FlowList = ReformFlow(requestData.Step, workFlowInfo) publicmethod.Result(0, sendInfo, c) } /* * @ 作者: 秦东 @ 时间: 2023-11-21 09:26:44 @ 功能: 重整工作流步进值 @ 参数 #step 当前在执行第几步 #nodeList 工作流主体 @ 返回值 #nodeKey 当前执行节点标识 #nodeMap 工作流主体 @ 方法原型 # */ func ReformFlow(step int, nodeList []RunFlow) (nodeKey string, nextStep int, nodeMap []RunFlow) { sort.Slice(nodeList, func(i, j int) bool { return nodeList[i].Step < nodeList[j].Step }) nodeNum := make(map[int]string) for i, v := range nodeList { nodeNum[i] = v.NodeKey } for i, v := range nodeList { if v.Step == step { nodeKey = v.NodeKey } lastStep := step + 1 if lastStep == v.Step { nextStep = lastStep } var nodeInfo RunFlow nodeInfo.Step = v.Step //步骤 nodeInfo.Types = v.Types //0:发起节点;1:审批节点;2:抄送;3:执行节点 nodeInfo.NodeKey = v.NodeKey //节点识别符 nodeInfo.NodeName = v.NodeName //节点名称 nodeInfo.Status = v.Status //1:未到达;2:已审批;3:已驳回;4:再次审批 if i-1 >= 0 { nodeInfo.FromNode = nodeNum[i-1] } if val, isOk := nodeNum[i+1]; isOk { nodeInfo.ArriveNode = val //到哪个节点 } else { nodeInfo.ArriveNode = "endflow" //到哪个节点 } nodeInfo.GoBackNode = v.GoBackNode //驳回返回节点 nodeInfo.ExamineMode = v.ExamineMode //多人审批时采用的审批方式。0:无操作 1依次审批 2会签 3:非会签 nodeInfo.NoHanderAction = v.NoHanderAction //审批人为空时 1自动审批通过/不允许发起 2转交给审核管理员 nodeInfo.CustomNode = v.CustomNode //由哪个节点指定本节点审批人 nodeInfo.JudgeList = v.JudgeList //是否可自己选中操作人 var operAry []OperatorList for _, op := range v.Operator { var operInfo OperatorList operInfo.Id = op.Id //操作人ID operInfo.Types = op.Types //1:人员;2:角色;3:行政组织 operInfo.Name = op.Name //操作人姓名 operInfo.Number = op.Number //操作人工号 operInfo.Icon = op.Icon //操作人头像 operInfo.IconBase64 = op.IconBase64 //操作人头像 operInfo.Wechat = op.Wechat //微信Openid operInfo.DepartmentId = op.DepartmentId //分厂Id operInfo.DepartmentName = op.DepartmentName //分厂名称 operInfo.PostId = op.PostId //职务Id operInfo.PostName = op.PostName //职务名称 operInfo.Tema = op.Tema //班组Id operInfo.TemaName = op.TemaName //班组名称 operInfo.LogList = op.LogList //操作记录 operInfo.NoEdit = true //不可删除 operInfo.Tel = op.Tel // operInfo.CompanyName = op.CompanyName operAry = append(operAry, operInfo) } nodeInfo.Operator = operAry //操作人 nodeInfo.RunType = v.RunType //运行时选择 0:禁闭;1:发起人自选,2:发起人自己,3:有选中得节点指定,4:抄送节点 nodeInfo.RunScope = v.RunScope //运行时选择范围 0:不可选,1:本公司;2:本部门;当RunType = 4时:1:自选;非1:不可自选 nodeInfo.PendPers = v.PendPers // nodeMap = append(nodeMap, nodeInfo) } // nodeMap = nodeList return } /* * @ 作者: 秦东 @ 时间: 2023-11-01 10:52:35 @ 功能: 无限极循环节点 @ 参数 #step 步进值 #creater 当前操作人 #orgId 执行行政组织 #condition 判定条件值 @ 返回值 # @ 方法原型 # */ func (n *NodePublicInfo) CircularParsing(step int, creater modelshr.ManCont, orgId int64, condition []ConditionListInfo, nodelPeople []NodelPeopleInfo) (nodeList []RunFlow) { // fmt.Printf("step: %v; name:%v; Types:%v\n", step, n.NodeName, n.Types) var nodeInfo RunFlow nodeInfo.Step = step nodeInfo.Types = n.Types nodeInfo.NodeKey = n.NodeNumber nodeInfo.NodeName = n.NodeName nodeInfo.Status = 1 nodeInfo.FromNode = n.FromNode if n.SendBackNode == "" { nodeInfo.GoBackNode = "beginnode" } else { nodeInfo.GoBackNode = n.SendBackNode } nodeInfo.ExamineMode = n.ExamineMode nodeInfo.NoHanderAction = n.NoHanderAction //判断节点类型 //0:发起人;1:审批;2:抄送;3:执行人;4:条件;5:路由 switch n.Types { case 1, 3: // 审批人设置 1:指定成员; 2:主管;3:行政岗位; 4:发起人自选; 5:发起人自己;6:连续多级主管;7:指定前置审批为本节点设置审批人;8:表单字段;9:权限矩阵 switch n.Settype { case 1: //指定成员 nodeInfo.Operator = OperatorHandle(n.NodeUserList) case 2: //主管 var levelUserList ContinuousMultiLevelSupervisor levelUserList.MaxLevel = n.DirectorLevel levelUserList.Continuity = false if n.Attribute == 1 { //申请人 nodeInfo.Operator = levelUserList.ObtainRelevantLevelLeaders(creater.AdminOrg) } else { //执行部门 nodeInfo.Operator = levelUserList.ObtainRelevantLevelLeaders(orgId) } case 3: //行政岗位 if n.Attribute == 1 { nodeInfo.Operator = GainOrgPostUserList(creater.AdminOrg, n.NodeUserList) } else { nodeInfo.Operator = GainOrgPostUserList(orgId, n.NodeUserList) } case 4: //发起人自选 nodeInfo.RunType = 1 nodeInfo.RunScope = n.SelectRange if n.SelectRange != 1 { // fmt.Printf("发起人自选--->%v\n--->%v\n", n.SelectRange, OperatorHandle(n.NodeUserList)) nodeInfo.PendPers = OperatorHandle(n.NodeUserList) } case 5: //发起人自己 var myCont modelshr.ManCont myCont.GetCont(map[string]interface{}{"`id`": creater.Id}, "`key`", "`name`", "`number`", "`icon`", "`icon_photo`", "`wechat`", "`work_wechat`", "`admin_org`", "`position`", "`teamid`", "`mobilephone`,`company`") nodeInfo.Operator = append(nodeInfo.Operator, TransformPublicUs(myCont)) case 6: //连续多级主管 var levelUserList ContinuousMultiLevelSupervisor levelUserList.MaxLevel = n.ExamineEndDirectorLevel levelUserList.Continuity = true if n.Attribute == 1 { //申请人 nodeInfo.Operator = levelUserList.ObtainRelevantLevelLeaders(creater.AdminOrg) } else { //执行部门 nodeInfo.Operator = levelUserList.ObtainRelevantLevelLeaders(orgId) } case 7: //指定前置审批为本节点设置审批人 nodeInfo.RunType = 3 nodeInfo.CustomNode = n.CustomNode case 8: //表单字段 reg1 := regexp.MustCompile(`\(([^)]+)\)`) //解析()内的数据 var userNumber []string //工号切片 for _, v := range n.NodeUserList { //判断本节点需要什么样的表格字段 for _, e := range nodelPeople { //循环找出提交得表格字段 if v.Id == e.FactorId { //判断提交得字段是否为当前节点操作字段 userAry := reg1.FindAllStringSubmatch(e.UserList, -1) //按照正则规则提取数据 for _, u := range userAry { vLen := len(u) if vLen > 0 { if !publicmethod.IsInTrue[string](u[vLen-1], userNumber) { userNumber = append(userNumber, u[vLen-1]) //将工号写入数组 } } } } } } if len(userNumber) > 0 { nodeInfo.Operator = GainUserCode(userNumber) } case 9: //权限矩阵 if n.Attribute == 1 { nodeInfo.Operator = GainMatrixUserList(creater.AdminOrg, n.Matrix) } else { nodeInfo.Operator = GainMatrixUserList(orgId, n.Matrix) } default: } // jsonCont, _ := json.Marshal(nodeInfo) // fmt.Printf("第%v步------>%v\n", step, string(jsonCont)) nodeList = append(nodeList, nodeInfo) if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(step+1, creater, orgId, condition, nodelPeople)...) } case 2: nodeInfo.RunType = 4 nodeInfo.RunScope = n.CcSelfSelectFlag nodeInfo.Operator = OperatorHandle(n.NodeUserList) nodeList = append(nodeList, nodeInfo) if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(step+1, creater, orgId, condition, nodelPeople)...) } case 4: case 5: if len(n.ConditionNodes) > 0 { //根据维度序号排序 sort.Slice(n.ConditionNodes, func(i, j int) bool { return n.ConditionNodes[i].PriorityLevel < n.ConditionNodes[j].PriorityLevel }) lastStrp := step for _, pv := range n.ConditionNodes { //循环解析相关条件 routerNodes := pv.ResolveRouting(step, creater, orgId, condition, nodelPeople) if len(routerNodes) > 0 { lastStrp = lastStrp + len(routerNodes) nodeList = append(nodeList, routerNodes...) break } } if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(lastStrp, creater, orgId, condition, nodelPeople)...) } } else { if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(step+1, creater, orgId, condition, nodelPeople)...) } } default: nodeInfo.RunType = 0 //发起人 var originator OperatorList originator.Id = strconv.FormatInt(creater.Key, 10) //操作人ID originator.Types = 1 //1:人员;2:角色;3:行政组织 originator.Name = creater.Name //操作人姓名 originator.Number = creater.Number //操作人工号 originator.Icon = creater.Icon //操作人头像 originator.IconBase64 = creater.IconPhpto //操作人头像 originator.Wechat = creater.Wechat //微信Openid if creater.WorkWechat != "" { originator.Wechat = creater.WorkWechat //企业微信Openid } _, companyId, _, _, _ := publicmethod.GetOrgStructurees(creater.AdminOrg) originator.DepartmentId = companyId //分厂Id if companyId != 0 { var orgCont modelshr.AdministrativeOrganization orgCont.GetCont(map[string]interface{}{"`id`": companyId}, "`name`") originator.DepartmentName = orgCont.Name //分厂名称 } //获取岗位 if creater.Position != 0 { var postCont modelshr.Position postCont.GetCont(map[string]interface{}{"`id`": creater.Position}, "`name`") originator.PostId = creater.Position //职务Id originator.PostName = postCont.Name //职务名称 } if creater.TeamId != 0 { var teamCont modelshr.TeamGroup teamCont.GetCont(map[string]interface{}{"`id`": creater.TeamId}, "`name`") originator.Tema = creater.TeamId //班组Id originator.TemaName = teamCont.Name //班组名称 } var logCont LogList logCont.State = 1 //状态 1、未操作;2、通过;3、驳回 logCont.TimeVal = publicmethod.UnixTimeToDay(time.Now().Unix(), 1) // originator.LogList = append(originator.LogList, logCont) //操作记录 nodeInfo.Operator = append(nodeInfo.Operator, originator) nodeList = append(nodeList, nodeInfo) if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(step+1, creater, orgId, condition, nodelPeople)...) } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-16 09:44:25 @ 功能: 解析条件 @ 参数 #step 步进值 #creater 当前操作人 #orgId 执行行政组织 #condition 判定条件值 @ 返回值 #nodeList 操作节点 @ 方法原型 # */ func (n *NodePublicInfoES) ResolveRouting(step int, creater modelshr.ManCont, orgId int64, condition []ConditionListInfo, nodelPeople []NodelPeopleInfo) (nodeList []RunFlow) { // fmt.Printf("解析条件---》%v\n", n.NodeName) if len(n.ConditionList) > 0 { // fmt.Printf("解析条件--1-》%v\n", n.ConditionList) termAry := 0 for _, v := range n.ConditionList { //条件类型:1:人员、行政组织、角色;2:自定义字段;3:关联表单字段; switch v.Types { case 1: if JudgingTermPeoOrgRoles(v.NodeUserList, creater) { //判断申请人是否在可允许范围之内 // termAry = append(termAry, 1) termAry++ } case 2: if JudgingCustomConditions(v.CustomFields, condition) { termAry++ } case 3: if ProcessMultipleSelectionResults(v, condition) { //判断表单 // termAry = append(termAry, 3) termAry++ } default: } } // fmt.Printf("termAry:%v----->%v\n", len(n.ConditionList), termAry) // if len(termAry) == len(n.ConditionList) { if termAry == len(n.ConditionList) { if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(step, creater, orgId, condition, nodelPeople)...) } } } else { if n.ChildNode != nil { nodeList = append(nodeList, n.ChildNode.CircularParsing(step, creater, orgId, condition, nodelPeople)...) } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-17 09:20:37 @ 功能: 处理自定义条件 @ 参数 #CustomFields 条件集合 #presetVal 提交项目 @ 返回值 #isTrue true:条件符合,验证通过;false:不通过 @ 方法原型 # */ func JudgingCustomConditions(customFields []CustomFieldsInfo, presetVal []ConditionListInfo) (isTrue bool) { isTrue = false if len(presetVal) < 1 { return } var subCustomFields []CustomFieldsInfo for _, v := range presetVal { if v.Types == 2 && len(v.CustomFields) > 0 { subCustomFields = append(subCustomFields, v.CustomFields...) } } if len(subCustomFields) < 1 { return } isOk := 0 for _, s := range subCustomFields { //提交的条件结果 for _, c := range customFields { //预设定条件 if s.Wordfield == c.Wordfield { switch c.OptType { case "1": //小于 sLeftVal, sErr := strconv.ParseFloat(s.LeftVal, 64) if sErr == nil { cLeftVal, cErr := strconv.ParseFloat(c.LeftVal, 64) if cErr == nil { if sLeftVal < cLeftVal { isOk++ } } } case "2": //大于 sLeftVal, sErr := strconv.ParseFloat(s.LeftVal, 64) if sErr == nil { cLeftVal, cErr := strconv.ParseFloat(c.LeftVal, 64) if cErr == nil { if sLeftVal > cLeftVal { isOk++ } } } case "3": //小于等于 sLeftVal, sErr := strconv.ParseFloat(s.LeftVal, 64) if sErr == nil { cLeftVal, cErr := strconv.ParseFloat(c.LeftVal, 64) if cErr == nil { if sLeftVal <= cLeftVal { isOk++ } } } case "4": //等于 sLeftVal, sErr := strconv.ParseFloat(s.LeftVal, 64) if sErr == nil { cLeftVal, cErr := strconv.ParseFloat(c.LeftVal, 64) if cErr == nil { if sLeftVal == cLeftVal { isOk++ } } } case "5": //大于等于 sLeftVal, sErr := strconv.ParseFloat(s.LeftVal, 64) if sErr == nil { cLeftVal, cErr := strconv.ParseFloat(c.LeftVal, 64) if cErr == nil { if sLeftVal >= cLeftVal { isOk++ } } } case "6": //介于两个数之间 leftIsOk := false rightIsOk := false sLeftVal, sLErr := strconv.ParseFloat(s.LeftVal, 64) sRightVal, sRErr := strconv.ParseFloat(s.RightVal, 64) if sLErr == nil && sRErr == nil { cLeftVal, cLErr := strconv.ParseFloat(c.LeftVal, 64) cRightVal, cRErr := strconv.ParseFloat(c.RightVal, 64) if cLErr == nil && cRErr == nil { if c.LeftOptType == "1" { if sLeftVal > cLeftVal { leftIsOk = true } } else { if sLeftVal >= cLeftVal { leftIsOk = true } } if c.RightOptType == "1" { if sRightVal < cRightVal { rightIsOk = true } } else { if sRightVal <= cRightVal { rightIsOk = true } } } } if leftIsOk && rightIsOk { isOk++ } case "7": //包含 setUpValAry := strings.Split(c.LeftVal, ",") // fmt.Printf("处理自定义条件-abc->%v-->%v-->%v-->%v\n", s.Wordfield, c.Wordfield, setUpValAry, publicmethod.IsInTrue[string](s.LeftVal, setUpValAry)) if publicmethod.IsInTrue[string](s.LeftVal, setUpValAry) { isOk++ } case "8": //不包含 setUpValAry := strings.Split(c.LeftVal, ",") if !publicmethod.IsInTrue[string](s.LeftVal, setUpValAry) { isOk++ } default: } } } } // fmt.Printf("处理自定义条件-->%v-->%v\n", isOk, len(customFields)) if isOk == len(customFields) { isTrue = true } return } /* * @ 作者: 秦东 @ 时间: 2023-11-17 08:48:24 @ 功能: 处理选择条件 @ 参数 #judging 选择条件 #presetVal 提交的判断提交 @ 返回值 #isTrue true:条件符合,验证通过;false:不通过 @ 方法原型 # */ func ProcessMultipleSelectionResults(judging ConditionListInfo, presetVal []ConditionListInfo) (isTrue bool) { isTrue = false if len(presetVal) < 1 { return } for _, v := range presetVal { if v.Types == 3 && judging.Factorid == v.Factorid { if judging.IsCheckbox { // fmt.Printf("termAry:%v----->%v----->%v\n", v.Answers, judging.Answers, len(v.Answers) <= len(judging.Answers)) //多选 if len(v.Answers) <= len(judging.Answers) { //判断答案个数是否小于等于设定条件值个数 isTrue = true for i := 0; i < len(v.Answers); i++ { if !publicmethod.IsInTrue[string](v.Answers[i], judging.Answers) { isTrue = false } } } } else { //单选 // fmt.Printf("termAry:%v----->%v----->%v\n", v.Oneanswer, judging.Oneanswer, v.Oneanswer == judging.Oneanswer) // if len(v.Answers) == len(judging.Answers) { // isTrue = false // for i := 0; i < len(v.Answers); i++ { // if !publicmethod.IsInTrue[string](v.Answers[i], judging.Answers) { // isTrue = false // } // } if v.Oneanswer == judging.Oneanswer { isTrue = true } // } } } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-17 08:12:29 @ 功能: 转变人员信息 @ 参数 #condition 判断条件中的人员信息 @ 返回值 #usAry 转变后的人员列表 @ 方法原型 # */ func CondToNodeUser(condition []FlowPermissionInfo) (usAry []NodeUserListInfo) { if len(condition) < 1 { return } for _, v := range condition { var usCont NodeUserListInfo usCont.Types = v.Types // 1:人员;2:角色;3:行政组织;4:职务 usCont.TargetId = v.TargetId // /相关内容识别符 usCont.Name = v.Name //相关内容名称 usCont.Icon = v.Icon //头像 usCont.IconToBase64 = v.IconToBase64 //头像Base64 usAry = append(usAry, usCont) } return } /* * @ 作者: 秦东 @ 时间: 2023-11-17 08:04:57 @ 功能: 判断路由条件(人员、行政组织、角色)是否满足 @ 参数 #term 预设可操作此节点的人 #creater 流程发起人 @ 返回值 #isTrue true:条件符合,验证通过;false:不通过 @ 方法原型 # */ func JudgingTermPeoOrgRoles(term []FlowPermissionInfo, creater modelshr.ManCont) (isTrue bool) { isTrue = false usList := CondToNodeUser(term) operatorList := OperatorHandle(usList) //获取所有可操作的人 var usKey []string for i := 0; i < len(operatorList); i++ { //提取可操作人的唯一识别符 if !publicmethod.IsInTrue[string](operatorList[i].Id, usKey) { usKey = append(usKey, operatorList[i].Id) } } creKey := strconv.FormatInt(creater.Key, 10) if publicmethod.IsInTrue[string](creKey, usKey) { //判断当前操作人是否在可执行人当中 isTrue = true } return } /* * @ 作者: 秦东 @ 时间: 2023-11-15 14:57:03 @ 功能: 矩阵拆分 @ 参数 # @ 返回值 # @ 方法原型 # */ func GainMatrixUserList(orgId int64, matrix MatrixInfo) (UserList []OperatorList) { allOrgId := publicmethod.HaveAllOrgRelation(orgId) //获取全部归属行政单位 // fmt.Printf("全部行政组织:%v---->%v\n", orgId, allOrgId) var keyVal int64 err := overall.CONSTANT_DB_AppPlatform.Model(&modelAppPlatform.MatrixHandler{}).Select("`number`").Where("`types` = 1 AND `mc_id` = ? AND `mh_id` = ? AND `hand_id` IN ?", matrix.MatrixId, matrix.FactorId, allOrgId).First(&keyVal).Error if err != nil { return } var userKeys []int64 err = overall.CONSTANT_DB_AppPlatform.Model(&modelAppPlatform.MatrixHandler{}).Select("`hand_id`").Where("`types` = 2 AND `mc_id` = ? AND `mh_id` = ? AND `number` = ?", matrix.MatrixId, matrix.OutcomeId, keyVal).Find(&userKeys).Error if err != nil || len(userKeys) < 1 { return } var userInfoAry []modelshr.ManCont overall.CONSTANT_DB_HR.Model(&modelshr.ManCont{}).Select("`key`,`name`,`number`,`icon`,`icon_photo`,`wechat`,`work_wechat`,`admin_org`,`position`,`teamid`,`mobilephone`,`company`").Where("`key` IN ? AND `emp_type` BETWEEN ? AND ?", userKeys, 1, 10).Find(&userInfoAry) if len(userInfoAry) > 0 { for _, uv := range userInfoAry { UserList = append(UserList, TransformPublicUs(uv)) } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-15 13:24:29 @ 功能: 岗位操作人解析 @ 参数 #orgId 行政组织 #approvers 审批人岗位 @ 返回值 #UserList 操作人 @ 方法原型 # */ func GainOrgPostUserList(orgId int64, approvers []NodeUserListInfo) (UserList []OperatorList) { if len(approvers) > 0 { _, companyId, _, _, _ := publicmethod.GetOrgStructurees(orgId) allOrgId := publicmethod.HaveAllOrgRelation(companyId) //获取全部归属行政单位 var userAry MultiLeveUserList for _, v := range approvers { //逐行分析职务 if v.Types == 4 { syncSeting.Add(1) go userAry.GainOrgPostPeople(allOrgId, v.Options) } } syncSeting.Wait() UserList = userAry.UserList } return } /* * @ 作者: 秦东 @ 时间: 2023-11-15 14:30:08 @ 功能: 获取职务相关人员 @ 参数 #orgId 行政组织 #options 操作职务 @ 返回值 # @ 方法原型 # */ func (m *MultiLeveUserList) GainOrgPostPeople(orgId []int64, options []OptionsInfo) { if len(options) > 0 { //判断职务编号 var postId []int for i := 0; i < len(options); i++ { piVal, _ := strconv.Atoi(options[i].Value) if !publicmethod.IsInTrue[int](piVal, postId) { postId = append(postId, piVal) } } if len(postId) > 0 { var userInfoAry []modelshr.ManCont overall.CONSTANT_DB_HR.Model(&modelshr.ManCont{}).Select("`key`,`name`,`number`,`icon`,`icon_photo`,`wechat`,`work_wechat`,`admin_org`,`position`,`teamid`,`mobilephone`,`company`").Where("`person_in_charge` = 1 AND `admin_org` IN ? AND position = ? AND `emp_type` BETWEEN ? AND ?", orgId, postId, 1, 10).Find(&userInfoAry) if len(userInfoAry) > 0 { for _, uv := range userInfoAry { m.UserList = append(m.UserList, TransformPublicUs(uv)) } } } } defer syncSeting.Done() } /* * @ 作者: 秦东 @ 时间: 2023-11-15 11:05:55 @ 功能: 获取单级或多级主管审批人 @ 参数 #orgId 行政组织 @ 返回值 # @ 方法原型 # */ func (c *ContinuousMultiLevelSupervisor) ObtainRelevantLevelLeaders(orgId int64) (UserList []OperatorList) { if c.MaxLevel == 0 { c.MaxLevel = 1 } c.ObtainRelevantLevelLeadersUser(1, orgId) if len(c.UserList) > 0 { if c.Continuity { //连续层级主管 sort.Slice(c.UserList, func(i, j int) bool { return c.UserList[i].Level < c.UserList[j].Level }) for _, v := range c.UserList { UserList = append(UserList, v.UserList...) } } else { //单一层级 for i := c.MaxLevel; i > 0; i-- { UserList = GainOneLevel(i, c.UserList) if len(UserList) > 0 { return } } } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-15 11:50:01 @ 功能: @ 参数 #level 层级 #UserList 操作人信息 @ 返回值 #UserAry 操作人列表 @ 方法原型 # */ func GainOneLevel(level int, UserList []MultiLeveUserList) (UserAry []OperatorList) { for _, v := range UserList { if v.Level == level { UserAry = v.UserList return } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-15 11:49:24 @ 功能: 循环获取主管层级负责人 @ 参数 #level 当前主管层级 #orgId 目标行政组织 @ 返回值 # @ 方法原型 # */ func (c *ContinuousMultiLevelSupervisor) ObtainRelevantLevelLeadersUser(level int, orgId int64) { var orgInfo modelshr.AdministrativeOrganization err := orgInfo.GetCont(map[string]interface{}{"`id`": orgId}, "`superior`") if err == nil { var userList []modelshr.ManCont err = overall.CONSTANT_DB_HR.Model(&modelshr.ManCont{}).Select("`key`,`name`,`number`,`icon`,`icon_photo`,`wechat`,`work_wechat`,`admin_org`,`position`,`teamid`,`mobilephone`,`company`").Where("`person_in_charge` = 1 AND `admin_org` = ? AND `emp_type` BETWEEN ? AND ?", orgId, 1, 10).Find(&userList).Error if err == nil { var userAry MultiLeveUserList userAry.Level = level for _, v := range userList { userAry.UserList = append(userAry.UserList, TransformPublicUs(v)) } c.UserList = append(c.UserList, userAry) } nextLevel := level + 1 if nextLevel <= c.MaxLevel { c.ObtainRelevantLevelLeadersUser(nextLevel, orgInfo.Superior) } } } /* * @ 作者: 秦东 @ 时间: 2023-11-01 16:16:33 @ 功能: 处理操作人 @ 参数 #userList 节点处理人 @ 返回值 #userAry 人员列表信息 @ 方法原型 # */ func OperatorHandle(userList []NodeUserListInfo) (userAry []OperatorList) { if len(userList) > 0 { var userIdAry []int64 for _, v := range userList { switch v.Types { //1:人员;2:角色;3:行政组织 case 1: myKey, myErr := strconv.ParseInt(v.TargetId, 10, 64) if myErr == nil { userIdAry = append(userIdAry, myKey) } case 2: //角色 var usIdList []int64 overall.CONSTANT_DB_HR.Model(&modelshr.PersonArchives{}).Select("`key`").Where("FIND_IN_SET(?,`role`) AND `emp_type` BETWEEN ? AND ?", v.TargetId, 1, 10).Find(&usIdList) if len(usIdList) > 0 { userIdAry = append(userIdAry, usIdList...) } case 3: //行政组织 myKey, myErr := strconv.ParseInt(v.TargetId, 10, 64) if myErr == nil { var sunOrg publicmethod.GetOrgAllParent sunOrg.GetOrgSonAllId(myKey) sunOrg.Id = append(sunOrg.Id, myKey) var usIdList []int64 overall.CONSTANT_DB_HR.Model(&modelshr.PersonArchives{}).Select("`key`").Where("`admin_org` IN ? AND `emp_type` BETWEEN ? AND ?", sunOrg.Id, 1, 10).Find(&usIdList) if len(usIdList) > 0 { userIdAry = append(userIdAry, usIdList...) } } default: } } var userContMap []modelshr.ManCont overall.CONSTANT_DB_HR.Model(&modelshr.ManCont{}).Select("`key`,`name`,`number`,`icon`,`icon_photo`,`wechat`,`work_wechat`,`admin_org`,`position`,`teamid`,`mobilephone`,`company`").Where("`key` IN ?", userIdAry).Find(&userContMap) for _, v := range userContMap { userAry = append(userAry, TransformPublicUs(v)) } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-15 11:37:00 @ 功能: 装通用执行人数据 @ 参数 #v 人员信息 @ 返回值 #userCont 统一操作人信息 @ 方法原型 # */ func TransformPublicUs(v modelshr.ManCont) (userCont OperatorList) { userCont.Id = strconv.FormatInt(v.Key, 10) userCont.Types = 1 //1:人员;2:角色;3:行政组织 userCont.Name = v.Name //操作人姓名 userCont.Number = v.Number //操作人工号 userCont.Icon = v.Icon //操作人头像 userCont.IconBase64 = v.IconPhpto //操作人头像 userCont.Wechat = v.Wechat //微信Openid、 userCont.Tel = v.Mobilephone if v.WorkWechat != "" { userCont.Wechat = v.WorkWechat //微信Openid } if v.Company != 0 { var orgGroupCont modelshr.AdministrativeOrganization orgGroupCont.GetCont(map[string]interface{}{"`id`": v.Company}, "`name`") userCont.CompanyName = orgGroupCont.Name //公司名称 } _, companyId, _, _, _ := publicmethod.GetOrgStructurees(v.AdminOrg) userCont.DepartmentId = companyId //分厂Id if companyId != 0 { var orgCont modelshr.AdministrativeOrganization orgCont.GetCont(map[string]interface{}{"`id`": companyId}, "`name`") userCont.DepartmentName = orgCont.Name //分厂名称 } //获取岗位 if v.Position != 0 { var postCont modelshr.Position postCont.GetCont(map[string]interface{}{"`id`": v.Position}, "`name`") userCont.PostId = v.Position //职务Id userCont.PostName = postCont.Name //职务名称 } if v.TeamId != 0 { var teamCont modelshr.TeamGroup teamCont.GetCont(map[string]interface{}{"`id`": v.TeamId}, "`name`") userCont.Tema = v.TeamId //班组Id userCont.TemaName = teamCont.Name //班组名称 } return } /* * @ 作者: 秦东 @ 时间: 2023-11-20 16:06:09 @ 功能: 根据工号获取人员信息 @ 参数 # @ 返回值 # @ 方法原型 # */ func GainUserCode(userNumber []string) (userAry []OperatorList) { var userInfoAry []modelshr.ManCont overall.CONSTANT_DB_HR.Model(&modelshr.ManCont{}).Select("`key`,`name`,`number`,`icon`,`icon_photo`,`wechat`,`work_wechat`,`admin_org`,`position`,`teamid`,`mobilephone`,`company`").Where("`number` IN ? AND `emp_type` BETWEEN ? AND ?", userNumber, 1, 10).Find(&userInfoAry) if len(userInfoAry) > 0 { for _, uv := range userInfoAry { userAry = append(userAry, TransformPublicUs(uv)) } } return } /* * @ 作者: 秦东 @ 时间: 2023-11-22 10:00:34 @ 功能: 获取操作人、 @ 参数 # @ 返回值 # @ 方法原型 # */ func (a *ApiMethod) GainFlowPeople(c *gin.Context) { var requestData GainFlowOperator err := c.ShouldBindJSON(&requestData) if err != nil || len(requestData.Numbers) < 1 { publicmethod.Result(10001, err, c) return } usSry := GainUserCode(requestData.Numbers) if len(usSry) < 1 { publicmethod.Result(10001, err, c, "没有数据") return } publicmethod.Result(0, usSry, c) } /* * @ 作者: 秦东 @ 时间: 2023-11-22 10:19:10 @ 功能: 自定义表单搜索人员 @ 参数 # @ 返回值 # @ 方法原型 # */ func (a *ApiMethod) SearchUserList(c *gin.Context) { var requestData SearchUserCont c.ShouldBindJSON(&requestData) if requestData.Page == 0 { requestData.Page = 1 } if requestData.PageSize == 0 { requestData.PageSize = 10 } gormDb := overall.CONSTANT_DB_HR.Model(&modelshr.PersonArchives{}).Select("`number`").Where("`number` NOT LIKE ?", "%W%") if requestData.Name != "" { gormDb = gormDb.Where("number LIKE ? OR name LIKE ?", "%"+requestData.Name+"%", "%"+requestData.Name+"%") } if requestData.Department != 0 { var sunOrg publicmethod.GetOrgAllParent sunOrg.GetOrgSonAllId(requestData.Department) sunOrg.Id = append(sunOrg.Id, requestData.Department) gormDb = gormDb.Where("admin_org IN ?", sunOrg.Id) } gormDb = gormDb.Where("emp_type BETWEEN ? AND ?", 1, 10) var total int64 totalErr := gormDb.Count(&total).Error if totalErr != nil { total = 0 } var idAry []string gormDb = publicmethod.PageTurningSettings(gormDb, requestData.Page, requestData.PageSize) err := gormDb.Find(&idAry).Error var userList []OperatorList if err != nil || len(idAry) < 1 { publicmethod.ResultList(0, requestData.Page, requestData.PageSize, total, int64(len(userList)), userList, c) return } usSry := GainUserCode(idAry) if len(usSry) < 1 { publicmethod.ResultList(0, requestData.Page, requestData.PageSize, total, int64(len(userList)), userList, c) return } publicmethod.ResultList(0, requestData.Page, requestData.PageSize, total, int64(len(usSry)), usSry, c) }