Skip to content

Aric-Sun/vsbo_oa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

爱博网OA

1. 项目介绍

项目名称:爱博OA

技术介绍:SpringMVC, Spring, Mybatis, MySQL, Tomcat, JSP, EL, JSTL, 声明式事务

开发环境:JDK8, Tomcat 9.0.41, MySQL8.0.17, IDEA2019, Spring4.2, Mybatis3.2.8

功能模块:部门信息管理, 员工信息管理,报销单处理

角色分析:员工,部门经理,总经理,财务

2. 用例分析

员工用例图

审批者用例图

3. 核心业务分析

项目的核心业务是报销流程,主要的过程是:填写,提交,审核,打款;

员工提交保险单推送到部门经理;

部门经理对报销单审核,可能出现的结果是通过,拒绝,打回;

报销单处理流程

4. 数据库设计

ER图

  1. 部门表department:描述部门相关内容; 列名:d_id, dname, address ;

  2. 员工表employee:描述员工相关信息; 列名:e_id , password, ename, job, d_id ;

  3. 报销单expense_account:总的报销单信息; 列名:ea_idcause, create_time, total_money, statuscreater_id, next_handler_id ;

  4. 报销单明细expense_detail:报销单是由一个一个的款项构成的,明细表主要是记录一笔一笔的款项; 列名:ed_id, type, money, description, ea_id;

  5. 处理记录表deal:整个报销的流程设计多个人,每个人的处理时间和流程都需要去记录下来; 列名:deal_id, deal_time, deal_type, deal_result, comment, ea_id, e_id;

5. 项目结构

新建maven项目,使用MVC的开发模式进行分层设计。

包结构说明:

  • Pojo - 实体类
  • Utils - 工具类
  • Controller - 控制器相关
  • Service - 业务逻辑接口
  • ServiceImpl - 业务逻辑的实现
  • Mapper - 持久层接口

6. 项目整合

  1. 建库建表,根据上面提供的表设计,在数据库中新建相关表的字段;

  2. 新建项目,新建项目结构,根据MVC的开发模式,创建包结构;

    Maven-3.6.1 , setting - 配置文件, - 地址

    注意:

    1. 如果你使用的是maven新建项目的话一定要选择maven-archetype-webapp, 不然后面会报错。
    2. 最好选择自己本地的maven,还有自己的配置文件。
    3. 选择这个骨架建好项目之后,默认是没有java和resources文件夹的,需要自己在main下面新建java和resources。
    4. 生成的index.jsp不是真正的jsp页面,上面少了声明,可以随便新建一个页面,复制一行就可以了。
  3. 引入依赖,分别引入项目所需要的依赖;spring,mybatis, springmvc和各自的依赖包。

  4. 在resources中进行配置文件编写,编写三个框架需要的配置文件和数据源信息。 配置文件包括:applicationContext.xml, springmvc.xml, mybatisConfig.xml, db.properties , log4j.properties, web.xml 。

  5. 根据数据库的内容,创建pojo对象。

  6. 部署测试,可以先创建一个pojo的实体类,测试ssm框架是否已经搭建完毕。比如获取一个员工信息或者获取一个部门信息都行。

7. 实施过程

1. 实施前准备

  1. 在正式的实施之前,请确保所有的数据库已经创建,所有的实体类信息创建,注意:数据库表和实体类的映射关系。
  2. 将素材中静态资源中的assents, js, vendor文件夹复制到web-app下,并且保证路径没有问题,注意:引入后要将oa改成自己的项目名。
  3. 在工具包下新建常量类Content,这个常量类中保存了一些固定值,常量一般使用大写,比如职务(4个),报销类型,报销单状态,处理方式等。

2. 部门管理

Department部门管理其实就是对部门进行增删改查的操作。

具体的实施步骤:

  1. 新建实体类Deptment;
  2. 编写mapper接口以及对应的sql映射文件并完成sql语句的编写;
  3. 编写控制器和业务层的代码;
  4. 页面处理,以查询所有为例,将三层代码联通;
  5. 添加部门,添加其实是由2个部分构成,一个是到添加页面,二是完成添加数据到数据库的功能;
  6. 修改部门,修改和添加类似,先发送请求到后台,根据编号查询到数据之后在页面回显,然后更新部门信息,显示部门列表;
  7. 删除部门,点击删除时先给个提示,确认删除嘛?确定的话就是删除部门然后回到列表,取消的就什么都不用做。

3. 员工管理

Employee员工管理,核心是针对员工相关的操作,查询所有员工信息,新增员工,删除员工,修改员工信息。

实施步骤:

  1. 新建实体类Employee;
  2. 编写mapper接口和三层结构,以及对应的mapper,并完成简单的sql语句编写(以查看所有员工为例);
  3. 查询所有员工信息,注意返回的数据中应该是包含了员工信息以及对应的部门名称;
  4. 添加员工,分2个步骤,
    1. 先到添加页面,在添加页面中需要显示所有部门的名称和职务的名称;
    2. 完成添加的功能,注意:部门传递是部门的编号,添加员工时可以为员工添加默认的密码,MD5对默认密码进行加密。
  5. 编辑用户,分为2步;
    1. 先查出当前用户的信息,部门信息,职位信息等存储到域中,然后回显到修改的页面;注意密码在这里不能修改,可以使用隐藏域;
    2. 完成修改的功能;注意工号不能修改,密码也不是在这里修改的,所以sql语句书写的时候要小心;
  6. 删除员工信息,在删除之前需要给个提示,确定才能删除,注意id的携带;

4. 登录及个人中心

这个模块主要涉及到的功能是登陆,退出,个人信息和修改密码,登陆拦截器等功能,需要注意的是在这个模块中需要对用户的登陆状态做判断。

  1. 登陆功能,2个部分构成,第一就是到登陆页面,第二就是完成登陆的功能,完成登陆功能后需要将用户名存储在session中,然后到个人中心;登陆失败给出提示;

  2. 个人中心,点击个人中心时,到个人中心页面,然后从session中将登陆用户的信息获取展示即可;

  3. 登陆拦截器,除了登陆页面,其他所有的功能都需要登陆之后才能操作,需要编写一个登陆拦截器,实现HandlerInterceptor, 主要是编写访问前的拦截方法

    登陆拦截器有3个核心:

    1. 判断用户的访问路径是否含有login和index关键字,如果有则说明在登陆,放行;

    2. 判断该用户是否已经登陆(session中是否有用户信息),如果已经登陆放行,如果既没有登陆也没有访问login的话,则将该请求重定向到登陆页面,让其登陆后在进行其他的操作,

    3. 编写好的拦截器并不会生效,需要在springmvc.xml中进行如下的配置才可以对所有的请求进行拦截。

      <mvc:interceptors>
          <mvc:interceptor>
              <mvc:mapping path="/**"/>
              <bean class="拦截器的路径"></bean>
          </mvc:interceptor>
      </mvc:interceptors>
    4. 修改密码,和其他功能一样,先到修改页面,然后完成修改的功能,需要校验原密码是否正确,2次新密码是否一致;

    5. 退出,退出时只需要将session的emp移除或者设置为null即可,退出后需要到登陆的页面;

5. 报销单处理

这是最核心的一个模块,涉及到的功能有:

  1. 报销单相关:新增报销单,修改报销单,删除报销单(根据编号),查询报销单(根据编号),查询某个创建者的所有报销单(员工编号),查询某个人的待处理报销单(员工编号);

  2. 报销单明细:新增明细,修改明细,删除明细,根据报销单查询该报销单的所有的明细;

  3. 处理记录:新增处理记录,根据报销单编号查询该报销单的所有的处理记录;处理记录类似于日志,不能删除和修改,只能新增和查看;

1. 报销单的准备工作

新建报销单,报销单明细,处理记录表的对应实体,三层架构,以及对应的xml文件;

2. 填写报销单

填写报销单,2步骤,先到填写页面,然后完成报销单的新增,完成新增之后页面跳转到报销单详情页面;

思路:需要三个控制器,1个是跳转到去填写页面,1个是填写之后的保存功能,还有1个是保存完成之后页面跳转到详情页面;

步骤:

  1. 报销单信息包含2个部分,一个是报销单基本信息的添加,另一个是报销单明细(集合)的添加;注意:

    1. 到报销单填写页面时,需要有报销费用类型的下拉框,需要从常量类中获取,携带到页面,遍历展示;
    2. 需要收集的数据比较特殊,可以声明一个dto类(ExpenceAccountInfo),类中有2个属性,一个是报销单,一个是明细集合,主要用于收集数据; 保存报销单在业务层分2步,一个是报销单基本信息的添加(其他信息在业务层补齐),一个是报销单明细的添加,操作的是2张不同的表, 需要在一个事务中;
    3. 新增报销单时(注意jsp中name的值),在表现层从info中将报销单和明细分开传递,并设置创建者编号(就是登陆用户,可以从session中获取);
    4. 在报销单业务层需要设置创建时间(当前时间),报销单状态(新建状态),下一个处理人编号(就是当前登陆用户自己);
    5. 报销单明细表新增的时候需要关联具体的报销单,所以新增报销单完成后必须要返回主键, 方便后面明细表的插入;
    6. 报销单明细是个集合,可以使用循环遍历,遍历出来的每一个对象都调用报销单明细新增的方法进行插入操作(注意设置关联的报销单编号);
  2. 完成报销单和明细添加之后,需要发一个进入报销单详情页面的请求(直接重定向即可),到明细页面需要进行查询的操作,在重定向时要将当前报销单编号进行传递;

  3. 在报销单业务层分别定义三个方法查询需要在页面上展示的内容,然后在报销单的表现层分别调用方法,并存储到域对象中,这三个方法都根据报销单编号查询

  4. 报销单明细页面中有三部分内容,一是报销单基本信息(注意sql语句的别名问题和返回值Map的封装),二是报销单明细(返回报销明细的集合),三是这个报销单的处理记录(处理记录得集合,和员工表关联,注意封装类型),注意时间格式,可以引入jstl的fmt:formatDate标签进行时间格式化,类型选择time即可;

3. 个人报销单、待处理报销单

这个模块主要是实现2个方法,一个是我自己填写的所有的报销单,第二个是我需要处理的报销单;

这两个方法都是应该返回一个集合,然后在列表中显示

步骤:

  1. 在报销单的Mapper中声明2个方法,1个是根据员工编号查询自己填写的报销单,查询结果返回一个集合;可以从session中获取当前登陆用户信息;另1个是我需要处理的报销单列表,也是根据员工编号进行查询,同样返回一个集合列表,

  2. 编写XML中的SQL语句,注意个人报销单和待处理报销单查询的结果类型应该使用HashMap来进行封装;

  3. 将查询到的结果存储在域中,并且在页面中显示,用户可以进行从操作有:修改,提交,详情,审核,打款,针对不同的状态可以进行的操作如下:

    1. 在判断之前需要使用jsp的page指令将常量类引入进来<%@ page import="Constent全路径" %>
    2. 如果报销单状态是新建或者已打回的,可以的操作有:修改,提交;
    3. 如果报销单的状态是已提交或者待复审的,可以的操作有:审核;
    4. 如果报销单的状态是已审核的状态,可以进出的操作是:打款;
    5. 任何状态下都可以进行的操作是:详情;

4. 提交报销单

在填写报销单的时候,这个报销单的已经新增到数据库中了,此时提交的话只需要将报销单的状态修改已提交,下一个处理人会发生变化,其实做的是一个更新操作;

步骤:报销单提交时,只需要提交一个报销单的ID,其他的数据在数据库中都已经存在,只需要修改部分内容即可;

  1. 在报销单Mapper中提供一个方法,根据提交报销单得编号,获取当前报销单对象;(其目地是获取报销单对象中的创建者编号,创建者编号其实就是员工编号);
  2. 在员工的mapper中提供一个方法,根据员工编号(保险单的创建者就是员工编号)来获取员工对象,目的是获取员工所在的部门,最终得到部门经理(和创建者是在同一个部门,职位是部门经理的那个员工);
  3. 在报销单业务层的提交报销单方法中,先获取保险单对象,再获取创建者,然后获取部门经理,修改报销单状态,将新创建的状态修改为已提交状态;
  4. 修改下一个处理人的ID,新创建的报销单由创建者处理,提交之后的报销单由部门经理进行审核,此时下一个处理者应该是部门经理的ID;
  5. 以上操作完成之后,直接调用报销单mapper接口中update方法即可,更新报销单中的相关内容。
  6. 处理记录保存:添加一条处理记录,处理时间就是当前时间,处理方式/类型是提交操作(常量类中获取),报销单编号就是接受参数,处理人就是当前员工编号,处理结果就是提交报销单(常量类中获取),备注可以自己添加默认的也可以无, 设置完上面几个属性后,调用处理记录的mapper,将这个记录新增到表中;
  7. 在报销单的控制器中编写一个处理提交请求的方法,该方法接受一个报销单编号,然后调用业务层的提交方法即可,执行完成之后,回到待处理页面即可!

5. 报销单处理

点击待处理报销单,会出现所有的需要当前登陆用户处理的报销单;点击审核后可以对报销单进行处理操作;

报销单的审核其实就是修改报销单的状态以及新增处理流程的操作;根据不同的角色页面出现不同的操作;

部门经理或者总经理具有的权限是:通过,打回,拒绝

财务具有的角色是:打款

注意:不同的操作的结果和是否需要复审

  1. 点击审核页面,查询当前报销单信息(基本信息,具体条目信息(明细),处理记录)回显到审核页面(详情页面和详情页很相似);
  2. 根据角色判断可以进行的操作,
    1. 部门经理和总经理可以进行的操作:通过,打回,拒绝
    2. 财务可以进行的操作是:打款
  3. 审核的实现步骤(通过,打回,拒绝)
    1. 页面点击审核或者打款时,发出请求跳转到处理页面,页面中显示该报销单所有数据(基本信息,明细信息,处理记录)等,和去详情页的控制器方法类似;

    2. 页面中的三个按钮都带有对应的处理方式,点击按钮时携带对应的处理方式,在控制器中还需要报销单编号(可以设置一个隐藏域进行传递)

    3. 在报销单控制器中处理审核的方法中需要接受2个参数,1个是报销单编号,1个是处理方式,另外要从session中获取当前登陆用户,这次的处理人编号就是这个登陆用户的员工编号;

    4. 控制器中获取到传递的2个参数以及获取到当前登陆用户后,调用业务层的审核方法,在业务层中做其他内容的设定和判断

    5. 在业务层审核的操作无非就是通过,拒绝,打回操作,根据不同的处理方式分情况判断即可:

      1. 第一步先根据报销单编号获取报销单对象信息,只需要简单的一个报销单对象即可;创建一个处理记录对象,不管做什么操作都需要新增一个记录,并设置处理方式,处理时间,报销单编号,处理人编号(当前登陆用户)

      2. 如果处理方式通过:通过的话有2中种情况

        1. 第一是金额小于5000或者当前审核者的职务是总经理,则审核之后状态就设置为已审核,下一个处理人编号变为财务,处理记录中的处理结果就说报销单状态,设置为已审核;
        2. 第二种情况就是金额大于5000的,这样就将状态设置为待复审,下一个处理人设置为总经理,处理结果和报销单状态一致为待复审
      3. 如果处理方式**打回:**则需要将报销单状态设置为已打回,下一个处理着为创建者(可以通过报销单对象获取创建者编号),处理结果和报销单状态一致

      4. 如果处理方式为**拒绝:**设置报销单状态为已终止状态(失败),下一个处理人就没有了,可以设置为0或者null, 处理结果和报销单状态一致为已终止状态

      5. 如果处理方式为打款操作,设置报销单状态为已打款状态(成功),下一个处理人也没有了,设置为null或者0 ,处理结果和报销单状态一致为已打款状态

      6. 所有判断都完成之后,在最后对报销单进行更新操作,对处理记录表进行新增操作

      7. 完成上面的操作之后,重定向到待处理报销单页面