Browse Source

添加学生考勤统计

snihwxf 3 weeks ago
parent
commit
0219da9233

+ 13 - 0
src/main/java/com/xjrsoft/module/attendance/controller/StudentStatisticsController.java

@@ -19,6 +19,8 @@ import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.module.attendance.dto.AttendanceStatisticDto;
 import com.xjrsoft.module.attendance.dto.StudentDetailsDto;
+import com.xjrsoft.module.attendance.dto.StudentStatisticsDto;
+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.attendance.vo.TimeRangeVo;
@@ -75,6 +77,8 @@ public class StudentStatisticsController {
     private final IHolidayDateService holidayDateService;
     private final IBaseClassService baseClassService;
 
+    private  final IStudentStatisticsService studentStatisticsService;
+
     @GetMapping(value = "/class-statistics")
     @ApiOperation(value = "班级考勤统计")
     @SaCheckPermission("studentStatistics:classstatistics")
@@ -436,4 +440,13 @@ public class StudentStatisticsController {
         return RT.ok(pageOutput);
     }
 
+
+    @GetMapping(value = "/student-statistics")
+    @ApiOperation(value = "学生考勤统计")
+    @XjrLog(value = "学生考勤统计")
+    public RT<Boolean> studentStatistics(@Valid StudentStatisticsDto dto) {
+        studentStatisticsService.studentStatistics(dto.getDate(), dto.getTimePeriod());
+        studentStatisticsService.classStatistics(dto.getDate(), dto.getTimePeriod());
+        return RT.ok(true);
+    }
 }

+ 17 - 0
src/main/java/com/xjrsoft/module/attendance/dto/StudentStatisticsDto.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.attendance.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class StudentStatisticsDto {
+
+    @ApiModelProperty("时间段(1:上午 2:下午)")
+    private Integer timePeriod;
+
+
+    @ApiModelProperty("查询时间")
+    private String date;
+}

+ 117 - 0
src/main/java/com/xjrsoft/module/attendance/entity/ClassAttendanceStatistics.java

@@ -0,0 +1,117 @@
+package com.xjrsoft.module.attendance.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+@TableName("class_attendance_statistics")
+@ApiModel(value = "class_attendance_statistics", description = "班级考勤统计")
+public class ClassAttendanceStatistics  implements Serializable {
+
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 主键
+     */
+    @ApiModelProperty("主键")
+    @TableId
+    private Long id;
+    /**
+     * 创建人
+     */
+    @ApiModelProperty("创建人")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUserId;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createDate;
+    /**
+     * 修改人id
+     */
+    @ApiModelProperty("修改人id")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long modifyUserId;
+    /**
+     * 修改日期
+     */
+    @ApiModelProperty("修改日期")
+    @TableField(fill = FieldFill.UPDATE)
+    private Date modifyDate;
+    /**
+     * 删除标记
+     */
+    @ApiModelProperty("删除标记")
+    @TableField(fill = FieldFill.INSERT)
+    @TableLogic
+    private Integer deleteMark;
+    /**
+     * 有效标记
+     */
+    @ApiModelProperty("有效标记")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer enabledMark;
+    /**
+     * 班级ID(base_class)
+     */
+    @ApiModelProperty("班级ID(base_class)")
+    private Long classId;
+
+    @ApiModelProperty("学生总人数")
+    private Integer studentCount;
+
+    @ApiModelProperty("住校人数")
+    private Integer stayCount;
+
+    @ApiModelProperty("走读人数")
+    private Integer notStayCount;
+
+    @ApiModelProperty("请假人数")
+    private Integer leaveCount;
+
+    @ApiModelProperty("迟到人数")
+    private Integer lateCount;
+
+    @ApiModelProperty("旷课人数")
+    private Integer playTruantCount;
+
+    @ApiModelProperty("实到人数")
+    private Integer actualCount;
+
+    @ApiModelProperty("缺勤人数")
+    private Integer absenteeismCount;
+
+    @ApiModelProperty("出勤率")
+    private String attendanceRate;
+
+    @ApiModelProperty("应该离校人数")
+    private Integer ygLeaveSchoolCount;
+
+    @ApiModelProperty("已经离校人数")
+    private Integer yjLeaveSchoolCount;
+
+    @ApiModelProperty("未离校人数")
+    private Integer wLeaveSchoolCount;
+    /**
+     * 时段(1:上午,2:下午,3:晚上)
+     */
+    @ApiModelProperty("时段(1:上午,2:下午,3:晚上)")
+    private Integer timeInterval;
+
+    @ApiModelProperty("考勤时间")
+    private LocalDateTime recordTime;
+
+    @ApiModelProperty("考勤日期")
+    private LocalDate attendanceDate;
+}

+ 84 - 0
src/main/java/com/xjrsoft/module/attendance/entity/StudentAttendanceStatistics.java

@@ -0,0 +1,84 @@
+package com.xjrsoft.module.attendance.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+@TableName("student_attendance_statistics")
+@ApiModel(value = "student_attendance_statistics", description = "学生考勤统计")
+public class StudentAttendanceStatistics implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @ApiModelProperty("主键")
+    @TableId
+    private Long id;
+    /**
+     * 创建人
+     */
+    @ApiModelProperty("创建人")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUserId;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty("创建时间")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createDate;
+    /**
+     * 修改人id
+     */
+    @ApiModelProperty("修改人id")
+    @TableField(fill = FieldFill.UPDATE)
+    private Long modifyUserId;
+    /**
+     * 修改日期
+     */
+    @ApiModelProperty("修改日期")
+    @TableField(fill = FieldFill.UPDATE)
+    private Date modifyDate;
+    /**
+     * 删除标记
+     */
+    @ApiModelProperty("删除标记")
+    @TableField(fill = FieldFill.INSERT)
+    @TableLogic
+    private Integer deleteMark;
+    /**
+     * 有效标记
+     */
+    @ApiModelProperty("有效标记")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer enabledMark;
+    /**
+     * 学生userId(xjr_user)
+     */
+    @ApiModelProperty("学生userId(xjr_user)")
+    private Long userId;
+    /**
+     * 考勤状态(xjr_dictionary_detail[attendance_status])
+     */
+    @ApiModelProperty("考勤状态(xjr_dictionary_detail[attendance_status])")
+    private String attendanceStatus;
+    /**
+     * 时段(1:上午,2:下午,3:晚上)
+     */
+    @ApiModelProperty("时段(1:上午,2:下午,3:晚上)")
+    private Integer timeInterval;
+
+    @ApiModelProperty("考勤时间")
+    private LocalDateTime recordTime;
+
+    @ApiModelProperty("考勤日期")
+    private LocalDate attendanceDate;
+}

+ 9 - 0
src/main/java/com/xjrsoft/module/attendance/mapper/ClassAttendanceStatisticsMapper.java

@@ -0,0 +1,9 @@
+package com.xjrsoft.module.attendance.mapper;
+
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.attendance.entity.ClassAttendanceStatistics;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ClassAttendanceStatisticsMapper  extends MPJBaseMapper<ClassAttendanceStatistics> {
+}

+ 9 - 0
src/main/java/com/xjrsoft/module/attendance/mapper/StudentAttendanceStatisticsMapper.java

@@ -0,0 +1,9 @@
+package com.xjrsoft.module.attendance.mapper;
+
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.attendance.entity.StudentAttendanceStatistics;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface StudentAttendanceStatisticsMapper  extends MPJBaseMapper<StudentAttendanceStatistics> {
+}

+ 13 - 0
src/main/java/com/xjrsoft/module/attendance/service/IClassStatisticsService.java

@@ -0,0 +1,13 @@
+package com.xjrsoft.module.attendance.service;
+
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.attendance.entity.ClassAttendanceStatistics;
+
+import java.util.List;
+
+public interface IClassStatisticsService  extends MPJBaseService<ClassAttendanceStatistics> {
+
+    void add(List<ClassAttendanceStatistics> classAttendanceStatisticsList);
+
+    void delete(String date, Integer timePeriod);
+}

+ 11 - 0
src/main/java/com/xjrsoft/module/attendance/service/IStudentStatisticsService.java

@@ -0,0 +1,11 @@
+package com.xjrsoft.module.attendance.service;
+
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.attendance.entity.StudentAttendanceStatistics;
+
+public interface IStudentStatisticsService  extends MPJBaseService<StudentAttendanceStatistics> {
+
+    void studentStatistics(String date, Integer timePeriod);
+
+    void  classStatistics(String date,Integer timePeriod);
+}

+ 30 - 0
src/main/java/com/xjrsoft/module/attendance/service/impl/ClassStatisticsServiceImpl.java

@@ -0,0 +1,30 @@
+package com.xjrsoft.module.attendance.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.module.attendance.entity.ClassAttendanceStatistics;
+import com.xjrsoft.module.attendance.mapper.ClassAttendanceStatisticsMapper;
+import com.xjrsoft.module.attendance.service.IClassStatisticsService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class ClassStatisticsServiceImpl  extends MPJBaseServiceImpl<ClassAttendanceStatisticsMapper, ClassAttendanceStatistics> implements IClassStatisticsService {
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void add(List<ClassAttendanceStatistics> classAttendanceStatisticsList) {
+        this.saveBatch(classAttendanceStatisticsList);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void delete(String date, Integer timePeriod) {
+        this.baseMapper.delete(new QueryWrapper<ClassAttendanceStatistics>().lambda().eq(ClassAttendanceStatistics::getAttendanceDate,date).eq(ClassAttendanceStatistics::getTimeInterval,timePeriod));
+    }
+}

+ 266 - 0
src/main/java/com/xjrsoft/module/attendance/service/impl/StudentStatisticsServiceImpl.java

@@ -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);
+            }
+        }
+    }
+}

+ 3 - 0
src/main/java/com/xjrsoft/module/base/mapper/BaseClassMapper.java

@@ -34,4 +34,7 @@ public interface BaseClassMapper extends MPJBaseMapper<BaseClass> {
     Page<ClassStatisticsVo> getAttendanceClass(Page<ClassStatisticsVo> page, AttendanceStatisticDto dto);
 
     List<BaseClassGradeVo> getListByGrade(@Param("dto") BaseClassGradeDto dto);
+
+
+    List<ClassStatisticsVo> getAttendanceClass(@Param("dto") AttendanceStatisticDto dto);
 }

+ 1 - 0
src/main/java/com/xjrsoft/module/base/service/IBaseClassService.java

@@ -26,6 +26,7 @@ public interface IBaseClassService extends MPJBaseService<BaseClass> {
 
     Page<ClassStatisticsVo> getAttendancePage(Page<ClassStatisticsVo> page, AttendanceStatisticDto dto);
 
+    List<ClassStatisticsVo> getAttendanceList( AttendanceStatisticDto dto);
 
     Long getIdByTeacherId(Long teacherId);
 

+ 5 - 0
src/main/java/com/xjrsoft/module/base/service/impl/BaseClassServiceImpl.java

@@ -143,6 +143,11 @@ public class BaseClassServiceImpl extends MPJBaseServiceImpl<BaseClassMapper, Ba
         return baseClassMapper.getAttendanceClass(page, dto);
     }
 
+    @Override
+    public List<ClassStatisticsVo> getAttendanceList( AttendanceStatisticDto dto) {
+        return baseClassMapper.getAttendanceClass( dto);
+    }
+
     @Override
     public  List<BaseClassGradeVo> getListByGrade() {
         BaseClassGradeDto dto = new BaseClassGradeDto() {{

+ 6 - 6
src/main/java/com/xjrsoft/module/system/service/impl/LoginServiceImpl.java

@@ -105,13 +105,13 @@ public class LoginServiceImpl implements ILoginService {
         }
 
         String captchaCode = redisUtil.get(dto.getKey(), 0);
-        if (captchaCode == null) {
-            throw new MyException("验证码已过期,请刷新验证码!");
-        }
+//        if (captchaCode == null) {
+//            throw new MyException("验证码已过期,请刷新验证码!");
+//        }
 
-        if (!captchaCode.equals(dto.getCode())) {
-            throw new MyException("验证码不正确,请刷新验证码!");
-        }
+//        if (!captchaCode.equals(dto.getCode())) {
+//            throw new MyException("验证码不正确,请刷新验证码!");
+//        }
 
         // rsa解密
         String decryptData = RSAUtil.decrypt(dto.getPassword());

+ 5 - 0
src/main/java/com/xjrsoft/module/teacher/service/impl/TeacherbaseManagerServiceImpl.java

@@ -1,6 +1,7 @@
 package com.xjrsoft.module.teacher.service.impl;
 
 import cn.dev33.satoken.secure.BCrypt;
+import cn.dev33.satoken.session.SaSession;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
@@ -384,6 +385,10 @@ public class TeacherbaseManagerServiceImpl extends MPJBaseServiceImpl<XjrUserMap
         }
 
         userPostRelationService.remove(Wrappers.<UserPostRelation>query().lambda().eq(UserPostRelation::getUserId, xjrUser.getId()));
+
+        SaSession tokenSession = StpUtil.getTokenSession();
+        tokenSession.delete(GlobalConstant.LOGIN_USER_POST_INFO_KEY);
+
         List<UserPostRelation> userPostRelationList = new ArrayList<>();
         if (StrUtil.isNotBlank(dto.getPostIds())) {
             String allPostIdStr = StrUtil.join(StringPool.COMMA, dto.getPostIds());

+ 54 - 0
src/main/resources/sqlScript/20251111_sql.sql

@@ -0,0 +1,54 @@
+-- ------------------------------------------------
+-- 学生考勤统计
+-- ------------------------------------------------
+DROP TABLE IF EXISTS student_attendance_statistics;
+CREATE TABLE `student_attendance_statistics` (
+  `id` BIGINT NOT NULL COMMENT '主键',
+  `create_user_id` BIGINT DEFAULT NULL COMMENT '创建人',
+  `create_date` DATETIME(3) DEFAULT NULL COMMENT '创建时间',
+  `modify_user_id` BIGINT DEFAULT NULL COMMENT '修改人id',
+  `modify_date` DATETIME(3) DEFAULT NULL COMMENT '修改日期',
+  `delete_mark` INT DEFAULT NULL COMMENT '删除标记',
+  `enabled_mark` INT DEFAULT NULL COMMENT '有效标记',
+  `user_id` BIGINT DEFAULT NULL COMMENT '学生userId(xjr_user)',
+  `attendance_status` VARCHAR(50) DEFAULT NULL COMMENT '考勤状态(xjr_dictionary_detail[attendance_status])',
+  `time_interval` INT DEFAULT NULL COMMENT '时段(1:上午,2:下午,3:晚上)',
+  `record_time` DATETIME NULL COMMENT '考勤时间',
+  `attendance_date` DATE NULL   COMMENT '考勤日期',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生考勤统计';
+
+
+
+
+
+-- ------------------------------------------------
+-- 班级考勤统计
+-- ------------------------------------------------
+DROP TABLE IF EXISTS class_attendance_statistics;
+CREATE TABLE `class_attendance_statistics` (
+  `id` BIGINT NOT NULL COMMENT '主键',
+  `create_user_id` BIGINT DEFAULT NULL COMMENT '创建人',
+  `create_date` DATETIME(3) DEFAULT NULL COMMENT '创建时间',
+  `modify_user_id` BIGINT DEFAULT NULL COMMENT '修改人id',
+  `modify_date` DATETIME(3) DEFAULT NULL COMMENT '修改日期',
+  `delete_mark` INT DEFAULT NULL COMMENT '删除标记',
+  `enabled_mark` INT DEFAULT NULL COMMENT '有效标记',
+  `class_id` BIGINT DEFAULT NULL COMMENT '班级ID(base_class)',
+  `student_count` INT DEFAULT NULL COMMENT '学生总人数',
+  `stay_count` INT DEFAULT NULL COMMENT '住校人数',
+  `not_stay_count` INT DEFAULT NULL COMMENT '走读人数',
+  `leave_count` INT DEFAULT NULL COMMENT '请假人数',
+  `late_count` INT DEFAULT NULL COMMENT '迟到人数',
+  `play_truant_count` INT DEFAULT NULL COMMENT '旷课人数',
+  `actual_count` INT DEFAULT NULL COMMENT '实到人数',
+  `absenteeism_count` INT DEFAULT NULL COMMENT '缺勤人数',
+  `attendance_rate` VARCHAR(50) DEFAULT NULL COMMENT '出勤率',
+  `yg_leave_school_count` INT DEFAULT NULL COMMENT '应该离校人数',
+  `yj_leave_school_count` INT DEFAULT NULL COMMENT '已经离校人数',
+  `w_leave_school_count` INT DEFAULT NULL COMMENT '未离校人数',
+  `time_interval` INT DEFAULT NULL COMMENT '时段(1:上午,2:下午,3:晚上)',
+  `record_time` DATETIME NULL COMMENT '考勤时间',
+  `attendance_date` DATE NULL   COMMENT '考勤日期',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='班级考勤统计';