码迷,mamicode.com
首页 > 其他好文 > 详细

12天OA项目

时间:2014-08-13 17:38:16      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   java   使用   os   io   文件   

OA(Office Automation):办公自动化--辅助管理,提高办公效率的系统。

OA的功能:
    文字处理,申请审批,办公用品管理,公文管理,会议管理,资料管理,知识管理,电子邮件等...
根据用户实际需求确定实际项目的功能。

BBS--论坛
CRM--客户关系管理系统
CMS--内容管理系统

1.软件开发的简单步骤:
    <1.需求分析
    <2.分析设计
    <3.编码实现
    <4.测试验证(修改)
    <5.部署与后期维护
    
2.每个步骤具体要做什么,谁来做?

3.我们要做什么?
    设计(模块部分设计),编码,测试

一、设计:
    整体设计:
    <1.分层:
        3层:View(显示层servlet/action)-->Servcie(接口/实现类)-->Dao(接口/实现类)
    <2.所用技术:
        Struts2 + Hibernate + Spring + Junit + JBPM + jQuery + ...
    <3.开发环境:
        Windows(OS) + Tomcat(Web Server) + MyEclipse(IDE) + MySQL(DB) + IE(web browser)
    <4.代码规范(增强可读性):
        代码格式:缩进
        命名规范:使用驼峰命名法(还有使用匈牙利命名法)--每个单词的首字母大写
        注释:注释不可没有,也不可过多,因为不是文档
        空行:是当初加入空行
        要格式化代码、一个java文件或方法的代码不要过多
    <5.一些约定:
        编码统一使用utf-8(避免乱码)
        实体的主键属性的类型使用Long
    <6.项目计划:
        共12天,完成4个模块:
        搭建环境--1
        系统管理--2
        权限--2
        论坛--2
        工作流+审批流转--2+2

****************************************************************************************************
搭建环境:

一.数据库:

1.创建数据库:
mysql> create database itcaseoa0720 default character set utf8;

二.MyEclipser项目:

1.新工程:Web工程,并把编码设为utf-8
2.添加框架环境:Struts2(jar包,struts.xml,web.xml)
     + Hibernate(jar包--<核心包,jdbc驱动,c3p0,jpa>,hibernate.cfg.xml,*.hbm.xml)
     + Spring(applicationContext.xml/beans.xml)
     + Junit
3.整合SSH:
    Struts2和Spring的整合:
        <1.在web.xml中配置spring的监听器
        <2.加入jar包spring-struts-plugins
将Struts的action对象交给spring管理。
    Hibernate和Spring的整合:
        <1.让Spring管理SeesionFactory实例(只需一个--单例)
        <2.声明式事物管理
4.资源分类
源码文件夹
    src    项目源代码
    config    配置文件按
    test    单元测试
WebRoot文件夹
    script    javascript脚本文件
    style    CSS样式文件
    WEB-INF/jsp    jsp页面(再创建子文件夹分类存放)
5.配置日志
    debug 调试信息
    info    一般信息
    warn    警告
    error    错误
    fatal    严重错误
用log4j日志程序需要用到以下三个jar包:
slf4j-api    是各种日志程序的接口
slf4j-log4j.jar    连接slf4j-log4j
log4j.jar    log4j的实现

****************************************************************************************************

系统管理模块,包含以下三个部分:

重点关注的功能有:增删改查、客户端表单验证、树状结构的设计与展示。

*1.岗位管理模块:

基本功能:(第15集)--ItcastOA
    BaseDao(Dao接口)
        有增删改查方法
    BaseImpl实现BaseDao,利用泛型是实现方法。
    各modelDao继承BaseDao(使用泛型)。
    各modelDaoImpl继承BaseImpl也实现各自的modelDao。

1.设计实体-->JvaBean-->hbm.xml-->建表(在生成SessioFactory的时候建立)(先设计实体而不是表示因为以面向对象的方式思考问题)
2.分析有几个功能,对应几个请求
3.实现功能
    <<1..写Action--写Action中的方法,确定Service中的方法
    <<2..写Service方法--确定Dao中的方法
    <<3..写Dao
    <<4..写页面jsp

转发和重定向:
    转发请求1个,重定向请求2个。
    重定向地址栏会变,转发不会(服务器端的跳转),所以在不同功能之间的转换使用重定向,同一个功能的各个部分之间使用转发。
    添加、修改、删除成功后,要重定向到列表功能,这样在刷新页面的时候才不会出现“又做一次增删改”的操作。

岗位管理的增删改查功能都使用重定向,共有6个请求。
列表(查)与删除共能只有一个请求,添加与修改功能有两个请求(即先转到添加和修改页面,再点确定才是真正提交请求)。
所以需要相应的6个Action方法,每个Action方法处理一种请求。

作用--方法名--返回值--对应的页面:
列表--list()--list--list.jsp
删除--delete()--toList
添加页面--addUI()--addUI--addUI.jsp
添加--add()--toList
修改页面--editUI()--editUI--editUI.jsp
修改--edit()--toList

<result name="toList" type="redirectAction">role_list</result>

由于addUI和editUI页面有很多相似之处,故将这个页面整合为一个页面saveUI.jsp(利用ID是否为空区分)。

crud的action的模板:

    public String list() throws Exception{    //列表
        return "list";
    }
    public String delete() throws Exception{    //删除
        return "toList";
    }
    public String addUI() throws Exception{    //添加页面
        return "saveUI";
    }
    public String add() throws Exception{    //添加
        return "toList";
    }
    public String edit() throws Exception{    //修改
        return "toList";
    }
    public String editUI() throws Exception{    //修改页面
        return "saveUI";
    }

*2.部门管理模块:
<1.基本的增删改查。
<2.增删改查中对于“上级部门”的处理。
<3.处理部门的树状结构显示。

部门管理小功能的实现:
    1.从列表转到添加页面时,应默认选中原列表的上级部门。
    2.增加“返回上一级”功能。
    3.添加、修改、删除成功后还转到原列表页面,而不是顶级列表页面。

Web程序中的懒加载异常说明及解决方案:
    可以使用自己配置过滤器的方法结解决:OpenSessionInViewFilter

*3.用户管理模块:

整改:由于service只实现简单的增删改查,所以不需要dao层,删除dao和daoimpl,直接利用service完成数据库相关的操作,将这些操作封装到daosupportimpl中,各serviceimpl继承它。

View + Service + Dao --> View + Service(原Service+原Dao)
合并Service与Dao
使用两层
在Service可以直接使用hibernateSession操作实体

****************************************************************************************************
设计实体的流程总结:

有几个实体?
    一般十一组增删改查对应一个实体。
实体之间有什么关系?
    一般是页面引用了其他的实体时,就表示与这个实体有关联关系。
每个实体中都有什么属性?
    1.主键
    2.关联关系属性
    3.一般属性
    4.特殊属性

Hibernate实体映射流程总结:
    1.写注释:
    格式为:?属性,表达的是本对象与?的?关系。
    例:"department属性,本对象与Department的多对一"
    2.拷模板:
    多对一:
        <many-to-one name="" class="" column=""></many-to-one>
    一对多(Set):
        <set name="">
            <key column=""></key>
            <one-to-many class=""/>
        </set>
    多对多(Set):
        <set name="" table="">
            <key column=""></key>
            <many-to-many class="" column=""></many-to-many>
        </set>
    3.填空:
    <1.name属性:属性名(注释中的第一问号)
    <2.class属性:关联的实体类型(注释中的第二个问号)
    <3.column属性:
        <<1. <many-to-one column="..">:一般可以写成属性名加Id后缀,如属性为department,则column值写成departmentId。
        <<2. 一对多中的<key column="..">:从关联的对方(对方是多对一)映射中把column值拷贝过来。 
        <<3. 多对多中的<key column=“..”>:一般可以写成本对象的名加Id后缀,如本对象名为User,则写为userId。
        <<4. 多对多中的<many-to-many column=“..”>:一般可以写为关联对象的名称加Id后缀。

实现一组正删改查功能的步骤:
一、做Action相关的准备(Action、JSP、配置):
    1,创建 MyAction extends BaseAction.
    2,定义出Action中的方法,要写出方法名、作用、返回值。
    3,创建出所用到的JSP页面(目前还没有具体内容)。
    4,配置Action:
        1,在MyAction上写注解 @Controller与@Scope("prototype").
        2,在strtus.xml中配置这个Action与所用到的result.
二、做Service相关的准备(接口、实现类、配置):
    1,创建接口MyService extends BaseDao.
    2,创建实现类MyServiceImpl extends BaseDaoImpl.
    3,配置:在MyServiceImpl上写注解:
        @Service 与 @Transactional
    4,声明:在BaseAction中声明:
        @Resource protected MyService myService;
三、填空(Action方法、Service方法、JSP页面):
    1,Action方法。
    2,新增的Service方法。
    3,JSP页面的内容:
        a,拷贝静态页面中的源代码到JSP中。
        b,包含进来公共的资源:
              <%@ include file=“../public/commons.jspf" %>
        c,把 ../ 替换为 ${pageContext.request.contextPath}/
        d,修改页面内容(使用自定义标签)

@Transactional
    可以写在方法上。
        对本方法有效
    可以定在类上。
        对本类中所有public方法有效。
        对子类的中方法有效。
        对父类声明的方法无效。

块操作模式:Shift + Alt + A

       MD5
文本 ------> 摘要

128位二进制 = 16字节 = 32个十六进制

****************************************************************************************************

权限管理模块:
    控制功能的使用。
Web应用中的权限:
    每个功能都有相应的URL地址。
    对功能的控制就是对URL地址的访问控制。
权限方案:
    用户( 多对多 )角色( 多对多 )权限
    用户的权限就是用户的所有角色的权限合集。
    对功能的控制就是对URL的访问控制。
一般的程序中,一个功能只可能对应一个url或者两个url:
    1.例如列表或者删除功能,对应一个url
    2.例如添加或者修改功能,对应两个url:添加或者修改页面,还有提交

 我们实际OA系统中与权限相关的功能具体有哪些?
    这里职位(role)就起到角色的作用。

    初始化数据(只在一开始初始化一次):
        1.权限数据
        2.超级管理员(拥有所有权限,不可更改其权限,不需要为其分配权限)

    分配权限:
        1.给角色分配权限。
        2.用户的权限就是用户所有角色的权限。

    使用权限:
        1.登录、注销、主界面。
        2.左侧的菜单是根据权限显示的。
        3.右侧页面中的连接是根据权限显示的。
        4.拦截每一个action请求,验证用户是否有权限访问。

Struts2中自定义标签:doStartTag()、doEndTag()

每个请求都进行权限验证:
    使用自定义拦截器。

权限分类说明:
    1.要控制的功能:需要登录用户,并且有相应的权限才可以使用。
    2.不需要控制的功能:只要登录就可以使用,需要进行控制,如:注销、使用主页等。
    3.登录功能:需要单独出来,未登录时可以使用。

细节处理:
    登录用户后,在Tomcat重启后还应是登录状态,实现序列化接口。
    登录页面嵌套的问题,使用js实现登陆后自动刷新。

****************************************************************************************************

登录输入用户名和密码错误时:

Action中
    addFieldError("name", "有错了!");

JSP中:
    <s:fielderror fieldName="name"/>
    <s:fielderror/>    显示全部错误消息
****************************************************************************************************

论坛模块:
    流程说明:实现一组功能的步骤:
    1.充分了解需求,包括所有的细节,需要知道要做一个什么样的功能。
    2.设计实体或者表(建议先设计表,以面向对象的角度来设计)
        正向工程:设计实体、映射文件->建表
        反向工程:设计表->映射文件、实体
    3.分析功能:
        分析每个请求。
        得到的结果是我们需要处理多少种请求,其中每种请求对应一个Action方法。
    4.实现功能:
        <1.创建Action,并定义出其中的方法。
        <2.实现Action方法,并创建出所用到的新的Service。
        <3.实现Servcie方法,并穿件出所用到的新的Dao方法。
        <4.实现Dao方法。
        <5.创建并完成JSP页面。
    5.测试、运行。

模块说明:
    1.分页:
        自定义过滤+自定义排序。
        要通用--有列表就要分页。
    2.主题列表的顺序。
    3.主题的类型:普通、指定、精华。
    4.回复列表中有楼层表示:楼主(发帖人)、沙发(1楼)、板凳(2楼)、地板(3楼)、4楼...

功能说明:
    *1.浏览:
        板块列表(版面、讨论区)->主题列表(显示单个板块)->主帖+回复列表(显示单个主题)
        Action配置:
            ForumAction:
                版块列表--一个请求(list)
                主题列表--一个请求(show)
            TopicAction:
                主帖+回复列表--一个请求(show)
                发新帖--两个请求(addUI、add)
            ReplyAction:
                回帖--两个请求(addUI、add)
    *2.参与:
        发帖与回帖
    *3.管理文章(管理员)--(课下完成):
        <1.主题:
            设置类型--修改
            移动到其他版块--删除+增加
            删除
            修改
        <2.回复:
            删除
            修改
    *4.版块管理:
        增删改查
        上下移动(在版块页面的位置)--利用属性position
            查询时要按position值排序。
            position的值要唯一。
            上下移动就是与上面或者下面的Forum交换position的值。    

实现以上功能的顺序:
    1.版块管理
        <1.设计实体。
        <2.分析与实现功能。
    2.其他功能(浏览+参与+文章管理)
        <1.设计实体。
        <2.分析与实现功能。

版块Forum (一对多) 主题Topic (一对多) 回复Reply

实体设计:
    Article: id title content postTime author ipAddr ...    (Article与User关系是一对多)
    <1.content应是text类型。
    <2.有一对一的关联关系。
下面两个继承Article
    Forum: Set<Topic> topicCount articleCount lastTopic
    Topic: Forum Set<Reply> type lastTopic replyCount lastUpdateTime
    Reply: Topic 
两个问题:
    1.主题列表的顺序?
        按时间顺序排列--增加一个特殊属性。
    置顶帖在最上面,其他按更新时间顺序排列。
    2.回帖楼层是否保存?
        由于楼层是不能改变的,增加一个标记,标记是否显示该回帖。

特殊属性:
    Forum:topicCount、articleCount、lastTopic
    Topic:replyCount、lastReply、lastUpdateTime
特殊属性的维护:
    1.发表新主题:
        topicCount(++)、articleCount(++)、lastTopic(更新)
        replyCount(0)、lastReply(0)、lastUpdateTime(主题的发表时间)
    2.发表新回复:
        topicCount、articleCount(++)、lastTopic
        replyCoun(++)t、lastReply(更新)、lastUpdateTime(更新)
****************************************************************************************************

使用FCKedit(第69集):
    1.导入JS文件
    2.写一段JS代码显示FCKedit

fckconfigs可以自己指定工具栏的模式。

****************************************************************************************************
分页:
    两个地方需要使用到分页--主题列表和回复列表。
分页需要显示的数据(准备数据):
    1.本页的数据列表

        <s:iterator value="%{recordList}">
            ...
        </s:iterator>

    2.分页信息(分页信息条)

    页数: %{currentCount}条/%{pageCount}页
    每页显示:%{pageSize}页
    总记录数:%{recordCount}条

    显示页码列表:
        <s:iterator begin="%{beginPageIndex}" end="%{endPageIndex}" var=""num>
            ...
        </s:iterator>    
    共10个页码:
        前4页+当前页+后5页
        首页(1)        first = (currentPage - 1) * pageSize
        末页(页码总数)    max   = pageSize
        pageCount = (recordCount + pageSize - 1) / pageSize;

        总页数小于等于10页,则全部显示
        总页数大于10页
        默认显示当前页附件近的10个页码(前4个 + 当前页 + 后5个)
        前面不足4个页码时,就显示前10个页码
        后面不足5个页码时,就显示后10个页码

    转到...页(下拉列表)
        <select onchange="gotoPage(this.value)">
            <s:iterator begin="1" end="%{pageCount}" var=""num>
                <option value="${num}">${name}</option>
            </s:iterator>            
        </select>

        <script>
            function gotoPage(pageNum){    //用于页面跳转
                window.location.href = "url?pageNum=" + pageNum;
            }
        </script>

页面需要显示的信息有(事先做好准备的数据):
    recordList    本页的数据列表
    currentPage    当前页
    pageCount    总页数
    pageSize    每页显示多少条记录
    recordCount    总记录数
    beginPageIndex    页码列表的开始索引(包含)
    endPageIndex    页码列表的结束索引(包含)
将以上7个信息封装乘一个pageBean。
pageBean = service.getPageBean();
req.setAttribute("",pageBean);

建立QueryHelper来拼接HQL语句:

获取分页信息的公共方法可以设计为:
    public PageBean getPageBean(int pageNum, HqlHelper hqlHelper);

FROM        
    实体名
WHERE
    条件1 AND 条件2 AND ... 条件n
ORDER BY 
    属性1, 属性2, ... 属性n


From子句        必须
Where子句        可选
OrderBy子句        可选

在Hibernate中获取一段数据的方式是:
    Query.setFirstResult(int)
    Query.setMaxResults(int)

****************************************************************************************************

审批流转模块:
    先只做请假功能,请假可以和考勤整合到一起。
    需要存储数据,有状态字段指示。
问题:
    流程多
    流程会有变化
    一变化就要改程序(程序员)
目标:
    不改程序
    即程序中支持用户定制流程与申请模板(用户)
    要有方便好用用户界面。
方案:
    通过上传下载实现定制模板。
    用画图的方式定制流程。
    
实现:
    ?画图程序怎么做(Swing/AWT+Applet,Flex)
    ?制定一个什么样的流程规则
    ?按规则解析与执行流程


===> 工作流框架 / 工作流管理系统
    需要用户定流程的情况(流程多、变化)
使用jbpm工作流框架。
    
****************************************************************************************************

JBPM:
    管理流程(流程定义):
        部署流程定义(添加)。
        查询流程定义(查询)。
        删除流程定义(删除)。
        修改流程定义(修改)--没有真正的修改,而是使用“再次部署+使用最新版本启动流程实例”的方式代替。
        查看流程图(查看xxx.png)。
        
    执行流程:
        启动流程实例
        查询任务列表
        办理任务
        向后执行一步

jbpm中所有的Id都是String型的。

API
    Configuration
        getProcessEngine()
        setResource(String res)
        buildProcessEngine()
    ProcessEngine
        getRepositoryService()
        getExecutionService()
        getTaskService()
        get...Service()

Deployment    部署对象
    说明:
        一次部署的多个文件的信息,通常是有xxx.jpdl.xml和xxx.png这两个文件。
    对应的表:
        jbpm4_deployment
        jbpm4_lob
        jbpm4_deployprop
    
ProcessDefinition    流程定义
    说明:
        解析xxx.jpdl.xml后得到的流程信息,其中包含流程中每个环节以及环节中的详细信息。

ProcessInstance    流程实例
    对应的表:
        jbpm4_execution    正在执行的信息表
        jbpm4_hist_procinst    已执行完的流程实例表
Task    任务
    对应的表:
        jbpm4_task    正在执行的任务表
        jbpm4_hist_task    已执行完的任务表

Activity    活动
    预先定义的活动:
        start    开始活动
        end    结束活动
        state    状态活动
        decision判断活动
        fork/join    分支/聚合活动
        task    任务活动
    自定义的活动:
        Custom + ..Class

在网页中高亮正在执行的活动:
    1.获取当前正在执行的活动名称
        processInstance.findActivityNames()
    2.获取活动对应的坐标
        repositoryService.getActivityCoordinates(processDefinitionId, activityName)
    3.获取流程图片
        repositoryService().getResourceAsStream(deploymentId, resourceName);

任务:
    指定个人任务的办理人的方式:
        1,直接指定:assignee="张三"
        2,使用变量:assignee="#{manager}",变量值是一个字符串
        3,使用AssignmentHandler
            assignable.setAssignee(userId); // 指定个人任务的办理人
        4,直接指定任务的办理人:
            taskService.assignTask(taskId, userId);

    组任务与组任务分配方式:
        1,直接指定:candidate-users="王工程师,李工程师,赵工程师"
        2,使用变量:candidate-users="#{userIds}"
            变量值是一个字符串,多个人之间使用英文的逗号隔开。
        3,使用AssignmentHandler
            assignable.addCandidateUser("小A"); // 添加一个候选人(组任务)
            assignable.addCandidateUser("小B"); // 添加一个候选人(组任务)
            assignable.addCandidateUser("小C"); // 添加一个候选人(组任务)
            
1,组任务:一个任务,很多人都能看到(同一组的人)。
2,先把任务拾取过来,就变成了自己的个人任务,别人就看不到了。
3,如果因事不能继续办理这个任务,可以选择:
    a, 退回到组任务列表,让别人再去拾取与办理。
    b, 直接把任务指定给某人。

不同版本spring配置文件的头信息不一样:
    OA第10天_工作流JBPM:7-在ItcastOA中添加JBPM4的开发环境.avi

****************************************************************************************************

申请流转(利用工作流框架jbpm4.4):
    提交申请 --> 审批
管理:
    审批流程管理:删除流程定义、查询流程定义、部署流程定义、查看流程图。
        对应5个请求方法。
    申请模板管理(上传/下载)
文件上传需要在JSP和Action中设置:
jsp:
    <form method="post" enctype="multipart/form-data">
        <input type="file" name="upload">
    </form>
Action:
    private File upload;    //上传临时文件(在临时文件夹中),要永久保存需要将其挪出,利用下面的两个标量
    private String fileName;    //上传文件的文件名
    private String contentype;    //上传文件的文件类型
    还有对应的getter和setter

**服务器端的文件存储方案:

方案一:存到数据库中(BLOB)。

方案二:存到服务器的某文件夹中(推荐)。
    需要String型的path(相对于服务器的一个相对路径)。
问题:
    文件重名:使用UUID做为文件名,如果需要原始的文件名,则可以存到数据库中(用一个列)。
****************************************************************************************************

<form method="默认为get" ...>

<s:form method="默认为post">

表单采用Post方式提交,解决乱码的方法为:
    request.setCharacterEncoding( myEncoding );

表单采用Get方式提交,解决乱码的方法为:
    方式一:
        key = new String(key.getBytes("iso8859-1"), "utf-8");
    方式二:
        修改server.xml:    URIEncoding="utf-8"
    方式三(不依赖Tomcat的配置,推荐):
        浏览器中两次URL编码。
        服务器中自己再做一次URL解码。

<s:a action="processDefinitionAction_delete" onclick="return delConfirm()">
    <s:param name="key" value="%{@java.net.URLEncoder@encode(key, ‘utf-8‘)}"></s:param>    
    删除
</s:a>

%{@java.net.URLEncoder@encode(key, ‘utf-8‘)}

‘中字‘的编码:
iso8859-1
utf-8            E4 B8 AD
gbk/gb2312        D6 D0

****************************************************************************************************
审批流程:
    第1个环节是“提交申请”,以后基本上都是“审批”环节。

约定:
    1,第一个环节一定要是“提交申请”,并且办理人是当前登录的用户。
    2,在JBPM中是使用一个字符串作为用户标识符,在ItcastOA中是User对象,不匹配。
        可以使用User中一个不会有重复值的字段转为String交给JBPM用。
        我们的User可以使用User.id.toString()或User.loginName。
        在这里,我们约定使用User.loginName作为JBPM中所用的用户标识符。
    3,在提交申请环节生成的信息要求在后面的环节中都能够方便的获取到。
        这是使用流程变量实现的。
        所有申请的信息都封装到一个application中了,所以只需要设置这个变量,key为"application"。
        要求在提交申请的环节就要设置这个变量。
    4,第一个环节“提交申请”的办理人应写为:
        assignee="#{application.applicant.loginName}"

 

12天OA项目,布布扣,bubuko.com

12天OA项目

标签:style   blog   color   java   使用   os   io   文件   

原文地址:http://www.cnblogs.com/mosquito-woo/p/3910130.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!