• JeeSite 工作流Activiti的应用实例


    1. 新建流程模型

      在线办公-流程管理-模型管理-新建模型 
      新建模型

    点击“提交”后会立即跳转到“流程在线设计器”页面,请看下一章节

    • 在线流程设计器 
      在线办公流程管理模型管理模型管理编辑

    1. 整体流程图

    这里写图片描述

    1. matter属性

    这里写图片描述

    1. 开始结点

    这里写图片描述

    1. 办公室审批结点

    这里写图片描述

    1. 箭线-是

    这里写图片描述

    1. 箭线-否

    这里写图片描述

    1. 部门意见结点

    这里写图片描述

    1. 个人处理结点

      这里写图片描述

    2. 事件完成

      这里写图片描述

    2.1 设置流程属性

    名称:流程定义名称 
    描述:流程定义描述 
    流程标识:流程定义KEY,对应procDefKey,用来标识一个流程 
    2.2 拖拽形状元素 
    Start event:开始事件 
    End entit:结束事件 
    User task:用户任务活动 
    Service task:服务任务活动 
    Exclusive gateway:排它网关通道,只能有一条分支执行,如if else 
    Parallel gateway:并行网关通道,所有分支一块执行 
    Enclusive gateway:包含网关通道,执行符合条件的分支 
    参考:http://www.mossle.com/docs/activiti/#bpmnConstructs

    2.3 流程发起人流程变量 
    在开始节点的属性中设置“流程发起人”变量名:如:apply

    这时,任务的参与者可设置${apply},来指定谁发起谁执行

    如发起人发起流程,被驳回是,驳回到发起人,可使用方法。

    2.4 挂接表单地址 
    全局表单:新建流程时或活动元素上未设置表单标识时调用的表单,位于开始事件属性中“表单标识”字段,指定表单访问地址。 
    活动表单:当前步骤使用的表单,使用活动节点属性“表单标识”字段。

    2.5 设置参与者 
    在活动节点属性中找到“参与者”属性,点击“…”弹出如下窗口

    assignee:任务执行人,设置系统中的“登录名”(loginName)。 
    candidateUsers:任务执行人,多个用逗号“,”隔开。 
    candidateGroups:任务执行组,多个用逗号“,”隔开,设置系统中的“角色英文名(enname)”。 
    assignee和candidateUsers的区别是:assignee不需要签收任务,直接可执行任务;candidateUsers为竞争方式分配任务,被指定人待办中都有一条任务,谁先签收谁就获得任务的执行权。 
    参与者可指定流程变量(EL表达式),动态指定参与者,如:${processer}

    2.6 设置流转条件 
    在流转线的属性中找到“流转条件”,这里,写EL表达式,返回true或false,如:${flag == ‘1’}

    2.7 保存流程设计图 
    工具栏上点击“保存”按钮

    这时,任务的参与者可设置${apply},来指定谁发起谁执行

    如发起人发起流程,被驳回是,驳回到发起人,可使用方法。

    2.8 注意事项 
    所有编号,如:模型编号、流程编号、活动节点编号,都不允许以数字开头。

    3 部署流程 
    - 部署流程 
    这里写图片描述

    -启动流程 
    这里写图片描述

    -信息填报 
    这里写图片描述

    上步咱们学习了流程设计,产生流程设计图,如何将我们的图部署到系统中并使用呢,请看如下操作: 
    在线办公流程管理模型管理模型管理部署 
    接着系统会提示“部署成功”信息,如果提示错误,说明你流程设计图有问题,请检查错误,重新执行部署操作。 
    另外两种部署方法,通过eclipse插件设计好的流程: 
    在线办公-流程管理-流程管理-部署流程-选择流程.bpmn.xml 
    编写并执行ant脚本,启动系统将自动部署 
    / jeesite/src/main/resources/act/build.xml。 
    设置流程分类:在流程管理中直接点击流程分类进行设置。 
    同一标识流程,部署多次,版本号自动加1 
    正在运行的流程,再次部署新流程后,正在运行的流程还按照原来流程设置走,再次新建的流程使用新流程走。

    • 事件 填报页面
    <%@ page contentType="text/html;charset=UTF-8" %>
    <%@ include file="/WEB-INF/views/include/taglib.jsp"%>
    <html>
    <head>
        <title>事件</title>
        <meta name="decorator" content="default"/>
        <script type="text/javascript">
            $(document).ready(function() {
                $("#name").focus();
                $("#inputForm").validate({
                    submitHandler: function(form){
                        lmatterding('正在提交,请稍等...');
                        form.submit();
                    },
                    errorContainer: "#messageBox",
                    errorPlacement: function(error, element) {
                        $("#messageBox").text("输入有误,请先更正。");
                        if (element.is(":checkbox")||element.is(":radio")||element.parent().is(".input-append")){
                            error.appendTo(element.parent().parent());
                        } else {
                            error.insertAfter(element);
                        }
                    }
                });
            });
        </script>
    </head>
    <body>
        <ul class="nav nav-tabs">
            <li><a href="${ctx}/matter/mzMatter/">事件列表</a></li>
            <li class="active"><a href="${ctx}/matter/mzMatter/form?id=${mzMatter.id}"><shiro:hasPermission name="matter:mzMatter:edit">${not empty mzMatter.id?'修改':'填报'}事件</shiro:hasPermission><shiro:lacksPermission name="matter:mzMatter:edit">查看</shiro:lacksPermission></a></li>
        </ul>
        <form:form id="inputForm" modelAttribute="mzMatter" action="${ctx}/matter/mzMatter/save" method="post" class="form-horizontal">
            <form:hidden path="id"/>
            <form:hidden path="act.taskId"/>
            <form:hidden path="act.taskName"/>
            <form:hidden path="act.taskDefKey"/>
            <form:hidden path="act.procInsId"/>
            <form:hidden path="act.procDefId"/>
            <form:hidden id="flag" path="act.flag"/>
            <sys:message content="${message}"/>
            <fieldset>
                <legend>事件填报</legend>
                <table class="table-form">
                    <tr>
    
                        <td class="tit">名称</td><td>
                            <form:input path="name" htmlEscape="false" maxlength="50"/>
                        </td>
                        <td class="tit">发生时间</td>
                        <td colspan="2"><input name="happenDate" type="text" readonly="readonly" maxlength="20" class="input-medium Wdate "
                        value="<fmt:formatDate value="${mzMatter.happenDate}" pattern="yyyy-MM-dd HH:mm:ss"/>"
                        onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',isShowClear:false});"/></td>
                    </tr>
                    <tr>
                        <td class="tit">事件内容描述</td>
                        <td colspan="5">
                            <form:textarea path="content" class="required" rows="5" maxlength="200" cssStyle="500px"/>
                        </td>
                    </tr>
                    <tr>
                        <td class="tit">类别</td>
                        <td colspan="2">
                    <form:select path="category" class="input-xlarge ">
                        <form:option value="" label=""/>
                        <form:options items="${fns:getDictList('matter_category')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
                    </form:select></td>
                    </tr>
                    <tr>
                        <td class="tit">紧急程度</td>
                        <td>
                            <form:select path="urgencyLevel" class="input-xlarge ">
                            <form:option value="" label=""/>
                            <form:options items="${fns:getDictList('urgency_level')}" itemLabel="label" itemValue="value" htmlEscape="false"/>
                            </form:select>
                        </td>
                        <td class="tit">地区</td><td>
                            <sys:treeselect id="area" name="area.id" value="${mzMatter.area.id}" labelName="area.name" labelValue="${mzMatter.area.name}"
                        title="区域" url="/sys/area/treeData" cssClass="required" allowClear="true" notAllowSelectParent="true"/>
                        </td>
                    </tr>
                    <tr>
                        <td class="tit">详细地址</td>
                        <td><form:input path="addressDetail" htmlEscape="false" maxlength="100" class="input-xlarge required"/></td>
                        <td class="tit">备注</td>
                        <td><form:input path="remarks" htmlEscape="false" maxlength="50"/></td>
                    </tr>
                    <tr>
                        <td class="tit">办公室意见</td>
                        <td colspan="5">
                            ${mzMatter.officeText}
                        </td>
                    </tr>
                    <tr>
                        <td class="tit">部门领导意见</td>
                        <td colspan="5">
                            ${mzMatter.depText}
                        </td>
                    </tr>
                    <tr>
                        <td class="tit">事件处理意见</td>
                        <td colspan="5">
                            ${mzMatter.personText}
                        </td>
                    </tr>
                </table>
            </fieldset>
            <div class="form-actions">
                <shiro:hasPermission name="matter:mzMatter:edit">
                    <input id="btnSubmit" class="btn btn-primary" type="submit" value="提交事件" onclick="$('#flag').val('yes')"/>&nbsp;
                    <c:if test="${not empty mzMatter.id}">
                        <input id="btnSubmit2" class="btn btn-inverse" type="submit" value="销毁事件" onclick="$('#flag').val('no')"/>&nbsp;
                    </c:if>
                </shiro:hasPermission>
                <input id="btnCancel" class="btn" type="button" value="返 回" onclick="history.go(-1)"/>
            </div>
            <c:if test="${not empty mzMatter.id}">
                <act:histoicFlow procInsId="${mzMatter.act.procInsId}" />
            </c:if>
        </form:form>
    </body>
    </html>
    
    • Controller
    
    package com.thinkgem.jeesite.modules.matter.web;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.shiro.authz.annotation.RequiresPermissions;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.servlet.mvc.support.RedirectAttributes;
    
    import com.thinkgem.jeesite.common.persistence.Page;
    import com.thinkgem.jeesite.common.web.BaseController;
    import com.thinkgem.jeesite.modules.sys.entity.User;
    import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
    import com.thinkgem.jeesite.modules.matter.entity.MzMatter;
    import com.thinkgem.jeesite.modules.matter.service.MzMatterService;
    
    /**
     * 审批Controller
     * @author thinkgem
     * @version 2014-05-16
     */
    @Controller
    @RequestMapping(value = "${adminPath}/matter/mzMatter")
    public class MzMatterController extends BaseController {
    
        @Autowired
        private MzMatterService mzMatterService;
    
        @ModelAttribute
        public MzMatter get(@RequestParam(required=false) String id){//, 
    //          @RequestParam(value="act.procInsId", required=false) String procInsId) {
            MzMatter mzMatter = null;
            if (StringUtils.isNotBlank(id)){
                mzMatter = mzMatterService.get(id);
    //      }else if (StringUtils.isNotBlank(procInsId)){
    //          mzMatter = mzMatterService.getByProcInsId(procInsId);
            }
            if (mzMatter == null){
                mzMatter = new MzMatter();
            }
            return mzMatter;
        }
    
        @RequiresPermissions("matter:mzMatter:view")
        @RequestMapping(value = {"list", ""})
        public String list(MzMatter mzMatter, HttpServletRequest request, HttpServletResponse response, Model model) {
            User user = UserUtils.getUser();
            if (!user.isAdmin()){
                mzMatter.setCreateBy(user);
            }
            Page<MzMatter> page = mzMatterService.findPage(new Page<MzMatter>(request, response), mzMatter); 
            model.addAttribute("page", page);
            return "modules/matter/matterList";
        }
    
        /**
         * 申请单填写
         * @param mzMatter
         * @param model
         * @return
         */
        @RequiresPermissions("matter:mzMatter:view")
        @RequestMapping(value = "form")
        public String form(MzMatter mzMatter, Model model) {
    
            String view = "matterForm";
    
            // 查看审批申请单
            if (StringUtils.isNotBlank(mzMatter.getId())){//.getAct().getProcInsId())){
    
                // 环节编号
                String taskDefKey = mzMatter.getAct().getTaskDefKey();
    
                // 查看工单
                if(mzMatter.getAct().isFinishTask()){
                    view = "matterView";
                }
                // 修改环节
                else if ("modify".equals(taskDefKey)){
                    view = "matterForm";
                }
                // 审核环节
                else if ("officedo".equals(taskDefKey)){
                    view = "matterAudit";
    //              String formKey = "/oa/mzMatter";
    //              return "redirect:" + ActUtils.getFormUrl(formKey, mzMatter.getAct());
                }
                // 审核环节2
                else if ("depdo".equals(taskDefKey)){
                    view = "matterAudit";
                }
    //          // 审核环节3
    //          else if ("audit3".equals(taskDefKey)){
    //              view = "matterAudit";
    //          }
    //          // 审核环节4
    //          else if ("audit4".equals(taskDefKey)){
    //              view = "mzMatterAudit";
    //          }
                // 兑现环节
                else if ("apply_end".equals(taskDefKey)){
                    view = "matterAudit";
                }
            }
    
            model.addAttribute("mzMatter", mzMatter);
            return "modules/matter/" + view;
        }
    
        /**
         * 申请单保存/修改
         * @param mzMatter
         * @param model
         * @param redirectAttributes
         * @return
         */
        @RequiresPermissions("matter:mzMatter:edit")
        @RequestMapping(value = "save")
        public String save(MzMatter mzMatter, Model model, RedirectAttributes redirectAttributes) {
            if (!beanValidator(model, mzMatter)){
                return form(mzMatter, model);
            }
            mzMatterService.save(mzMatter);
            addMessage(redirectAttributes, "提交审批'" + mzMatter.getCurrentUser().getName() + "'成功");
            return "redirect:" + adminPath + "/act/task/todo/";
        }
    
        /**
         * 工单执行(完成任务)
         * @param mzMatter
         * @param model
         * @return
         */
        @RequiresPermissions("matter:mzMatter:edit")
        @RequestMapping(value = "saveMatter")
        public String saveAudit(MzMatter mzMatter, Model model) {
            if (StringUtils.isBlank(mzMatter.getAct().getFlag())
                    || StringUtils.isBlank(mzMatter.getAct().getComment())){
                addMessage(model, "请填写审核意见。");
                return form(mzMatter, model);
            }
            mzMatterService.auditSave(mzMatter);
            return "redirect:" + adminPath + "/act/task/todo/";
        }
    
        /**
         * 删除工单
         * @param id
         * @param redirectAttributes
         * @return
         */
        @RequiresPermissions("matter:mzMatter:edit")
        @RequestMapping(value = "delete")
        public String delete(MzMatter mzMatter, RedirectAttributes redirectAttributes) {
            mzMatterService.delete(mzMatter);
            addMessage(redirectAttributes, "删除审批成功");
            return "redirect:" + adminPath + "/oa/mzMatter/?repage";
        }
    
    }
    

    -Service

    
    package com.thinkgem.jeesite.modules.matter.service;
    
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.google.common.collect.Maps;
    import com.thinkgem.jeesite.common.persistence.Page;
    import com.thinkgem.jeesite.common.service.CrudService;
    import com.thinkgem.jeesite.common.utils.StringUtils;
    import com.thinkgem.jeesite.modules.act.service.ActTaskService;
    import com.thinkgem.jeesite.modules.act.utils.ActUtils;
    import com.thinkgem.jeesite.modules.matter.entity.MzMatter;
    import com.thinkgem.jeesite.modules.matter.dao.MzMatterDao;
    import com.thinkgem.jeesite.modules.oa.entity.TestAudit;
    
    /**
     * 民宗事件Service
     * @author lmm
     * @version 2017-05-15
     * 
     * 
     */
    @Service
    @Transactional(readOnly = true)
    public class MzMatterService extends CrudService<MzMatterDao, MzMatter> {
    
        @Autowired
        private ActTaskService actTaskService;
    
        public MzMatter get(String id) {
            return super.get(id);
        }
    
        public List<MzMatter> findList(MzMatter mzMatter) {
            return super.findList(mzMatter);
        }
    
        public Page<MzMatter> findPage(Page<MzMatter> page, MzMatter mzMatter) {
            return super.findPage(page, mzMatter);
        }
    
        @Transactional(readOnly = false)
        public void save(MzMatter mzMatter) {
    
            // 申请发起
            if (StringUtils.isBlank(mzMatter.getId())){
                mzMatter.preInsert();
                dao.insert(mzMatter);
    
                // 启动流程
                actTaskService.startProcess(ActUtils.PD_MATTER[0], ActUtils.PD_MATTER[1], mzMatter.getId(), mzMatter.getContent());
    
            }
    
            // 重新编辑申请       
            else{
                mzMatter.preUpdate();
                dao.update(mzMatter);
    
                mzMatter.getAct().setComment(("yes".equals(mzMatter.getAct().getFlag())?"[重申] ":"[销毁] ")+mzMatter.getAct().getComment());
    
                // 完成流程任务
                Map<String, Object> vars = Maps.newHashMap();
                vars.put("pass", "yes".equals(mzMatter.getAct().getFlag())? "1" : "0");
                actTaskService.complete(mzMatter.getAct().getTaskId(), mzMatter.getAct().getProcInsId(), mzMatter.getAct().getComment(), mzMatter.getContent(), vars);
            }
        }
    
        @Transactional(readOnly = false)
        public void delete(MzMatter mzMatter) {
            super.delete(mzMatter);
        }
    
        /**
         * 审核审批保存
         * @param testAudit
         */
        @Transactional(readOnly = false)
        public void auditSave(MzMatter mzMatter) {
    
            // 设置意见
            mzMatter.getAct().setComment(("yes".equals(mzMatter.getAct().getFlag())?"[同意] ":"[驳回] ")+mzMatter.getAct().getComment());
    
            mzMatter.preUpdate();
    
            // 对不同环节的业务逻辑进行操作
            String taskDefKey = mzMatter.getAct().getTaskDefKey();
    
            // 审核环节
            if ("officedo".equals(taskDefKey)){
                mzMatter.setOfficeText(mzMatter.getAct().getComment());
                dao.updateOfficeText(mzMatter);
            }
            else if ("depdo".equals(taskDefKey)){
                mzMatter.setDepText(mzMatter.getAct().getComment());
                dao.updateDepText(mzMatter);
            }
            else if ("apply_end".equals(taskDefKey)){
                mzMatter.setPersonText(mzMatter.getAct().getComment());
                dao.updatePersonText(mzMatter);
            }
    
            // 未知环节,直接返回
            else{
                return;
            }
    
            // 提交流程任务
            Map<String, Object> vars = Maps.newHashMap();
            vars.put("pass", "yes".equals(mzMatter.getAct().getFlag())? "1" : "0");
            actTaskService.complete(mzMatter.getAct().getTaskId(), mzMatter.getAct().getProcInsId(), mzMatter.getAct().getComment(), vars);
    
    //      vars.put("var_test", "yes_no_test2");
    //      actTaskService.getProcessEngine().getTaskService().addComment(testAudit.getAct().getTaskId(), testAudit.getAct().getProcInsId(), testAudit.getAct().getComment());
    //      actTaskService.jumpTask(testAudit.getAct().getProcInsId(), testAudit.getAct().getTaskId(), "audit2", vars);
        }
    
    }
  • 相关阅读:
    202011.19
    202011.18
    202011.17
    202011.16
    202011.14
    jdk的下载和配置
    layui中form表单
    JS中utocomplete
    转:JqueryUI学习笔记-自动完成autocomplete
    JSON.parse()与JSON.stringify()的区别
  • 原文地址:https://www.cnblogs.com/firstdream/p/8017570.html
Copyright © 2020-2023  润新知