='"+shireDate+"'");}查询结束后将查询到的信息封装到employee对象中,添加到list集合员工信息删除操作:与部门删除操作大致相同,SQL语句:String sql = "delete from employee where empid = ?";注意:删除成功后跳转页面不能跳转到当前页面,而是跳转到执行查询操作,重新进行一次员工信息查询,不能使用转发,因为两个方法中都包含String empId = req.getParameter("empId");会使数据接收意外共享,改用重定向或者在删除操作中定义不同的值即可员工信息更新操作:与部门更新相似,先做查询,再做修改提交,SQL语句:String sql = "update employee set password=?,deptno=?,posid=?,mgrid=?,realname=?,sex=?,birthdate=?,"+" hiredate=?,leavedate=?,onduty=?,emptype=?,phone=?,qq=?,emercontactperson=?,idcard=? where empid=?";注意:修改时的用户名不能被修改,要加上readonly属性对于性别属性以及是否在职属性,要加上判断,根据判断条件来分别添加checked属性登录操作:数据访问层步骤:1.获取登录信息(用户名、密码)2.调用业务层完成操作 3.页面跳转(成功重定向到操作系统界面,失败报出错误 信息,并且请求转发至登录界面)业务层:分两步判断登录是否成功。"/>
Home
>
办公自动化 发展史
>
jsp办公自动化系统
jsp办公自动化系统

time:2020-07-25 11:20:09

author:重庆佰鼎科技有限公司

【Font size: big medium smail

本文由重庆佰鼎科技有限公司提供,重点介绍了jsp办公自动化系统相关内容。重庆佰鼎科技有限公司专业提供办公自动化 发展史,办公自动化软件合同,办公自动化word教程等多项产品服务。公司的产品服务被广泛应用于其专属行业,市场覆盖率高,售后保障良好,质量高,价格低。

jsp办公自动化系统OA项目总结:

关于JSP、MVC、Servlet贯穿案例OA系统:

OA:办公自动化(收支、考勤、报销、审核、查看部门和员工)

1.首先根据导入的项目中html给定的样式确定需要实现的功能(部门管理、员工管理、员工上下级之间的关系、签到签退功能、考勤管理(包括导出功能poi插件)、报销信息、待审报销、审核报销、收支管理(对于收入统计和支出统计使用echarts插件)等操作)

2.导入项目所需的sql表:部门表dept、员工表employee、岗位表position、考勤表duty、报销单表expense、报销单明细表expenseitem、报销单审核表auditing、收入表income、支出表payment

3.搭建项目框架:创建oa项目(web project)并修改workspace统一编码为utf-8,接下来创建MVC分层对应的几个层:分别为dao、pojo、service、servlet、util(可以按需要选择添加test层用作测试编写的代码:new-sourceFolder创建文件夹,文件夹下可以与src有同名的包,但不能有同名的文件),在webroot下创建对应表的文件夹,用来存放表对应的jsp页面

导入jar包:gson、ojdbc和log4j(放入webinf中的lib),在myeclipse中创建Junit的jar包(buildpath-添加类库-添加Junit)

加入工具类:dbutil

加入数据库连接文件:jdbc.properties

加入BaseServlet

加入界面原型:js、css、html等(文件报错:右键选择myeclipse-exclude忽略错误信息)

4.实现功能:

添加部门功能:1.根据sql中dept表信息创建实体类Department,包含dept表中对应的字段信息

2.dao层创建DepartmentDao接口,并创建添加部门方法,返回值为int

3.dao层impl创建DepartmentDao接口的实现类,添加接口中定义的方法(编写sql语句,调用dbutil工具类实现添加部门)

4.service层中接口定义添加方法,并且在实现类访问dao层对象调用添加方法

5.servlet层:1.接收视图层的表单数据 2.调用业务层完成添加操作 3.根据结果跳转到不同的页面(如果需要把信息放在request中,跳转必须使用转发,因为要复用保存在request中的数据)(request.getContextPath()方法动态的获取上下文数据)

6.视图层:添加form表单,method属性必须是POST,并在左侧菜单(left.jsp)中修改添加部门的url

注意:如果出现没有找到该add方法,注意查看自己的方法修饰符是否为public,不可以是protected,表单提交成功,使用重定向,可以避免表单的重复提交

查询部门信息:逻辑:页面上请求查询所有部门信息,将该请求发送至servlet层,servlet接收到请求后,调用service方法,service层再调用dao层,查询到信息后dao层返回数据给service层,service返回给servlet层,servlet返回给视图层jsp页面,服务器解析jsp,在前端页面上展示

代码实现:servlet调用service层方法后返回的是list集合,用来存储查询到的部门数据,查询的dao层实现类的代码与添加方法不同(步骤:1.建立和数据库的连接 2.创建sql命令发送器 3.使用sql命令发送器发送sql命令给数据库,并得到返回的结果4.处理返回结果(取出各个字段的值、将当前各个字段的值封装到实体类对象中,将实体类放入实体类集合list))

视图层:采用jstl(<%@taglib prefix="别名" uri="核心uri"%>)中的foreach循环遍历获取到的集合数据(注意:items属性要填写el表达式,不要写字符串)

删除和修改部门信息:删除方法中需要传参(id),根据id删除对应的数据信息,最后界面的跳转跳到查询方法在当前页面重新执行查询操作(删除提醒操作:jsp页面添加删除方法)

删除逻辑:页面发出删除请求,servlet接收删除请求,调用service层,service层调用dao层进行删除操作,dao层得到返回值传递给service层,service层传给servlet层,调用一次查询方法,再返回给jsp页面,最后在前端页面展示数据信息

实现更新方法需要首先定义根据id查询的方法,查询到对象数据后附带信息跳转到更新页面(注意id的只读),更新成功跳转到查询操作,更新失败跳转到更新页面

添加员工功能:实现员工上下级(数据库中使用外键实现),在java类中使用属性的关联来实现(定义department实体类的对象,不仅包含部门编号,同时也包含其他信息)

注意:对于Date方法,导入的包是util包,实际使用应该new java.sql.Date(对象.getDate类型().getTime()),在获取Date类型的信息时,返回值类型定义为字符串时,使用SimpleDateFormat()方法转换,再用parse方法解析,赋值给需要的时间字段即可

servlet层步骤(1.获取员工的信息 2.调用业务层完成添加操作 3.根据结果进行页面跳转)

对于离职日期报空指针异常:加判断,如果不为空时调用getTime方法

jsp页面中的直接上级下拉框:使用foreach循环遍历上级数据集合,放在select标签中,赋值给option标签的value属性

日历插件:导入My97DatePicker包,,添加事件使用onfocus属性调用WdatePicker()方法

字体插件:导入kindEditor包,使用KE.show()方法

查询员工信息功能:注意sql语句的编写:

String sql = "select e.empid,e.deptno,e.posid,e.mgrid,e.realname,e.sex,e.hiredate,"

+" e.phone,d.deptname,p.pname,mgr.empid,mgr.realname"

+" from employee e"

+" join dept d"

+" on e.deptno = d.deptno"jsp办公自动化系统

+" join position p"

+" on e.posid = p.posid"

+" join employee mgr"

+" on e.mgrid = mgr.empid";jsp办公自动化系统

如果使用多条件查询员工信息:使用sql语句的拼接进行查询

调用Sql.append()方法:

StringBuilder sql =new StringBuilder( "select e.empid,e.deptno,e.posid,e.mgrid,e.realname,e.sex,e.hiredate,"

+" e.phone,d.deptname,p.pname,mgr.empid,mgr.realname"

+" from employee e"

+" join dept d"

+" on e.deptno = d.deptno"

+" join position p"

+" on e.posid = p.posid"

+" join employee mgr"

+" on e.mgrid = mgr.empid where 1=1");

if(empId2 != null && !"".equals(empId2)){

sql.append(" and e.empid like '%"+empId2+"%'");

}

if(deptno2 != 0){

sql.append(" and e.deptno="+deptno2);

}

//if(){

sql.append(" and e.onDuty ="+onDuty);

//}

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

if(hireDate2 != null){

String shireDate = sdf.format(hireDate2);

sql.append(" and to_char(e.hiredate,'YYYY-MM-DD') >='"+shireDate+"'");

}

查询结束后将查询到的信息封装到employee对象中,添加到list集合

员工信息删除操作:与部门删除操作大致相同,SQL语句:String sql = "delete from employee where empid = ?";

注意:删除成功后跳转页面不能跳转到当前页面,而是跳转到执行查询操作,重新进行一次员工信息查询,不能使用转发,因为两个方法中都包含

String empId = req.getParameter("empId");

会使数据接收意外共享,改用重定向或者在删除操作中定义不同的值即可

员工信息更新操作:与部门更新相似,先做查询,再做修改提交,SQL语句:

String sql = "update employee set password=?,deptno=?,posid=?,mgrid=?,realname=?,sex=?,birthdate=?,"

+" hiredate=?,leavedate=?,onduty=?,emptype=?,phone=?,qq=?,emercontactperson=?,idcard=? where empid=?";

注意:修改时的用户名不能被修改,要加上readonly属性

对于性别属性以及是否在职属性,要加上判断,根据判断条件来分别添加checked属性

登录操作:数据访问层步骤:1.获取登录信息(用户名、密码)2.调用业务层完成操作 3.页面跳转(成功重定向到操作系统界面,失败报出错误 信息,并且请求转发至登录界面)

业务层:分两步判断登录是否成功。先比较用户名,再比较密码

验证码:用作保护,防止恶意入侵、破解密码等。

使用java图形界面技术生成验证码(项目中为RandomServlet.java),jsp中使用img标签显示验证码

实现思路:接收用户输入的验证码,获取到正确的验证码后,比较两个验证码,如果不同,跳转回登录页面

签到签退功能:当前登录的用户进行签到签退操作,向duty考勤表添加或修改数据,签到成功对应的SQL语句:

String sql = "insert into duty values(seq_duty.nextval,?,?,?,null)";

用户进行签退操作,签退成功对应的SQL语句:

String sql = "update duty set signouttime = ? where empid = ? and dtdate = ?";

签到签退按钮绑定单击事件,不需要实现页面的跳转,直接返回结果,定义一个结果result,根据data判断是否重复签到,对result内容执行不同的操作(注意jq的导入),签退可以重复执行,执行签退前判断是否执行过签到操作,后签到的时间会覆盖之前签退的时间,以最后一次签退时间为准

注意:序列的创建以及在sql语句中的调用,ajax的使用“$.ajax()”

系统当前时间的获取:

Date now = new Date();

java.sql.Date today = new java.sql.Date(now.getTime());

java类中定义的Date类型是导入util包中的Date,在与数据库进行连接时,需要将其转化为java.sql.Date类型

注意:对于基层员工和管理层,进入操作系统的界面是不同的,使用if判断将两种区分开

考勤管理功能(考勤表查询操作):servlet层中获取到部门(获取到dept对象后使用Gson中的toJson转译成Json格式),使用ajax获取所有的部门列表(eval方法将json字符串转换成js,然后通过循环拼接所有的部门。注意:使用部门数组的下标来获取单个部门对象输出对象的编号以及名称)

考勤管理的条件查询:首先进行三个表的关联,后通过判断执行SQL语句的拼接完成对应的查询操作

三表关联:

StringBuilder sql = new StringBuilder( "select dt.*,e.deptno,e.realname,d.deptname from duty dt "

+" join employee e on dt.empid = e.empid"

+" join dept d on e.deptno = d.deptno where 1=1");

sql语句的拼接使用append方法,为sql语句拼接不同的条件:

if(empId != null & !"".equals(empId)){

sql.append(" and dt.empId= '"+empId+"'");

}

if(deptno != 0){

sql.append(" and e.deptno="+deptno);

}

if(dtDate != null){

DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

String sdtDate = sdf.format(dtDate);

sql.append(" and to_char(dt.dtdate,'YYYY-MM-DD')>='"+sdtDate+"'");

}

注意sql语句中to_char的格式和使用

导出功能:使用POI导出,导入poi-3.9-20121203.jar这个jar包,复制其中的方法,填充表格内容

response.setContentType("application/vnd.ms-excel");

response.setHeader("Content-disposition" , "attachment;filename=duty.xls" );

附件形式下载,存储为duty.xls文件

注意:导出操作不需要使用ajax(回调函数处理结果),导出xls是直接返回流,也不需要使用转发和重定向

报销:两个实体类:报销表和报销明细表

添加报销单操作:获取当前用户的用户名和真实姓名,自动获取当前用户的上级,填写到“审批人”中,保存后在expense表中添加一条数据信息,同时在其对应上级的待审报销中添加一条对应的信息

在接收数据明细时,定义三个对应的数组存放数据信息,再通过下标获取存储信息,使用for循环输出封装到每个明细表对象中,最后添加到itemList集合中

DBUtil2中的ThreadLocal:

定义一个threadlocal变量,存放的是connection,保证dao层多个dml操作用的都是这一个连接,保证这些操作是一个事务

可以保证在同一个线程中,不同层次、不同方法都使用threadlocal的connection,使用的是同一个connection

JavaSE中每启动一个main就开启一个线程,主线程可以再开启其他线程

JavaEE中每个请求就是一个线程(servlet----service----dao)

使用ThreadLocal可以存储某个变量的副本,让同一个线程中不同方法共用

将Connection放入TheadLocal可以实现不同层次、不同DML操作使用同一个Connection

待审报销:下级添加报销单信息,会在自己的待审报销中添加一条对应的信息,审核完成后审核人变更,该条待审报销单不会在自己的待审中显示(在ajax中添加data判断,如果审核成功,调用window.opener.location.reload()方法刷新父窗口)

报销单审核:分为通过、拒绝和打回三种情况:如果通过,则把该待审报销转移到财务的待审报销中,如果拒绝则审核结束,如果打回,则需要下级重新提交报销单信息

收支操作:收支统计使用echarts插件echarts.min.js,在前端页面展示柱状图和饼状图

查询收入操作:SQL语句:String sql = "select ictype,sum(amount) from income group by ictype";

支出操作:财务审核成功后,在支出表中添加一条支出信息,根据支出表信息调用echarts生成饼状图

String sql = "insert into payment values(seq_payment.nextval,?,?,?,?,?)";

Object [] params = {pm.getPayEmpId(),pm.getAmount(),new java.sql.Timestamp(pm.getPayTime().getTime()),pm.getExpId(),pm.getExpEmpId()};

在官网挑选合适的图形案例,把案例内容拷贝,进行内容的填充

payment表的条件查询:基础SQL语句:

StringBuilder sql = new StringBuilder( "select item.type,sum(item.amount)"

+" from payment pm"

+" join expense exp"

+" on pm.expid = exp.expid"

+" join expenseitem item"

+" on exp.expid = item.expid"

+" where 1=1");

进行sql语句的拼接:

if(type == 1){

sql.append(" and to_char(paytime,'YYYY-MM-DD HH:MI:SS') > '"+DateUtil.getNowMonthBeginTime()+"'");

}else if(type == 2){

sql.append(" and to_char(paytime,'YYYY-MM-DD HH:MI:SS') <= '"+DateUtil.getNowYearEndTime()+"'");

sql.append(" and to_char(paytime,'YYYY-MM-DD HH:MI:SS') > '"+DateUtil.getNowYearBeginTime()+"'");

}else if(type == 3){

sql.append(" and to_char(paytime,'YYYY-MM-DD HH:MI:SS') <= '"+DateUtil.getLastYearEndTime()+"'");

sql.append(" and to_char(paytime,'YYYY-MM-DD HH:MI:SS') > '"+DateUtil.getLastYearBeginTime()+"'");

}

sql.append(" group by item.type");

sql.append(" order by item.type");

注意:DataUtil工具类的导入,拼接前的sql语句先在数据库中执行一下,测试是否出结果

Reprint please indicate:http://www.cnsoftweb.com/bgzdh-3170.html