本篇博客的主要内容是:【请假审批内嵌页面】,【审批弹出框】的点击“确认提交”后,后台的逻辑:主要是Dao层和Service层这些后台逻辑;

 说明:

(1)目前来看,为了实现某个功能,【一个比较好的编程逻辑和实现流程】比【实际敲代码去实现】重要的多得多!!!

(2.1)底层的SQL语句,updata和insert语句的参数,一般是一个实体类对象,注意一下这个习惯(或者说是普遍采用的策略);

(2.2)而且,一般为了更新某些数据,一般的策略先查询出要更改数据,用一个实体类对象去承载;然后,修改这个实体类对象,然后再调用update方法(updata的参数就是这个修改后的实体类对象),已达到更新这些数据的目的;

(2.3)2.2中的例子可以看出,我们尽量在Mapper xml中编写那些具有通用性的SQL,或者说是可以完成某个“普遍性”功能的SQL语句;这样一来,当我们需要完成某个具体的业务逻辑的时候,就可以调用这些【具有“通用性、普遍性”功能的SQL语句】,来完成我们具体的某个业务逻辑!这一条思想非常重要!!!

目录

一:【审批】流程和逻辑分析

(1)如果请假时间 >= 72小时:需要【部门经理审批】和【总经理审批】

(2)如果请假时间 < 72小时:需要【部门经理审批】和【总经理审批】

二:通过【一:【审批】流程和逻辑分析】中的分析,构思具体编码的的实现分支和结构

三:具体的实现

1.第一个步骤:无论审批结果是同意还是驳回,当前任务状态变更为complete;

(1.1)首先,在process_flow.xml中编写SQL语句

(1.2)然后,在ProcessFlowDao中,编写上述在process_flow.xml中声明的两个SQL语句的方法声明

(1.3)然后,在LeaveFormService中,编写实现【把当前任务状态变更为complete;】的业务逻辑

2.第二个步骤:如果当前任务是最后一个节点,代表流程结束,更新leave_form表中的请假单状态为对应的approved或者refused

(1)首先,在leave_form.xml中增加两个SQL语句;

(2)然后,就在LeaveFormDao中编写方法的定义

(3)然后,就在LeaveFormService中,调用Dao层方法,实现本步骤的逻辑

3.第三个步骤:如果当前任务不是最后一个节点,如果审批通过,那么下一个节点的状态从ready改为process

4.第四个步骤:如果当前任务不是最后一个节点,如果审批驳回,则后续所有任务的状态变为cancel,同时更新leave_form表中的请假单状态为refused

5.最后的一个设置,因为整个操作不需要返回值,所以return null;

四:测试

(1)测试数据

(2)编写测试用例

(3)实际运行测试用例


一:【审批】流程和逻辑分析

(1)如果请假时间 >= 72小时:需要【部门经理审批】和【总经理审批】

如上,目前的审批环节是【部门经理审批】。

(情况一:中间节点审批通过了:)

● 如果部门经理审批通过:

然后,【总经理】审批了:总经理审批:总经理可能审批通过,也可能审批不通过

情况二:中间节点审批不通过: )

● 如果部门经理审批不通过:那么这个请假直接就无需总经理审批了,直接不同意了。

(2)如果请假时间 < 72小时:需要【部门经理审批】和【总经理审批】

情况三:当前节点是最后一个节点:

即,【审批的流程和逻辑】可以抽取成三个不同的情况:【情况一:当前审批是中间节点,而且审批通过了】;【情况二:当前审批是中间节点,但是审批没通过】;【情况三:当前审批是最后一个的节点】;


二:通过【一:【审批】流程和逻辑分析】中的分析,构思具体编码的的实现分支和结构

通过【一:【审批】流程和逻辑分析】中的分析,在实际编码的时候,其实现逻辑可以梳理为:

1.无论审批结果是同意还是驳回,当前任务状态变更为complete;(即,只要当前环节审批了,无论同意还是驳回,当前审批环节审批后,当前环节的状态都需要改为complete)

2.如果当前任务是最后一个节点,代表流程结束,更新leave_form表中的请假单状态为对应的approved或者refused

3.如果当前任务不是最后一个节点,如果审批通过,那么下一个节点的状态从ready改为process

4.如果当前任务不是最后一个节点,如果审批驳回,则后续所有任务的状态变为cancel,同时更新leave_form表中的请假单状态为refused

(PS:这个【为了实现某个功能,构建更加良好的代码结构和逻辑的能力,需要慢慢提升啦;确实,目前来看,【为了实现某个功能,一个比较好的编程逻辑和实现流程】比【实际敲代码去实现】重要的多得多!!!


三:具体的实现

1.第一个步骤:无论审批结果是同意还是驳回,当前任务状态变更为complete;

(1.1)首先,在process_flow.xml中编写SQL语句

经过思考后,可以发现,为了实现本步骤的逻辑,需要两个底层的SQL操作:一个是查询当前表单的所有审批环节;二是,更改某一审批环节;

PS:上面的selectByFormId马虎写错了,多了一个c....所以,及时的单元测试非常重要!!

process_flow.xml:上述新增内容的代码

    <select id="selectByFormId" parameterType="Long" resultType="com.imooc.oa.entity.ProcessFlow">select * from adm_process_flow where form_id = #{value} order by order_no</select><update id="update" parameterType="com.imooc.oa.entity.ProcessFlow">UPDATE adm_process_flow SET form_id = #{formId}, operator_id = #{operatorId}, action = #{action}, result = #{result}, reason = #{reason}, create_time = #{createTime}, audit_time = #{auditTime}, order_no = #{orderNo}, state = #{state}, is_last = #{isLast}WHERE process_id = #{processId}</update>

(1.2)然后,在ProcessFlowDao中,编写上述在process_flow.xml中声明的两个SQL语句的方法声明

(1.3)然后,在LeaveFormService中,编写实现【把当前任务状态变更为complete;】的业务逻辑

实现【第一个步骤:无论审批结果是同意还是驳回,当前任务状态变更为complete;】的代码:

    /**** @param formId:该条请假信息的formId(可以从前台传过来的)* @param operatorId:经办人编号(从当前的session会话对象中获得的)* @param result:审批结果(可以从前台传过来的)* @param reason:审批意见(可以从前台传过来的)*/public void audit(Long formId,Long operatorId,String result,String reason){MybatisUtils.executeUpdate(sqlSession -> {//1.无论审批结果是同意还是驳回,当前任务状态变更为complete//(1.1)首先获取,当前表单的所有流程数据;ProcessFlowDao processFlowDao = sqlSession.getMapper(ProcessFlowDao.class);List<ProcessFlow> processFlowList = processFlowDao.selectByFormId(formId);if (processFlowList.size() == 0) {  //if判断,是作了一个容错处理,如果查询的流程数据为0的话,需要抛一个异常;throw new BussinessException("PF001", "无效的审批流程");// 这个错误编码是自定义的;}//(1.2)获取当前审批环节的数据//获取当前的审批流程:一个审批流程要想判定为是当前审批流程需要满足以下两个条件:一是当前环节的状态state应该为process;二是当前环节的经办人operator_id应该是当前的登录用户。// 通过Lambda表达式的Stream流来做数据筛选的List<ProcessFlow> currentProcessFlowList = processFlowList.stream().filter(p -> p.getOperatorId() == operatorId && p.getState().equals("process")).collect(Collectors.toList());ProcessFlow processFlow = null;if (currentProcessFlowList.size() == 0) {  //if判断,是作了一个容错处理,如果没有在process_flow表中找到当前审批流程,需要抛一个异常;throw new BussinessException("PF002", "未找到待处理任务");// 这个错误编码是自定义的;} else { //如果找到了当前审批流程数据,就把这个审批流程数据提取出来processFlow = currentProcessFlowList.get(0);processFlow.setState("complete");processFlow.setResult(result);processFlow.setReason(reason);processFlow.setAuditTime(new Date());processFlowDao.update(processFlow);}//2.如果当前任务是最后一个节点,代表流程结束,更新leave_form表中的请假单状态为对应的approved或者refused//3.如果当前任务不是最后一个节点,如果审批通过,那么下一个节点的状态从ready改为process//4.如果当前任务不是最后一个节点,如果审批驳回,则后续所有任务的状态变为cancel,同时更新leave_form表中的请假单状态为refused})}

说明:

(1)因为所有的审批操作,要么全部OK,要么全部不做,所以把上面的代码,都写在了一个【MybatisUtils.executeUpdate()】中:

(2) 首先,获取【当前表单的所有流程数据】;其中加了一个判断的容错处理,如果一切正常的话,应该会获取得到的,但是万一获取不到,就抛出一个自定义的BussinessException异常;

(3) 然后,从【当前表单的所有流程数据】中,筛选出【当前审批环节的数据】;其中加了一个判断的容错处理,如果一切正常的话,应该会获取得到的,但是万一获取不到,就抛出一个自定义的BussinessException异常;(因为,在前面显示【待审批请假数据】的时候,就是按照这个规则筛选的。但是,如果万一由于某些原因找不到的话,就报异常)

这儿使用了Lambda表达式的stream流来做的,如果忘记了,可以参考Lambda表达式七:Stream流一:Stream介绍及附近相关文章。

(4)更新当前审批环节的数据


2.第二个步骤:如果当前任务是最后一个节点,代表流程结束,更新leave_form表中的请假单状态为对应的approved或者refused

(1)首先,在leave_form.xml中增加两个SQL语句;

因为为了实现第二步的逻辑,底层需要两个SQL支撑:一是根据form_id查询form表单数据;二是更新某条form表单数据

PS:上面update标签中的参数写错了,写成了LeaveForm,实际上应该是com.imooc.oa.entity.LeaveForm,而这个错误在后面运行发布的时候也导致了NoClassDefFoundError错误,以至于系统无法登录。所以,及时的单元测试非常重要!!!

leave_form.xml中增加两个SQL语句的代码:

    <select id="selectById" parameterType="Long" resultType="com.imooc.oa.entity.LeaveForm">select * from adm_leave_form where form_id = #{value}</select><update id="update" parameterType="com.imooc.oa.entity.LeaveForm">UPDATE adm_leave_form SET employee_id = #{employeeId} , form_type = #{formType}, start_time = #{startTime}, end_time = #{endTime}, reason = #{reason}, state = #{state} ,create_time = #{createTime} WHERE form_id = #{formId}</update>

(2)然后,就在LeaveFormDao中编写方法的定义

(3)然后,就在LeaveFormService中,调用Dao层方法,实现本步骤的逻辑


3.第三个步骤:如果当前任务不是最后一个节点,如果审批通过,那么下一个节点的状态从ready改为process

从这儿就可以看到,因为前面我们编写底层SQL语句的时候,都是编写的【具有“通用性、普遍性”功能的SQL语句】,所以,在本步骤我们直接调用那些【具有“通用性、普遍性”功能的SQL语句】来完成【本步骤这个具体的业务逻辑了】


4.第四个步骤:如果当前任务不是最后一个节点,如果审批驳回,则后续所有任务的状态变为cancel,同时更新leave_form表中的请假单状态为refused

从这儿就可以看到,因为前面我们编写底层SQL语句的时候,都是编写的【具有“通用性、普遍性”功能的SQL语句】,所以,在本步骤我们直接调用那些【具有“通用性、普遍性”功能的SQL语句】来完成【本步骤这个具体的业务逻辑了】


5.最后的一个设置,因为整个操作不需要返回值,所以return null;


四:测试

(PS:感觉在实际开发中,最好还是每写完一个Service模块或者是每写完一个Dao模块就测试一下,不要等到一个功能全部编写完了之后再测试)

(1)测试数据

可以看到,共有三条测试数据,其form_id依次是31,32,33;

(2)编写测试用例

针对本次测试内容,编写以下三个测试方法:

package com.imooc.oa.service;import com.imooc.oa.entity.LeaveForm;
import org.junit.Test;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;import static org.junit.Assert.*;public class LeaveFormServiceTest {LeaveFormService leaveFormService = new LeaveFormService();/*** 请假3天以上,部门经理审批通过*/@Testpublic void audit1(){leaveFormService.audit(31l,2l,"approved","祝早日康复");}/*** 请假3天以上,部门经理审批驳回*/@Testpublic void audit2(){leaveFormService.audit(32l,2l,"refused","工期紧张,请勿拖延");}/*** 部门经理请假,总经理审批通过*/@Testpublic void audit3(){leaveFormService.audit(33l,1l,"approved","同意");}}

(3)实际运行测试用例

 运行audit1():

运行audit2():

运行audit3():

 


至此,说明业务逻辑部分编写就OK了,接下来就是编写Controller和前台界面了。 

OA系统二十四:请假审批五:【点击“审批”后的审批弹出框】的后台逻辑;(审批结果提交的Dao层和Service层逻辑)相关推荐

  1. OA系统二十:请假审批一:审批功能概述;显示【请假审批】这个内嵌界面中【待审批请假数据】的SQL语句;

    本篇博客的主要内容就是:在请假审批这个内嵌界面中,显示待审批请假数据的SQL语句: 目录 1.[请假审批]功能需要实现什么? 2.[请假审批界面]中[待审批请假数据]之:SQL语句 (1)审批列表中需 ...

  2. [系统安全] 二十四.逆向分析之OllyDbg调试INT3断点、反调试、硬件断点与内存断点

    您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列.因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全.逆向分 ...

  3. 【Visual C++】游戏开发五十七 浅墨DirectX教程二十四 打造游戏GUI界面(二)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/16922703 作者:毛星 ...

  4. 大话设计模式笔记(二十一、二十二、二十三、二十四、二十五、二十六)

    二十一.单例模式(Singleton) 定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点. 1.通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象.一个最好的办法就是 ...

  5. 2021年春季学期-信号与系统-第十四次作业参考答案

    ▓ 第十四次作业各小题参考答案: 2021年春季学期-信号与系统-第十四次作业参考答案-第一小题参考答案 2021年春季学期-信号与系统-第十四次作业参考答案-第二小题参考答案 2021年春季学期-信 ...

  6. cad怎么选择一个对象打散vba_CAD制图的二十四字秘诀!

    就像练武一样,原来CAD也有相应的二十四字秘诀,没想到吧. 当然,倘若大家觉得记住这"秘诀"就能成为一名出色的CAD设计师,那您就真的想多了,做比记住难很多. 但,如果没有大神总结 ...

  7. 【Microsoft Azure 的1024种玩法】二十四.通过Azure Front Door 的 Web 应用程序防火墙来对 OWASP TOP 10 威胁进行防御

    [简介] 我们都知道像 SQL 注入.跨站点脚本攻击(XSS)之类的恶意攻击以及 OWASP 发现的十大威胁都可能会导致服务中断或数据丢失,让 Web 应用程序所有者受到巨大威胁.那么如何有效的解决O ...

  8. (二十四)优秀员工 - 5

    处理与幸福之家大行客服组和各礼品供应商有关的数据问题,便成了钱三日常工作的主要内容.由于类似的问题处理多了,便成了重复而熟悉的操作,钱三的工作也变得更简单和容易,同时也开始变得有些了无趣味. 在一次下 ...

  9. VLSI数字信号处理系统——第十四章冗余运算

    VLSI数字信号处理系统--第十四章冗余运算 作者:夏风喃喃 参考: (1) VLSI数字信号处理系统:设计与实现 (美)Keshab K.Parhi/著 (2) socvista https://w ...

最新文章

  1. 今天看到两个题 写出来思考一下
  2. 软件工程系列教材:软件架构设计实践教程
  3. 编程之美-连连看游戏设计方法整理
  4. Gstreamer基础知识介绍
  5. 13. 找出数组中重复的数字【难度: 简单 / 知识点: 模拟】
  6. Duilib教程-自动布局1
  7. python中lxml模块的使用
  8. jpetstore开发实战--(1)
  9. [Redis]Node操作Redis
  10. 为什么Laravel会成为最成功的PHP框架
  11. 数据分析第二章确定分析思路
  12. Hyperledger Fabric无排序组织以Raft协议启动多个Orderer服务、TLS组织运行维护Orderer服务
  13. 结对开发石家庄地铁查询系统
  14. 百度地图、高德地图的数据从哪里得到的?[声明我只是此文章的搬运工]
  15. 世界GDP和新冠疫情直接关系
  16. thinkadmin打印sql语句调试sql
  17. 手机访问电脑本地html文件
  18. 【沃顿商学院学习笔记】宏观经济学——11全球治理Global Governance
  19. Pytorch 3D卷积
  20. Ubuntu 复制文件到远端时错误,Permission denied 失败原因深度探索

热门文章

  1. java后台发送post请求 MultipartFile、json
  2. JPA以外键为条件查询出的List(外键过滤并存入JSONObject)
  3. 信息学奥林匹克竞赛-编程语言
  4. Linux学习_Sinno_Song_新浪博客
  5. c语言fread()函数
  6. 计算机应用杂志-投稿经历
  7. 如何安装和使用A-ops工具?
  8. YOLOv3测试人物和舰船检测效果
  9. Web服务器入侵痕迹检测
  10. MySQL创建用户,更改密码