|
@@ -1,28 +1,46 @@
|
|
|
package com.xjrsoft.module.attendance.service.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.github.yulichang.base.MPJBaseServiceImpl;
|
|
|
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
+import com.google.gson.JsonArray;
|
|
|
+import com.google.gson.JsonObject;
|
|
|
import com.xjrsoft.common.exception.MyException;
|
|
|
+import com.xjrsoft.common.utils.VoToColumnUtil;
|
|
|
import com.xjrsoft.module.attendance.dto.AddAttendanceStatisticsDto;
|
|
|
import com.xjrsoft.module.attendance.dto.AttendanceStatisticsPageDto;
|
|
|
import com.xjrsoft.module.attendance.dto.AttendanceStatisticsRecordDto;
|
|
|
+import com.xjrsoft.module.attendance.entity.AttendanceRuleDetails;
|
|
|
import com.xjrsoft.module.attendance.entity.AttendanceStatistics;
|
|
|
import com.xjrsoft.module.attendance.entity.AttendanceStatisticsRecord;
|
|
|
+import com.xjrsoft.module.attendance.entity.AttendanceUserRelation;
|
|
|
+import com.xjrsoft.module.attendance.entity.TeacherAttendanceRecord;
|
|
|
import com.xjrsoft.module.attendance.mapper.AttendanceStatisticsMapper;
|
|
|
-import com.xjrsoft.module.attendance.mapper.AttendanceStatisticsRecordMapper;
|
|
|
+import com.xjrsoft.module.attendance.service.IAttendanceRuleCategoryService;
|
|
|
+import com.xjrsoft.module.attendance.service.IAttendanceStatisticsRecordService;
|
|
|
import com.xjrsoft.module.attendance.service.IAttendanceStatisticsService;
|
|
|
+import com.xjrsoft.module.attendance.service.ITeacherAttendanceRecordService;
|
|
|
import com.xjrsoft.module.attendance.vo.AttendanceStatisticsPageVo;
|
|
|
import com.xjrsoft.module.attendance.vo.AttendanceStatisticsRecordVo;
|
|
|
+import com.xjrsoft.module.organization.entity.User;
|
|
|
+import com.xjrsoft.module.organization.service.IUserService;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import me.zhyd.oauth.log.Log;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
import java.util.Objects;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -37,7 +55,13 @@ import java.util.stream.Collectors;
|
|
|
public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<AttendanceStatisticsMapper, AttendanceStatistics> implements IAttendanceStatisticsService {
|
|
|
private final AttendanceStatisticsMapper statisticsMapper;
|
|
|
|
|
|
- private final AttendanceStatisticsRecordMapper recordMapper;
|
|
|
+ private final IAttendanceStatisticsRecordService statisticsRecordService;
|
|
|
+
|
|
|
+ private final ITeacherAttendanceRecordService recordService;
|
|
|
+
|
|
|
+ private final IUserService userService;
|
|
|
+
|
|
|
+ private final IAttendanceRuleCategoryService ruleCategoryService;
|
|
|
|
|
|
|
|
|
@Override
|
|
@@ -57,7 +81,7 @@ public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<Attendan
|
|
|
//********************************* AttendanceStatisticsRecord 增删改 开始 *******************************************/
|
|
|
{
|
|
|
// 查出所有子级的id
|
|
|
- List<AttendanceStatisticsRecord> attendanceStatisticsRecordList = recordMapper.selectList(Wrappers.lambdaQuery(AttendanceStatisticsRecord.class).eq(AttendanceStatisticsRecord::getAttendanceStatisticsId, attendanceStatistics.getId()).select(AttendanceStatisticsRecord::getId));
|
|
|
+ List<AttendanceStatisticsRecord> attendanceStatisticsRecordList = statisticsRecordService.list(Wrappers.lambdaQuery(AttendanceStatisticsRecord.class).eq(AttendanceStatisticsRecord::getAttendanceStatisticsId, attendanceStatistics.getId()).select(AttendanceStatisticsRecord::getId));
|
|
|
List<Long> attendanceStatisticsRecordIds = attendanceStatisticsRecordList.stream().map(AttendanceStatisticsRecord::getId).collect(Collectors.toList());
|
|
|
//原有子表单 没有被删除的主键
|
|
|
List<Long> attendanceStatisticsRecordOldIds = attendanceStatistics.getAttendanceStatisticsRecordList().stream().map(AttendanceStatisticsRecord::getId).filter(Objects::nonNull).collect(Collectors.toList());
|
|
@@ -67,18 +91,18 @@ public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<Attendan
|
|
|
for (AttendanceStatisticsRecord attendanceStatisticsRecord : attendanceStatistics.getAttendanceStatisticsRecordList()) {
|
|
|
//如果不等于空则修改
|
|
|
if (attendanceStatisticsRecord.getId() != null) {
|
|
|
- recordMapper.updateById(attendanceStatisticsRecord);
|
|
|
+ statisticsRecordService.updateById(attendanceStatisticsRecord);
|
|
|
}
|
|
|
//如果等于空 则新增
|
|
|
else {
|
|
|
//已经不存在的id 删除
|
|
|
attendanceStatisticsRecord.setAttendanceStatisticsId(attendanceStatistics.getId());
|
|
|
- recordMapper.insert(attendanceStatisticsRecord);
|
|
|
+ statisticsRecordService.save(attendanceStatisticsRecord);
|
|
|
}
|
|
|
}
|
|
|
//已经不存在的id 删除
|
|
|
if(attendanceStatisticsRecordRemoveIds.size() > 0){
|
|
|
- recordMapper.deleteBatchIds(attendanceStatisticsRecordRemoveIds);
|
|
|
+ statisticsRecordService.removeBatchByIds(attendanceStatisticsRecordRemoveIds);
|
|
|
}
|
|
|
}
|
|
|
//********************************* AttendanceStatisticsRecord 增删改 结束 *******************************************/
|
|
@@ -90,7 +114,7 @@ public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<Attendan
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public Boolean delete(List<Long> ids) {
|
|
|
statisticsMapper.deleteBatchIds(ids);
|
|
|
- recordMapper.delete(Wrappers.lambdaQuery(AttendanceStatisticsRecord.class).in(AttendanceStatisticsRecord::getAttendanceStatisticsId, ids));
|
|
|
+ statisticsRecordService.remove(Wrappers.lambdaQuery(AttendanceStatisticsRecord.class).in(AttendanceStatisticsRecord::getAttendanceStatisticsId, ids));
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -117,18 +141,159 @@ public class AttendanceStatisticsServiceImpl extends MPJBaseServiceImpl<Attendan
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public Boolean refreshRecord(Long id) {
|
|
|
try {
|
|
|
+ //1、修改状态为统计中
|
|
|
AttendanceStatistics statistics = this.getById(id);
|
|
|
statistics.setStatus(0);
|
|
|
statistics.setModifyDate(new Date());
|
|
|
this.updateById(statistics);
|
|
|
+
|
|
|
+ //2、删除以前的数据
|
|
|
+ statisticsRecordService.remove(
|
|
|
+ new QueryWrapper<AttendanceStatisticsRecord>().lambda()
|
|
|
+ .eq(AttendanceStatisticsRecord::getAttendanceStatisticsId, id)
|
|
|
+ );
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 3、重新计算数据并入库
|
|
|
+ */
|
|
|
+ //3.1、根据考勤规则和统计的时间段查询这个规则下面所涉及到的老师
|
|
|
+ List<User> userList = userService.list(
|
|
|
+ new MPJLambdaWrapper<User>()
|
|
|
+ .select(User::getId)
|
|
|
+ .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
|
|
|
+ .innerJoin(AttendanceUserRelation.class, AttendanceUserRelation::getUserId, User::getId)
|
|
|
+ .eq(AttendanceUserRelation::getAttendanceRuleCategoryId, statistics.getAttendanceRuleCategoryId())
|
|
|
+ );
|
|
|
+ if(userList.isEmpty()){
|
|
|
+ throw new MyException("该规则下无考勤人员");
|
|
|
+ }
|
|
|
+ List<Long> userIds = userList.stream().map(User::getId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ //查询固化的考勤数据
|
|
|
+ List<TeacherAttendanceRecord> attendanceRecords = recordService.list(
|
|
|
+ new QueryWrapper<TeacherAttendanceRecord>().lambda()
|
|
|
+ .eq(TeacherAttendanceRecord::getTimeInterval, statistics.getTimePeriod())
|
|
|
+ .in(TeacherAttendanceRecord::getUserId, userIds)
|
|
|
+ .between(TeacherAttendanceRecord::getCreateDate, statistics.getStartDate(), statistics.getEndDate())
|
|
|
+ );
|
|
|
+ //3.2、计算出所有的天数
|
|
|
+ List<LocalDate> dateList = getDatesBetween(statistics.getStartDate(), statistics.getEndDate());
|
|
|
+ //3.3、循环用户进行统计查询
|
|
|
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
|
|
|
+ DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("HH:mm");
|
|
|
+ Map<String, String> weekCnMap = initWeekCn();
|
|
|
+ Map<String, String> weekEnMap = initWeekEn();
|
|
|
+
|
|
|
+ //3.4、查询这个考勤规则下面的所有细则并转换成map
|
|
|
+ List<AttendanceRuleDetails> ruleList = ruleCategoryService.getRules(statistics.getAttendanceRuleCategoryId());
|
|
|
+ Map<String, AttendanceRuleDetails> ruleMap = ruleList.stream().collect(Collectors.toMap(AttendanceRuleDetails::getDateType, x -> x));
|
|
|
+ //3.5、循环计算,并存入insertList,方便后续批量入库
|
|
|
+ List<AttendanceStatisticsRecord> insertList = new ArrayList<>();
|
|
|
+ for (User user : userList) {
|
|
|
+ AttendanceStatisticsRecord record = new AttendanceStatisticsRecord();
|
|
|
+ record.setUserId(user.getId());
|
|
|
+ Long normalCount = 0L;
|
|
|
+ Long leaveCount = 0L;
|
|
|
+ Long absenteeCount = 0L;
|
|
|
+ JsonArray daysData = new JsonArray();
|
|
|
+ for (LocalDate localDate : dateList) {
|
|
|
+ String dayOfWeekName = localDate.getDayOfWeek().name();
|
|
|
+ AttendanceRuleDetails ruleDetails = ruleMap.get(weekEnMap.get(dayOfWeekName));
|
|
|
+ JsonObject daysJson = new JsonObject();
|
|
|
+ daysJson.addProperty("date", localDate.format(dtf));
|
|
|
+ daysJson.addProperty("week", weekCnMap.get(dayOfWeekName));
|
|
|
+ String content = "";
|
|
|
+ if(statistics.getTimePeriod() == 1){
|
|
|
+ content += "(" + ruleDetails.getAmStartTime().toLocalTime().format(timeDtf) + ")上班 ";
|
|
|
+ }else if(statistics.getTimePeriod() == 2){
|
|
|
+ content += "(" + ruleDetails.getPmStartTime().toLocalTime().format(timeDtf) + ")上班 ";
|
|
|
+ }
|
|
|
+ List<TeacherAttendanceRecord> collect = attendanceRecords.stream().filter(el -> el.getRecordTime().toLocalDate().equals(localDate)).collect(Collectors.toList());
|
|
|
+ for (TeacherAttendanceRecord attendanceRecord : collect) {
|
|
|
+ if("到校".equals(attendanceRecord.getAttendanceStatus())){
|
|
|
+ normalCount ++;
|
|
|
+ content += "正常(" + attendanceRecord.getRecordTime().toLocalTime().format(timeDtf) + ")";
|
|
|
+ }else if("请假".equals(attendanceRecord.getAttendanceStatus())){
|
|
|
+ leaveCount ++;
|
|
|
+ content += "请假";
|
|
|
+ }else{
|
|
|
+ absenteeCount ++;
|
|
|
+ content += "缺勤";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ daysJson.addProperty("content", content);
|
|
|
+ daysData.add(daysJson);
|
|
|
+ }
|
|
|
+ record.setNormalCount(normalCount);
|
|
|
+ record.setLeaveCount(leaveCount);
|
|
|
+ record.setAbsenteeCount(absenteeCount);
|
|
|
+ record.setDaysData(daysData.toString());
|
|
|
+ insertList.add(record);
|
|
|
+ }
|
|
|
+
|
|
|
+ //3.6、插入数据
|
|
|
+ if(!insertList.isEmpty()){
|
|
|
+ statisticsRecordService.saveBatch(insertList);
|
|
|
+ }
|
|
|
+
|
|
|
+ //4、将状态改为统计完成
|
|
|
+ statistics = this.getById(id);
|
|
|
+ statistics.setStatus(1);
|
|
|
+ statistics.setModifyDate(new Date());
|
|
|
+ this.updateById(statistics);
|
|
|
}catch (Exception e){
|
|
|
Log.error(e.getMessage(), e);
|
|
|
- throw new MyException("刷新出错,请联系管理员");
|
|
|
+ if(e.getClass().equals(MyException.class)){
|
|
|
+ throw new MyException(e.getMessage());
|
|
|
+ }else{
|
|
|
+ throw new MyException("刷新出错,请联系管理员");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+ private List<LocalDate> getDatesBetween(LocalDate startDate, LocalDate endDate) {
|
|
|
+ List<LocalDate> dates = new ArrayList<>();
|
|
|
+
|
|
|
+ long numOfDaysBetween = ChronoUnit.DAYS.between(startDate, endDate) + 1; // +1 包含结束日期
|
|
|
+ for (long i = 0; i < numOfDaysBetween; i++) {
|
|
|
+ dates.add(startDate.plusDays(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ return dates;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, String> initWeekCn() {
|
|
|
+ Map<String, String> result = new HashMap<>();
|
|
|
+
|
|
|
+ result.put("MONDAY", "周一");
|
|
|
+ result.put("TUESDAY", "周一");
|
|
|
+ result.put("WEDNESDAY", "周一");
|
|
|
+ result.put("THURSDAY", "周一");
|
|
|
+ result.put("FRIDAY", "周一");
|
|
|
+ result.put("SATURDAY", "周一");
|
|
|
+ result.put("SUNDAY", "周日");
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<String, String> initWeekEn() {
|
|
|
+ Map<String, String> result = new HashMap<>();
|
|
|
+
|
|
|
+ result.put("MONDAY", "monday");
|
|
|
+ result.put("TUESDAY", "tuesday");
|
|
|
+ result.put("WEDNESDAY", "wednesday");
|
|
|
+ result.put("THURSDAY", "thursday");
|
|
|
+ result.put("FRIDAY", "friday");
|
|
|
+ result.put("SATURDAY", "saturday");
|
|
|
+ result.put("SUNDAY", "sunday");
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public byte[] recordExport(Long id) throws IOException {
|
|
|
return new byte[0];
|