转:传智播客--Jbpm(四)

1. 完成职务的修改;
2. 完成人员的管理:
    -- UserForm
        -- 所属部门使用int deptId;
        -- 职务使用int [] roleIds;
    -- 使用BeanUtils复制两个不同对象的相同的属性;
        修改部分:
        BeanUtils.copyProperties(userForm, user);
        userForm.setDeptId(user.getDepartment()==null ? 0 : user.getDepartment().getId());
        int[] roleIds = new int[user.getRoles().size()];
        int index = 0;
        for (Role role : user.getRoles()){
            roleIds[index++] = role.getId();
        }
        userForm.setRoleIds(roleIds);

        添加部分:
        BeanUtils.copyProperties(user, userForm);
        Department dept = null;
        user.setDepartment(dept);

        if ( roleIds != null ) {
            for (int roleId : roles) {
                Role role = null;
                user.getRoles().add(role);
            }
        }
  
    -- 通过这个3个模块的增删改查,发现他们的Service可以共享;
       所以使用BaseAction extends DispatchAction,这个BaseAction管理所有的
       Service,并把它们作为protected,专供子类使用;
       这和论坛中的处理方法一致;

    -- 出错:
        -- 没有非空约束:但是报了roleId不能为空;
           中间表,user_role中userId, roleId一起作为主键;
           roleIds是一个数组,需要单独处理
        -- 有事务控制;

    -- 返回到.do的请求,尽量用重定向;

    -- User页面save.jsp中增加选择部门:
        -- 页面显示部门名称,增加隐藏字段:部门id
        -- js代码;
        -- UserForm代码,增加deptName字段;

    -- User页面save.jsp中增加选择职务:
        -- fieldset, legend, html:multibox
            <c:forEach items="${roles}" var="role">
                <html:multibox property="roleIds" value="${role.id}"></html:multibox>${role.name}<br>
            </c:forEach>
          
        -- checkbox与multibox
            checkbox -- boolean
            multibox -- 集合

        -- 修改职务时,如果一个都不选择,就不能保存;
            原因分析:
            解决: user.getRoles().clear();

   == 复习
        需求:  Department的模块,每次修改或删除一个部门后,不能转向当前的部门级别,
                而是显示总公司的部门列表;
        解决:
                因为Struts的forward的配置不能修改,要想在这个forward后面追加参数,使用下面的方法:
                af = mapping.findForward("list");
                new ActionForward(af.getPath()) + "&parentId=" + deptForm.getParentId(), );

        注意:  这种用法在论坛中也使用过;可以查看源码复习;


3. 分析流程定义;
    (1) 为什么流程定义不能删除?
        笔记有解释;
        查询历史记录时会有问题;删除流程定义时,导致下面的级联删除;
            流程定义->流程实例->任务实例;
        jbpm的解决方法是使用版本控制;每次都启动新的流程定义;

    (2) 项目中如何实现流程定义的删除?
        只有管理员可以删除;

    (3) 功能:
        流程定义列表;
        部署(par包);
        流程定义查看;

4. 根据上述分析,写出程序框架,属于详细设计

    (1) 写出PdAction的框架基本方法:
        list(), deploy(), viewPdFile(), viewPdImage(), download(), delete();
        deployUI()

    (2) Service->ServiceImpl;
        -- 统一管理jbpmContext; 把管理的方法放在BaseService;
            JbpmContextMangaer.getInstance().getJbpmContext();
       
        -- 所有与jbpm有关的操作,一定要使用jbpm API;
           最常用的就是jbpmContext;

来源:(http://blog.sina.com.cn/s/blog_5ecfe46a0100doco.html) - 传智播客--Jbpm(四)_hhl_bj_新浪博客
        -- PdForm
            id, resource(FormFile,部署流程定义文件的par包)


    (3) jsp页面:

    (4) 部署流程定义:
        -- 包装输入流
            new ZipInputStream(pdForm.getResource().getInputStream);
        -- 流的关闭:
            在调用的方法中关闭,被调用的方法只管用;

    (5) 下载
        -- 如何将文件打包?
            File file = new File("c:/test/a.txt");
            FileInputStream in = new FileInputStream(file);
            byte[] fiel1 = new byte[(int)file.length()];
          
            in.read(file1);
            in.close();


            File file = new File("c:/test/b.txt");
            FileInputStream in = new FileInputStream(file);
            byte[] fiel2 = new byte[(int)file.length()];
          
            in.read(file2);
            in.close();


            FileOutputStream fos = new FileOutputStream("c:/text/xx.zip");
            zipOutputStream zipos = new ZipOutputStream(fos);

            zipOutputStream.putNextEntry(ZipEntry("a.txt")));
            zipOutputStream.write(file1));
            zipOutputStream.close();
          
            zipOutputStream.putNextEntry(ZipEntry("b.txt")));
            zipOutputStream.write(file2));
            zipOutputStream.closeEntry();

            zipOutputStream.close();

            == 出现文件结构如何修改
                指定的名字就是相对压缩包的相对路径;"c/c.txt"
             
            == 空文件夹
                "emptyDir/"

    **************** 关于流程定义的处理方法,整理一下
    (1) 显示流程定义文件内容;
        使用response直接在浏览器上显示;
        -- 设置response的contentType="text/xml;charset=utf-8";
        -- 获取xml文件的内容:FileDefinition.getBytes();
        -- 使用response将内容输出:response.write();
        -- 不需要再返回jsp页面:return null;
        -- jsp页面使用 href="#";

    (2) 显示图片
        -- response.setContentType("image/jpeg");
        -- 修改文件名为流程定义的jpg文件;
        -- 其他操作同上;

    (3) 备份到本地:
        -- 将所有的文件打包;
            Map<String, byte[]> files = pd.getFileDefinition().getBytesMap();
            ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());
            for ( String fileName : files.keySet() ) {
              
                byte[] content = file.get(fileName);
                zipOutputStream.putNextEntry(new ZipEntry(fileName));
                zipOutputStream.write(content);
                zipOutputStream.closeEntry();
            }
            zipOutputStream.close(); // 必须,否则下载的文件不完整;
            return null;
        -- 让下载后的文件名改变;
            流程定义名_版本.zip
            zipName = pd.getName() + "_" + pd.getVersion() + ".zip";
            zipName = URLEncoder.encode(zipName, "utf-8");
            response.addHeader("Content-Disposition", "attachment;filename=\""+zipName);
            response.setContentType("application/zip");

        -- 下载带空文件夹,多层文件夹的流程定义文件:
            zipOutputStream.write(content);
            改为
            if ( content != null )
                zipOutputStream.write(content);

        -- 删除
            所有jbpm的操作尽量使用jbpmContext来操作;
      
5. 页面框架:Outlook Like Bar Version 1.7

6. 请假流程

    (1) 经理审批:
        Handler方式分配任务的角色,不使用actor,这是分配任务的第二种方式:
        AssignmentHandler
            assign(Assignable , ExecutionContext);
                //申请人; 做审批工作的职务; 查询:申请人所在部门的做审批工作的职务的那个人(可能多个);
                // 1,只有一个人审批;
                    assignable.setActorId();
                // 2, 多个人;
                    assignable.setPooledActors();

    (2) 总经理审批

        代码内容与部门经理的代码内容相似;
        重用代码;
          
        -- 将局部变量roleName作为成员变量
            privateString roleName;
        -- Config Info:
            Assignment的配置里面可以设置成员变量的初始值;
            这样就可以将部门经理和总经理的这个变量的初始值
            分别设为部门经理和总经理;
        -- Config Type
            field,bean,construtor ; 参考Spring;

    assign
        -- 所有的操作应该和executionContext有关;
        -- 获取变量
            executionContext.getVariable();
        -- 获取JbpmContext;从而获取session,获取数据库中的值
            executionContext.getJbpmContext();
        -- 组任务查询语句:Hibernate
            from User u where  and ? in elementes(u.roles);
           流程定义中设置了actorId的初始值,它表示的是职务名称;
           在assign中需要通过它获取担任该职务的人员名称;
           要实现这些,需要2步:
           1. 通过actorId获取Role对象;
           2. 通过Role对象获取User列表;

你可能感兴趣的:(框架,jsp,配置管理,项目管理,jbpm)