云尚办公项目学习

完整的笔记可以参考这个专栏,写的挺详细的:云尚办公课件笔记,come on boy

form-create前端组件
formProps记录了表单有哪些表单项,分别是哪些类型(下拉,单选,输入框)
formOptions记录了表单的一些配置项,比如label-width等

在这里插入图片描述
mybatisplus生成代码

oa_process_type 审批类型
oa_process_template 审批模板

oa_prcess 审批列表(关联审批流流程实例id)

1,创建审批类型
2,创建审批类型下的审批模板
3,为指定的审批模板设置模板名称,表单项,
4,为指定的审批模板上传流程定义文件,将该文件保存到指定的目录下,并保存到审批模板的流程定义path字段,流程定义文件的文件名(不包括后缀名)作为审批模板的流程定义key字段
5,发布该审批模板,就是将此审批模板流程定义path字段所指定的路径所对应的文件读取成流,部署到activiti中,修改审批模板为已发布状态

6,发起审批,首先获取审批模板对应的表单,申请人填写表单内容,表单内容会转换为json数据传给后台,后台根据审批模板将数据保存到业务审批表,申请人填写的表单内容就保存在业务审批表的form_values字段中,这样就可以得到业务id了,然后activiti使用审批模板所保存的流程定义key启动流程实例,并传入业务id,同时传入将申请人填写的表单内容json数据转为的map存入到key为data的map中,这样流程实例就启动了,并且和业务id绑定了,并且也有了申请人填写的表单内容作为流程变量。

在流程实例启动后,立即查询当前流程实例的下一个节点的审批人(有可能有多个),取到这些审批人的assignee,给这些审批人推送消息以便于提醒他们尽快去审批。

推送完消息之后,将流程实例id保存到业务审批表的流程实例id字段。

//启动流程
@Override
public void startUp(ProcessFormVo processFormVo) {//1 根据当前用户id获取用户信息SysUser sysUser = sysUserService.getById(LoginUserInfoHelper.getUserId());//2 根据审批模板id把模板信息查询ProcessTemplate processTemplate = processTemplateService.getById(processFormVo.getProcessTemplateId());//3 保存提交审批信息到业务表,oa_processProcess process = new Process();//processFormVo复制到process对象里面BeanUtils.copyProperties(processFormVo,process);//其他值process.setStatus(1); //审批中String workNo = System.currentTimeMillis() + "";process.setProcessCode(workNo);process.setUserId(LoginUserInfoHelper.getUserId());process.setFormValues(processFormVo.getFormValues());process.setTitle(sysUser.getName() + "发起" + processTemplate.getName() + "申请");baseMapper.insert(process);//4 启动流程实例 - RuntimeService//4.1 流程定义keyString processDefinitionKey = processTemplate.getProcessDefinitionKey();//4.2 业务key  processIdString businessKey = String.valueOf(process.getId());//4.3 流程参数 form表单json数据,转换map集合String formValues = processFormVo.getFormValues();//formDataJSONObject jsonObject = JSON.parseObject(formValues);JSONObject formData = jsonObject.getJSONObject("formData");//遍历formData得到内容,封装map集合Map<String,Object> map = new HashMap<>();for(Map.Entry<String,Object> entry:formData.entrySet()) {map.put(entry.getKey(),entry.getValue());}Map<String,Object> variables = new HashMap<>();variables.put("data",map);//启动流程实例ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey, variables);//5 查询下一个审批人//审批人可能多个List<Task> taskList = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();List<String> nameList = new ArrayList<>();for(Task task : taskList) {String assigneeName = task.getAssignee();SysUser user = sysUserService.getUserByUserName(assigneeName);String name = user.getName();nameList.add(name);//推送消息messageService.pushPendingMessage(process.getId(),user.getId(),task.getId());}process.setProcessInstanceId(processInstance.getId());process.setDescription("等待"+ StringUtils.join(nameList.toArray(), ",")+"审批");//7 业务和流程关联  更新oa_process数据baseMapper.updateById(process);//记录操作审批信息记录processRecordService.record(process.getId(),1,"发起申请");
}

7、审批记录
用来记录1个审批所走过的轨迹,首先添加审批记录表,如下
在这里插入图片描述
在开启流程实例的方法中,生成一条审批记录存入到审批记录表当中(调用处在上面)

@Override
public void record(Long processId, Integer status, String description) {Long userId = LoginUserInfoHelper.getUserId();SysUser sysUser = sysUserService.getById(userId);ProcessRecord processRecord = new ProcessRecord();processRecord.setProcessId(processId);processRecord.setStatus(status);processRecord.setDescription(description);processRecord.setOperateUser(sysUser.getName());processRecord.setOperateUserId(userId);baseMapper.insert(processRecord);
}

8,审批人查询待办任务

使用activiti工作流提供的taskService根据当前用户作为assignee查询当前用户的的任务列表(并且使用了分页),遍历这个任务列表,可以拿到每个任务对应的流程实例,然后拿到流程实例对应的业务key(其实,通过task就可以直接拿到businessKey),拿到businessKey之后,就可以查询业务审批表,来获取到申请人所填写的申请表单内容了。这样当前审批人就可以根据申请人提交的表单内容做审批了。注意,工作流的taskId也带上去了。

//查询待处理任务列表
@Overridepublic IPage<ProcessVo> findfindPending(Page<Process> pageParam) {//1 封装查询条件,根据当前登录的用户名称TaskQuery query = taskService.createTaskQuery().taskAssignee(LoginUserInfoHelper.getUsername()).orderByTaskCreateTime().desc();//2 调用方法分页条件查询,返回list集合,待办任务集合//listPage方法有两个参数//第一个参数:开始位置  第二个参数:每页显示记录数int begin = (int)((pageParam.getCurrent()-1)*pageParam.getSize());int size = (int)pageParam.getSize();List<Task> taskList = query.listPage(begin, size);long totalCount = query.count();//3 封装返回list集合数据 到 List<ProcessVo>里面//List<Task> -- List<ProcessVo>List<ProcessVo> processVoList = new ArrayList<>();for(Task task : taskList) {//从task获取流程实例idString processInstanceId = task.getProcessInstanceId();//根据流程实例id获取实例对象ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();//从流程实例对象获取业务key---processIdString businessKey = processInstance.getBusinessKey();if(businessKey == null) {continue;}//根据业务key获取Process对象long processId = Long.parseLong(businessKey);Process process = baseMapper.selectById(processId);//Process对象 复制 ProcessVo对象ProcessVo processVo = new ProcessVo();BeanUtils.copyProperties(process,processVo);processVo.setTaskId(task.getId());//放到最终list集合processVoListprocessVoList.add(processVo);}//4 封装返回IPage对象IPage<ProcessVo> page = new Page<ProcessVo>(pageParam.getCurrent(),pageParam.getSize(),totalCount);page.setRecords(processVoList);return page;}

9,发起审批测试
测试步骤如下,

先添加审批模板,然后发布,使用admin填写审批表单发起1个审批,然后下一节点审批人zhangsan查看自己的待办任务
在这里插入图片描述
张三查看自己的待办任务列表如下
在这里插入图片描述
10,审批人查看审批单的审批详情信息

前面张三查看到了自己的待办任务列表,待办任务列表数据的id是业务表的id,因此前端将此id传进来,来查询审批详情信息(比如用户什么时间提的申请,填写的表单内容)。

接着,继续使用业务表的id查询审批记录表中的审批记录(前面发起审批时,记录了,当前自己审批时,也须往这个表中记录)

接着,根据审批业务表的id得到审批模板信息

接着,查询当前人是否可以审批该审批流程实例(这里要推敲下)

下面这个代码感觉有点问题:上面查询待办的时候,拿的就是当前人作为assignee查询的任务,那么查到的审批单对应的审批人是一定包括当前人的(可能有多个审批人),并且,也是有查询到对应的taskId的,我觉得这里应该让前端把taskId传过来,就可以得到这个taskId对应的assignee是不是当前人。但是好好想想,他这样做也没啥问题,他其实就是在判断当前人是否是这个流程实例的当前所在节点的审批人,如果是的话,那就可以审批,不是的话,就不可以审批

//查看审批详情信息
@Override
public Map<String, Object> show(Long id) {//1 根据流程id获取流程信息ProcessProcess process = baseMapper.selectById(id);//2 根据流程id获取流程记录信息LambdaQueryWrapper<ProcessRecord> wrapper = new LambdaQueryWrapper<>();wrapper.eq(ProcessRecord::getProcessId,id);List<ProcessRecord> processRecordList = processRecordService.list(wrapper);//3 根据模板id查询模板信息ProcessTemplate processTemplate = processTemplateService.getById(process.getProcessTemplateId());//4 判断当前用户是否可以审批//可以看到信息不一定能审批,不能重复审批boolean isApprove = false;List<Task> taskList = this.getCurrentTaskList(process.getProcessInstanceId());for(Task task : taskList) {//判断任务审批人是否是当前用户String username = LoginUserInfoHelper.getUsername();if(task.getAssignee().equals(username)) {isApprove = true;}}//5 查询数据封装到map集合,返回Map<String,Object> map = new HashMap<>();map.put("process", process);map.put("processRecordList", processRecordList);map.put("processTemplate", processTemplate);map.put("isApprove", isApprove);return map;
}

张三点击审批详情后,进入到如下页面

在这里插入图片描述
11,最重要的一步来了,审批人对当前审批单进行审批(同意or驳回)。驳回即审批不通过,流程结束。
如果当前审批人 对 此审批单 审批通过,那么流程引擎会自动将任务流转到下1个审批人那里(如果还有下一个任务节点的话),并通知下一个审批人(可能是多个人),下一个人就可以查询到自己的待办任务。

如果当前审批人 对 此审批单 驳回,那么流程结束。结束流程的代码是固定模式的。

不管当前审批人 对 此审批单 是审批通过 还是驳回,都要记录到审批记录表,并且更新审批的业务表。

//审批
@Override
public void approve(ApprovalVo approvalVo) {//1 从approvalVo获取任务id,根据任务id获取流程变量String taskId = approvalVo.getTaskId();Map<String, Object> variables = taskService.getVariables(taskId);for(Map.Entry<String,Object> entry:variables.entrySet()) {System.out.println(entry.getKey());System.out.println(entry.getValue());}//2 判断审批状态值if(approvalVo.getStatus() == 1) {//2.1 状态值 =1  审批通过Map<String, Object> variable = new HashMap<>();taskService.complete(taskId,variable);} else {//2.2 状态值 = -1 驳回,流程直接结束this.endTask(taskId);}//3 记录审批相关过程信息 oa_process_recordString description = approvalVo.getStatus().intValue() ==1 ? "已通过" : "驳回";processRecordService.record(approvalVo.getProcessId(),approvalVo.getStatus(),description);//4 查询下一个审批人,更新流程表记录 process表记录Process process = baseMapper.selectById(approvalVo.getProcessId());//查询任务List<Task> taskList = this.getCurrentTaskList(process.getProcessInstanceId());if(!CollectionUtils.isEmpty(taskList)) {List<String> assignList = new ArrayList<>();for(Task task : taskList) {String assignee = task.getAssignee();SysUser sysUser = sysUserService.getUserByUserName(assignee);assignList.add(sysUser.getName());//TODO 公众号消息推送}//更新process流程信息process.setDescription("等待" + StringUtils.join(assignList.toArray(), ",") + "审批");process.setStatus(1);} else {if(approvalVo.getStatus().intValue() == 1) {process.setDescription("审批完成(通过)");process.setStatus(2);} else {process.setDescription("审批完成(驳回)");process.setStatus(-1);}}baseMapper.updateById(process);
}
//结束流程
private void endTask(String taskId) {//1 根据任务id获取任务对象 TaskTask task = taskService.createTaskQuery().taskId(taskId).singleResult();//2 获取流程定义模型 BpmnModelBpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());//3 获取结束流向节点List<EndEvent> endEventList = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class);if(CollectionUtils.isEmpty(endEventList)) {return;}FlowNode endFlowNode = (FlowNode)endEventList.get(0);//4 当前流向节点FlowNode currentFlowNode = (FlowNode)bpmnModel.getMainProcess().getFlowElement(task.getTaskDefinitionKey());//  临时保存当前活动的原始方向List originalSequenceFlowList = new ArrayList<>();originalSequenceFlowList.addAll(currentFlowNode.getOutgoingFlows());//5 清理当前流动方向currentFlowNode.getOutgoingFlows().clear();//6 创建新流向SequenceFlow newSequenceFlow = new SequenceFlow();newSequenceFlow.setId("newSequenceFlow");newSequenceFlow.setSourceFlowElement(currentFlowNode);newSequenceFlow.setTargetFlowElement(endFlowNode);//7 当前节点指向新方向List newSequenceFlowList = new ArrayList();newSequenceFlowList.add(newSequenceFlow);currentFlowNode.setOutgoingFlows(newSequenceFlowList);//8 完成当前任务taskService.complete(task.getId());
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/324911.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

复试 || 就业day04(2024.01.05)项目一

文章目录 前言线性回归房价预测加载数据数据查看数据拆分数据建模模型的验证、应用模型的评估 总结 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;本文内容来自某机构网课&#xff0c;是我为复试准备的第一个项目 &#…

【书生·浦语大模型实战营01】《书生·浦语大模型全链路开源体系》

《书生浦语大模型全链路开源体系》 1. 大模型成为热门关键词 LLM发展时间轴 2. 书生浦语全链条开源开放体系 微调&#xff1a;XTuner 支持全参数微调支持LoRA等低成本微调 评测&#xff1a;OpenCompass 全方位评测&#xff0c;性能可复现80套评测集&#xff0c; 40万道题目…

AR技术改变汽车行业,AR看车、AR车书、AR售后维修震撼登场!

引言&#xff1a; 随着中国汽车市场步入存量发展阶段&#xff0c;车企正迎来新的机遇和挑战。这一发展意味着庞大的汽车后市场需求&#xff0c;同时也要求企业和经销商能够快速响应市场需求&#xff0c;提供高质量的服务。而培养具备全面技能的成熟售后服务人员需要企业投入大…

为什么云性能监控如此重要?

在当今数字化时代&#xff0c;企业越来越依赖云服务来支持其业务需求。为了确保云服务的可用性、性能和稳定性&#xff0c;云性能监控成为管理和优化云基础架构的关键一环。那么&#xff0c;为什么云性能监控如此重要?下面&#xff0c;就来看看具体介绍吧! 一、实时故障检测 云…

基于sumo实现交通灯控制算法的模板

基于sumo实现交通灯控制算法的模板 目录 在windows安装run hello world networkroutesviewsettings & configurationsimulation 交通灯控制系统 介绍文件生成器类&#xff08;FileGenerator&#xff09;道路网络&#xff08;Network&#xff09;辅助函数生成道路网络&am…

B端产品经理学习-B端产品的业务规划

B端产品的业务规划 什么是业务规划能力 B/C端产品区别以及对架构的影响 C端 B端 用户 角色&#xff1a;面向单一的消费者&#xff0c;通常只有一个用户角色 角色&#xff1a;通常涉及多个角色 架构要求&#xff1a;需要额外的权限和角色管理来实现的分工和写作 产品类型…

视频剪辑方法:一键批量转码,视频转GIF教程详解

在数字媒体时代&#xff0c;视频剪辑已经成为一项必备技能。无论是专业人士还是普通用户&#xff0c;都要对视频进行剪辑、转码和制作。但是视频剪辑并不简单&#xff0c;要掌握一定的技巧和知识。下面一起来看云炫AI智剪简单易学的视频剪辑方法&#xff1a;一键批量转码和视频…

时代变革,亿发进销存引领批发业转型:从‘瞎盲’到高效盈利

2024年&#xff0c;许多传统批发老板们忙得不可开交。抱怨生意难做、年关难熬。 有些老板为了降低成本&#xff0c;开除了一两个店员&#xff0c;结果却发现自己要同时盯着店&#xff0c;又得亲自开单&#xff0c;一天中至少有10个小时被拴在店里&#xff0c;就是为了减少支出…

linux防护与集群——系统安全及应用

一、账号安全控制&#xff1a; 用户账号是计算机使用者的身份凭证或标识&#xff0c;每个要访问系统资源的人&#xff0c;必须凭借其用户账号才能进入计算机。在Linux系统中&#xff0c;提供了多种机制来确保用户账号的正当、安全使用 1.1 基本安全措施&#xff1a; 在Linux…

PCIe 6.0生态业内进展分析总结

上一篇&#xff0c;我们针对PCIe 6.0的功能更新与实现挑战做了简单的分析与总结。更多详细内容可以参考&#xff1a; 扩展阅读&#xff1a;浅析PCIe 6.0功能更新与实现的挑战 那么&#xff0c;PCIe 6.0已经发布了一段时间了&#xff0c;业内硬件支持PCIe 6.0目前有哪些进展呢…

c语言:用共同体输出数据|练习题

一、题目 设置一个c语言共同体&#xff0c;并用共同体输出数据 如图&#xff1a; 二、代码图片【带注释】 三、源代码【带注释】 #include <stdio.h> #include<string.h> //定义一个共同体 union test { int i; char ch[10]; int id; }; //注意&…

创意无限:火星文和变异字体的魅力世界

在互联网的浩瀚星空里&#xff0c;火星文和变异字体如同璀璨的繁星&#xff0c;照亮了网络世界的角落。它们以独特的创意和视觉冲击力&#xff0c;吸引着无数网友的目光。让我们一起走进这个充满创意和想象力的世界&#xff0c;感受火星文和变异字体的无限魅力。 火星文生成器…