接上一个
开发多级审批流程


设计约束
每一个请假单对应一个审批流程
请假单创建后,按业务规则生成部门经理、总经理审批任务
审批任务的经办人只能审批自己辖区内的请假申请
所有审批任务"通过",代表请假已经批准
任意审批任务"驳回"操作,其余审批任务取消,请假申请被驳回
请假流程中任意节点产生的操作都要生成对应的系统通知

请假申请表


请假流程表


请假通知表


相关的实体类都进行创建

请假单接口的创建

public interface LeaveFormDao {public void insert(LeaveForm form);public List<Map> selectByParams(@Param("pf_state") String pfState,@Param("pf_operator_id") Long operatorId);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace与包名一致-->
<mapper namespace="com.imooc.oa.dao.LeaveFormDao"><!--id与方法名对应parameterType与方法参数类型对应resultType与方法返回类型对应--><insert id="insert" parameterType="com.imooc.oa.entity.LeaveForm"useGeneratedKeys="true" keyProperty="formId" keyColumn="form_id">INSERT INTO adm_leave_form(employee_id, form_type, start_time, end_time,reason, create_time, state)VALUES (#{employeeId}, #{formType}, #{startTime}, #{endTime},#{reason}, #{createTime}, #{state})</insert>
</mapper>

在配置文件中进行注册
剩下两个表的操作都一样

开发请假功能
请假单流程服务和消息提示 LeaveFormService

 public LeaveForm createLeaveForm(LeaveForm form) {LeaveForm savedForm = (LeaveForm) MybatisUtils.excuteUpdate(sqlSession -> {//1.持久化form表单数据,8级以下员工表单状态为processing(正在审批) ,8级(总经理)状态为approved(审批通过)EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);Employee employee = employeeDao.selectById(form.getEmployeeId());//传入员工编号 获取员工信息// 判断请假单审批状态if (employee.getLevel() == 8) {form.setState("approved");//审批通过} else {form.setState("processing");//正在审批}LeaveFormDao leaveFormDao = sqlSession.getMapper(LeaveFormDao.class);// 将当前状态写入请假表单中leaveFormDao.insert(form);//2.增加第一条流程数据,说明申请人的表单已提交,状态为complete(正在处理)ProcessFlowDao processFlowDao = sqlSession.getMapper(ProcessFlowDao.class);ProcessFlow flow1 = new ProcessFlow();flow1.setFormId(form.getFormId());//表单编号flow1.setOperatorId(employee.getEmployeeId());//经办人编号,这里应该是自己的编号flow1.setAction("apply");//申请flow1.setCreateTime(new Date());flow1.setOrderNo(1);//任务序号flow1.setState("complete");flow1.setIsLast(0);//是否为最后一个流程processFlowDao.insert(flow1);//3.分情况创建其余流程数据//3.1 7级以下员工,生成部门经理审批任务,请假时间大于36小时,还需生成总经理审批任务SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH时");NoticeDao noticeDao = sqlSession.getMapper(NoticeDao.class);/*普通员工请假<72小时 部门经理审批>72小时 部门经理审批通过,还需要总经理审批*/ if (employee.getLevel() < 7) {// 获取上级对象Employee dmanager = employeeDao.selectLeader(employee);// 创建部门经理审批流程ProcessFlow flow2 = new ProcessFlow();flow2.setFormId(form.getFormId());flow2.setOperatorId(dmanager.getEmployeeId());flow2.setAction("audit");//审批flow2.setCreateTime(new Date());flow2.setOrderNo(2);flow2.setState("process");//正在处理long diff = form.getEndTime().getTime() - form.getStartTime().getTime();float hours = diff / (1000 * 60 * 60) * 1f;// 大于72小时需要再创建一个总经理审批流程if (hours >= BussinessConstants.MANAGER_AUDIT_HOURS) {flow2.setIsLast(0);processFlowDao.insert(flow2);Employee manager = employeeDao.selectLeader(dmanager);ProcessFlow flow3 = new ProcessFlow();flow3.setFormId(form.getFormId());flow3.setOperatorId(manager.getEmployeeId());flow3.setAction("audit");//审批flow3.setCreateTime(new Date());flow3.setState("ready");//准备审批flow3.setOrderNo(3);//任务序号flow3.setIsLast(1);//为最后节点processFlowDao.insert(flow3);} else {flow2.setIsLast(1);processFlowDao.insert(flow2);}// 创建请假单用户的提示消息// 请假单已提交信息String noticeContent = String.format("您的请假申请[%s-%s]已提交,请等待上级批准.",sdf.format(form.getStartTime()), sdf.format(form.getEndTime()));// 接收人(提交表单的员工)   显示的消息noticeDao.insert(new Notice(employee.getEmployeeId(), noticeContent));// 接收人(上级) 通知部门经理审批消息noticeContent = String.format("%s-%s提起请假申请[%s-%s],请尽快审批",employee.getTitle(), employee.getName(), sdf.format(form.getStartTime()),sdf.format(form.getEndTime()));noticeDao.insert(new Notice(dmanager.getEmployeeId(), noticeContent));} else if (employee.getLevel() == 7) {//部门经理//3.2 7级员工,生成总经理审批任务Employee manager = employeeDao.selectLeader(employee);ProcessFlow flow = new ProcessFlow();flow.setFormId(form.getFormId());flow.setOperatorId(manager.getEmployeeId());flow.setAction("audit");flow.setCreateTime(new Date());flow.setState("process");flow.setOrderNo(2);flow.setIsLast(1);processFlowDao.insert(flow);// 请假单已提交信息String noticeContent = String.format("您的请假申请[%s-%s]已提交,请等待上级批准.",sdf.format(form.getStartTime()), sdf.format(form.getEndTime()));// 接收人(提交表单的员工)   显示的消息noticeDao.insert(new Notice(employee.getEmployeeId(), noticeContent));// 接收人(上级) 通知总经理审批消息noticeContent = String.format("%s-%s提起请假申请[%s-%s],请尽快审批",employee.getTitle(), employee.getName(), sdf.format(form.getStartTime()),sdf.format(form.getEndTime()));noticeDao.insert(new Notice(manager.getEmployeeId(), noticeContent));} else if (employee.getLevel() == 8) {//3.3 8级员工,生成总经理审批任务,系统自动通过ProcessFlow flow = new ProcessFlow();flow.setFormId(form.getFormId());flow.setOperatorId(employee.getEmployeeId());flow.setAction("audit");flow.setResult("approved");flow.setReason("自动通过");flow.setCreateTime(new Date());flow.setAuditTime(new Date());flow.setState("complete");flow.setOrderNo(2);flow.setIsLast(1);processFlowDao.insert(flow);// 请假单已提交信息String noticeContent = String.format("您的请假申请[%s-%s]系统已自动批准通过,请等待上级批准.",sdf.format(form.getStartTime()), sdf.format(form.getEndTime()));// 接收人(提交表单的员工)   显示的消息noticeDao.insert(new Notice(employee.getEmployeeId(), noticeContent));}return form;});return savedForm;}

创建一个动态SQL根据传入的员工获取对应的上级主管对象

/*** 根据传入员工对象获取上级主管对象* @param employee 员工对象* @return 上级主管对象*/public Employee selectLeader(@Param("emp") Employee employee);
<select id="selectLeader" parameterType="com.imooc.oa.entity.Employee"resultType="com.imooc.oa.entity.Employee">select * from adm_employeewhere<if test="emp.level &lt; 7">level = 7 and department_id = #{emp.departmentId}</if><if test="emp.level == 7">level = 8</if><if test="emp.level == 8">employee_id = #{emp.employeeId}</if></select>

Servlet

@WebServlet(name = "LeaveFormServlet", urlPatterns = "/leave/*")
public class LeaveFormServlet extends HttpServlet {private LeaveFormService leaveFormService = new LeaveFormService();private Logger logger = LoggerFactory.getLogger(LeaveFormService.class);@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {request.setCharacterEncoding("utf-8");response.setContentType("text/html;charset=utf-8");//http://localhost/leave/createString uri = request.getRequestURI();// 对url进行截取String methodName = uri.substring(uri.lastIndexOf("/") + 1);// 创建请假表单if (methodName.equals("create")) {this.create(request, response);} else if (methodName.equals("list")) {//获取请假表单this.getLeaveFormList(request, response);} else if (methodName.equals("audit")) {//审核请假单this.audit(request, response);}}@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {this.doPost(request, response);}// 创建请假单private void create(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {// 1.接收各项请假单数据集HttpSession session = request.getSession();// 获取登录用户 // 获取用户提交的请假单数据User user = (User) session.getAttribute("login_user");String formType = request.getParameter("formType");String strStartTime = request.getParameter("startTime");String strEndTime = request.getParameter("endTime");String reason = request.getParameter("reason");SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH");Map<String, String> result = new HashMap();try {LeaveForm form = new LeaveForm();form.setEmployeeId(user.getEmployeeId());form.setStartTime(sdf.parse(strStartTime));form.setEndTime(sdf.parse(strEndTime));form.setFormType(Integer.parseInt(formType));form.setReason(reason);//请假原因form.setCreateTime(new Date());// 2.调用业务逻辑方法// 创建请假单leaveFormService.createLeaveForm(form);result.put("code", "0");result.put("message", "success");} catch (Exception e) {e.printStackTrace();logger.error("请假申请异常", e);result.put("code", e.getClass().getCanonicalName());result.put("message", e.getMessage());}// 组织相应结果String json = JSON.toJSONString(result);response.getWriter().println(json);}/*** 查询需要审核的请假单列表** @param request* @param response* @throws ServletException* @throws IOException*/public void getLeaveFormList(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {// 获取登录用户User user = (User) request.getSession().getAttribute("login_user");// 获取 List<Map> formList = leaveFormService.getLeaveFormList("process", user.getEmployeeId());Map result = new HashMap();result.put("code", "0");result.put("msg", "");result.put("count", formList.size());result.put("data", formList);String json = JSON.toJSONString(result);response.getWriter().println(json);}// 审核public void audit(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {String formId = request.getParameter("formId");String result = request.getParameter("result");String reason = request.getParameter("reason");User user = (User) request.getSession().getAttribute("login_user");Map<String, String> mpResult = new HashMap<>();try {leaveFormService.audit(Long.parseLong(formId), user.getEmployeeId(), result, reason);mpResult.put("code", "0");mpResult.put("message", "success");} catch (Exception e) {logger.error("请假单审核失败", e);mpResult.put("code", e.getClass().getSimpleName());mpResult.put("message", e.getMessage());}String json = JSON.toJSONString(mpResult);response.getWriter().println(json);}
}

前端代码就不列出来了。

为了解决页面显示问题

@WebServlet(name = "ForwardServlet", urlPatterns = "/forward/*")
public class ForwardServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {String uri = request.getRequestURI();/** /forward/form* /forward/a/b/c/form*/String subUri = uri.substring(1);String page = subUri.substring(subUri.indexOf("/"));request.getRequestDispatcher(page + ".ftl").forward(request, response);}
}

请假审批功能
首先查询自己要审批的表单条件是,审批人为自己和审批状态为processing(正在处理)

<select id="selectByParams" parameterType="java.util.Map" resultType="java.util.Map">select f.*, e.name, d.*from adm_leave_form f,adm_process_flow pf,adm_employee e,adm_department dwhere f.form_id = pf.form_idand pf.state = #{pf_state}and pf.operator_id = #{pf_operator_id}and f.employee_id = e.employee_idand e.department_id = d.department_id</select>
public List<Map> getLeaveFormList(String pfState, Long operatorId) {return (List<Map>) MybatisUtils.executeQuery(sqlSession -> {LeaveFormDao dao = sqlSession.getMapper(LeaveFormDao.class);List<Map> formList = dao.selectByParams(pfState, operatorId);//状态、经办人编号return formList;});}
/*** 查询需要审核的请假单列表*/public void getLeaveFormList(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {User user = (User) request.getSession().getAttribute("login_user");List<Map> formList = leaveFormService.getLeaveFormList("process", user.getEmployeeId());//当前登录的员工编号Map result = new HashMap();result.put("code", "0");result.put("msg", "");result.put("count", formList.size());result.put("data", formList);String json = JSON.toJSONString(result);response.getWriter().println(json);}

审批业务逻辑
情况1:普通员工请假,小于72小时,部门经理审批
情况2:普通员工请假,大于72小时,部门经理审批通过,总经理需要再次审批
情况3:普通员工请假,大于72小时,部门经理审批未通过,总经理不用审批
情况4:部门经理请假,总经理审批
情况5:总经理请假,直接通过

/*** 修改流程表审批状态、申请表状态、和通知信息* @param formId     申请表ID* @param operatorId 经办人编号* @param result     approved-同意 refused-驳回* @param reason     审批意见*/public void audit(Long formId, Long operatorId, String result, String reason) {MybatisUtils.excuteUpdate(sqlSession -> {//1.无论同意/驳回,当前任务状态变更为complete(处理完成).ProcessFlowDao processFlowDao = sqlSession.getMapper(ProcessFlowDao.class);// 根据对应的表单号查询该表单对应的处理流程顺序信息List<ProcessFlow> flowList = processFlowDao.selectByFormId(formId);if (flowList.size() == 0) {throw new BussinessException("PF001", "无效的审批流程");}// process 正在处理  把处理过程为process的提取出来List<ProcessFlow> processList = flowList.stream().filter(p -> p.getOperatorId().equals(operatorId) && p.getState().equals("process")).collect(Collectors.toList());ProcessFlow process = null;if (processList.size() == 0) {throw new BussinessException("PF002", "未找到待处理任务");} else {process = processList.get(0);process.setState("complete");process.setResult(result);// 设置同意还是驳回process.setReason(reason);// 设置审批意见process.setAuditTime(new Date());processFlowDao.update(process);}//2.如果当前任务是最后一个节点,代表流程结束,更新请假单状态为对应的approved/refusedLeaveFormDao leaveFormDao = sqlSession.getMapper(LeaveFormDao.class);// 查询请假表内容LeaveForm form = leaveFormDao.selectById(formId);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH时");EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);Employee employee = employeeDao.selectById(form.getEmployeeId());Employee operator = employeeDao.selectById(operatorId);NoticeDao noticeDao = sqlSession.getMapper(NoticeDao.class);// 当前为最后一个流程 代表流程结束,更新请假表单状态对应的approved/refusedif (process.getIsLast() == 1) {form.setState(result);// 通过/拒绝leaveFormDao.update(form);String strResult = null;if (result.equals("approved")) {strResult = "批准";} else if (result.equals("refused")) {strResult = "驳回";}// 起始时间-结束时间-经办人职务-经办人名字-批准/驳回-审批意见String noticeContent = String.format("您的请假申请[%s-%s]%s%s已%s,审批意见:%s,审批流程已结束",sdf.format(form.getStartTime()), sdf.format(form.getEndTime()), operator.getTitle(),operator.getName(), strResult, reason);// 发给表单提交人noticeDao.insert(new Notice(form.getEmployeeId(), noticeContent));// 职务-员工-起始时间-结束时间-审核/驳回-审批意见noticeContent = String.format("%s-%s提起的请假申请[%s-%s]您已%s,审批意见:%s,审批流程已结束",employee.getTitle(), employee.getName(), sdf.format(form.getStartTime()),sdf.format(form.getEndTime()),strResult, reason);//发给审批人的通知noticeDao.insert(new Notice(operator.getEmployeeId(), noticeContent));} else {// 不是最后一个流程// readyList包含所有的后序节点List<ProcessFlow> readyList =flowList.stream().filter(p -> p.getState().equals("ready")).collect(Collectors.toList());//3.如果当前任务不是最后一个节点且审批通过,那下一个节点的状态从ready变为processif (result.equals("approved")) {//同意ProcessFlow readyProcess = readyList.get(0);readyProcess.setState("process");processFlowDao.update(readyProcess);// 消息1:通知表单提交人,部门经理已经审批通过,交由上级处理String noticeContent1 = String.format("您的请假申请[%s-%s]%s%s已批准,审批意见:%s,请等待上级领导审批",sdf.format(form.getStartTime()), sdf.format(form.getEndTime()),operator.getTitle(), operator.getName(), reason);noticeDao.insert(new Notice(form.getEmployeeId(), noticeContent1));// 消息2:通知总经理有新的审批任务String noticeContent2 = String.format("%s-%s提起请假申请[%s-%s],请尽快审批",employee.getTitle(), employee.getName(), sdf.format(form.getStartTime()),sdf.format(form.getEndTime()));noticeDao.insert(new Notice(readyProcess.getOperatorId(), noticeContent2));// 消息3:通知部门经理(当前经办人),员工的申请单你已批准,交由上级继续审批String noticeContent3 = String.format("%s-%s提起的请假申请[%s-%s]您已批准,审批意见:%s,请等待上级领导审批",employee.getTitle(), employee.getName(), sdf.format(form.getStartTime()),sdf.format(form.getEndTime()),reason);noticeDao.insert(new Notice(operator.getEmployeeId(), noticeContent3));} else if (result.equals("refused")) {// 驳回//4.如果当前任务不是最后一个节点且审批驳回,则后续所有任务状态变为cancel,请假单状态变为refusedfor (ProcessFlow p :readyList) {p.setState("cancel");processFlowDao.update(p);}// 表单设置为被拒绝form.setState("refused");leaveFormDao.update(form);// 消息1:通知申请人表单已经被驳回String noticeContent1 = String.format("您的请假申请[%s-%s]%s%s已驳回,原因是%s",sdf.format(form.getStartTime()), sdf.format(form.getEndTime()),operator.getTitle(), operator.getName(), reason);noticeDao.insert(new Notice(form.getEmployeeId(), noticeContent1));//消息2:通知经办人表单"您已驳回"String noticeContent3 = String.format("%s-%s提起的请假申请[%s-%s]您已驳回,审批意见%s,审批流程已结束",employee.getTitle(), employee.getName(), sdf.format(form.getStartTime()),sdf.format(form.getEndTime()),reason);noticeDao.insert(new Notice(operator.getEmployeeId(), noticeContent3));}}return null;});}

OA系统实现(请假审批,mybatis)-2相关推荐

  1. OA系统实现(请假审批,mybatis)-1

    办公自动化OA系统 1.办公自动化系统(Office Automation)是替代传统办公的解决方案 2.OA系统是利用软件技术构建的单位内部办公平台,用于辅助办公 3.利用OA系统可将办公数据数字化 ...

  2. php办公oa系统带流程审批支持手机版wap源码

    php办公oa系统带流程审批支持手机版wap源码 一款强大的oa办公行政系统带流程审批手机wap版支持手机浏览php+mysql开发php源码 演示地址:http://www.phprr.com/de ...

  3. OA系统常见的审批流程

    审批流程是OA系统应用的核心,有的企业每天要在OA系统上流转上百个流程,这些流程涉及几百名审批人员,保证他们审批操作的正确性,对他们的操作权限进行合理的规范,就成为了保证流程顺畅运行的重要工作.本篇将 ...

  4. 如何在OA系统中设定审批流程(一)固定流程

    在OA系统中,我们公司很多事情的审批流程都是固定的,并且不允许随意更改,能不能让每个人在发起申请的时候自动调用这个流程呢?制定好的入职手续老是不能严格地执行,技术人员都工作一周了人事部门才得到信息,怎 ...

  5. OA系统中 流程审批数据库的设计

    参考: http://www.cnblogs.com/kingeric/p/6052826.html

  6. OA系统有哪些功能?在企业中发挥怎样的作用?

    OA系统是什么?为什么企业要引进OA系统?OA系统的主要功能和作用又有哪些? 一.OA系统是什么 首先,OA是office automation的简写,也就是办公自动化的意思,面向组织的日常运作和管理 ...

  7. 免费OA系统让企业管理变得更加简单

    免费OA系统让企业管理变得更加简单 现在很多企业都在使用点晴OA这款免费OA办公系统,那么大家有没有感受到免费OA系统的魔力所在.免费OA系统是如何让企业管理变得更加简单. 如果没有免费OA系统,员工 ...

  8. OA系统,满足各行业办公所需的管理软件

    OA系统以其卓越的协同办公技术及完善的流程化管理体系一改传统办公流程冗杂.审批低效.资源浪费严重等弊端,成为各信息化建设.提升办公管理效率,节约管理成本的可信赖办公管理软件. 1.OA系统可助力金融行 ...

  9. 学校课程设计——OA系统

    下载地址:OA系统 技术栈 SpringBoot Mybatis JWToken Mysql Redis 功能模块 登录模块: 1.基本账号密码加密校验登录. 2.生成JWToken,存入Sessio ...

最新文章

  1. windows下配置redis集群,启动节点报错:createing server TCP listening socket *:7000:listen:Unknown error...
  2. 15级团队学习成果汇报 -- 利用C#语言实现展览厅
  3. arguments.callee查询调用b函数的是哪个函数
  4. Demo:基于 Flink SQL 构建流式应用
  5. OSChina 周五乱弹 —— 静静的思考下人生
  6. 最小/大加代数(Min/max-Plus Algebra)
  7. linux信号学习02
  8. android opengl es 绘制位图字体
  9. leaflet调用mysql_PHP和MySQL以及Leaflet API
  10. wr885n虚拟服务器设置,动态IP设置:选择动态IP(以太网宽带
  11. 医生- 患者 - 图标
  12. VMware Workstation 12 pro + 激活码+VMware Workstation 10 + 激活码
  13. 谈逻辑与数学界线之淡化(修正版)
  14. Learning Git Branching 题解(基础、高级、Git远程仓库)
  15. Java实现复数运算
  16. css cubic-bezier,使用cubic-bezier()创建带有反弹特效的CSS动画
  17. 清默网络——CCIE考试经验与心得(1)
  18. Linux-C C语言编译过程
  19. 云计算和云服务器分别表示什么?
  20. 汪源:数据分析热词迭出,“三个统一”值得关注

热门文章

  1. [附源码]Python计算机毕业设计SSM基于Java的流浪动物救助系统(程序+LW)
  2. Java基于springboot+vue的流浪动物救助收养平台 nodejs 前后端分离
  3. ssm框架整合(含ssm配置)实现crud
  4. vscode美化插件推荐
  5. 我差点错过高校毕业生毕业之后这个3000元现金直接打入银行卡的补贴!
  6. C/C++中的指针*是靠近数据类型还是靠近数据变量书写?
  7. CMake教程之构建Qt平台
  8. HTML报错 Malformed markup: Attribute “xxx“ appears more than once in element
  9. op 圣诞节活动_20种免费的圣诞节符号字体下载
  10. 电容电压不能突变和电感电流不能突变仿真分析