5
0

4 Achegas 819dc978bd ... cdddf3194b

Autor SHA1 Mensaxe Data
  snihwxf cdddf3194b 修改统计课时量 hai 1 semana
  snihwxf b2ff3d5096 修改数据 hai 1 semana
  snihwxf 9033cb4654 修改考勤统计 hai 1 semana
  zcuishan c3a27a3a87 feat:增加学生食堂消费数据导入接口 hai 2 semanas
Modificáronse 24 ficheiros con 665 adicións e 86 borrados
  1. 2 0
      src/main/java/com/xjrsoft/module/attendance/controller/StudentStatisticsController.java
  2. 3 0
      src/main/java/com/xjrsoft/module/attendance/entity/ClassAttendanceStatistics.java
  3. 3 0
      src/main/java/com/xjrsoft/module/attendance/entity/StudentAttendanceStatistics.java
  4. 2 0
      src/main/java/com/xjrsoft/module/attendance/service/impl/StudentStatisticsServiceImpl.java
  5. 6 0
      src/main/java/com/xjrsoft/module/attendance/vo/ClassStatisticsExcelVo.java
  6. 3 0
      src/main/java/com/xjrsoft/module/attendance/vo/ClassStatisticsVo.java
  7. 5 0
      src/main/java/com/xjrsoft/module/attendance/vo/StudentStatisticsExcelVo.java
  8. 3 0
      src/main/java/com/xjrsoft/module/attendance/vo/StudentStatisticsPageVo.java
  9. 6 0
      src/main/java/com/xjrsoft/module/classtime/dto/ClassCourseTimeStatisticsSetGroupPageDto.java
  10. 6 0
      src/main/java/com/xjrsoft/module/classtime/dto/ClassCourseTimeStatisticsSetPageDto.java
  11. 10 5
      src/main/java/com/xjrsoft/module/classtime/service/impl/ClassCourseTimeStatisticsSetServiceImpl.java
  12. 206 1
      src/main/java/com/xjrsoft/module/classtime/service/impl/ClassTimeStatisticsServiceImpl.java
  13. 66 40
      src/main/java/com/xjrsoft/module/student/controller/ConsumptionController.java
  14. 86 0
      src/main/java/com/xjrsoft/module/student/entity/StudentConsumption.java
  15. 10 0
      src/main/java/com/xjrsoft/module/student/mapper/StudentConsumptionMapper.java
  16. 10 1
      src/main/java/com/xjrsoft/module/student/service/IPbVXsxxsfytbService.java
  17. 171 37
      src/main/java/com/xjrsoft/module/student/service/impl/PbVXsxxsfytbServiceImpl.java
  18. 23 0
      src/main/java/com/xjrsoft/module/student/vo/CafeteriaImportExcelVo.java
  19. 17 0
      src/main/java/com/xjrsoft/module/student/vo/StudentImportDetailVo.java
  20. 10 0
      src/main/java/com/xjrsoft/module/system/controller/LoginController.java
  21. 5 1
      src/main/resources/mapper/base/BaseClass.xml
  22. 4 0
      src/main/resources/mapper/classtime/ClassCourseTimeStatisticsSetGroupMapper.xml
  23. 3 0
      src/main/resources/mapper/classtime/ClassCourseTimeStatisticsSetMapper.xml
  24. 5 1
      src/main/resources/sqlScript/20251111_sql.sql

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

@@ -311,6 +311,7 @@ public class StudentStatisticsController {
                 .selectAs(StudentAttendanceStatistics::getUserId, StudentStatisticsPageVo::getUserId)
                 .selectAs(StudentAttendanceStatistics::getAttendanceStatus, StudentStatisticsPageVo::getStatus)
                 .selectAs(StudentAttendanceStatistics::getRecordTime, StudentStatisticsPageVo::getRecordTime)
+                .selectAs(StudentAttendanceStatistics::getReasonLeave, StudentStatisticsPageVo::getReasonLeave)
 
                 .select("CONCAT(LEFT(t1.mobile, 3), '****', RIGHT(t1.mobile, 4))", StudentStatisticsPageVo::getMobile)
                 .select("CONCAT(LEFT(t1.credential_number, 6), '****', RIGHT(t1.credential_number, 4))", StudentStatisticsPageVo::getCredentialNumber)
@@ -591,6 +592,7 @@ public class StudentStatisticsController {
                 .selectAs(User::getName, StudentStatisticsExcelVo::getStudentName)
                 .selectAs(StudentAttendanceStatistics::getAttendanceStatus, StudentStatisticsExcelVo::getStatus)
                 .selectAs(StudentAttendanceStatistics::getRecordTime, StudentStatisticsExcelVo::getRecordTime)
+                .selectAs(StudentAttendanceStatistics::getReasonLeave, StudentStatisticsPageVo::getReasonLeave)
 
                 .select("CONCAT(LEFT(t1.mobile, 3), '****', RIGHT(t1.mobile, 4))", StudentStatisticsExcelVo::getMobile)
                 .select("CONCAT(LEFT(t1.credential_number, 6), '****', RIGHT(t1.credential_number, 4))", StudentStatisticsExcelVo::getCredentialNumber)

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

@@ -139,4 +139,7 @@ public class ClassAttendanceStatistics  implements Serializable {
 
     @ApiModelProperty("考勤日期")
     private LocalDate attendanceDate;
+
+    @ApiModelProperty("实习总人数")
+    private Integer internshipCount;
 }

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

@@ -86,4 +86,7 @@ public class StudentAttendanceStatistics implements Serializable {
 
     @ApiModelProperty("考勤日期")
     private LocalDate attendanceDate;
+
+    @ApiModelProperty("请假原因")
+    private String reasonLeave;
 }

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

@@ -133,6 +133,7 @@ public class StudentStatisticsServiceImpl  extends MPJBaseServiceImpl<StudentAtt
 
                 if (studentLeave != null) {
                     studentAttendanceStatistics.setAttendanceStatus(studentLeave.getLeaveType());
+                    studentAttendanceStatistics.setReasonLeave(studentLeave.getReason());
                 } else {
                     StudentOutInRecord outInRecord = outInMap.get(record.getUserId());
                     if (outInRecord != null) {
@@ -203,6 +204,7 @@ public class StudentStatisticsServiceImpl  extends MPJBaseServiceImpl<StudentAtt
                 classAttendanceStatistics.setNotStayCount(record.getNotStayCount());
                 classAttendanceStatistics.setTimeInterval(timePeriod);
                 classAttendanceStatistics.setAttendanceDate(queryDate);
+                classAttendanceStatistics.setInternshipCount(record.getInternshipCount());
 
                 List<StudentAttendanceStatistics> studentAttendanceStatisticsFilter = studentAttendanceStatisticsList.stream().filter(row -> Objects.equals(row.getClassId(), record.getId())).collect(Collectors.toList());
 

+ 6 - 0
src/main/java/com/xjrsoft/module/attendance/vo/ClassStatisticsExcelVo.java

@@ -38,6 +38,11 @@ public class ClassStatisticsExcelVo {
     @ApiModelProperty("请假人数")
     private Integer leaveCount;
 
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("实习总人数")
+    @ApiModelProperty("实习总人数")
+    private Integer internshipCount;
+
     @ContentStyle(dataFormat = 49)
     @ExcelProperty("迟到人数")
     @ApiModelProperty("迟到人数")
@@ -62,4 +67,5 @@ public class ClassStatisticsExcelVo {
     @ExcelProperty("出勤率")
     @ApiModelProperty("出勤率")
     private String attendanceRate;
+
 }

+ 3 - 0
src/main/java/com/xjrsoft/module/attendance/vo/ClassStatisticsVo.java

@@ -57,4 +57,7 @@ public class ClassStatisticsVo {
     @ApiModelProperty("未离校人数")
     private Integer wLeaveSchoolCount;
 
+    @ApiModelProperty("实习总人数")
+    private Integer internshipCount;
+
 }

+ 5 - 0
src/main/java/com/xjrsoft/module/attendance/vo/StudentStatisticsExcelVo.java

@@ -54,4 +54,9 @@ public class StudentStatisticsExcelVo {
     @ExcelProperty("监护人电话")
     @ApiModelProperty("监护人电话")
     private String guardianPhone;
+
+    @ContentStyle(dataFormat = 49)
+    @ExcelProperty("请假原因")
+    @ApiModelProperty("请假原因")
+    private String reasonLeave;
 }

+ 3 - 0
src/main/java/com/xjrsoft/module/attendance/vo/StudentStatisticsPageVo.java

@@ -46,4 +46,7 @@ public class StudentStatisticsPageVo {
 
     @ApiModelProperty("监护人电话")
     private String guardianPhone;
+
+    @ApiModelProperty("请假原因")
+    private String reasonLeave;
 }

+ 6 - 0
src/main/java/com/xjrsoft/module/classtime/dto/ClassCourseTimeStatisticsSetGroupPageDto.java

@@ -35,4 +35,10 @@ public class ClassCourseTimeStatisticsSetGroupPageDto extends PageInput {
      */
     @ApiModelProperty("课程名称")
     private String courseName;
+
+    /**
+     * 类别(1:权重 2:费用设置 3:课时量)
+     */
+    @ApiModelProperty("类别(1:权重 2:费用设置 3:课时量)")
+    private Integer category;
 }

+ 6 - 0
src/main/java/com/xjrsoft/module/classtime/dto/ClassCourseTimeStatisticsSetPageDto.java

@@ -35,4 +35,10 @@ public class ClassCourseTimeStatisticsSetPageDto extends PageInput {
      */
     @ApiModelProperty("课程名称")
     private String courseName;
+
+    /**
+     * 类别(1:权重 2:费用设置 3:课时量)
+     */
+    @ApiModelProperty("类别(1:权重 2:费用设置 3:课时量)")
+    private Integer category;
 }

+ 10 - 5
src/main/java/com/xjrsoft/module/classtime/service/impl/ClassCourseTimeStatisticsSetServiceImpl.java

@@ -77,6 +77,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
 
                 boolean exists = classCourseTimeStatisticsSetGroupMapper.exists(new QueryWrapper<ClassCourseTimeStatisticsSetGroup>()
                         .lambda()
+                        .eq(ClassCourseTimeStatisticsSetGroup::getCategory,dto.getCategory())
                         .like(ClassCourseTimeStatisticsSetGroup::getClassIds, classId)
                         .like(ClassCourseTimeStatisticsSetGroup::getCourseIds, courseId));
 
@@ -108,7 +109,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
                             setCourseId(courseId);
                             setClassId(classId);
                             setCreateDate(LocalDateTime.now());
-                            setCategory(2);
+                            setCategory(dto.getCategory());
                             setJsonContent(dto.getJsonContent());
                             setIsDefault(0);
                             setDeleteMark(DeleteMark.NODELETE.getCode());
@@ -126,7 +127,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
             setCourseIds(courseIds);
             setClassIds(classIds);
             setCreateDate(LocalDateTime.now());
-            setCategory(2);
+            setCategory(dto.getCategory());
             setJsonContent(dto.getJsonContent());
             setIsDefault(0);
             setDeleteMark(DeleteMark.NODELETE.getCode());
@@ -148,7 +149,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
                             setCourseId(0L);
                             setClassId(classId);
                             setCreateDate(LocalDateTime.now());
-                            setCategory(2);
+                            setCategory(dto.getCategory());
                             setJsonContent(dto.getJsonContent());
                             setIsDefault(1);
                             setDeleteMark(DeleteMark.NODELETE.getCode());
@@ -201,6 +202,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
                 for (Long courseId : soruceCourseIds) {
                     classCourseTimeStatisticsSetMapper.delete(new QueryWrapper<ClassCourseTimeStatisticsSet>()
                             .lambda()
+                            .eq(ClassCourseTimeStatisticsSet::getCategory,dto.getCategory())
                             .eq(ClassCourseTimeStatisticsSet::getClassId, classId)
                             .eq(ClassCourseTimeStatisticsSet::getCourseId, courseId));
                 }
@@ -212,6 +214,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
                 for (Long classId : soruceClassIds) {
                     classCourseTimeStatisticsSetMapper.delete(new QueryWrapper<ClassCourseTimeStatisticsSet>()
                             .lambda()
+                            .eq(ClassCourseTimeStatisticsSet::getCategory,dto.getCategory())
                             .eq(ClassCourseTimeStatisticsSet::getClassId, classId)
                             .eq(ClassCourseTimeStatisticsSet::getCourseId, courseId));
                 }
@@ -226,6 +229,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
                                 .lambda()
                                 .like(ClassCourseTimeStatisticsSetGroup::getClassIds, classId)
                                 .like(ClassCourseTimeStatisticsSetGroup::getCourseIds, courseId)
+                                .eq(ClassCourseTimeStatisticsSetGroup::getCategory,dto.getCategory())
                                 .ne(ClassCourseTimeStatisticsSetGroup::getId,dto.getId()));
                 if(exists){
                     String className = baseClassList.stream()
@@ -247,6 +251,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
 
                 ClassCourseTimeStatisticsSet classCourseTimeStatisticsSet = classCourseTimeStatisticsSetMapper.selectOne(new QueryWrapper<ClassCourseTimeStatisticsSet>()
                         .lambda()
+                        .eq(ClassCourseTimeStatisticsSet::getCategory,dto.getCategory())
                         .eq(ClassCourseTimeStatisticsSet::getClassId, classId)
                         .eq(ClassCourseTimeStatisticsSet::getCourseId, courseId)
                 );
@@ -256,7 +261,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
                                 setCourseId(courseId);
                                 setClassId(classId);
                                 setCreateDate(LocalDateTime.now());
-                                setCategory(2);
+                                setCategory(dto.getCategory());
                                 setJsonContent(dto.getJsonContent());
                                 setIsDefault(0);
                                 setDeleteMark(DeleteMark.NODELETE.getCode());
@@ -282,7 +287,7 @@ public class ClassCourseTimeStatisticsSetServiceImpl extends MPJBaseServiceImpl<
             setCourseIds(courseIds);
             setClassIds(classIds);
             setCreateDate(LocalDateTime.now());
-            setCategory(2);
+            setCategory(dto.getCategory());
             setJsonContent(dto.getJsonContent());
             setIsDefault(0);
             setDeleteMark(DeleteMark.NODELETE.getCode());

+ 206 - 1
src/main/java/com/xjrsoft/module/classtime/service/impl/ClassTimeStatisticsServiceImpl.java

@@ -692,7 +692,7 @@ public class ClassTimeStatisticsServiceImpl extends MPJBaseServiceImpl<ClassTime
             List<ClassTimeStatisticsRecord> insertList = new ArrayList<>();
             List<ClassCourseTimeStatisticsRecord> insertCourseList = new ArrayList<>();
 
-            List<ClassCourseTimeStatisticsSet> classCourseTimeStatisticsSetList = statisticsCourseSetService.list();
+            List<ClassCourseTimeStatisticsSet> classCourseTimeStatisticsSetList = statisticsCourseSetService.list(Wrappers.<ClassCourseTimeStatisticsSet>lambdaQuery().eq(ClassCourseTimeStatisticsSet::getCategory,2));
 
             //循环教师,准备开始计算
             for (TeacherListVo teacher : teacherList) {
@@ -1476,6 +1476,211 @@ public class ClassTimeStatisticsServiceImpl extends MPJBaseServiceImpl<ClassTime
             List<CourseListVo> allCourseList = this.baseMapper.getCourseList(statistics);
             allCourseList.addAll(this.baseMapper.getHolidayReplaceCourseList(statistics));
 
+
+
+            //查询删除课时的数据,将每个班删除的具体日期统计出来
+            List<ClassTimeDelete> deleteList = deleteService.list(
+                    new QueryWrapper<ClassTimeDelete>().lambda()
+                            .ne(ClassTimeDelete::getStatus, 2)
+                            .eq(ClassTimeDelete::getDeleteMark, DeleteMark.NODELETE.getCode())
+                            .eq(ClassTimeDelete::getEnabledMark, EnabledMark.ENABLED.getCode())
+            );
+            Map<Long, List<ClassTimeDelete>> deleteDataMap = deleteList.stream().collect(Collectors.groupingBy(ClassTimeDelete::getClassId));
+            Map<Long, Map<LocalDate, String>> deleteMap = new HashMap<>();//将每个班级计算出来所有被删除的日期存入map
+            for (Long classId : deleteDataMap.keySet()) {
+                Map<LocalDate, String> dateMap = new HashMap<>();
+                for (ClassTimeDelete classTimeDelete : deleteDataMap.get(classId)) {
+                    LocalDate currentDate = classTimeDelete.getStartDate();
+                    while (!currentDate.isAfter(classTimeDelete.getEndDate())) {
+                        dateMap.put(currentDate, classTimeDelete.getTimePeriod());
+                        currentDate = currentDate.plusDays(1); // 增加一天
+                    }
+                }
+                //去重并存到map中
+                deleteMap.put(classId, dateMap);
+            }
+            JsonParser parser = new JsonParser();
+
+            //权重设置jsonArray
+            JsonArray weightSetArray = parser.parse(statistics.getWeightSetJson()).getAsJsonArray();
+            Map<String, Double> weightLabelMap = new LinkedHashMap<>();
+            Map<String, Double> weightFieldMap = new LinkedHashMap<>();
+            for (JsonElement jsonElement : weightSetArray) {
+                JsonObject object = jsonElement.getAsJsonObject();
+                weightLabelMap.put(object.get("label").getAsString(), object.get("value").getAsDouble());
+                weightFieldMap.put(object.get("field").getAsString(), object.get("value").getAsDouble());
+            }
+
+            //查询行政工作量并转成map
+            List<ClassTimeStatisticsAdministration> administrationList = administrationMapper.selectList(
+                    new QueryWrapper<ClassTimeStatisticsAdministration>().lambda()
+                            .eq(ClassTimeStatisticsAdministration::getClassTimeStatisticsId, statistics.getId())
+                            .eq(ClassTimeStatisticsAdministration::getDeleteMark, DeleteMark.NODELETE.getCode())
+                            .eq(ClassTimeStatisticsAdministration::getEnabledMark, EnabledMark.ENABLED.getCode())
+            );
+            Map<Long, Double> administrationMap = administrationList.stream().collect(Collectors.toMap(ClassTimeStatisticsAdministration::getUserId, ClassTimeStatisticsAdministration::getWorkload));
+
+
+
+            List<ClassTimeStatisticsRecord> insertList = new ArrayList<>();
+            List<ClassCourseTimeStatisticsRecord> insertCourseList = new ArrayList<>();
+            List<ClassCourseTimeStatisticsSet> classCourseTimeStatisticsSetList = statisticsCourseSetService.list(Wrappers.<ClassCourseTimeStatisticsSet>lambdaQuery().eq(ClassCourseTimeStatisticsSet::getCategory,3));
+
+
+            for (TeacherListVo teacher : teacherList) {
+                ClassTimeStatisticsRecord record = new ClassTimeStatisticsRecord();
+                record.setUserId(teacher.getId());
+                record.setClassTimeStatisticsId(statistics.getId());
+                record.setEmployType(teacher.getEmployType());
+                record.setClassTime1(statistics.getWeeks());
+
+                //早自习、正课、晚辅、顶课、调课
+                Double classTime7 = 0D, classTime8 = 0D, classTime9 = 0D;
+
+                List<String> zkList = Arrays.asList("上1", "上2", "上3", "上4", "下1", "下2", "下3", "下4");
+                List<String> wzxList = Arrays.asList("晚1", "晚2", "晚3");
+                //查询出老师的课程
+                List<CourseListVo> courseList = allCourseList.stream()
+                        .filter(x -> x.getTeacherId().contains(teacher.getId().toString()))
+                        .collect(Collectors.toList());
+
+                //循环,统计出各项数据
+                for (CourseListVo courseListVo : courseList) {
+                    Map<LocalDate, String> deleteDates = deleteMap.get(courseListVo.getClassId());
+                    if (deleteDates != null && deleteDates.containsKey(courseListVo.getScheduleDate()) && deleteDates.get(courseListVo.getScheduleDate()) != null
+                            && deleteDates.get(courseListVo.getScheduleDate()).contains(courseListVo.getTimeNumber())) {
+                        continue;
+                    }
+
+
+                    ClassCourseTimeStatisticsRecord classCourseTimeStatisticsRecord = checkCourseSet(classCourseTimeStatisticsSetList, insertCourseList, courseListVo.getClassId(), courseListVo.getCourseId(), teacher);
+
+                    if (classCourseTimeStatisticsRecord != null) {
+                        //早自习、正课、晚辅
+                        Double _classTime8 = classCourseTimeStatisticsRecord.getClassTime8(),
+                                _classTime9 = classCourseTimeStatisticsRecord.getClassTime9();
+
+                        //费用设置jsonArray
+                        JsonArray _weightLabelArray = parser.parse(classCourseTimeStatisticsRecord.getCostSetJson()).getAsJsonArray();
+                        Map<String, Double> _weightLabelMap = new LinkedHashMap<>();
+                        for (JsonElement jsonElement : _weightLabelArray) {
+                            JsonObject object = jsonElement.getAsJsonObject();
+                            _weightLabelMap.put(object.get("label").getAsString(), object.get("value").getAsDouble());
+                        }
+
+                        if ("早自习".equals(courseListVo.getShortName())) {
+                            _classTime8 += _weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : _weightLabelMap.get(courseListVo.getShortName());
+                            classTime8 += _weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : _weightLabelMap.get(courseListVo.getShortName());
+                        } else if (zkList.contains(courseListVo.getShortName())) {
+                            _classTime8 += _weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : _weightLabelMap.get(courseListVo.getShortName());
+                            classTime8 += _weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : _weightLabelMap.get(courseListVo.getShortName());
+                        } else if (wzxList.contains(courseListVo.getShortName())) {
+                            _classTime9 += _weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : _weightLabelMap.get(courseListVo.getShortName());
+                            classTime9 += _weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : _weightLabelMap.get(courseListVo.getShortName());
+                        }
+
+                        classCourseTimeStatisticsRecord.setClassTime8(_classTime8);
+                        classCourseTimeStatisticsRecord.setClassTime9(_classTime9);
+
+                        Double _llClassTime = _classTime8 + _classTime9;
+
+                        classCourseTimeStatisticsRecord.setAllClassTime(_llClassTime);
+
+                    } else {
+                        if ("早自习".equals(courseListVo.getShortName())) {
+                            classTime8 += weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : weightLabelMap.get(courseListVo.getShortName());
+                        } else if (zkList.contains(courseListVo.getShortName())) {
+                            classTime8 += weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : weightLabelMap.get(courseListVo.getShortName());
+                        } else if (wzxList.contains(courseListVo.getShortName())) {
+                            classTime9 += weightLabelMap.get(courseListVo.getShortName()) == null ? 0d : weightLabelMap.get(courseListVo.getShortName());
+                        }
+                    }
+
+                }
+                record.setClassTime7(classTime7);
+                record.setClassTime8(classTime8);
+                record.setClassTime9(classTime9);
+                //计算总课时:正课课时+晚辅
+                Double allTimes = classTime8 + classTime9;
+                record.setAllClassTime(allTimes);
+                //计算周平均课时:总课时÷总周次
+                double classTime2 = BigDecimal.valueOf(allTimes).divide(BigDecimal.valueOf(record.getClassTime1()), 2, RoundingMode.HALF_UP).doubleValue();
+                record.setClassTime2(classTime2);
+                //行政工作量
+                record.setClassTime3(administrationMap.get(record.getUserId()));
+
+                //总平均课时
+                Double classTime4 = (record.getClassTime3() == null ? 0D : record.getClassTime3()) + (record.getClassTime2() == null ? 0D : record.getClassTime2());
+                record.setClassTime4(classTime4);
+
+                Double time13 = weightFieldMap.get("time13");
+                if (classTime4 > time13) {
+                    record.setClassTime5(time13);
+                } else {
+                    record.setClassTime5(classTime4);
+                }
+
+                insertList.add(record);
+            }
+
+            if (!insertList.isEmpty()) {
+                Double overWorkloadNumber = statistics.getOverWorkloadNumber() == null ? 0D : statistics.getOverWorkloadNumber();
+                Double time14 = weightFieldMap.get("time14");//工作量得分
+                Double time13 = weightFieldMap.get("time13");//超工作量得分
+                if (statistics.getOverWorkloadNumberStatus() != 1) {
+                    //取出最大总平均课时
+                    Double maxClassTime4 = insertList.stream().mapToDouble(ClassTimeStatisticsRecord::getClassTime4).max().getAsDouble();
+                    //计算超工作量基数
+                    if (!maxClassTime4.equals(time13)) {
+
+                        overWorkloadNumber = BigDecimal.valueOf(time14).divide((BigDecimal.valueOf(maxClassTime4).subtract(BigDecimal.valueOf(time13))), 2, RoundingMode.HALF_UP).doubleValue();
+                    }
+                }
+                double allClassTime = insertList.stream().filter(x -> x.getAllClassTime() != null).mapToDouble(ClassTimeStatisticsRecord::getAllClassTime).sum();
+                statistics.setAllClassTime(allClassTime);
+                statistics.setOverWorkloadNumber(overWorkloadNumber);
+                //先删除
+                String sql = "delete from class_time_statistics_record where class_time_statistics_id = " + statistics.getId();
+                SqlRunnerAdapter.db().delete(sql);
+                for (ClassTimeStatisticsRecord record : insertList) {
+                    if (overWorkloadNumber != 0D && time13 < record.getClassTime4()) {
+                        double classTime6 = BigDecimal.valueOf(record.getClassTime4())
+                                .subtract(BigDecimal.valueOf(time13))
+                                .multiply(BigDecimal.valueOf(overWorkloadNumber)).doubleValue();
+                        if (classTime6 > 0d) {
+                            record.setClassTime6(classTime6);
+                        }
+                    }
+                    recordMapper.insert(record);
+                }
+
+                sql = "delete from class_course_time_statistics_record where class_time_statistics_id = " + statistics.getId();
+                SqlRunnerAdapter.db().delete(sql);
+                for (ClassCourseTimeStatisticsRecord record : insertCourseList) {
+                    recordCourseMapper.insert(record);
+                }
+            }
+        } catch (Exception e) {
+            Log.error(e.getMessage(), e);
+            throw new MyException("刷新统计出错,请联系管理员");
+        } finally {
+            statistics.setStatus(1);
+            this.updateById(statistics);
+        }
+        return true;
+    }
+
+    public Boolean refreshCourseRecordOld(ClassTimeStatistics statistics) {
+        try {
+            // 1、查询教师
+            List<TeacherListVo> teacherList = this.baseMapper.getTeacherList();
+
+            //查询课程数据,排除开节假日的数据
+            List<CourseListVo> allCourseList = this.baseMapper.getCourseList(statistics);
+            allCourseList.addAll(this.baseMapper.getHolidayReplaceCourseList(statistics));
+
+
+
             //查询删除课时的数据,将每个班删除的具体日期统计出来
             List<ClassTimeDelete> deleteList = deleteService.list(
                     new QueryWrapper<ClassTimeDelete>().lambda()

+ 66 - 40
src/main/java/com/xjrsoft/module/student/controller/ConsumptionController.java

@@ -26,6 +26,7 @@ import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
 import java.io.ByteArrayOutputStream;
@@ -62,57 +63,69 @@ public class ConsumptionController {
             qfCountMap.put(qfCountVo.getId(), qfCountVo.getCount());
         }
 
-        voList.add(new BaseClassTreeVo() {{
-            setId(6L);
-            setName("年级");
-        }});
+        voList.add(new BaseClassTreeVo() {
+            {
+                setId(6L);
+                setName("年级");
+            }
+        });
 
         List<BaseClassGradeVo> classGradeVoList = baseClassService.getListByGrade();
 
         if (!classGradeVoList.isEmpty()) {
             for (BaseClassGradeVo classGradeVo : classGradeVoList) {
 
-                voList.add(new BaseClassTreeVo() {{
-                    setId(classGradeVo.getId());
-                    setName(classGradeVo.getName());
-                    setParentId(classGradeVo.getGradeId());
-                    setStatus(0);
-                    if (qfCountMap.get(classGradeVo.getId()) != null && qfCountMap.get(classGradeVo.getId()) > 0) {
-                        setStatus(1);
+                voList.add(new BaseClassTreeVo() {
+                    {
+                        setId(classGradeVo.getId());
+                        setName(classGradeVo.getName());
+                        setParentId(classGradeVo.getGradeId());
+                        setStatus(0);
+                        if (qfCountMap.get(classGradeVo.getId()) != null && qfCountMap.get(classGradeVo.getId()) > 0) {
+                            setStatus(1);
+                        }
                     }
-                }});
+                });
 
                 if (voList.stream().noneMatch(item -> Objects.equals(item.getId(), classGradeVo.getGradeId()))) {
-                    voList.add(new BaseClassTreeVo() {{
-                        setId(classGradeVo.getGradeId());
-                        setName(classGradeVo.getGradeName());
-                        setParentId(6L);
-                    }});
+                    voList.add(new BaseClassTreeVo() {
+                        {
+                            setId(classGradeVo.getGradeId());
+                            setName(classGradeVo.getGradeName());
+                            setParentId(6L);
+                        }
+                    });
                 }
             }
         } else {
 
             baseGradeService.list().forEach((node) -> {
                 if (node.getStatus() == 1) {
-                    voList.add(new BaseClassTreeVo() {{
-                        setId(node.getId());
-                        setName(node.getName());
-                        setParentId(6L);
-                    }});
+                    voList.add(new BaseClassTreeVo() {
+                        {
+                            setId(node.getId());
+                            setName(node.getName());
+                            setParentId(6L);
+                        }
+                    });
                 }
             });
 
-            baseClassService.list(new QueryWrapper<BaseClass>().lambda().eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())).forEach((node) -> {
-                voList.add(new BaseClassTreeVo() {{
-                    setId(node.getId());
-                    setName(node.getName());
-                    setParentId(node.getGradeId());
-                    setStatus(0);
-                    if (qfCountMap.get(node.getId()) != null && qfCountMap.get(node.getId()) > 0) {
-                        setStatus(1);
-                    }
-                }});
-            });
+            baseClassService.list(
+                    new QueryWrapper<BaseClass>().lambda().eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode()))
+                    .forEach((node) -> {
+                        voList.add(new BaseClassTreeVo() {
+                            {
+                                setId(node.getId());
+                                setName(node.getName());
+                                setParentId(node.getGradeId());
+                                setStatus(0);
+                                if (qfCountMap.get(node.getId()) != null && qfCountMap.get(node.getId()) > 0) {
+                                    setStatus(1);
+                                }
+                            }
+                        });
+                    });
         }
 
         List<BaseClassTreeVo> treeVoList = TreeUtil.build(voList);
@@ -150,8 +163,9 @@ public class ConsumptionController {
         }
 
         List<BaseClassGradeVo> classGradeVoList = baseClassService.getListByGrade();
-        if((dto.getClassIds() == null || dto.getClassIds().isEmpty()) && !classGradeVoList.isEmpty()) {
-            dto.setClassIdList(classGradeVoList.stream().map(BaseClassGradeVo::getId).map(String::valueOf).collect(Collectors.toList()));
+        if ((dto.getClassIds() == null || dto.getClassIds().isEmpty()) && !classGradeVoList.isEmpty()) {
+            dto.setClassIdList(classGradeVoList.stream().map(BaseClassGradeVo::getId).map(String::valueOf)
+                    .collect(Collectors.toList()));
         }
 
         IPage<PbVXsxxsfytbPageVo> page = pbVXsxxsfytbService.getPage(dto);
@@ -174,7 +188,8 @@ public class ConsumptionController {
     public ResponseEntity<byte[]> exportData(@RequestBody PbVXsxxsfytbExcelDto dto) {
         List<PbVXsxxsfytbExcelVo> dataList = pbVXsxxsfytbService.getList(dto);
         ByteArrayOutputStream bot = new ByteArrayOutputStream();
-        EasyExcel.write(bot, PbVXsxxsfytbExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(dataList);
+        EasyExcel.write(bot, PbVXsxxsfytbExcelVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet()
+                .doWrite(dataList);
 
         return RT.fileStream(bot.toByteArray(), "PbVXsxxsfytbExcel" + ExcelTypeEnum.XLSX.getValue());
     }
@@ -208,7 +223,8 @@ public class ConsumptionController {
     @SaCheckPermission("consumption:classqfpage")
     @XjrLog(value = "班级欠费排序")
     public RT<PageOutput<ClassQfPageVo>> classQfPage(@Valid PbVXsxxsfytbStatDto dto) {
-        Page<ClassQfPageVo> classQfPage = pbVXsxxsfytbService.getClassQfPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
+        Page<ClassQfPageVo> classQfPage = pbVXsxxsfytbService.getClassQfPage(new Page<>(dto.getLimit(), dto.getSize()),
+                dto);
         PageOutput<ClassQfPageVo> pageOutput = ConventPage.getPageOutput(classQfPage, ClassQfPageVo.class);
         return RT.ok(pageOutput);
     }
@@ -230,11 +246,21 @@ public class ConsumptionController {
         dto.setLimit(1);
         dto.setSize(Integer.parseInt(count + ""));
 
-
-        List<ClassQfPageVo> records = pbVXsxxsfytbService.getClassQfPage(new Page<>(dto.getLimit(), dto.getSize()), dto).getRecords();
+        List<ClassQfPageVo> records = pbVXsxxsfytbService.getClassQfPage(new Page<>(dto.getLimit(), dto.getSize()), dto)
+                .getRecords();
         ByteArrayOutputStream bot = new ByteArrayOutputStream();
 
-        EasyExcel.write(bot, ClassQfPageVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet().doWrite(records);
+        EasyExcel.write(bot, ClassQfPageVo.class).automaticMergeHead(false).excelType(ExcelTypeEnum.XLSX).sheet()
+                .doWrite(records);
         return RT.fileStream(bot.toByteArray(), "classQf" + ExcelTypeEnum.XLSX.getValue());
     }
+
+    @PostMapping(value = "/cafeteria-import")
+    @ApiOperation(value = "食堂消费数据导入")
+    @SaCheckPermission("consumption:classqfexportquery")
+    @XjrLog(value = "食堂消费数据导入")
+    public RT<String> cafeteriaImport(@RequestParam("file") MultipartFile file) {
+        pbVXsxxsfytbService.importCafeteriaData(file);
+        return RT.ok("导入成功");
+    }
 }

+ 86 - 0
src/main/java/com/xjrsoft/module/student/entity/StudentConsumption.java

@@ -0,0 +1,86 @@
+package com.xjrsoft.module.student.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 学生消费数据
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("student_consume_date")
+@ApiModel(value = "StudentConsumptionDate", description = "学生消费数据")
+public class StudentConsumption implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(type = IdType.ASSIGN_ID)
+    @ApiModelProperty(value = "主键编号")
+    private Long id;
+
+    @ApiModelProperty(value = "创建人")
+    private Long createUserId;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createDate;
+
+    @ApiModelProperty(value = "修改人")
+    private Long modifyUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    private Date modifyDate;
+
+    @ApiModelProperty(value = "删除标记")
+    private Integer deleteMark;
+
+    @ApiModelProperty(value = "有效标志")
+    private Integer enabledMark;
+
+    @ApiModelProperty(value = "序号")
+    private Integer sortCode;
+
+    @ApiModelProperty(value = "班级id")
+    private Long classId;
+
+    @ApiModelProperty(value = "班级名称")
+    private String className;
+
+    @ApiModelProperty(value = "学生id")
+    private Long studentId;
+
+    @ApiModelProperty(value = "学生姓名")
+    private String studentName;
+
+    @ApiModelProperty(value = "学生学号")
+    private String studentUserName;
+
+    @ApiModelProperty(value = "消费时间")
+    private Date consumeTime;
+
+    @ApiModelProperty(value = "消费金额")
+    private BigDecimal consumeMoney;
+
+    @ApiModelProperty(value = "消费类型")
+    private String consumeType;
+
+    @ApiModelProperty(value = "年级名称")
+    private String gradeName;
+
+    @ApiModelProperty(value = "年级id")
+    private String gradeId;
+
+    @ApiModelProperty(value = "专业名称")
+    private String majorName;
+
+    @ApiModelProperty(value = "专业id")
+    private String majorId;
+}

+ 10 - 0
src/main/java/com/xjrsoft/module/student/mapper/StudentConsumptionMapper.java

@@ -0,0 +1,10 @@
+package com.xjrsoft.module.student.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.xjrsoft.module.student.entity.StudentConsumption;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface StudentConsumptionMapper extends BaseMapper<StudentConsumption> {
+
+}

+ 10 - 1
src/main/java/com/xjrsoft/module/student/service/IPbVXsxxsfytbService.java

@@ -12,11 +12,14 @@ import com.xjrsoft.module.student.vo.*;
 
 import java.util.List;
 
+import org.springframework.web.multipart.MultipartFile;
+
 /**
  * @title:
  * @Author dzx
  * @Date: 2024-03-13
  * @Version 1.0
+ * @description:
  */
 
 public interface IPbVXsxxsfytbService extends MPJBaseService<PbVXsxxsfytb> {
@@ -28,7 +31,6 @@ public interface IPbVXsxxsfytbService extends MPJBaseService<PbVXsxxsfytb> {
 
     List<BaseClassQfCountVo> getClassQfCount();
 
-
     PbVXsxxsfytbFeeitemVo getStudentFeeInfo(String credentialNumber);
 
     List<FeeDetailListVo> getFeeDetail(String studentcode, String beltcode);
@@ -48,4 +50,11 @@ public interface IPbVXsxxsfytbService extends MPJBaseService<PbVXsxxsfytb> {
     Page<ClassQfPageVo> getClassQfPage(Page<ClassQfPageVo> page, PbVXsxxsfytbStatDto dto);
 
     PbFeeitemStatVo feeitemStat(PbVXsxxsfytbStatDto dto);
+
+    /**
+     * 导入食堂消费数据
+     * 
+     * @param file
+     */
+    void importCafeteriaData(MultipartFile file);
 }

+ 171 - 37
src/main/java/com/xjrsoft/module/student/service/impl/PbVXsxxsfytbServiceImpl.java

@@ -27,7 +27,6 @@ import com.xjrsoft.module.student.vo.*;
 import com.xjrsoft.module.teacher.entity.XjrUser;
 import lombok.AllArgsConstructor;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
@@ -40,6 +39,18 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.read.listener.PageReadListener;
+import com.xjrsoft.module.base.entity.BaseGrade;
+import com.xjrsoft.module.base.entity.BaseMajorSet;
+import com.xjrsoft.module.student.entity.BaseMajor;
+import com.xjrsoft.module.student.entity.StudentConsumption;
+import com.xjrsoft.module.student.vo.CafeteriaImportExcelVo;
+import com.xjrsoft.module.student.vo.StudentImportDetailVo;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.Date;
+
 /**
  * @title:
  * @Author dzx
@@ -48,12 +59,15 @@ import java.util.stream.Collectors;
  */
 @Service
 @AllArgsConstructor
-public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapper, PbVXsxxsfytb> implements IPbVXsxxsfytbService {
+public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapper, PbVXsxxsfytb>
+        implements IPbVXsxxsfytbService {
 
     private final PbVXsxxsfytbMapper pbVXsxxsfytbMapper;
     private final PbSemesterConfigMapper pbSemesterConfigMapper;
 
     private final BaseSemesterMapper baseSemesterMapper;
+    private final com.xjrsoft.module.student.mapper.StudentConsumptionMapper studentConsumptionMapper;
+    private final com.xjrsoft.module.teacher.mapper.XjrUserMapper xjrUserMapper;
 
     @Override
     public PersonalPortraitFeeInformationVo listCostInformation(PersonalPortraitFeeInformationDto dto) {
@@ -61,15 +75,15 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
 
         // 获取年份
         int year = currentDate.getYear();
-        if(StringUtils.isEmpty(dto.getYear())){
+        if (StringUtils.isEmpty(dto.getYear())) {
             dto.setYear(year + "");
         }
 
         LambdaQueryWrapper<BaseSemester> baseSemesterLambdaQueryWrapper = new LambdaQueryWrapper<>();
         baseSemesterLambdaQueryWrapper
-                .select(BaseSemester.class, x -> VoToColumnUtil.fieldsToColumns(BaseSemester.class).contains(x.getProperty()))
-                .like(BaseSemester::getName, dto.getYear())
-                ;
+                .select(BaseSemester.class,
+                        x -> VoToColumnUtil.fieldsToColumns(BaseSemester.class).contains(x.getProperty()))
+                .like(BaseSemester::getName, dto.getYear());
         List<BaseSemester> baseSemesters = baseSemesterMapper.selectList(baseSemesterLambdaQueryWrapper);
 
         // 查出所有的消费记录
@@ -77,18 +91,19 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
         pbVXsxxsfytbMPJLambdaWrapper
                 .selectAs(BaseSemester::getId, PbVXsxxsfytbPersonal::getBaseSemester)
                 .selectAs(BaseSemester::getName, PbVXsxxsfytbPersonal::getBaseSemesterCn)
-                .select(PbVXsxxsfytb.class, x -> VoToColumnUtil.fieldsToColumns(PbVXsxxsfytbPersonal.class).contains(x.getProperty()))
+                .select(PbVXsxxsfytb.class,
+                        x -> VoToColumnUtil.fieldsToColumns(PbVXsxxsfytbPersonal.class).contains(x.getProperty()))
                 .leftJoin(XjrUser.class, XjrUser::getCredentialNumber, PbVXsxxsfytb::getPersonalid)
                 .leftJoin(PbSemesterConfig.class, PbSemesterConfig::getBeltcode, PbVXsxxsfytb::getBeltcode)
                 .leftJoin(BaseSemester.class, BaseSemester::getId, PbSemesterConfig::getBaseSemesterId)
                 .eq(dto.getUserId() != null && dto.getUserId() > 0, XjrUser::getId, dto.getUserId())
-                .like(dto.getYear() != null && !dto.getYear().isEmpty(), PbVXsxxsfytb::getBeltcode, dto.getYear())
-        ;
-        List<PbVXsxxsfytbPersonal> pbVXsxxsfytbPersonalList = this.selectJoinList(PbVXsxxsfytbPersonal.class, pbVXsxxsfytbMPJLambdaWrapper);
+                .like(dto.getYear() != null && !dto.getYear().isEmpty(), PbVXsxxsfytb::getBeltcode, dto.getYear());
+        List<PbVXsxxsfytbPersonal> pbVXsxxsfytbPersonalList = this.selectJoinList(PbVXsxxsfytbPersonal.class,
+                pbVXsxxsfytbMPJLambdaWrapper);
 
-        if(CollectionUtils.isEmpty(pbVXsxxsfytbPersonalList)){
+        if (CollectionUtils.isEmpty(pbVXsxxsfytbPersonalList)) {
             pbVXsxxsfytbPersonalList = new ArrayList<>();
-            for (BaseSemester b : baseSemesters){
+            for (BaseSemester b : baseSemesters) {
                 PbVXsxxsfytbPersonal pbVXsxxsfytbPersonal = new PbVXsxxsfytbPersonal();
                 pbVXsxxsfytbPersonal.setBaseSemester(b.getId().toString());
                 pbVXsxxsfytbPersonal.setBaseSemesterCn(b.getName());
@@ -107,7 +122,8 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
 
         // 统计总消费金额
         BigDecimal totalConsumption = pbVXsxxsfytbPersonalList.stream()
-                .map(p -> p.getFactrecarmny().add((p.getArrearagemny() == null ? BigDecimal.ZERO : p.getArrearagemny())))
+                .map(p -> p.getFactrecarmny()
+                        .add((p.getArrearagemny() == null ? BigDecimal.ZERO : p.getArrearagemny())))
                 .reduce(BigDecimal.ZERO, BigDecimal::add);
 
         // 按学期分组并处理数据
@@ -120,19 +136,23 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
 
                     // 合并相同缴费项目
                     Map<String, PbVXsxxsfytbPersonal> pbVXsxxsfytbPersonalByItemMap = pbVXsxxsfytbPersonals.stream()
-                            .collect(Collectors.toMap(PbVXsxxsfytbPersonal::getFeeitemcode, p -> p, (existing, replacement) -> {
-                                existing.setFactar(existing.getFactar().add(replacement.getFactar()));
-                                existing.setFactrecarmny(existing.getFactrecarmny().add(replacement.getFactrecarmny()));
-                                existing.setAdjustmny(existing.getAdjustmny().add(replacement.getAdjustmny()));
-                                existing.setArrearagemny(existing.getArrearagemny().add(replacement.getArrearagemny()));
-                                return existing;
-                            }));
+                            .collect(Collectors.toMap(PbVXsxxsfytbPersonal::getFeeitemcode, p -> p,
+                                    (existing, replacement) -> {
+                                        existing.setFactar(existing.getFactar().add(replacement.getFactar()));
+                                        existing.setFactrecarmny(
+                                                existing.getFactrecarmny().add(replacement.getFactrecarmny()));
+                                        existing.setAdjustmny(existing.getAdjustmny().add(replacement.getAdjustmny()));
+                                        existing.setArrearagemny(
+                                                existing.getArrearagemny().add(replacement.getArrearagemny()));
+                                        return existing;
+                                    }));
 
                     // 构建PbVXsxxsfytbPersonalMap对象
                     PbVXsxxsfytbPersonalMap pbVXsxxsfytbPersonalMap = new PbVXsxxsfytbPersonalMap();
                     pbVXsxxsfytbPersonalMap.setBaseSemester(baseSemester);
                     pbVXsxxsfytbPersonalMap.setBaseSemesterCn(pbVXsxxsfytbPersonals.get(0).getBaseSemesterCn());
-                    pbVXsxxsfytbPersonalMap.setPbVXsxxsfytbPersonalList(new ArrayList<>(pbVXsxxsfytbPersonalByItemMap.values()));
+                    pbVXsxxsfytbPersonalMap
+                            .setPbVXsxxsfytbPersonalList(new ArrayList<>(pbVXsxxsfytbPersonalByItemMap.values()));
 
                     return pbVXsxxsfytbPersonalMap;
                 })
@@ -156,17 +176,22 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
 
         MPJLambdaWrapper<PbVXsxxsfytb> pbVXsxxsfytbMPJLambdaWrapper = new MPJLambdaWrapper<>();
         if (dto.getSemesterId() != null && dto.getSemesterId() > 0) {
-            pbVXsxxsfytbMPJLambdaWrapper.exists("select 1 from `pb_semester_config` where base_semester_id = " + dto.getSemesterId() + " and beltcode = t.beltcode");
+            pbVXsxxsfytbMPJLambdaWrapper.exists("select 1 from `pb_semester_config` where base_semester_id = "
+                    + dto.getSemesterId() + " and beltcode = t.beltcode");
         }
 
         pbVXsxxsfytbMPJLambdaWrapper
                 .disableSubLogicDel()
-                .like(dto.getFeeitemname() != null && !dto.getFeeitemname().isEmpty(), PbVXsxxsfytb::getFeeitemname, dto.getFeeitemname())
+                .like(dto.getFeeitemname() != null && !dto.getFeeitemname().isEmpty(), PbVXsxxsfytb::getFeeitemname,
+                        dto.getFeeitemname())
                 .like(StrUtil.isNotEmpty(dto.getName()), PbVXsxxsfytb::getFeeobjname, dto.getName())
                 .eq(StrUtil.isNotEmpty(dto.getStudentId()), BaseStudent::getStudentId, dto.getStudentId())
-                .eq(StrUtil.isNotEmpty(dto.getCredentialNumber()), XjrUser::getCredentialNumber, dto.getCredentialNumber())
-                .in(dto.getClassIdList() != null && !dto.getClassIdList().isEmpty(), BaseStudentSchoolRoll::getClassId, dto.getClassIdList())
-                .eq(dto.getSemesterId() != null && dto.getSemesterId() > 0, PbSemesterConfig::getBaseSemesterId, dto.getSemesterId())
+                .eq(StrUtil.isNotEmpty(dto.getCredentialNumber()), XjrUser::getCredentialNumber,
+                        dto.getCredentialNumber())
+                .in(dto.getClassIdList() != null && !dto.getClassIdList().isEmpty(), BaseStudentSchoolRoll::getClassId,
+                        dto.getClassIdList())
+                .eq(dto.getSemesterId() != null && dto.getSemesterId() > 0, PbSemesterConfig::getBaseSemesterId,
+                        dto.getSemesterId())
                 .like(dto.getJfzt() != null && !"".equals(dto.getJfzt()), PbVXsxxsfytb::getJfzt, dto.getJfzt())
                 .eq(dto.getTeacherId() != null, BaseClass::getTeacherId, dto.getTeacherId())
                 .eq(BaseStudentSchoolRoll::getArchivesStatus, ArchivesStatusEnum.FB2901.getCode())
@@ -184,8 +209,8 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
                 .selectAs(BaseClass::getName, PbVXsxxsfytbPageVo::getClassname)
                 .selectAs(PbVXsxxsfytb::getPersonalid, PbVXsxxsfytbPageVo::getCredentialNumber)
                 .selectAs(BaseSemester::getName, PbVXsxxsfytbPageVo::getBaseSemesterCn)
-                .select(PbVXsxxsfytb.class, x -> VoToColumnUtil.fieldsToColumns(PbVXsxxsfytbPageVo.class).contains(x.getProperty()))
-        ;
+                .select(PbVXsxxsfytb.class,
+                        x -> VoToColumnUtil.fieldsToColumns(PbVXsxxsfytbPageVo.class).contains(x.getProperty()));
         if (StrUtil.isNotEmpty(dto.getField()) && StrUtil.isNotEmpty(dto.getOrder())) {
             if ("ascend".equals(dto.getOrder())) {
                 if ("baseSemesterCn".equals(dto.getField())) {
@@ -233,7 +258,8 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
                 }
             }
         }
-        return this.selectJoinListPage(ConventPage.getPageCustomOrder(dto), PbVXsxxsfytbPageVo.class, pbVXsxxsfytbMPJLambdaWrapper);
+        return this.selectJoinListPage(ConventPage.getPageCustomOrder(dto), PbVXsxxsfytbPageVo.class,
+                pbVXsxxsfytbMPJLambdaWrapper);
     }
 
     @Override
@@ -242,7 +268,8 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
 
         pbVXsxxsfytbMPJLambdaWrapper
                 .disableSubLogicDel()
-                .in(dto.getPksfxxytbs() != null && !dto.getPksfxxytbs().isEmpty(), PbVXsxxsfytb::getPksfxxytb, dto.getPksfxxytbs())
+                .in(dto.getPksfxxytbs() != null && !dto.getPksfxxytbs().isEmpty(), PbVXsxxsfytb::getPksfxxytb,
+                        dto.getPksfxxytbs())
                 .leftJoin(XjrUser.class, XjrUser::getCredentialNumber, PbVXsxxsfytb::getPersonalid)
                 .leftJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId, XjrUser::getId)
                 .leftJoin(PbSemesterConfig.class, PbSemesterConfig::getBeltcode, PbVXsxxsfytb::getBeltcode)
@@ -252,11 +279,11 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
                 .selectAs(BaseSemester::getId, PbVXsxxsfytbExcelVo::getBaseSemester)
                 .selectAs(XjrUser::getId, PbVXsxxsfytbExcelVo::getUserId)
                 .selectAs(BaseSemester::getName, PbVXsxxsfytbExcelVo::getBaseSemesterCn)
-                .select(PbVXsxxsfytb.class, x -> VoToColumnUtil.fieldsToColumns(PbVXsxxsfytbExcelVo.class).contains(x.getProperty()))
-        ;
+                .select(PbVXsxxsfytb.class,
+                        x -> VoToColumnUtil.fieldsToColumns(PbVXsxxsfytbExcelVo.class).contains(x.getProperty()));
         List<PbVXsxxsfytbExcelVo> list = this.selectJoinList(PbVXsxxsfytbExcelVo.class, pbVXsxxsfytbMPJLambdaWrapper);
         for (PbVXsxxsfytbExcelVo pbVXsxxsfytbExcelVo : list) {
-            if (pbVXsxxsfytbExcelVo.getQfje().compareTo(BigDecimal.ZERO) > 0) {//正数
+            if (pbVXsxxsfytbExcelVo.getQfje().compareTo(BigDecimal.ZERO) > 0) {// 正数
                 pbVXsxxsfytbExcelVo.setQfje(pbVXsxxsfytbExcelVo.getQfje().abs());
                 pbVXsxxsfytbExcelVo.setKtje(BigDecimal.ZERO);
             } else if (pbVXsxxsfytbExcelVo.getQfje().compareTo(BigDecimal.ZERO) < 0) {
@@ -297,8 +324,7 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
         Long l = pbVXsxxsfytbMapper.selectCount(
                 new QueryWrapper<PbVXsxxsfytb>().lambda()
                         .eq(PbVXsxxsfytb::getPersonalid, credentialNumber)
-                        .gt(PbVXsxxsfytb::getQfje, 0)
-        );
+                        .gt(PbVXsxxsfytb::getQfje, 0));
         if (l > 1) {
             l = 1L;
         }
@@ -326,7 +352,8 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
                 + (result.getPoorCount() == null ? 0 : result.getPoorCount());
         BigDecimal divide = BigDecimal.ZERO;
         if (allCount != 0) {
-            divide = BigDecimal.valueOf(result.getInclusiveCount()).divide(BigDecimal.valueOf(allCount), 4, RoundingMode.HALF_UP);
+            divide = BigDecimal.valueOf(result.getInclusiveCount()).divide(BigDecimal.valueOf(allCount), 4,
+                    RoundingMode.HALF_UP);
         }
         result.setInclusiveRatio(divide.doubleValue());
         return result;
@@ -351,7 +378,8 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
             result.setStayCount(0);
         }
         if (allCount != 0) {
-            divide = BigDecimal.valueOf(result.getStayCount()).divide(BigDecimal.valueOf(allCount), 4, RoundingMode.HALF_UP);
+            divide = BigDecimal.valueOf(result.getStayCount()).divide(BigDecimal.valueOf(allCount), 4,
+                    RoundingMode.HALF_UP);
         }
         result.setStayRatio(divide.doubleValue());
 
@@ -385,4 +413,110 @@ public class PbVXsxxsfytbServiceImpl extends MPJBaseServiceImpl<PbVXsxxsfytbMapp
         }
         return result;
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void importCafeteriaData(MultipartFile file) {
+        try {
+            EasyExcel.read(file.getInputStream(), CafeteriaImportExcelVo.class,
+                    new PageReadListener<CafeteriaImportExcelVo>(dataList -> {
+                        if (CollectionUtils.isEmpty(dataList)) {
+                            return;
+                        }
+                        // 1. 提取所有工号
+                        List<String> userNames = dataList.stream()
+                                .map(CafeteriaImportExcelVo::getUserName)
+                                .filter(StringUtils::isNotBlank)
+                                .collect(Collectors.toList());
+
+                        if (CollectionUtils.isEmpty(userNames)) {
+                            return;
+                        }
+
+                        // 2. 查询学生信息
+                        MPJLambdaWrapper<XjrUser> wrapper = new MPJLambdaWrapper<>();
+                        wrapper.selectAll(XjrUser.class)
+                                .selectAs(XjrUser::getId, StudentImportDetailVo::getUserId)
+                                .selectAs(XjrUser::getUserName, StudentImportDetailVo::getUserName)
+                                .selectAs(XjrUser::getName, StudentImportDetailVo::getStudentName)
+                                .selectAs(BaseStudentSchoolRoll::getGradeId, StudentImportDetailVo::getGradeId)
+                                .selectAs(BaseStudentSchoolRoll::getClassId, StudentImportDetailVo::getClassId)
+                                .selectAs(BaseStudentSchoolRoll::getMajorSetId, StudentImportDetailVo::getMajorSetId)
+                                .selectAs(BaseGrade::getName, StudentImportDetailVo::getGradeName)
+                                .selectAs(BaseClass::getName, StudentImportDetailVo::getClassName)
+                                .selectAs(BaseMajor::getName, StudentImportDetailVo::getMajorName)
+                                .selectAs(BaseMajor::getId, StudentImportDetailVo::getMajorId)
+                                .innerJoin(BaseStudentSchoolRoll.class, BaseStudentSchoolRoll::getUserId,
+                                        XjrUser::getId)
+                                .innerJoin(BaseGrade.class, BaseGrade::getId, BaseStudentSchoolRoll::getGradeId)
+                                .innerJoin(BaseClass.class, BaseClass::getId, BaseStudentSchoolRoll::getClassId)
+                                .innerJoin(BaseMajorSet.class, BaseMajorSet::getId,
+                                        BaseStudentSchoolRoll::getMajorSetId)
+                                .innerJoin(BaseMajor.class, BaseMajor::getId, BaseMajorSet::getMajorId)
+                                .in(XjrUser::getUserName, userNames)
+                                .eq(XjrUser::getDeleteMark, 0)
+                                .eq(XjrUser::getEnabledMark, 1);
+
+                        List<StudentImportDetailVo> studentDetails = xjrUserMapper
+                                .selectJoinList(StudentImportDetailVo.class, wrapper);
+                        Map<String, StudentImportDetailVo> studentMap = studentDetails.stream()
+                                .collect(Collectors.toMap(StudentImportDetailVo::getUserName, v -> v, (v1, v2) -> v1));
+
+                        // 3. 组装数据
+                        List<StudentConsumption> consumptionList = new ArrayList<>();
+                        for (CafeteriaImportExcelVo excelVo : dataList) {
+                            StudentImportDetailVo student = studentMap.get(excelVo.getUserName());
+                            if (student != null) {
+                                StudentConsumption consumption = new StudentConsumption();
+                                consumption.setStudentId(student.getUserId());
+                                consumption.setStudentName(student.getStudentName());
+                                consumption.setStudentUserName(student.getUserName());
+                                consumption.setClassId(student.getClassId());
+                                consumption.setClassName(student.getClassName());
+                                consumption.setGradeId(student.getGradeId());
+                                consumption.setGradeName(student.getGradeName());
+                                consumption.setMajorId(student.getMajorId());
+                                consumption.setMajorName(student.getMajorName());
+
+                                consumption.setConsumeTime(excelVo.getConsumeTime());
+                                consumption.setConsumeMoney(excelVo.getConsumeMoney());
+
+                                // 场景处理
+                                String consumeType = excelVo.getConsumeType();
+                                if ("智慧食堂".equals(consumeType)) {
+                                    consumption.setConsumeType("consume_type_1");
+                                } else {
+                                    consumption.setConsumeType(consumeType);
+                                }
+
+                                consumption.setDeleteMark(0);
+                                consumption.setEnabledMark(1);
+                                consumption.setCreateDate(new Date());
+                                // 设置其他默认值或从上下文获取创建人等
+
+                                consumptionList.add(consumption);
+                            }
+                        }
+
+                        // 4. 批量插入
+                        if (CollectionUtils.isNotEmpty(consumptionList)) {
+                            // 使用 MyBatis-Plus 的 saveBatch 或者循环插入
+                            // 这里假设注入了 StudentConsumptionMapper,但 Mapper 没有 saveBatch 方法(除非继承 IService)
+                            // 为了简单,循环插入或者使用 Service。由于没有 StudentConsumptionService,这里循环插入。
+                            // 或者更好的是,注入 IStudentConsumptionService 如果有的话。
+                            // 既然没有创建 Service,我将在 Mapper 中循环插入,或者直接在这里循环。
+                            for (StudentConsumption consumption : consumptionList) {
+                                try {
+                                    studentConsumptionMapper.insert(consumption);
+                                } catch (Exception e) {
+                                    // 忽略插入错误,如唯一索引冲突
+                                }
+                            }
+                        }
+
+                    })).sheet().headRowNumber(5).doRead();
+        } catch (Exception e) {
+            throw new RuntimeException("导入失败: " + e.getMessage());
+        }
+    }
 }

+ 23 - 0
src/main/java/com/xjrsoft/module/student/vo/CafeteriaImportExcelVo.java

@@ -0,0 +1,23 @@
+package com.xjrsoft.module.student.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class CafeteriaImportExcelVo {
+
+    @ExcelProperty("工号")
+    private String userName;
+
+    @ExcelProperty("应付金额")
+    private BigDecimal consumeMoney;
+
+    @ExcelProperty("下单时间")
+    private Date consumeTime;
+
+    @ExcelProperty("场景")
+    private String consumeType;
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/student/vo/StudentImportDetailVo.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.student.vo;
+
+import lombok.Data;
+
+@Data
+public class StudentImportDetailVo {
+    private Long userId;
+    private String userName;
+    private String studentName;
+    private String gradeId;
+    private Long classId;
+    private String majorSetId;
+    private String gradeName;
+    private String className;
+    private String majorName;
+    private String majorId;
+}

+ 10 - 0
src/main/java/com/xjrsoft/module/system/controller/LoginController.java

@@ -1,6 +1,9 @@
 package com.xjrsoft.module.system.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.context.model.SaCookie;
+import cn.dev33.satoken.context.model.SaResponse;
 import cn.dev33.satoken.session.SaSession;
 import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.util.IdUtil;
@@ -147,6 +150,13 @@ public class LoginController {
 
         String token = redisUtil.get(dto.getLoginCode());
 
+        SaResponse res = SaHolder.getResponse();
+        SaCookie cookie = new SaCookie()
+                .setName("Authorization")
+                .setValue(token);
+
+        res.addCookie(cookie);
+
         loginCheckQRCodeVo.setToken(token);
         loginCheckQRCodeVo.setStatus(0);
         return RT.ok(loginCheckQRCodeVo);

+ 5 - 1
src/main/resources/mapper/base/BaseClass.xml

@@ -125,7 +125,11 @@
         (SELECT COUNT(*) FROM base_student_school_roll c1
         INNER JOIN xjr_user c2 ON c1.user_id = c2.id
         WHERE c1.delete_mark = 0 AND c1.delete_mark = 0
-        AND c1.class_id = t1.id AND c1.archives_status = 'FB2901' AND c1.stduy_status = 'FB3001') AS not_stay_count FROM base_class t1
+        AND c1.class_id = t1.id AND c1.archives_status = 'FB2901' AND c1.stduy_status = 'FB3001') AS not_stay_count,
+        (SELECT COUNT(*) FROM base_student_school_roll c1
+        INNER JOIN xjr_user c2 ON c1.user_id = c2.id
+        WHERE c1.delete_mark = 0 AND c1.delete_mark = 0
+        AND c1.class_id = t1.id AND c1.archives_status = 'FB2901' AND c1.internship_state = 'IT_0002') AS internship_count FROM base_class t1
         LEFT JOIN xjr_user t2 ON t1.teacher_id = t2.id
         WHERE t1.delete_mark = 0
         <if test="dto.classId != null">

+ 4 - 0
src/main/resources/mapper/classtime/ClassCourseTimeStatisticsSetGroupMapper.xml

@@ -39,6 +39,10 @@
             AND c.name like concat('%', #{dto.courseName},'%')
         )
         </if>
+
+        <if test="dto.category != null and dto.category != ''">
+            and t1.category = #{dto.category}
+        </if>
         order by t1.create_date desc
     </select>
 </mapper>

+ 3 - 0
src/main/resources/mapper/classtime/ClassCourseTimeStatisticsSetMapper.xml

@@ -14,6 +14,9 @@
         <if test="dto.courseName != null and dto.courseName != ''">
             and t3.name like concat('%', #{dto.courseName},'%')
         </if>
+        <if test="dto.category != null and dto.category != ''">
+            and t1.category = #{dto.category}
+        </if>
         order by t1.create_date desc
     </select>
 </mapper>

+ 5 - 1
src/main/resources/sqlScript/20251111_sql.sql

@@ -48,4 +48,8 @@ CREATE TABLE `class_attendance_statistics` (
   `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='班级考勤统计';
+) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='班级考勤统计';
+
+ALTER TABLE class_attendance_statistics ADD internship_count INT DEFAULT NULL COMMENT '实习总人数';
+
+ALTER TABLE student_attendance_statistics ADD reason_leave VARCHAR(400) DEFAULT NULL COMMENT '请假原因';