|
@@ -8,10 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.management.platform.constant.Constant;
|
|
|
import com.management.platform.entity.*;
|
|
|
import com.management.platform.entity.bo.*;
|
|
|
-import com.management.platform.mapper.FeishuInfoMapper;
|
|
|
-import com.management.platform.mapper.FeishuSendMapper;
|
|
|
-import com.management.platform.mapper.SysRoleMapper;
|
|
|
-import com.management.platform.mapper.UserMapper;
|
|
|
+import com.management.platform.mapper.*;
|
|
|
import com.management.platform.service.FeishuInfoService;
|
|
|
import com.management.platform.util.HttpRespMsg;
|
|
|
import com.management.platform.util.MD5Util;
|
|
@@ -27,10 +24,7 @@ import javax.servlet.http.HttpServletRequest;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
-import java.time.Instant;
|
|
|
-import java.time.LocalDate;
|
|
|
-import java.time.LocalDateTime;
|
|
|
-import java.time.ZoneId;
|
|
|
+import java.time.*;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
@@ -82,9 +76,13 @@ public class FeishuInfoServiceImpl extends ServiceImpl<FeishuInfoMapper, FeishuI
|
|
|
@Resource
|
|
|
SysRoleMapper sysRoleMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
+ UserFvTimeMapper userFvTimeMapper;
|
|
|
+
|
|
|
@Autowired
|
|
|
private RestTemplate restTemplate;
|
|
|
|
|
|
+
|
|
|
@Override
|
|
|
public String getAppAccessToken(FeishuInfo feishuInfo) {
|
|
|
String result="";
|
|
@@ -504,14 +502,14 @@ public class FeishuInfoServiceImpl extends ServiceImpl<FeishuInfoMapper, FeishuI
|
|
|
// Integer companyId = user.getCompanyId();
|
|
|
|
|
|
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
|
|
|
- lqw.select(User::getId,User::getJobNumber).isNotNull(User::getJobNumber)
|
|
|
+ lqw.select(User::getId,User::getJobNumber,User::getCompanyId).isNotNull(User::getJobNumber)
|
|
|
.in(User::getId,Arrays.asList(queryBO.getWtUserIds()));
|
|
|
List<User> users = userMapper.selectList(lqw);
|
|
|
if(CollectionUtils.isEmpty(users)){
|
|
|
msg.setError("未查询到飞书工号");
|
|
|
return msg;
|
|
|
}
|
|
|
- Map<String, String> jobNumIdMap = users.stream().collect(Collectors.toMap(User::getJobNumber, User::getId));
|
|
|
+ Map<String, User> jobNumUserMap = users.stream().collect(Collectors.toMap(User::getJobNumber, t->t));
|
|
|
String[] feishuUserIdArr = users.stream().map(User::getJobNumber).toArray(String[]::new);
|
|
|
queryBO.setUserIds(feishuUserIdArr);
|
|
|
|
|
@@ -520,11 +518,11 @@ public class FeishuInfoServiceImpl extends ServiceImpl<FeishuInfoMapper, FeishuI
|
|
|
msg.setError("飞书获取用户考勤数据失败,请联系管理员");
|
|
|
return msg;
|
|
|
}
|
|
|
- for (FeishuClockUserTaskResult userTaskResult : feishuClockData.getUser_task_results()) {
|
|
|
- for (FeishuClockTaskRecord record : userTaskResult.getRecords()) {
|
|
|
- record.setDateTime();
|
|
|
- }
|
|
|
- }
|
|
|
+// for (FeishuClockUserTaskResult userTaskResult : feishuClockData.getUser_task_results()) {
|
|
|
+// for (FeishuClockTaskRecord record : userTaskResult.getRecords()) {
|
|
|
+// record.setDateTime();
|
|
|
+// }
|
|
|
+// }
|
|
|
// msg.setData(userTaskResults);
|
|
|
|
|
|
//用户id、day、考勤组、班次、打卡记录list
|
|
@@ -545,81 +543,199 @@ public class FeishuInfoServiceImpl extends ServiceImpl<FeishuInfoMapper, FeishuI
|
|
|
List<Map<String,Object>> res = new ArrayList();
|
|
|
SimpleDateFormat HMFormat = new SimpleDateFormat("HH:mm");
|
|
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ List<UserFvTime> toAddFvTimeList = new ArrayList<>();
|
|
|
for (FeishuClockUserTaskResult userTaskResult : feishuClockData.getUser_task_results()) {
|
|
|
int day = userTaskResult.getDay();//日期 yyyyMMdd
|
|
|
- String dayStr = String.valueOf(day).substring(0,4)+"-"+String.valueOf(day).substring(4,6)+"-"+String.valueOf(day).substring(6,7);
|
|
|
+ String dayStr = String.valueOf(day).substring(0,4)+"-"+String.valueOf(day).substring(4,6)+"-"+String.valueOf(day).substring(6,8);
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ UserFvTime userFvTime = new UserFvTime();
|
|
|
+ userFvTime.setUserId(jobNumUserMap.get(userTaskResult.getUser_id()).getId());
|
|
|
//获取正常上班时间段
|
|
|
Optional<FeishuClockTaskRecord> first = userTaskResult.getRecords().stream()
|
|
|
.filter(t -> 0 == t.getTask_shift_type())
|
|
|
.findFirst();
|
|
|
if(first.isPresent()){
|
|
|
- Map<String,Object> map = new HashMap<>();
|
|
|
FeishuClockTaskRecord record = first.get();
|
|
|
- UserFvTime userFvTime = new UserFvTime();
|
|
|
//计算时长 需考虑考勤--待处理
|
|
|
-
|
|
|
FeishuShiftResult shiftResult = shiftResultMap.get(userTaskResult.getShift_id());
|
|
|
//判断弹性上下班
|
|
|
- Integer flexibleMinutes = null;
|
|
|
+ Integer earlyFlexibleMinutes = null; //下班最多可早走
|
|
|
+ Integer lateFlexibleMinutes = null; //上班最多可晚到
|
|
|
if(shiftResult.is_flexible()){
|
|
|
//可以弹性上下班
|
|
|
- flexibleMinutes = shiftResult.getFlexible_minutes();
|
|
|
- if(null == flexibleMinutes || 0 == flexibleMinutes){
|
|
|
+ earlyFlexibleMinutes = shiftResult.getFlexible_minutes();
|
|
|
+ lateFlexibleMinutes = shiftResult.getFlexible_minutes();
|
|
|
+ if(null == shiftResult.getFlexible_minutes() || 0 == shiftResult.getFlexible_minutes()){
|
|
|
//从规则中获取
|
|
|
if(CollectionUtils.isNotEmpty(shiftResult.getFlexible_rule())){
|
|
|
//此处仅获取第一个作为规则
|
|
|
- flexibleMinutes = shiftResult.getFlexible_rule().get(0).getFlexible_early_minutes();
|
|
|
+ earlyFlexibleMinutes = shiftResult.getFlexible_rule().get(0).getFlexible_early_minutes();
|
|
|
+ lateFlexibleMinutes = shiftResult.getFlexible_rule().get(0).getFlexible_late_minutes();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
- flexibleMinutes = null==flexibleMinutes?0:flexibleMinutes;
|
|
|
+ earlyFlexibleMinutes = null==earlyFlexibleMinutes?0:earlyFlexibleMinutes;
|
|
|
+ lateFlexibleMinutes = null==lateFlexibleMinutes?0:lateFlexibleMinutes;
|
|
|
//获取打卡规则
|
|
|
FeishuPunchTimeRule feishuPunchTimeRule = null;
|
|
|
if(CollectionUtils.isNotEmpty(shiftResult.getPunch_time_rule())){
|
|
|
//仅获取第一个
|
|
|
feishuPunchTimeRule = shiftResult.getPunch_time_rule().get(0);
|
|
|
}
|
|
|
- /**
|
|
|
- * 弹性时间 0 非0
|
|
|
- * 0 仅判断是否缺卡
|
|
|
- * 非0 先判断弹性,再判断是否缺卡
|
|
|
- * */
|
|
|
- if(null != feishuPunchTimeRule){
|
|
|
- LocalDateTime.parse(feishuPunchTimeRule.getOn_time(),DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
- }
|
|
|
|
|
|
+ map.put("feishuPunchTimeRule",feishuPunchTimeRule);
|
|
|
|
|
|
- Instant checkInInstant = Instant.ofEpochSecond(Long.parseLong(record.getCheck_in_record().getCheck_time()));
|
|
|
- LocalDateTime checkInLocalTime = LocalDateTime.ofInstant(checkInInstant, ZoneId.of("GMT+8"));
|
|
|
- Instant checkOutInstant = Instant.ofEpochSecond(Long.parseLong(record.getCheck_out_record().getCheck_time()));
|
|
|
- LocalDateTime checkOutLocalTime = LocalDateTime.ofInstant(checkOutInstant, ZoneId.of("GMT+8"));
|
|
|
+ if(null != feishuPunchTimeRule){
|
|
|
+ //转换上下班规则时间
|
|
|
+ LocalDateTime onLocalDateTime = LocalDateTime.parse(dayStr + " " + feishuPunchTimeRule.getOn_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
|
|
|
+ LocalDateTime offLocalDateTime = LocalDateTime.parse(dayStr + " " + feishuPunchTimeRule.getOff_time(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
|
|
|
+ /**
|
|
|
+ * 弹性时间 0 非0
|
|
|
+ * 0 仅判断是否缺卡
|
|
|
+ * 非0 先判断弹性,再判断是否缺卡
|
|
|
+ * */
|
|
|
+// if("Lack".equals(record.getCheck_in_result()) || "Todo".equals(record.getCheck_in_result())){
|
|
|
+//
|
|
|
+// } else if ("Normal".equals(record.getCheck_in_result()) || "Early".equals(record.getCheck_in_result())) {
|
|
|
+//
|
|
|
+// }
|
|
|
+ //上下班打卡时间
|
|
|
+ LocalDateTime checkInLocalTime = null;
|
|
|
+ LocalDateTime checkOutLocalTime = null;
|
|
|
+ if(null != record.getCheck_in_record()){
|
|
|
+ Instant checkInInstant = Instant.ofEpochSecond(Long.parseLong(record.getCheck_in_record().getCheck_time()));
|
|
|
+ checkInLocalTime = LocalDateTime.ofInstant(checkInInstant, ZoneId.of("GMT+8"));
|
|
|
+ }
|
|
|
+ if(null != record.getCheck_out_record()){
|
|
|
+ Instant checkOutInstant = Instant.ofEpochSecond(Long.parseLong(record.getCheck_out_record().getCheck_time()));
|
|
|
+ checkOutLocalTime = LocalDateTime.ofInstant(checkOutInstant, ZoneId.of("GMT+8"));
|
|
|
+ }
|
|
|
|
|
|
- System.out.println("checkInInstant=== "+checkInLocalTime+",checkOutLocalTime=== "+checkOutLocalTime);
|
|
|
+ String startTime = null;
|
|
|
+ String endTime = null;
|
|
|
+ long workSeconds = 0l;
|
|
|
+ if(null == checkInLocalTime || null==checkOutLocalTime){
|
|
|
+ //记录为缺卡,工时为0
|
|
|
+ startTime = null == record.getCheck_in_record()?null:
|
|
|
+ checkInLocalTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
+ endTime = null == record.getCheck_out_record()?null:
|
|
|
+ checkOutLocalTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
+ }else{
|
|
|
+ startTime = checkInLocalTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
+ endTime = checkOutLocalTime.format(DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
+
|
|
|
+ if((checkInLocalTime.isBefore(onLocalDateTime) || checkInLocalTime.isEqual(onLocalDateTime))
|
|
|
+ && (checkOutLocalTime.isAfter(offLocalDateTime) || checkOutLocalTime.isEqual(offLocalDateTime))){
|
|
|
+ //正常上下班
|
|
|
+ long offStamp = offLocalDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ long onStamp = onLocalDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ workSeconds = offStamp-onStamp;
|
|
|
+ }else{
|
|
|
+
|
|
|
+ //判断上班是否满足缺卡条件
|
|
|
+ if(checkInLocalTime.isAfter(onLocalDateTime.plusMinutes(feishuPunchTimeRule.getLate_minutes_as_lack()))){
|
|
|
+ workSeconds = 0;
|
|
|
+ } else if (checkOutLocalTime.isBefore(offLocalDateTime.plusMinutes(feishuPunchTimeRule.getEarly_minutes_as_lack()))) {
|
|
|
+ workSeconds = 0;
|
|
|
+ }else {
|
|
|
+ //判断弹性时间
|
|
|
+ if(checkInLocalTime.isAfter(onLocalDateTime)){ //上班时间 在规定时间之后,查看上班是否在弹性,下班是否在弹性
|
|
|
+ long offStamp = checkOutLocalTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ long onStamp = checkInLocalTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ workSeconds = offStamp-onStamp;
|
|
|
+ //判断上班是否在弹性
|
|
|
+ boolean checkInFlag = checkInLocalTime.isBefore(onLocalDateTime.plusMinutes(lateFlexibleMinutes))
|
|
|
+ || checkInLocalTime.isEqual(onLocalDateTime.plusMinutes(lateFlexibleMinutes));
|
|
|
+ if(checkInFlag){
|
|
|
+ //在弹性上班范围内,判断下班
|
|
|
+ if(checkOutLocalTime.isAfter(offLocalDateTime.plusMinutes(lateFlexibleMinutes))
|
|
|
+ ||checkOutLocalTime.isEqual(offLocalDateTime.plusMinutes(lateFlexibleMinutes))){
|
|
|
+ offStamp = offLocalDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ onStamp = onLocalDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ workSeconds = offStamp-onStamp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if(checkOutLocalTime.isBefore(offLocalDateTime)){ //下班时间 在规定时间之前,查看下班是否在弹性,上班是否在弹性
|
|
|
+ long offStamp = checkOutLocalTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ long onStamp = checkInLocalTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ workSeconds = offStamp-onStamp;
|
|
|
+ //判断下班是否在弹性
|
|
|
+ boolean checkOutFlag = checkOutLocalTime.isAfter(offLocalDateTime.minusMinutes(earlyFlexibleMinutes))
|
|
|
+ || checkOutLocalTime.isEqual(offLocalDateTime.minusMinutes(earlyFlexibleMinutes));
|
|
|
+ if(checkOutFlag){
|
|
|
+ //在弹性下班范围内,判断上班
|
|
|
+ if(checkInLocalTime.isBefore(onLocalDateTime.minusMinutes(earlyFlexibleMinutes))
|
|
|
+ ||checkInLocalTime.isEqual(onLocalDateTime.minusMinutes(earlyFlexibleMinutes))){
|
|
|
+ offStamp = offLocalDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ onStamp = onLocalDateTime.toEpochSecond(ZoneOffset.of("+8"));
|
|
|
+ workSeconds = offStamp-onStamp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+// userFvTime.setStartTime(startTime);
|
|
|
+// userFvTime.setEndTime(endTime);
|
|
|
+ userFvTime.setWorkDate(LocalDate.parse(String.valueOf(day),DateTimeFormatter.ofPattern("yyyyMMdd")));
|
|
|
+ userFvTime.setCompanyId(jobNumUserMap.get(userTaskResult.getUser_id()).getCompanyId());
|
|
|
+// userFvTime.setWorkHours(workHours);
|
|
|
+
|
|
|
+ //计算休息时长
|
|
|
+ int sumRestSecond = 0;
|
|
|
+ List<FeishuRestTimeRule> restTimeRule = null == shiftResult.getRest_time_rule()?new ArrayList<>():shiftResult.getRest_time_rule();
|
|
|
+ for (FeishuRestTimeRule feishuRestTimeRule : restTimeRule) {
|
|
|
+ LocalTime tmpBeginTime = LocalTime.parse(feishuRestTimeRule.getRest_begin_time(), DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
+ LocalTime tmpEndTime = LocalTime.parse(feishuRestTimeRule.getRest_end_time(), DateTimeFormatter.ofPattern("HH:mm"));
|
|
|
+ sumRestSecond = tmpEndTime.toSecondOfDay() - tmpBeginTime.toSecondOfDay();
|
|
|
+ }
|
|
|
|
|
|
+ //获取加班时间段
|
|
|
+ //TODO 先不从班次规则里获取,直接类型为加班的记录相减
|
|
|
+ List<FeishuClockTaskRecord> overTimeList = userTaskResult.getRecords().stream().filter(t -> 1 == t.getTask_shift_type())
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ long sumOverTimeSeconds = 0;
|
|
|
+ if(CollectionUtils.isNotEmpty(overTimeList)){
|
|
|
+ for (FeishuClockTaskRecord feishuClockTaskRecord : overTimeList) {
|
|
|
+ long startOver = Long.parseLong(feishuClockTaskRecord.getCheck_in_record().getCheck_time());
|
|
|
+ long endOver = Long.parseLong(feishuClockTaskRecord.getCheck_in_record().getCheck_time());
|
|
|
+ sumOverTimeSeconds = endOver-startOver;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ userFvTime.setOverTimeSeconds(sumOverTimeSeconds);
|
|
|
+
|
|
|
+ float workHours = BigDecimal.valueOf((workSeconds - sumRestSecond + sumOverTimeSeconds) / (60 * 60f))
|
|
|
+ .setScale(2, RoundingMode.HALF_UP).floatValue();
|
|
|
+
|
|
|
+ userFvTime.setWorkHours(workHours);
|
|
|
+ userFvTime.setWorkDate(LocalDate.parse(String.valueOf(userTaskResult.getDay()), DateTimeFormatter.ofPattern("yyyyMMdd")));
|
|
|
+ //需要关联user表job_number
|
|
|
+ userFvTime.setUserId(jobNumUserMap.get(userTaskResult.getUser_id()).getId());
|
|
|
+ Date checkInTime = new Date(Long.parseLong(record.getCheck_in_record().getCheck_time()) * 1000);
|
|
|
+ Date checkOutTime = new Date(Long.parseLong(record.getCheck_out_record().getCheck_time()) * 1000);
|
|
|
+ userFvTime.setStartTime(HMFormat.format(checkInTime));
|
|
|
+ userFvTime.setEndTime(HMFormat.format(checkOutTime));
|
|
|
+
|
|
|
+ map.put("data",userFvTime);
|
|
|
+ map.put("startDateTime",format.format(checkInTime));
|
|
|
+ map.put("endDateTime",format.format(checkOutTime));
|
|
|
+ res.add(map);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- long secondCost = Long.parseLong(record.getCheck_out_record().getCheck_time())
|
|
|
- -Long.parseLong(record.getCheck_in_record().getCheck_time());
|
|
|
-// long hourCost = BigDecimal.valueOf(secondCost / (60 * 60))
|
|
|
-// .setScale(0, RoundingMode.UP).longValue();
|
|
|
- float hourCost = BigDecimal.valueOf(secondCost / (60 * 60f)).setScale(2, RoundingMode.HALF_UP).floatValue();
|
|
|
- userFvTime.setWorkHours(hourCost);
|
|
|
- userFvTime.setWorkDate(LocalDate.parse(String.valueOf(userTaskResult.getDay()), DateTimeFormatter.ofPattern("yyyyMMdd")));
|
|
|
- //需要关联user表job_number
|
|
|
- userFvTime.setUserId(jobNumIdMap.get(userTaskResult.getUser_id()));
|
|
|
- Date checkInTime = new Date(Long.parseLong(record.getCheck_in_record().getCheck_time()) * 1000);
|
|
|
- Date checkOutTime = new Date(Long.parseLong(record.getCheck_out_record().getCheck_time()) * 1000);
|
|
|
- userFvTime.setStartTime(HMFormat.format(checkInTime));
|
|
|
- userFvTime.setStartTime(HMFormat.format(checkOutTime));
|
|
|
+ toAddFvTimeList.add(userFvTime);
|
|
|
+ }
|
|
|
|
|
|
- map.put("data",userFvTime);
|
|
|
- map.put("startDateTime",format.format(checkInTime));
|
|
|
- map.put("endDateTime",format.format(checkOutTime));
|
|
|
- res.add(map);
|
|
|
- }
|
|
|
+ if(CollectionUtils.isNotEmpty(toAddFvTimeList)){
|
|
|
+ userFvTimeMapper.batchInsert(toAddFvTimeList);
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
msg.setData(res);
|
|
|
return msg;
|
|
|
}
|