|
|
@@ -0,0 +1,266 @@
|
|
|
+package com.xjrsoft.module.attendance.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.github.yulichang.base.MPJBaseServiceImpl;
|
|
|
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
+import com.xjrsoft.common.enums.ArchivesStatusEnum;
|
|
|
+import com.xjrsoft.common.enums.OutInStatusEnum;
|
|
|
+import com.xjrsoft.common.enums.StudyStatusEnum;
|
|
|
+import com.xjrsoft.common.exception.MyException;
|
|
|
+import com.xjrsoft.common.model.result.RT;
|
|
|
+import com.xjrsoft.common.page.ConventPage;
|
|
|
+import com.xjrsoft.common.utils.VoToColumnUtil;
|
|
|
+import com.xjrsoft.module.attendance.dto.AttendanceStatisticDto;
|
|
|
+import com.xjrsoft.module.attendance.entity.ClassAttendanceStatistics;
|
|
|
+import com.xjrsoft.module.attendance.entity.StudentAttendanceStatistics;
|
|
|
+import com.xjrsoft.module.attendance.mapper.StudentAttendanceStatisticsMapper;
|
|
|
+import com.xjrsoft.module.attendance.service.IClassStatisticsService;
|
|
|
+import com.xjrsoft.module.attendance.service.IStudentStatisticsService;
|
|
|
+import com.xjrsoft.module.attendance.vo.ClassStatisticsVo;
|
|
|
+import com.xjrsoft.module.attendance.vo.StudentStatisticsPageVo;
|
|
|
+import com.xjrsoft.module.base.entity.BaseClass;
|
|
|
+import com.xjrsoft.module.base.service.IBaseClassService;
|
|
|
+import com.xjrsoft.module.holiday.entity.HolidayDate;
|
|
|
+import com.xjrsoft.module.holiday.service.IHolidayDateService;
|
|
|
+import com.xjrsoft.module.organization.entity.User;
|
|
|
+import com.xjrsoft.module.organization.service.IUserService;
|
|
|
+import com.xjrsoft.module.outint.entity.StudentOutInRecord;
|
|
|
+import com.xjrsoft.module.outint.service.IStudentOutInRecordService;
|
|
|
+import com.xjrsoft.module.outint.vo.StudentOutInRecordVo;
|
|
|
+import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
|
|
|
+import com.xjrsoft.module.student.entity.StudentLeave;
|
|
|
+import com.xjrsoft.module.student.service.IStudentLeaveService;
|
|
|
+import com.xjrsoft.module.system.entity.DictionaryDetail;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import me.zhyd.oauth.log.Log;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+@Service
|
|
|
+@AllArgsConstructor
|
|
|
+public class StudentStatisticsServiceImpl extends MPJBaseServiceImpl<StudentAttendanceStatisticsMapper, StudentAttendanceStatistics> implements IStudentStatisticsService {
|
|
|
+
|
|
|
+ private final IUserService xjrUserService;
|
|
|
+ private final IHolidayDateService holidayDateService;
|
|
|
+ private final IStudentLeaveService studentLeaveService;
|
|
|
+ private final IStudentOutInRecordService studentOutInRecordService;
|
|
|
+
|
|
|
+ private final IBaseClassService classService;
|
|
|
+
|
|
|
+ private final IClassStatisticsService classStatisticsService;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void studentStatistics(String date, Integer timePeriod) {
|
|
|
+ try {
|
|
|
+ MPJLambdaWrapper<User> queryUser = new MPJLambdaWrapper<>();
|
|
|
+ queryUser.disableSubLogicDel().distinct()
|
|
|
+ .eq(BaseStudentSchoolRoll::getArchivesStatus, ArchivesStatusEnum.FB2901.getCode())
|
|
|
+
|
|
|
+ .selectAs(User::getId, StudentStatisticsPageVo::getUserId)
|
|
|
+ .selectAs(DictionaryDetail::getName, StudentStatisticsPageVo::getStduyStatusCn)
|
|
|
+
|
|
|
+ .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, User::getId)
|
|
|
+ .innerJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId)
|
|
|
+ .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseStudentSchoolRoll::getStduyStatus);
|
|
|
+
|
|
|
+ List<StudentStatisticsPageVo> userList = xjrUserService.selectJoinList(StudentStatisticsPageVo.class, queryUser);
|
|
|
+
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
|
|
|
+ LocalDate queryDate = LocalDate.parse(date, formatter);
|
|
|
+ HolidayDate holidayDate = holidayDateService.getOne(
|
|
|
+ new QueryWrapper<HolidayDate>().lambda()
|
|
|
+ .eq(HolidayDate::getDate, queryDate)
|
|
|
+ );
|
|
|
+ if (holidayDate != null && holidayDate.getWay() != null && holidayDate.getWay() != 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime startTime, endTime;
|
|
|
+
|
|
|
+ if (timePeriod == 1) {
|
|
|
+ startTime = queryDate.atTime(5, 0, 0);
|
|
|
+ endTime = queryDate.atTime(12, 0, 0);
|
|
|
+ } else if (timePeriod == 2) {
|
|
|
+ startTime = queryDate.atTime(12, 0, 0);
|
|
|
+ endTime = queryDate.atTime(18, 0, 0);
|
|
|
+ } else if (timePeriod == 3) {
|
|
|
+ startTime = queryDate.atTime(18, 0, 0);
|
|
|
+ endTime = queryDate.atTime(23, 59, 59);
|
|
|
+ } else {
|
|
|
+ startTime = queryDate.atTime(0, 0, 0);
|
|
|
+ endTime = queryDate.atTime(23, 59, 59);
|
|
|
+ }
|
|
|
+ //查询当前时间段存在请假的学生
|
|
|
+ Map<Long, StudentLeave> leaveList = studentLeaveService.getLeaveList(startTime, endTime);
|
|
|
+ //查询进入记录
|
|
|
+ List<StudentOutInRecord> outInRecords = studentOutInRecordService.list(
|
|
|
+ new MPJLambdaWrapper<StudentOutInRecord>()
|
|
|
+ .select(StudentOutInRecord.class, x -> VoToColumnUtil.fieldsToColumns(StudentOutInRecord.class).contains(x.getProperty()))
|
|
|
+ .eq(StudentOutInRecord::getStatus, OutInStatusEnum.enter.getCode())
|
|
|
+ .le(StudentOutInRecord::getRecordTime, endTime)
|
|
|
+ .eq("DATE_FORMAT(record_time, '%Y-%m-%d')", endTime.toLocalDate())
|
|
|
+ );
|
|
|
+ Map<Long, StudentOutInRecord> outInMap = new HashMap<>();
|
|
|
+ for (StudentOutInRecord inRecord : outInRecords) {
|
|
|
+ outInMap.put(inRecord.getUserId(), inRecord);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<StudentAttendanceStatistics> studentAttendanceStatisticsList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (StudentStatisticsPageVo record : userList) {
|
|
|
+ StudentLeave studentLeave = leaveList.get(record.getUserId());
|
|
|
+
|
|
|
+ StudentAttendanceStatistics studentAttendanceStatistics = new StudentAttendanceStatistics();
|
|
|
+
|
|
|
+ studentAttendanceStatistics.setUserId(record.getUserId());
|
|
|
+ studentAttendanceStatistics.setAttendanceDate(queryDate);
|
|
|
+ studentAttendanceStatistics.setTimeInterval(timePeriod);
|
|
|
+
|
|
|
+ if (studentLeave != null) {
|
|
|
+ studentAttendanceStatistics.setAttendanceStatus(studentLeave.getLeaveType());
|
|
|
+ } else {
|
|
|
+ StudentOutInRecord outInRecord = outInMap.get(record.getUserId());
|
|
|
+ if (outInRecord != null) {
|
|
|
+ studentAttendanceStatistics.setRecordTime(outInRecord.getRecordTime());
|
|
|
+ studentAttendanceStatistics.setAttendanceStatus(outInRecord.getAttendanceStatus());
|
|
|
+ } else {
|
|
|
+ studentAttendanceStatistics.setAttendanceStatus("缺勤");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StudyStatusEnum.InResidence.getValue().equals(record.getStduyStatusCn())) {
|
|
|
+ studentAttendanceStatistics.setAttendanceStatus("不考勤");
|
|
|
+ }
|
|
|
+
|
|
|
+ studentAttendanceStatisticsList.add(studentAttendanceStatistics);
|
|
|
+ }
|
|
|
+
|
|
|
+ this.baseMapper.delete(new QueryWrapper<StudentAttendanceStatistics>().lambda().eq(StudentAttendanceStatistics::getAttendanceDate,date).eq(StudentAttendanceStatistics::getTimeInterval,timePeriod));
|
|
|
+
|
|
|
+ if (!studentAttendanceStatisticsList.isEmpty()) {
|
|
|
+ this.saveBatch(studentAttendanceStatisticsList);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ Log.error(e.getMessage(), e);
|
|
|
+ throw new MyException("统计学生考勤出错");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void classStatistics(String date,Integer timePeriod) {
|
|
|
+
|
|
|
+ AttendanceStatisticDto dto = new AttendanceStatisticDto();
|
|
|
+ dto.setDate(date);
|
|
|
+ dto.setTimePeriod(timePeriod);
|
|
|
+
|
|
|
+ List<ClassStatisticsVo> attendanceList = classService.getAttendanceList(dto);
|
|
|
+ List<Long> classIds = new ArrayList<>();
|
|
|
+ for (ClassStatisticsVo record : attendanceList) {
|
|
|
+ classIds.add(record.getId());
|
|
|
+ }
|
|
|
+ if (dto.getDate() != null && !dto.getDate().isEmpty()) {
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE;
|
|
|
+ LocalDate queryDate = LocalDate.parse(dto.getDate(), formatter);
|
|
|
+
|
|
|
+ HolidayDate holidayDate = holidayDateService.getOne(
|
|
|
+ new QueryWrapper<HolidayDate>().lambda()
|
|
|
+ .eq(HolidayDate::getDate, queryDate)
|
|
|
+ );
|
|
|
+ if (holidayDate != null && holidayDate.getWay() != null && holidayDate.getWay() != 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime startTime, endTime;
|
|
|
+
|
|
|
+
|
|
|
+ if (dto.getTimePeriod() != null && dto.getTimePeriod() == 1) {
|
|
|
+ startTime = queryDate.atTime(5, 0, 0);
|
|
|
+ endTime = queryDate.atTime(12, 0, 0);
|
|
|
+ } else if (dto.getTimePeriod() != null && dto.getTimePeriod() == 2) {
|
|
|
+ startTime = queryDate.atTime(12, 0, 0);
|
|
|
+ endTime = queryDate.atTime(18, 0, 0);
|
|
|
+ } else if (dto.getTimePeriod() != null && dto.getTimePeriod() == 3) {
|
|
|
+ startTime = queryDate.atTime(18, 0, 0);
|
|
|
+ endTime = queryDate.atTime(23, 59, 59);
|
|
|
+ } else {
|
|
|
+ startTime = queryDate.atTime(0, 0, 0);
|
|
|
+ endTime = queryDate.atTime(23, 59, 59);
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询每个班的走读生实到人数
|
|
|
+ Map<Long, List<StudentOutInRecordVo>> notStayMap = studentOutInRecordService.getList(startTime, endTime, classIds);
|
|
|
+
|
|
|
+ //查询各班的请假人数
|
|
|
+ Map<Long, Integer> classLeaveCount = studentLeaveService.getClassLeaveCount(startTime, endTime);
|
|
|
+
|
|
|
+ List<ClassAttendanceStatistics> classAttendanceStatisticsList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (ClassStatisticsVo record : attendanceList) {
|
|
|
+
|
|
|
+ ClassAttendanceStatistics classAttendanceStatistics = new ClassAttendanceStatistics();
|
|
|
+
|
|
|
+ classAttendanceStatistics.setClassId(record.getId());
|
|
|
+ classAttendanceStatistics.setStudentCount(record.getStudentCount());
|
|
|
+ classAttendanceStatistics.setStayCount(record.getStayCount());
|
|
|
+ classAttendanceStatistics.setNotStayCount(record.getNotStayCount());
|
|
|
+ classAttendanceStatistics.setTimeInterval(timePeriod);
|
|
|
+ classAttendanceStatistics.setAttendanceDate(queryDate);
|
|
|
+// classAttendanceStatistics.setLateCount(record.getLateCount());
|
|
|
+// classAttendanceStatistics.setLeaveCount(record.getLeaveCount());
|
|
|
+
|
|
|
+
|
|
|
+ Integer leaveCount = 0;
|
|
|
+ if (classLeaveCount.get(record.getId()) != null) {
|
|
|
+ leaveCount = classLeaveCount.get(record.getId());
|
|
|
+ }
|
|
|
+ classAttendanceStatistics.setLeaveCount(leaveCount);
|
|
|
+ int actualCount = 0;
|
|
|
+ Set<Long> userIds = new HashSet<>();
|
|
|
+ Integer lateCount = 0, playTruantCount = 0;
|
|
|
+ for (StudentOutInRecordVo outInRecordVo : notStayMap.get(record.getId())) {
|
|
|
+ if (userIds.contains(outInRecordVo.getUserId())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if ("迟到".equals(outInRecordVo.getAttendanceStatus())) {
|
|
|
+ lateCount++;
|
|
|
+ } else if ("旷课".equals(outInRecordVo.getAttendanceStatus())) {
|
|
|
+ playTruantCount++;
|
|
|
+ }
|
|
|
+ actualCount++;
|
|
|
+ userIds.add(outInRecordVo.getUserId());
|
|
|
+ }
|
|
|
+ classAttendanceStatistics.setActualCount(actualCount);
|
|
|
+ classAttendanceStatistics.setPlayTruantCount(playTruantCount);
|
|
|
+ classAttendanceStatistics.setLateCount(lateCount);
|
|
|
+
|
|
|
+ //最后通过总人数-实到人数-请假人数计算出缺勤人数
|
|
|
+ classAttendanceStatistics.setAbsenteeismCount(classAttendanceStatistics.getNotStayCount() - classAttendanceStatistics.getLeaveCount() - classAttendanceStatistics.getActualCount());
|
|
|
+
|
|
|
+ //计算出勤率
|
|
|
+ BigDecimal divide = BigDecimal.ZERO;
|
|
|
+ if (classAttendanceStatistics.getNotStayCount() != null && classAttendanceStatistics.getNotStayCount() != 0) {
|
|
|
+ divide = BigDecimal.valueOf(classAttendanceStatistics.getActualCount()).divide(BigDecimal.valueOf(classAttendanceStatistics.getNotStayCount()), 4, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+ classAttendanceStatistics.setAttendanceRate(divide.doubleValue() + "");
|
|
|
+
|
|
|
+ classAttendanceStatisticsList.add(classAttendanceStatistics);
|
|
|
+ }
|
|
|
+ classStatisticsService.delete(date, timePeriod);
|
|
|
+ if (!classAttendanceStatisticsList.isEmpty()) {
|
|
|
+ classStatisticsService.add(classAttendanceStatisticsList);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|