1、前段时间做了个员工工作量统计报表需求,员工工作时需要同时进行两份工作:接打电话和在线客服的文字回复(在线客服后面统一描述为:文字);业务需要统记计算每个坐席的当日工作量;
2、数据结构说明:数据存在两个时间点,形成一个时间区间;
工作开始-工作结束、休息开始-休息结束;
我简单构建了一个数据库表,将两个工作的数据每天跑批汇总到当前表中,大致结构如下:
3、需求说明:业务要求统计当前员工工作量;规则为:当前员工在进行任何一项工作,则当前时间需计算为工作时间;如同时进行两项工作,当前时间数据只统计一次,不可重复计算;详细描述如图所示
4、实现方案:时间是线型的,将所有时间数据汇总成一列时间点数据形成一个数组1,然后再将当前员工的所有数据正常查询到代码中,形成数组2;将数组1中的时间节点组合成一个一个线型的区间,判断当前区间在数组2 中的哪些时间区间内,判断完后即可计算当前时间区间的工作时长;
5、简单的代码:
图1
图2
public static void main(String[] args) {
ArrayList<HashMap> timeList = new ArrayList<>();//时间数组图1数据结构
ArrayList<HashMap> timeList2 = new ArrayList<>();//时间区间数组图2数据结构
ArrayList<String> timeObjList = new ArrayList<>();//用于存储时间区间
Long allWorkTime = 0L; //当前员工总工作量
if (timeList != null && timeList.size() > 0) {
for (HashMap hashMap : timeList) {
HashSet<String> setResult = new HashSet<>();//用于存储当前员工工作类型及状态
HashSet<String> workResult = new HashSet<>();//用于存储当前员工的工作类型
String times = String.valueOf(hashMap.get("times"));//获取数据中的时间数据
timeObjList.add(times); //将当前时间数据添加到数组中
if (timeObjList.size()>=2) {//当前时间数据大于等于2时,则形成了时间区间;
String starTime = timeObjList.get(0);//获取开始时间
String endTime = timeObjList.get(1);//获取结束时间
if (timeList2 != null && timeList2.size() > 0) {
//遍历当前员工的所有时间区间数据
for (HashMap map : timeList2) {
String userStrTime = String.valueOf(map.get("str"));//获取数据中的开始时间数据
String userEndTime = String.valueOf(map.get("end"));//获取数据中的结束时间数据
String workType = String.valueOf(map.get("work_type"));//工作类型
String woekTtar = String.valueOf(map.get("woek_star"));//工作状态
// 判断当前的两个时间点是否在对应的时间区间中,如果是,则记录当前时间数据类型
if (isbefoTime(starTime,userStrTime,userEndTime) && isbefoTime(endTime,userStrTime,userEndTime)){
//将工作状态和类型存入到set数据中 比如:电话工作、电话休息、文字工作、文字休息
setResult.add(workType + woekTtar);
workResult.add(workType);
}
}
if (setResult != null && setResult.size() > 0){
int size = setResult.size();
// 进行逻辑判断,可以直接进行数据长度的判断,
// 休息时间是一定在工作时间区间内的,工作时间是类似于上下班打卡时间段
//如果长度为1 或者为3时,当前时间段数据则一定是需要计算为工作时间段的
if (size==1 || size==3){
allWorkTime = calculationTime(allWorkTime,starTime,endTime);
}else if (size == 2){
// 当前长度为2时,有两种情况,1:同时进行两个工作类型,比如:电话-工作、文字-工作,该种情况时需要进行工作量计算
// 2:只进行一种工作,比如:电话-工作、电话-休息;该种情况则不进行工作量计算
if (workResult.size()==2){//进行工作类型数量判断
allWorkTime = calculationTime(allWorkTime,starTime,endTime);
}
}
}
}
// 当时间区间使用完后,不要忘了将第一个时间节点数据删除,
// 在进行下一次循环时,再获取一个新的时间节点存入数组,再次形成一个新的时间区间
// 利用线型的时间,来进行数据处理
timeObjList.remove(0);
}
}
}
}
/** 自行百度一个时间判断的写进去,主要判断时间是否在时间区间内
* @param nowtime 开始时间
* @param starSection 开始时间区间
* @param endSection 结束时间区间
* @return
*/
public static boolean isbefoTime(String nowtime, String starSection, String endSection){
return true;
}
/**计算当前时间数据,,自行百度一个计算时间段数据的方法
* @return
*/
public static Long calculationTime(Long allWorkTime , String starTime, String endTime){
return allWorkTime;
}
因为当时需求时间短(一周3个报表功能),加上本人能力一般,是个菜鸟开发,所以只能想出一个这样的方案进行数据计算;其中代码里面有很多地方应该还有优化空间(比如这个代码只能进行单个员工的工作量计算),或者各位大佬如果有更好的方案,欢迎在评论区进行指导本菜鸡;