目录
项目详解
前端
API
组件
后端
FlowDefinitionController.java
FlowTaskController.java
FlowInstanceController.java
项目开发
流程图
创建数据库
后端
ExcApply包详解
前端
创建教师申请页面:
关联流程
申请(ActApplyBtn.vue)
重新提交(ActHandleBtn.vue):
撤销(ActCancelBtn.vue):
审批历史(ActHandleBtn.vue)
项目详解
前端
API
API
flowable/api/definition.js:实现流程定义相关操作的api,连接后端FlowDefinitionController.java中的方法
flowable/api/finished.js、flowable/api/process.js、flowable/api/tode.js:实现流程执行相关操作的api
组件
flowable/components/ActApplyBtn.vue:提交按钮(启动流程)
flowable/components/ActCancelBtn.vue:撤回(销毁流程)
flowable/components/ActHandleBtn.vue:处理流程(0 通过、退回节点:1 驳回、2 退回、3 重新提交)
flowable/components/ActHistoricDetailBtn.vue:审批处理历史
flowable/components/HistoricDetail.vue:审批处理历史页面组件
后端
FlowDefinitionController.java
flowable/controller/FlowDefinitionController.java:工作流程定义
例如:获取流程定义列表、导入流程文件、读取xml文件等
FlowTaskController.java
flowable/controller/FlowTaskController.java:工作流任务管理
例如:查看发起流程、取消申请、撤回流程、获取待办任务等
FlowInstanceController.java
flowable/controller/FlowInstanceController.java:工作流流程实例管理
例如:激活或挂起流程实例、删除流程实例
项目开发
首先要实现任课老师提交实验课授课方式申请的工作流
流程图
先用部署好的流程设计页面画好流程图:
创建流程图时要选好候选人员:
若有网关要写好网关的条件表达式(排他网关一定得写条件表达式):
创建数据库
利用Jeecg-boot Online表单在线开发功能,为老师申请实验课任课方式创建数据库exc_apply
生成代码包ExcApply
后端ExcApply包详解
ExcApply/controller/ExcApplyController.java:完成后端相关操作例如添加、修改、删除、查询等)
实现relationAct接口,使得申请能够关联上流程
@AutoLog(value = "关联流程")
@ApiOperation(value="关联流程", notes="关联流程")
@RequestMapping(value = "/relationAct",method = RequestMethod.GET)
public Result> relationAct(HttpServletRequest request,HttpServletResponse response){
String dataId = request.getParameter("dataId");
excApplyService.relationAct(dataId);
return Result.OK();
}
ExcApply/entity/ExcApply.java:对应exc_apply数据库的属性类
ExcApply/mapper/xml/ExcApplyMapper.xml:数据库exc_apply的xml
ExcApply/mapper/ExcApplyMapper.java:对应任课老师申请授课方式model的属性类
为使用IPage和Page实现分页:
public interface ExcApplyMapper extends BaseMapper{ IPage myPage(Page page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper); }
service/IExcApplyServiceImpl.java:服务接口
为使用IPage和Page实现分页:
public interface IExCApplyService extends IService{ IPage myPage(Page page, QueryWrapper queryWrapper); void relationAct(String dataId); }
service/impl/ExCApplyServiceImpl.java:
Service必须继承FlowCallBackServiceI接口并实现其方法
@Service("excApplyService")
public class ExcApplyServiceImpl extends ServiceImpl implements IExcApplyService , FlowCallBackServiceI {
@Override
public void relationAct(String dataId) {
flowCommonService.initActBusiness("实验授课申请:dataId"+dataId,dataId,"excApplyService","process_tpho5a4q","process_tpho5a4q:4:32128f7c-ce77-11ec-843e-927841cf098b");
}
@Autowired
FlowCommonService flowCommonService;
@Override
public IPage myPage(Page page, QueryWrapper queryWrapper) {
return this.baseMapper.myPage(page,queryWrapper);
}
@Override
public void afterFlowHandle(FlowMyBusiness business) {
//流程操作后做些什么
business.getTaskNameId();//接下来审批的节点
business.getValues();//前端传进来的参数
business.getActStatus();//流程状态 ActStatus.java
//....其他
}
@Override
public Object getBusinessDataById(String dataId) {
return this.getById(dataId);
}
@Override
public Map flowValuesOfTask(String taskNameId, Map values) {
return null;
}
@Override
public List flowCandidateUsernamesOfTask(String taskNameId, Map values) {
// 案例,写死了jeecg,实际业务中通过当前节点来判断下一个节点的候选人并写回到反参中,如果为null,流程模块会根据默认设置处理
return Lists.newArrayList("jeecg");
}
@Override
public boolean save(ExcApply excApply){
excApply.setId(IdUtil.fastSimpleUUID());
this.relationAct(excApply.getId());
return super.save(excApply);
}
@Override
public boolean removeById(Serializable id){
flowCommonService.delActBusiness(id.toString());
return super.removeById(id);
}
}
所实现的方法afterFlowHandle将在流程处理过程中被回调,用以增强处理业务层业务逻辑(之后修改
@Override
public void afterFlowHandle(FlowMyBusiness business) {
//流程操作后做些什么
business.getTaskNameId();//接下来审批的节点
business.getValues();//前端传进来的参数
business.getActStatus();//流程状态 ActStatus.java
//....其他
}
在业务数据新增时,必须初始化业务和流程间的关联,调用FlowCommonService.initActBusiness方法
public void initActBusiness(String title, String dataId, String serviceImplName, String processDefinitionKey, String processDefinitionId){
flowCommonService.initActBusiness(title,dataId,"exCApplyService","process_tpho5a4q","process_tpho5a4q:3:b18ae95d-ce02-11ec-8534-927841cf098b");
}
删除业务数据时调用flowCommonService.delActBusiness(id.toString());
@Override
public boolean removeById(Serializable id){
flowCommonService.delActBusiness(id.toString());
return super.removeById(id);
}
前端
创建教师申请页面:
关联流程
教师申请完首先得点击“关联流程”按钮,让其与流程相关联:
关联流程
relationAct(r){
getAction("/ExcApply/excApply/relationAct",{dataId:r.id}).then(res=>{
if(res.success){
this.$message.success("操作成功")
this.loadData()
}else{
this.$message.error("操作失败")
}
})
}
relationAct方法调用后端relationAct方法:
@AutoLog(value = "关联流程")
@ApiOperation(value="关联流程", notes="关联流程")
@RequestMapping(value = "/relationAct",method = RequestMethod.GET)
public Result> relationAct(HttpServletRequest request,HttpServletResponse response){
String dataId = request.getParameter("dataId");
excApplyService.relationAct(dataId);
return Result.OK();
}
申请(ActApplyBtn.vue)
然后点击申请按钮提交申请:
调用ActApplyBtn组件,此组件添加点击事件,调用definitionStartByDataId方法:
import {definitionStartByDataId} from "@views/flowable/api/definition";
applySubmit() {
if (this.dataId && this.dataId.length < 1) {
this.error = '必须传入参数dataId';
this.$message.error(this.error);
return;
} else {
this.error = '';
}
this.submitLoading = true;
var params = Object.assign({
dataId: this.dataId
}, this.variables);
console.log(params);
definitionStartByDataId(this.dataId, params)
.then(res => {
if (res.success) {
this.$message.success('操作成功');
this.$emit('success');
} else {
this.$message.error(res.message);
}
})
.finally(() => (this.submitLoading = false));
}
definitionStartByDataId()方法调用后端FlowDefinitionServiceImpl.java中的startByDataId接口实现流程实例的部署:
// 部署流程实例
export function definitionStartByDataId(dataId,data) {
return request({
url: '/flowable/definition/startByDataId/' + dataId,
method: 'post',
data: data
})
}
重新提交(ActHandleBtn.vue):
调用ActHandleBtn组件,0通过、退回节点(1驳回、2退回、3重新提交)。此组件添加点击事件处理不同类型的按钮:
handle() {
this.form.comment = ''
this.candidateUsersSelecteds = []
if (this.type === this.handleType.delegate) {
// this.delegateTask();
} else if (this.type === this.handleType.pass) {
this.passTask();
} else if (this.type === this.handleType.back) {
this.backTask();
} else if(this.type === this.handleType.return){
this.returnTask();
} else if(this.type === this.handleType.reApply){
this.reApply();
}
else {
this.$message.warn('未知类型type,参见 handleType');
}
}
重新提交:
reApply() {
const v = this;
this.modalTaskTitle = '确认重新提交';
this.modalTaskVisible = true;
},
其他类似
撤销(ActCancelBtn.vue):
撤销按钮绑定点击事件cancel(),让撤销面板可见,填写撤销原因
cancel() {
this.modalCancelVisible = true;
},
handelSubmitCancel() {
this.submitLoading = true;
deleteByDataId(this.dataId, this.cancelForm.reason)
.then(res => {
if (res.success) {
this.$message.success('操作成功');
this.modalCancelVisible = false;
this.$emit('success');
} else {
this.$message.error(res.message);
}
})
.finally(() => (this.submitLoading = false));
}
}
审批历史(ActHandleBtn.vue)
点击审批历史按钮可查看进展:
点击事件与提交类似



