当前位置: 首页 > news >正文

怎么建视频网站免费的做网站主机选择

怎么建视频网站免费的,做网站主机选择,保定网站建设方案优化,网站建设书模板1.写在前面 一个完整的流程表单审批#xff08;起表单--各环节审批--回退--重新审批--完成#xff09;#xff0c;前端由Vue2jsElement UI升级为Vue3tsElement Plus#xff0c;后端流程框架使用Flowable#xff0c;项目参考了ruoyi-vue-pro(https://gite…1.写在前面 一个完整的流程表单审批起表单--各环节审批--回退--重新审批--完成前端由Vue2jsElement UI升级为Vue3tsElement Plus后端流程框架使用Flowable项目参考了ruoyi-vue-pro(https://gitee.com/zhijiantianya/ruoyi-vue-pro)项目。 2.视频演示 OA系统自定义表单审批流转流程演示 3.表单 3.1表单的设计 依据业务需求完全自定义表单可以依据流程节点设置表单中每个属性的读写实现原理是读取审批节点的编码依据编码控制每个属性的读写。 el-tree-select:disabled!requiredv-modelform.deptCode:datadeptList:propsdefaultPropsForDatacheck-strictlynode-keyidplaceholder请选择集团成员单位//*** 根据不同参数控制表单属性的可读可写* param pattern*/ const changeRequiredByPattern (pattern: string) {if (pattern create) {//说明增加required.value true} else if (pattern update || pattern starter) {//修改required.value truegetBid()} else {//只读required.value falsegetBid()} } 3.2.表单与流程关联 通过设计流程时定义的流程编码在创建表单的后端服务调用中实现表单与流程的绑定。 /*** 投标对应的流程定义 KEY*/public static final String PROCESS_KEY bidApproval;//发起BPM流程MapString, Object processInstanceVariables new HashMap();processInstanceVariables.put(deptId, bidDO.getDeptId());processInstanceVariables.put(bidMoney, bidDO.getBidMoney());String processInstanceId processInstanceApi.createProcessInstance(getLoginUserId(),new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY).setVariables(processInstanceVariables).setBusinessKey(bidDO.getProjectName())); 3.3.表单与前端流程实例的关联 在通过待办打开需要审批的表单时不同的流程实例如何对应不同的表单并在页面展示具体的表单数据了答案是通过定义流程时填写的表单组件名称利用Vue的component元组件来实现。 componentrefformDetailRefv-ifprocessInstance.id ! undefined:isprocessInstance.processDefinition.formComponentName:processInstanceIdprocessInstance.id:patternrunningTasks.length 0 ? runningTasks[0].definitionKey : readOnlysuccessgetDetail/ 3.4.表单的保存 表单的保存分为提交时的保存与不提交的保存。不提交的保存用于修改数据但流程不需要提交到下一节点审批的情况方便保存数据进入待办里面进行后续的修改。提交的时流程会自动调用保存接口先进行业务数据的保存然后再进行流程的提交。 el-button color#626aef clickhandleSaveIcon iconep:coin /保存/el-buttonel-button typesuccess clickhandleApproval(item)Icon iconep:select /提交/el-button/** 处理保存表单的操作 只更新表单数据 不提交流程任务 */ const formDetailRef ref() const handleSave () {formDetailRef.value.submitForm() }/** 处理审批通过的操作 */ const approvalRef ref() const handleApproval async (item) {approvalRef.value.open(item) } OverrideTransactional(rollbackFor Exception.class)public Long updateBid(BidUpdateReqVO updateReqVO) {BidDO bidDO BidConvert.INSTANCE.convert3(updateReqVO);//checkDeptIsMateTendererDept(deptRespDTO, tendererDeptRespDTO);bidDO.setDeptId(findDeptByCode(updateReqVO.getDeptCode()).getId());bidDO.setTendererId(findDeptByName(updateReqVO.getTendererName()).getId());fileApi.deleteFile(bidMapper.selectById(bidDO.getId()).getFiles(), bidDO.getFiles());bidMapper.updateById(bidDO);return bidDO.getId();}OverrideTransactional(rollbackFor Exception.class)public void approveProcessTask(BidUpdateReqVO bidUpdateReqVO, BpmProcessTaskApprovalDTO bpmProcessTaskApprovalDTO) {//需要根据流程中不同的节点 更改对应的表单信息 比如 需要在流程最后一个节点点击提交时 更改流程状态为完成BidDO bidDO BidConvert.INSTANCE.convert3(bidUpdateReqVO);bidDO.setDeptId(findDeptByCode(bidUpdateReqVO.getDeptCode()).getId());bidDO.setTendererId(findDeptByName(bidUpdateReqVO.getTendererName()).getId());updateFlowInfoByProcessInstanceState(bidDO);fileApi.deleteFile(bidMapper.selectById(bidDO.getId()).getFiles(), bidDO.getFiles());bidMapper.updateById(bidDO);bpmProcessTaskApi.approvalTask(bpmProcessTaskApprovalDTO);} 4.流程的审批 流程的审批按照设计流程的审批节点依次进行流转不支持夸环节提交支持流程的自由回退。提交当前审批任务时进行下一节点的人员选择在流程设计时每个节点审批的人员的选择逻辑已经确定也支持自由选择组织中的所有人员。 4.1.流程审批人员的设置 流程审批节点的人员设置主要思路为给定一个角色让审批人员提交任务时从角色中选择一个人员这样可以缩小选择的范围。如果表单有对应的部门属性可以设置审批人员是某个角色中且部门与表单部门属性相同的人员。 // 选择角色中的人员 private SetLong calculateTaskCandidateUsersByRole(BpmTaskAssignRuleDO rule) {return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());}//依据角色选择表单部门中的所属人员 private SetLong calculateTaskCandidateUsersByRolePerson(MapString, Object variables, BpmTaskAssignRuleDO rule) {Long deptId (Long) variables.get(deptId);//获取流程实例变量的部门//从角色中获取属于该部门的人员SetLong userIdsByRoleId permissionApi.getUserRoleIdListByRoleIds(rule.getOptions());SetLong userIdsByDeptId userApi.getUsersByDeptId(deptId);return new HashSet(CollUtil.intersection(userIdsByDeptId, userIdsByRoleId));} 4.2.流程的流转 流程的流转其实没有什么好说的就是按照流程设计的审批节点依次往下走遇到网关时根据前期设计好的条件读取对应的属性跳转到不同审批支线。本例中会根据投标金额是否大于500万做判断走不同的分支而500万的属性在创建流程时就已经传入了流程实例的变量中。 流程的回退流程的回退依据流程的节点图不管流程流转了多少圈回退只允许回退当前审批节点的前面节点。 public SetBpmDoneUserTaskNodeRespVO getDoneUserTaskNodes(String taskId) {SetBpmDoneUserTaskNodeRespVO resultList new HashSet();//获取流程实例idTask task getTask(taskId);// 校验流程实例存在ProcessInstance instance processInstanceService.getProcessInstance(task.getProcessInstanceId());//获取历史任务实例 条件为 流程实例 未完成 按照任务开始时间降序排列ListHistoricTaskInstance historicTaskInstances historyService.createHistoricTaskInstanceQuery().processInstanceId(instance.getProcessInstanceId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();//需要做一个筛选只能选择当前任务节点之前的节点进行回退// 1. 获取流程模型实例 BpmnModelBpmnModel bpmnModel bpmProcessDefinitionService.getBpmnModel(task.getProcessDefinitionId());// 2. 通过任务节点id来获取当前节点信息FlowElement flowElement bpmnModel.getFlowElement(task.getTaskDefinitionKey());// 3.获取下一个节点或者多个节点的信息,需要去重因为并行的节点之前的节点会找多遍SetFlowElement flowElements new HashSet();// 4.获取流程实例的变量MapString, Object variables taskService.getVariables(taskId);getBeforeNodes(flowElement, flowElements, variables);if (flowElements.isEmpty()){//说明处于第一个节点此时不能回退throw exception(TASK_ROLLBACK_FORBIDDEN);}//找交集for(FlowElement f: flowElements) {HistoricTaskInstance h historicTaskInstances.stream().filter( hi - hi.getTaskDefinitionKey().equals(f.getId())).findFirst().orElse(null);if (h null){//没有获取到最新的的节点审批信息是不正常的情况throw exception(TASK_ROLLBACK_APPROVED_INFO_NULL);}//获取 审批人员的编号Long assignee Long.valueOf(h.getAssignee());//获取人员信息UserRespDTO userRespDTO adminUserApi.getUser(assignee);//获取部门信息DeptRespDTO deptRespDTO deptApi.getDept(userRespDTO.getDeptId());resultList.add(BpmTaskConvert.INSTANCE.convertBpmDoneUserTaskNodeRespVO(h, userRespDTO, deptRespDTO));}return resultList;} 5.流程审批详情 流程审批详情包括审批记录与流程图的展示。 5.1.审批记录详情 审批记录根据审批的先后顺序展示数据状态根据提交回退的不同使用不同颜色的标签显示。 el-table v-loadingloading :datatasks borderel-table-column aligncenter propname label审批环节 width200 /el-table-column aligncenter propassigneeUser.nickname label审批人 width180 /el-table-columnlabel任务开始时间aligncenterpropcreateTimewidth180:formatterdateFormatter/el-table-columnlabel任务结束时间aligncenterpropendTimewidth180:formatterdateFormatter/el-table-column label任务耗时 aligncenter propdurationInMillis width150template #defaultscopespan{{ formatPast2(scope.row.durationInMillis) }}/span/template/el-table-columnel-table-column label审批结果 aligncenter propresult width150template #defaultscopeel-tag :typegetTimelineItemType(scope.row){{ getDictLabel(DICT_TYPE.BPM_PROCESS_INSTANCE_RESULT, scope.row.result) }}/el-tag/template/el-table-columnel-table-column label审批意见 aligncenter propreason width250 //el-table public ListBpmTaskRespVO getTaskListByProcessInstanceId(String processInstanceId) {// 获得任务列表ListHistoricTaskInstance tasks historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceStartTime().desc() // 创建时间倒序.list();if (CollUtil.isEmpty(tasks)) {return Collections.emptyList();}// 获得 TaskExtDO MapListBpmTaskExtDO bpmTaskExtDOs taskExtMapper.selectListByTaskIds(convertSet(tasks, HistoricTaskInstance::getId));MapString, BpmTaskExtDO bpmTaskExtDOMap convertMap(bpmTaskExtDOs, BpmTaskExtDO::getTaskId);// 获得 ProcessInstance MapHistoricProcessInstance processInstance processInstanceService.getHistoricProcessInstance(processInstanceId);// 获得 User MapSetLong userIds convertSet(tasks, task - NumberUtils.parseLong(task.getAssignee()));userIds.add(NumberUtils.parseLong(processInstance.getStartUserId()));MapLong, UserRespDTO userMap adminUserApi.getUserMap(userIds);// 获得 Dept MapMapLong, DeptRespDTO deptMap deptApi.getDeptMap(convertSet(userMap.values(), UserRespDTO::getDeptId));// 拼接数据return BpmTaskConvert.INSTANCE.convertList3(tasks, bpmTaskExtDOMap, processInstance, userMap, deptMap);} 5.2.流程图显示 流程图显示比较复杂可以查看对应的代码主要就是使用了bpmn-js库根据后端的数据进行不同的展示核心代码个人理解是这一块。 const highlightDiagram async () {const activityList activityLists.valueif (activityList.length 0) {return}// 参考自 https://gitee.com/tony2y/RuoYi-flowable/blob/master/ruoyi-ui/src/components/Process/index.vue#L222 实现// 再次基础上增加不同审批结果的颜色等等let canvas bpmnModeler.get(canvas)let todoActivity: any activityList.find((m: any) !m.endTime) // 找到待办的任务let endActivity: any activityList[activityList.length - 1] // 获得最后一个任务// debuggerbpmnModeler.getDefinitions().rootElements[0].flowElements?.forEach((n: any) {let activity: any activityList.find((m: any) m.key n.id) // 找到对应的活动if (!activity) {return}if (n.$type bpmn:UserTask) {// 用户任务// 处理用户任务的高亮const task: any taskList.value.find((m: any) m.id activity.taskId) // 找到活动对应的 taskIdif (!task) {return}// 高亮任务canvas.addMarker(n.id, getResultCss(task.result))// 如果非通过就不走后面的线条了if (task.result ! 2) {return}// 处理 outgoing 出线const outgoing getActivityOutgoing(activity)outgoing?.forEach((nn: any) {// debuggerlet targetActivity: any activityList.find((m: any) m.key nn.targetRef.id)// 如果目标活动存在则根据该活动是否结束进行【bpmn:SequenceFlow】连线的高亮设置if (targetActivity) {canvas.addMarker(nn.id, targetActivity.endTime ? highlight : highlight-todo)} else if (nn.targetRef.$type bpmn:ExclusiveGateway) {// TODO 芋艿这个流程暂时没走到过canvas.addMarker(nn.id, activity.endTime ? highlight : highlight-todo)canvas.addMarker(nn.targetRef.id, activity.endTime ? highlight : highlight-todo)} else if (nn.targetRef.$type bpmn:EndEvent) {// TODO 芋艿这个流程暂时没走到过if (!todoActivity endActivity.key n.id) {canvas.addMarker(nn.id, highlight)canvas.addMarker(nn.targetRef.id, highlight)}if (!activity.endTime) {canvas.addMarker(nn.id, highlight-todo)canvas.addMarker(nn.targetRef.id, highlight-todo)}}})} else if (n.$type bpmn:ExclusiveGateway) {// 排它网关// 设置【bpmn:ExclusiveGateway】排它网关的高亮canvas.addMarker(n.id, getActivityHighlightCss(activity))// 查找需要高亮的连线let matchNN: any undefinedlet matchActivity: any undefinedconst outgoing getActivityOutgoing(activity)outgoing.forEach((nn: any) {let targetActivity activityList.find((m: any) m.key nn.id)if (!targetActivity) {return}// 特殊判断 endEvent 类型的原因ExclusiveGateway 可能后续连有 2 个路径// 1. 一个是 UserTask EndEvent// 2. 一个是 EndEvent// 在选择路径 1 时其实 EndEvent 可能也存在导致 1 和 2 都高亮显然是不正确的。// 所以在 matchActivity 为 EndEvent 时需要进行覆盖~~if (!matchActivity || matchActivity.type endEvent) {matchNN nnmatchActivity targetActivity}})if (matchNN matchActivity) {canvas.addMarker(matchNN.id, getActivityHighlightCss(matchActivity))}} else if (n.$type bpmn:ParallelGateway) {// 并行网关// 设置【bpmn:ParallelGateway】并行网关的高亮canvas.addMarker(n.id, getActivityHighlightCss(activity))const outgoing getActivityOutgoing(activity)outgoing.forEach((nn: any) {// 获得连线是否有指向目标。如果有则进行高亮const targetActivity activityList.find((m: any) m.key nn.targetRef.id)if (targetActivity) {canvas.addMarker(nn.id, getActivityHighlightCss(targetActivity)) // 高亮【bpmn:SequenceFlow】连线// 高亮【...】目标。其中 ... 可以是 bpm:UserTask、也可以是其它的。当然如果是 bpm:UserTask 的话其实不做高亮也没问题因为上面有逻辑做了这块。canvas.addMarker(nn.targetRef.id, getActivityHighlightCss(targetActivity))}})} else if (n.$type bpmn:StartEvent) {// 开始节点 流程只要发起 开始节点就是完成状态let targetActivity activityList.find((m) m.key n.id)if (targetActivity) {canvas.addMarker(n.id, highlight) // 高亮【bpmn:StartEvent】开始节点自己}// 开始节点const outgoing getActivityOutgoing(activity)outgoing.forEach((nn) {// outgoing 例如说【bpmn:SequenceFlow】连线// 获得连线是否有指向目标。如果有则进行高亮let targetActivity activityList.find((m: any) m.key nn.targetRef.id)if (targetActivity) {canvas.addMarker(nn.id, highlight) // 高亮【bpmn:SequenceFlow】连线canvas.addMarker(n.id, highlight) // 高亮【bpmn:StartEvent】开始节点自己}})} else if (n.$type bpmn:EndEvent) {// 结束节点if (!processInstance.value || processInstance.value.result 1) {return}canvas.addMarker(n.id, getResultCss(processInstance.value.result))} else if (n.$type bpmn:ServiceTask) {//服务任务if (activity.startTime 0 activity.endTime 0) {//进入执行标识进行色canvas.addMarker(n.id, getResultCss(1))}if (activity.endTime 0) {// 执行完成节点标识完成色, 所有outgoing标识完成色。canvas.addMarker(n.id, getResultCss(2))const outgoing getActivityOutgoing(activity)outgoing?.forEach((out) {canvas.addMarker(out.id, getResultCss(2))})}}}) } 6.写在最后 本文简单的介绍了一个OA办公系统表单审批的全过程行文比较粗糙代码只展示了很少的一部分如果有兴趣一起研究讨论的欢迎留言批评指教。
http://www.pierceye.com/news/849746/

相关文章:

  • 网站建设什么原因最主要怎么制作网站首页
  • 网站建设深圳赶集网网页设计工程师工资
  • 哪家企业网站建设好闵行区网站制作
  • 重庆行业网站建设陕西省建设监理协会查询官方网站
  • 手机网站 尺寸网站规划的认识
  • 永川网站制作联系电话wordpress 参数 传递
  • 西宁市网站建设高端网站开发人员要求
  • 前端做商城网站需要多久yum wordpress
  • 便宜网站建设成都免费建网站视频教程
  • 班级网站自助建设功能没有充值入口的传奇
  • 杭州网站seo免费网站建设
  • 好看的网站设计网站开发龙岗网站建设
  • 物流如何做网站wordpress qq互联插件
  • 权威发布李建济南做seo排名
  • 六安网站建设 220广州安尔捷做的网站好吗
  • 企业网站写好如何发布wordpress免插件生成地图
  • 公司 网站 苏州链接下载
  • 网站页面设计素材网站做权重的方法
  • 网站优化标题怎么做宿迁房产网备案查询
  • 建设企业官方网站的流程秦皇岛网站备案
  • 北京网站优化前景建设银行包头分行网站
  • 南京江宁区住房建设局网站电商交流平台有哪些
  • 查询网站流量排名做网站 我们的工人怎么写
  • 龙岗-网站建设深圳信科免备案的网站空间
  • 360网站推广官网软件安徽海外网络推广
  • c# asp.net网站开发书考试网站怎么做的
  • 网站开发 技术路线融资融券配资网站建设
  • 建设网站如国家高新技术企业证书
  • 网站服务是什么网站建设投标书报价表
  • 商业网站开发与设计宝塔面板wordpress安装