Browse Source

Merge branch 'pre'

dzx 8 months ago
parent
commit
687b5bb0ad
100 changed files with 4847 additions and 423 deletions
  1. 15 0
      src/main/java/com/xjrsoft/common/enums/CourseAdjustTypeEnum.java
  2. 50 0
      src/main/java/com/xjrsoft/common/enums/MeetingTypeEnum.java
  3. 30 0
      src/main/java/com/xjrsoft/common/enums/TeaChangeTypeEnum.java
  4. 32 111
      src/main/java/com/xjrsoft/module/banding/service/impl/BandingTaskClassStudentServiceImpl.java
  5. 1 1
      src/main/java/com/xjrsoft/module/base/dto/BaseClassPageDto.java
  6. 2 0
      src/main/java/com/xjrsoft/module/base/service/IBaseClassService.java
  7. 41 1
      src/main/java/com/xjrsoft/module/base/service/impl/BaseClassServiceImpl.java
  8. 8 0
      src/main/java/com/xjrsoft/module/databoard/controller/DataboardController.java
  9. 260 109
      src/main/java/com/xjrsoft/module/databoard/controller/DatadetailController.java
  10. 36 0
      src/main/java/com/xjrsoft/module/databoard/dto/TeacherChangeStatisticsDetailDto.java
  11. 4 0
      src/main/java/com/xjrsoft/module/databoard/vo/DistributionVo.java
  12. 19 0
      src/main/java/com/xjrsoft/module/databoard/vo/TeacherChangeStatisticsDetailVo.java
  13. 0 1
      src/main/java/com/xjrsoft/module/databoard/vo/TeacherStatisticsDetailVo.java
  14. 2 2
      src/main/java/com/xjrsoft/module/job/BaseNewStudentTask.java
  15. 25 17
      src/main/java/com/xjrsoft/module/job/JianyuekbScheduleTask.java
  16. 6 0
      src/main/java/com/xjrsoft/module/liteflow/node/StudentDropOutNode.java
  17. 12 1
      src/main/java/com/xjrsoft/module/liteflow/node/WfMeetingApplyNode.java
  18. 7 1
      src/main/java/com/xjrsoft/module/liteflow/node/WfRoomApplicantNode.java
  19. 41 0
      src/main/java/com/xjrsoft/module/liteflow/node/WfTeacherDepartNode.java
  20. 30 6
      src/main/java/com/xjrsoft/module/material/controller/MaterialTaskController.java
  21. 5 0
      src/main/java/com/xjrsoft/module/material/service/impl/MaterialTypeServiceImpl.java
  22. 1 1
      src/main/java/com/xjrsoft/module/oa/controller/NewsController.java
  23. 250 0
      src/main/java/com/xjrsoft/module/oa/controller/WfMeetingApplyController.java
  24. 42 0
      src/main/java/com/xjrsoft/module/oa/dto/AddMeetingConfereeOpinionDto.java
  25. 29 0
      src/main/java/com/xjrsoft/module/oa/dto/HistoryMeetingMobilePageDto.java
  26. 22 0
      src/main/java/com/xjrsoft/module/oa/dto/MeetingConfereeListDto.java
  27. 19 0
      src/main/java/com/xjrsoft/module/oa/dto/MeetingConfereeOpinionListDto.java
  28. 46 0
      src/main/java/com/xjrsoft/module/oa/dto/MeetingRoomListDto.java
  29. 29 0
      src/main/java/com/xjrsoft/module/oa/dto/SponsorMeetingMobilePageDto.java
  30. 27 0
      src/main/java/com/xjrsoft/module/oa/dto/TodayMeetingMobilePageDto.java
  31. 21 0
      src/main/java/com/xjrsoft/module/oa/dto/UpdateMeetingCheckInDto.java
  32. 34 0
      src/main/java/com/xjrsoft/module/oa/dto/UpdateMeetingSummaryDto.java
  33. 22 0
      src/main/java/com/xjrsoft/module/oa/dto/UpdateRevocationMeetingDto.java
  34. 45 0
      src/main/java/com/xjrsoft/module/oa/dto/WfMeetingApplyPageDto.java
  35. 98 0
      src/main/java/com/xjrsoft/module/oa/entity/MeetingConferee.java
  36. 93 0
      src/main/java/com/xjrsoft/module/oa/entity/MeetingConfereeOpinion.java
  37. 121 0
      src/main/java/com/xjrsoft/module/oa/entity/MeetingRoom.java
  38. 86 49
      src/main/java/com/xjrsoft/module/oa/entity/WfMeetingApply.java
  39. 17 0
      src/main/java/com/xjrsoft/module/oa/mapper/MeetingConfereeMapper.java
  40. 17 0
      src/main/java/com/xjrsoft/module/oa/mapper/MeetingConfereeOpinionMapper.java
  41. 17 0
      src/main/java/com/xjrsoft/module/oa/mapper/MeetingRoomMapper.java
  42. 6 6
      src/main/java/com/xjrsoft/module/oa/mapper/WfMeetingApplyMapper.java
  43. 29 0
      src/main/java/com/xjrsoft/module/oa/service/IWfMeetingApplyService.java
  44. 692 44
      src/main/java/com/xjrsoft/module/oa/service/impl/WfMeetingApplyServiceImpl.java
  45. 68 0
      src/main/java/com/xjrsoft/module/oa/vo/HistoryMeetingMobilePageVo.java
  46. 47 0
      src/main/java/com/xjrsoft/module/oa/vo/MeetingConfereeListVo.java
  47. 50 0
      src/main/java/com/xjrsoft/module/oa/vo/MeetingConfereeOpinionListVo.java
  48. 118 0
      src/main/java/com/xjrsoft/module/oa/vo/MeetingMobileInfoVo.java
  49. 50 0
      src/main/java/com/xjrsoft/module/oa/vo/MeetingRoomListVo.java
  50. 36 0
      src/main/java/com/xjrsoft/module/oa/vo/MeetingSummaryVo.java
  51. 73 0
      src/main/java/com/xjrsoft/module/oa/vo/SponsorMeetingMobilePageVo.java
  52. 73 0
      src/main/java/com/xjrsoft/module/oa/vo/TodayMeetingMobilePageVo.java
  53. 144 0
      src/main/java/com/xjrsoft/module/oa/vo/WfMeetingApplyInWorkflowVo.java
  54. 108 0
      src/main/java/com/xjrsoft/module/oa/vo/WfMeetingApplyPageVo.java
  55. 12 5
      src/main/java/com/xjrsoft/module/organization/controller/UserController.java
  56. 17 0
      src/main/java/com/xjrsoft/module/organization/dto/UnbindOpenidDto.java
  57. 4 2
      src/main/java/com/xjrsoft/module/organization/service/IUserService.java
  58. 68 16
      src/main/java/com/xjrsoft/module/organization/service/impl/UserServiceImpl.java
  59. 32 0
      src/main/java/com/xjrsoft/module/organization/vo/BindOpenidVo.java
  60. 3 0
      src/main/java/com/xjrsoft/module/room/dto/RoomBedPageDto.java
  61. 25 23
      src/main/java/com/xjrsoft/module/room/mapper/RoomBedMapper.java
  62. 1 1
      src/main/java/com/xjrsoft/module/schedule/controller/ScheduleController.java
  63. 72 0
      src/main/java/com/xjrsoft/module/schedule/controller/TodayScheduleController.java
  64. 19 0
      src/main/java/com/xjrsoft/module/schedule/dto/TodaySchedulePageDto.java
  65. 54 0
      src/main/java/com/xjrsoft/module/schedule/entity/TodaySchedule.java
  66. 20 0
      src/main/java/com/xjrsoft/module/schedule/mapper/TodayScheduleMapper.java
  67. 21 0
      src/main/java/com/xjrsoft/module/schedule/service/ITodayScheduleService.java
  68. 50 0
      src/main/java/com/xjrsoft/module/schedule/service/impl/TodayScheduleServiceImpl.java
  69. 4 4
      src/main/java/com/xjrsoft/module/schedule/util/DataUtil.java
  70. 43 0
      src/main/java/com/xjrsoft/module/schedule/vo/TodayScheduleVo.java
  71. 4 0
      src/main/java/com/xjrsoft/module/student/controller/BaseStudentAssessmentInspectionController.java
  72. 3 0
      src/main/java/com/xjrsoft/module/student/dto/BaseStudentAssessmentInspectionPageDto.java
  73. 5 0
      src/main/java/com/xjrsoft/module/student/service/impl/BaseStudentGraduateServiceImpl.java
  74. 4 1
      src/main/java/com/xjrsoft/module/student/service/impl/BaseStudentSchoolRollServiceImpl.java
  75. 137 0
      src/main/java/com/xjrsoft/module/teacher/controller/BaseTeacherChangeRecordController.java
  76. 62 6
      src/main/java/com/xjrsoft/module/teacher/controller/TeacherbaseManagerController.java
  77. 48 0
      src/main/java/com/xjrsoft/module/teacher/dto/AddBaseTeacherChangeRecordDto.java
  78. 43 0
      src/main/java/com/xjrsoft/module/teacher/dto/BaseTeacherChangeRecordPageDto.java
  79. 32 0
      src/main/java/com/xjrsoft/module/teacher/dto/UpdateBaseTeacherChangeRecordDto.java
  80. 98 0
      src/main/java/com/xjrsoft/module/teacher/entity/BaseTeacherChangeRecord.java
  81. 0 2
      src/main/java/com/xjrsoft/module/teacher/entity/BaseTeacherRegular.java
  82. 178 0
      src/main/java/com/xjrsoft/module/teacher/entity/WfTeacherDepart.java
  83. 17 0
      src/main/java/com/xjrsoft/module/teacher/mapper/BaseTeacherChangeRecordMapper.java
  84. 17 0
      src/main/java/com/xjrsoft/module/teacher/mapper/WfTeacherDepartMapper.java
  85. 17 0
      src/main/java/com/xjrsoft/module/teacher/service/IBaseTeacherChangeRecordService.java
  86. 2 0
      src/main/java/com/xjrsoft/module/teacher/service/ITeacherbaseManagerService.java
  87. 25 0
      src/main/java/com/xjrsoft/module/teacher/service/impl/BaseTeacherChangeRecordServiceImpl.java
  88. 165 0
      src/main/java/com/xjrsoft/module/teacher/service/impl/TeacherbaseManagerServiceImpl.java
  89. 73 0
      src/main/java/com/xjrsoft/module/teacher/vo/BaseTeacherChangeRecordPageVo.java
  90. 49 0
      src/main/java/com/xjrsoft/module/teacher/vo/BaseTeacherChangeRecordVo.java
  91. 34 2
      src/main/java/com/xjrsoft/module/teacher/vo/XjrUserPageVo.java
  92. 4 9
      src/main/java/com/xjrsoft/module/textbook/controller/WfTextbookClaimController.java
  93. 1 1
      src/main/java/com/xjrsoft/module/workflow/controller/WorkflowExecuteController.java
  94. 42 0
      src/main/java/com/xjrsoft/module/workflow/service/impl/WorkflowExecuteServiceImpl.java
  95. 1 0
      src/main/resources/mapper/base/BaseClass.xml
  96. 3 0
      src/main/resources/mapper/room/RoomBedMapper.xml
  97. 9 0
      src/main/resources/mapper/schedule/TodayScheduleMapper.xml
  98. 3 0
      src/main/resources/mapper/student/BaseStudentAssessmentInspectionMapper.xml
  99. 1 1
      src/main/resources/mapper/student/PbVXsxxsfytbMapper.xml
  100. 169 0
      src/main/resources/sqlScript/20250324_sql.sql

+ 15 - 0
src/main/java/com/xjrsoft/common/enums/CourseAdjustTypeEnum.java

@@ -1,5 +1,8 @@
 package com.xjrsoft.common.enums;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * @author dzx
  * @date 2024/2/3
@@ -19,6 +22,14 @@ public enum CourseAdjustTypeEnum {
     final String code;
     final String value;
 
+    private static final Map<String, String> lookup = new HashMap<>();
+
+    static {
+        for (ArchivesStatusEnum s : ArchivesStatusEnum.values()) {
+            lookup.put(s.getCode(), s.getValue());
+        }
+    }
+
     public String getCode() {
         return this.code;
     }
@@ -31,4 +42,8 @@ public enum CourseAdjustTypeEnum {
         this.code = code;
         this.value = message;
     }
+
+    public static String fromCode(String code) {
+        return lookup.get(code);
+    }
 }

+ 50 - 0
src/main/java/com/xjrsoft/common/enums/MeetingTypeEnum.java

@@ -0,0 +1,50 @@
+package com.xjrsoft.common.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 会议形式(xjr_dictionary_item(meeting_type))
+ */
+public enum MeetingTypeEnum {
+
+    /**
+     * 在读
+     * */
+    HMT0001("HMT0001", "线上会议"),
+    /**
+     * 休学
+     * */
+    HMT0002("HMT0002", "线下会议");
+
+    final String code;
+    final String value;
+
+    private static final Map<String, String> lookup = new HashMap<>();
+
+    static {
+        for (MeetingTypeEnum s : MeetingTypeEnum.values()) {
+            lookup.put(s.getCode(), s.getValue());
+        }
+    }
+
+
+
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    MeetingTypeEnum(final String code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+
+    public static String fromCode(String code) {
+        return lookup.get(code);
+    }
+
+}

+ 30 - 0
src/main/java/com/xjrsoft/common/enums/TeaChangeTypeEnum.java

@@ -0,0 +1,30 @@
+package com.xjrsoft.common.enums;
+
+/**
+ * @description: 教职工异动类型tea_change_type
+ * @author: phoenix
+ * @create: 2023/12/21 11:27
+ * @Version 1.0
+ */
+public enum TeaChangeTypeEnum {
+    /**
+     * 在职状态
+     * */
+    TCT0001("TCT0001", "在职状态");
+
+    final String code;
+    final String value;
+
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+    TeaChangeTypeEnum(final String code, final String message) {
+        this.code = code;
+        this.value = message;
+    }
+}

+ 32 - 111
src/main/java/com/xjrsoft/module/banding/service/impl/BandingTaskClassStudentServiceImpl.java

@@ -11,24 +11,19 @@ import com.xjrsoft.common.enums.ArchivesStatusEnum;
 import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.EnabledMark;
 import com.xjrsoft.common.enums.RoleEnum;
-import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.utils.LocalDateUtil;
 import com.xjrsoft.common.utils.RedisUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.config.CommonPropertiesConfig;
-import com.xjrsoft.module.banding.dto.BandingTaskClassStudentPageDto;
 import com.xjrsoft.module.banding.dto.ChangeClassDto;
 import com.xjrsoft.module.banding.dto.StudentDto;
-import com.xjrsoft.module.banding.entity.BandingTask;
 import com.xjrsoft.module.banding.entity.BandingTaskClass;
 import com.xjrsoft.module.banding.entity.BandingTaskClassStudent;
 import com.xjrsoft.module.banding.mapper.BandingTaskClassMapper;
 import com.xjrsoft.module.banding.mapper.BandingTaskClassStudentMapper;
 import com.xjrsoft.module.banding.mapper.BandingTaskMapper;
 import com.xjrsoft.module.banding.service.IBandingTaskClassStudentService;
-import com.xjrsoft.module.banding.vo.BandingTaskClassSureListVo;
 import com.xjrsoft.module.base.entity.BaseClass;
-import com.xjrsoft.module.base.entity.BaseMajorSet;
 import com.xjrsoft.module.base.entity.BaseSemester;
 import com.xjrsoft.module.base.mapper.BaseMajorSetMapper;
 import com.xjrsoft.module.base.service.IBaseClassService;
@@ -38,7 +33,6 @@ import com.xjrsoft.module.organization.entity.UserRoleRelation;
 import com.xjrsoft.module.organization.service.IUserRoleRelationService;
 import com.xjrsoft.module.organization.service.IUserService;
 import com.xjrsoft.module.student.dto.BaseNewStudentPageDto;
-import com.xjrsoft.module.student.entity.BaseClassMajorSet;
 import com.xjrsoft.module.student.entity.BaseNewStudent;
 import com.xjrsoft.module.student.entity.BaseStudent;
 import com.xjrsoft.module.student.entity.BaseStudentFamily;
@@ -58,8 +52,8 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -123,34 +117,11 @@ public class BandingTaskClassStudentServiceImpl extends MPJBaseServiceImpl<Bandi
                         .in(BandingTaskClassStudent::getNewStudentId, dto.getNewStudentIds())
         );
 
-        BandingTaskClass taskClass = taskClassMapper.selectById(dto.getBandingTaskClassId());
-
-        //新增报到计划,如果有多个分班任务确认,需要保证试读报到计划只有一个
-        BaseSemester semester = semesterService.getCurrentSemester();
-        StudentReportPlan plan = reportPlanService.getOne(
-                new QueryWrapper<StudentReportPlan>().lambda()
-                        .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
-                        .eq(StudentReportPlan::getEnabledMark, EnabledMark.ENABLED.getCode())
-                        .eq(StudentReportPlan::getSemesterId, semester.getId())
-                        .eq(StudentReportPlan::getCategory, 2)
-                        .eq(StudentReportPlan::getBandingTaskId, taskClass.getBandingTaskId())
-        );
-        if(plan == null){
-            plan = new StudentReportPlan();
-            plan.setStatus(0);
-            plan.setCategory(2);
-            plan.setBandingTaskId(taskClass.getBandingTaskId());
-            plan.setDeleteMark(DeleteMark.NODELETE.getCode());
-            plan.setEnabledMark(EnabledMark.ENABLED.getCode());
-            plan.setCreateDate(new Date());
-            plan.setCreateUserId(StpUtil.getLoginIdAsLong());
-            reportPlanService.save(plan);
-        }
+        BaseClass aClass = classService.getById(dto.getBandingTaskClassId());
 
         List<BandingTaskClassStudent> dataList = new ArrayList<>();
         long createUserId = StpUtil.getLoginIdAsLong();
 
-        List<StudentReportRecord> insertList = new ArrayList<>();
         for (Long newStudentId : dto.getNewStudentIds()) {
             dataList.add(
                     new BandingTaskClassStudent(){{
@@ -164,33 +135,42 @@ public class BandingTaskClassStudentServiceImpl extends MPJBaseServiceImpl<Bandi
                         }
                     }}
             );
-            if(dto.getIsHandle() != null && dto.getIsHandle() == 1){
-                StudentReportRecord record = new StudentReportRecord();
-                record.setCreateDate(new Date());
-                record.setCreateUserId(StpUtil.getLoginIdAsLong());
-                record.setUserId(newStudentId);
-                record.setStudentReportPlanId(plan.getId());
-                record.setDeleteMark(DeleteMark.NODELETE.getCode());
-                record.setEnabledMark(EnabledMark.ENABLED.getCode());
-                insertList.add(record);
-            }
         }
         if(!dataList.isEmpty()){
             this.saveBatch(dataList);
         }
 
-        if(!insertList.isEmpty()){
-            for (StudentReportRecord studentReportRecord : insertList) {
-                reportRecordMapper.insert(studentReportRecord);
-            }
-        }
-
         List<Long> studentIds = dataList.stream().map(BandingTaskClassStudent::getNewStudentId).collect(Collectors.toList());
         List<BaseNewStudent> list = newStudentService.list(
                 new QueryWrapper<BaseNewStudent>().lambda()
                         .in(BaseNewStudent::getId, studentIds)
         );
+
         if(dto.getIsHandle() != null && dto.getIsHandle() == 1){
+            //新增报到计划,如果有多个分班任务确认,需要保证试读报到计划只有一个
+            BaseSemester semester = semesterService.getCurrentSemester();
+            List<StudentReportPlan> planList = reportPlanService.list(
+                    new QueryWrapper<StudentReportPlan>().lambda()
+                            .eq(StudentReportPlan::getDeleteMark, DeleteMark.NODELETE.getCode())
+                            .eq(StudentReportPlan::getEnabledMark, EnabledMark.ENABLED.getCode())
+                            .eq(StudentReportPlan::getSemesterId, semester.getId())
+                            .in(StudentReportPlan::getCategory, Arrays.asList(2, 3))
+            );
+
+            for (StudentReportPlan plan : planList) {
+                for (Long newStudentId : studentIds) {
+                    StudentReportRecord record = new StudentReportRecord();
+                    record.setCreateDate(new Date());
+                    record.setCreateUserId(StpUtil.getLoginIdAsLong());
+                    record.setUserId(newStudentId);
+                    record.setStudentReportPlanId(plan.getId());
+                    record.setDeleteMark(DeleteMark.NODELETE.getCode());
+                    record.setEnabledMark(EnabledMark.ENABLED.getCode());
+                    reportRecordMapper.insert(record);
+                }
+            }
+
+
             List<BaseNewStudent> updateList = new ArrayList<>();
             for (BaseNewStudent student : list) {
                 student.setStatus(1);
@@ -202,64 +182,6 @@ public class BandingTaskClassStudentServiceImpl extends MPJBaseServiceImpl<Bandi
                 newStudentService.updateBatchById(updateList);
             }
             {
-                Date createDate = new Date();
-                BandingTask bandingTask = bandingTaskMapper.selectById(taskClass.getBandingTaskId());
-                List<BandingTaskClassSureListVo> classSure = taskClassMapper.getClassSure(new BandingTaskClassStudentPageDto() {{
-                    setBandingTaskId(taskClass.getBandingTaskId());
-                }});
-
-                Map<Long, Integer> classTotal = classSure.stream().collect(Collectors.toMap(BandingTaskClassSureListVo::getId, BandingTaskClassSureListVo::getNumber));
-                Map<Long, Integer> classBoy = classSure.stream().collect(Collectors.toMap(BandingTaskClassSureListVo::getId, BandingTaskClassSureListVo::getMaleCount));
-                Map<Long, Integer> classGirl = classSure.stream().collect(Collectors.toMap(BandingTaskClassSureListVo::getId, BandingTaskClassSureListVo::getFemaleCount));
-
-
-                //生成班级数据
-                Map<Long, Long> classMap = new HashMap<>();
-                Map<Long, Long> taskClassMajorMap = new HashMap<>();
-                //查询出需要新增的班级信息
-                Map<Long, Long> majorDeptMap = majorSetMapper.selectList(
-                        new QueryWrapper<BaseMajorSet>()
-                ).stream().collect(Collectors.toMap(BaseMajorSet::getId, BaseMajorSet::getDepartmentId));
-                //先查询是否已经存在这个班级,如果存在就更新,不存在就新增
-                BaseClass baseClass = classService.getOne(
-                        new QueryWrapper<BaseClass>().lambda()
-                                .eq(BaseClass::getName, taskClass.getName())
-                                .eq(BaseClass::getGradeId, bandingTask.getGradeId())
-                                .eq(BaseClass::getEnrollType, bandingTask.getEnrollType())
-                );
-                if(baseClass == null){
-                    baseClass = new BaseClass() {{
-                        setName(taskClass.getName());
-                        setClassroomId(taskClass.getClassroomId());
-                        setTeacherId(taskClass.getTeacherId());
-                        setIsGraduate(1);
-                        setMajorSetId(taskClass.getMajorSetId());
-                        setOrgId(majorDeptMap.get(taskClass.getMajorSetId()));
-                        setIsOrderClass(taskClass.getIsOrderClass()==null?0:taskClass.getIsOrderClass().intValue());
-                        setGradeId(bandingTask.getGradeId());
-                        setDeleteMark(DeleteMark.NODELETE.getCode());
-                        setEnrollType(bandingTask.getEnrollType());
-                        setCreateDate(new Date());
-                    }};
-
-                    classService.save(baseClass);
-
-                    BaseClassMajorSet majorSet = new BaseClassMajorSet() {{
-                        setCreateDate(createDate);
-                        setMajorSetId(taskClass.getMajorSetId());
-                        setPlanTotalStudent(taskClass.getNumber());
-                        setTotalStudent(classTotal.get(taskClass.getId()));
-                        setBoyNum(classBoy.get(taskClass.getId()));
-                        setGirlNum(classGirl.get(taskClass.getId()));
-                    }};
-                    majorSet.setClassId(baseClass.getId());
-                    classMajorSetMapper.insert(majorSet);
-                }
-
-
-                classMap.put(taskClass.getId(), baseClass.getId());
-                taskClassMajorMap.put(taskClass.getId(), taskClass.getMajorSetId());
-
                 /**
                  * 新增学生数据
                  * 1、新增用户xjr_user,需要先查询用户信息是否已经存在
@@ -282,10 +204,9 @@ public class BandingTaskClassStudentServiceImpl extends MPJBaseServiceImpl<Bandi
                     userSet.put(student.getCredentialNumber(), student.getId());
                     userDeleteMarkMap.put(student.getCredentialNumber(), student.getDeleteMark());
                 }
-                Map<Long, Long> studentClassRelation = dataList.stream().collect(Collectors.toMap(BandingTaskClassStudent::getNewStudentId, BandingTaskClassStudent::getBandingTaskClassId));
                 for (BaseNewStudent student : updateList) {
                     if(userSet.containsKey(student.getCredentialNumber())){
-                        schoolRollService.updateStudentClass(classMap.get(studentClassRelation.get(student.getId())), userSet.get(student.getCredentialNumber()));
+                        schoolRollService.updateStudentClass(dto.getBandingTaskClassId(), userSet.get(student.getCredentialNumber()));
                         Integer deleteMark = userDeleteMarkMap.get(student.getCredentialNumber());
                         if(deleteMark != null && deleteMark == 1){
                             userService.recoveryStudentInfo(userSet.get(student.getCredentialNumber()));
@@ -334,12 +255,12 @@ public class BandingTaskClassStudentServiceImpl extends MPJBaseServiceImpl<Bandi
                         }
 
                         setGraduatedUniversity(student.getGraduateSchool());
-                        setClassId(classMap.get(studentClassRelation.get(student.getId())));
-                        setMajorSetId(taskClassMajorMap.get(studentClassRelation.get(student.getId())));
+                        setClassId(dto.getBandingTaskClassId());
+                        setMajorSetId(aClass.getMajorSetId());
                         setStduyStatus(student.getStduyStatus());
-                        setEnrollType(bandingTask.getEnrollType());
+                        setEnrollType(aClass.getEnrollType());
                         setStudentSource(student.getSource());
-                        setGradeId(bandingTask.getGradeId());
+                        setGradeId(aClass.getGradeId());
                         setArchivesStatus(ArchivesStatusEnum.FB2901.getCode());
                         setCreateDate(now);
                     }};

+ 1 - 1
src/main/java/com/xjrsoft/module/base/dto/BaseClassPageDto.java

@@ -39,7 +39,7 @@ public class BaseClassPageDto extends PageInput {
     private Long teacherId;
 
     @ApiModelProperty("在读状态(1: 在读 2: 毕业)")
-    private Integer isGraduate;
+    private Integer isGraduate = 1;
 
     @ApiModelProperty("是否订单班(1: 是 0: 否)")
     private Integer isOrderClass;

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

@@ -31,4 +31,6 @@ public interface IBaseClassService extends MPJBaseService<BaseClass> {
     Boolean addClass(AddBaseClassPageDto dto);
 
     Boolean updateClass(UpdateBaseClassPageDto dto);
+
+    String initClassCode(Long gradeId);
 }

+ 41 - 1
src/main/java/com/xjrsoft/module/base/service/impl/BaseClassServiceImpl.java

@@ -20,7 +20,9 @@ import com.xjrsoft.module.base.dto.AddBaseClassPageDto;
 import com.xjrsoft.module.base.dto.BaseClassPageDto;
 import com.xjrsoft.module.base.dto.UpdateBaseClassPageDto;
 import com.xjrsoft.module.base.entity.BaseClass;
+import com.xjrsoft.module.base.entity.BaseGrade;
 import com.xjrsoft.module.base.mapper.BaseClassMapper;
+import com.xjrsoft.module.base.mapper.BaseGradeMapper;
 import com.xjrsoft.module.base.service.IBaseClassService;
 import com.xjrsoft.module.base.vo.BaseClassPageVo;
 import com.xjrsoft.module.base.vo.StudentClassVo;
@@ -59,6 +61,8 @@ public class BaseClassServiceImpl extends MPJBaseServiceImpl<BaseClassMapper, Ba
 
     private final IBandingTaskClassService bandingTaskClassService;
 
+    private final BaseGradeMapper gradeMapper;
+
     /**
      * 获取家长关联的学生 id 是家长的ID
      *
@@ -161,6 +165,7 @@ public class BaseClassServiceImpl extends MPJBaseServiceImpl<BaseClassMapper, Ba
         baseClass.setCreateDate(new Date());
         baseClass.setEnabledMark(EnabledMark.ENABLED.getCode());
         baseClass.setCreateUserId(StpUtil.getLoginIdAsLong());
+        baseClass.setCode(initClassCode(baseClass.getGradeId()));
         if (baseClass.getTeacherId() != null) {
             //查询该班主任是否是其他在读班级
             long count = this.count(
@@ -224,10 +229,21 @@ public class BaseClassServiceImpl extends MPJBaseServiceImpl<BaseClassMapper, Ba
                             .ne(BaseClass::getId, dto.getId())
             );
             if (count > 0) {
-                throw new MyException("该老师已是其他在读班级班主任,无法添加");
+                throw new MyException("该老师已是其他在读班级班主任,无法修改");
+            }
+        }
+        if(!aClass.getCode().equals(dto.getCode())){
+            List<BaseClass> list = this.list(
+                    new QueryWrapper<BaseClass>().lambda()
+                            .eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
+                            .eq(BaseClass::getCode, dto.getCode())
+            );
+            if(!list.isEmpty()){
+                throw new MyException("班级编码已存在,无法修改");
             }
         }
 
+
         BaseClass baseClass = BeanUtil.toBean(dto, BaseClass.class);
         baseClass.setModifyDate(new Date());
         baseClass.setModifyUserId(StpUtil.getLoginIdAsLong());
@@ -291,4 +307,28 @@ public class BaseClassServiceImpl extends MPJBaseServiceImpl<BaseClassMapper, Ba
         return update;
     }
 
+    /**
+     * 根据年级,查询并生成最新的classCode
+     * @param gradeId 年级id
+     * @return classCode
+     */
+    @Override
+    public String initClassCode(Long gradeId) {
+        BaseGrade baseGrade = gradeMapper.selectById(gradeId);
+        String year = baseGrade.getTitle().replace("年", "");
+        List<BaseClass> list = this.list(
+                new QueryWrapper<BaseClass>().lambda()
+                        .eq(BaseClass::getDeleteMark, DeleteMark.NODELETE.getCode())
+                        .eq(BaseClass::getGradeId, gradeId)
+                        .orderByDesc(BaseClass::getCode)
+        );
+        if(!list.isEmpty()){
+            String code = list.get(0).getCode();
+            code = code.trim().substring(code.length() - 3);
+
+            return year + String.format("%03d", Integer.parseInt(code) + 1);
+        }
+        return year + "001";
+    }
+
 }

+ 8 - 0
src/main/java/com/xjrsoft/module/databoard/controller/DataboardController.java

@@ -256,6 +256,13 @@ public class DataboardController {
                 .map(BaseStudentUserPageVo::getId).collect(Collectors.toSet());
         result.setStudentNotStayFemaleCount(studentNotStayFemaleSet.size());
 
+        List<String> jobStates = new ArrayList<>();
+        jobStates.add("JOB_DDSX");
+        jobStates.add("JOB_WCPX");
+        jobStates.add("ZZZT10009");
+        jobStates.add("ZZZT10004");
+
+
         MPJLambdaWrapper<XjrUser> queryWrapper = MPJWrappers.<XjrUser>lambdaJoin()
                 .disableSubLogicDel()
                 .orderByDesc(XjrUser::getId)
@@ -265,6 +272,7 @@ public class DataboardController {
                 .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getJobState, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getJobState))
                 .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getCredentialType, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getCredentialType))
                 .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getEmployType, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getEmployWay))
+                .in(BaseTeacher::getJobState, jobStates)
                 .selectAsClass(BaseTeacher.class, XjrUserPageVo.class);
 
         List<XjrUserPageVo> teacherList = teacherService.selectJoinList(XjrUserPageVo.class, queryWrapper);

+ 260 - 109
src/main/java/com/xjrsoft/module/databoard/controller/DatadetailController.java

@@ -1,19 +1,37 @@
 package com.xjrsoft.module.databoard.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
-import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.github.yulichang.toolkit.MPJWrappers;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.annotation.XjrLog;
+import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.GenderDictionaryEnum;
 import com.xjrsoft.common.enums.StudyStatusEnum;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
 import com.xjrsoft.common.utils.SqlRunnerAdapterUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.base.entity.BaseSemester;
+import com.xjrsoft.module.base.mapper.BaseSemesterMapper;
 import com.xjrsoft.module.databoard.dto.StatisticsDetailDto;
-import com.xjrsoft.module.databoard.vo.*;
+import com.xjrsoft.module.databoard.dto.TeacherChangeStatisticsDetailDto;
+import com.xjrsoft.module.databoard.vo.CourseCountListVo;
+import com.xjrsoft.module.databoard.vo.CourseStatisticsDetailVo;
+import com.xjrsoft.module.databoard.vo.DistributionVo;
+import com.xjrsoft.module.databoard.vo.DurationVo;
+import com.xjrsoft.module.databoard.vo.HealthItemCountVo;
+import com.xjrsoft.module.databoard.vo.HealthStatisticsDetailVo;
+import com.xjrsoft.module.databoard.vo.ItemCountAmountVo;
+import com.xjrsoft.module.databoard.vo.ItemCountRatioVo;
+import com.xjrsoft.module.databoard.vo.ItemCountVo;
+import com.xjrsoft.module.databoard.vo.ItemDoubleVo;
+import com.xjrsoft.module.databoard.vo.ProcessStatisticsDetailVo;
+import com.xjrsoft.module.databoard.vo.StudnetStatisticsDetailVo;
+import com.xjrsoft.module.databoard.vo.SubscriptionStatisticsDetailVo;
+import com.xjrsoft.module.databoard.vo.TeacherChangeStatisticsDetailVo;
+import com.xjrsoft.module.databoard.vo.TeacherStatisticsDetailVo;
 import com.xjrsoft.module.oa.entity.WfSubscription;
 import com.xjrsoft.module.oa.service.IWfSubscriptionService;
 import com.xjrsoft.module.student.dto.BaseStudentUserPageDto;
@@ -23,20 +41,18 @@ import com.xjrsoft.module.student.vo.StudentReportRecordItemVo;
 import com.xjrsoft.module.system.entity.DictionaryDetail;
 import com.xjrsoft.module.teacher.entity.BaseTeacher;
 import com.xjrsoft.module.teacher.entity.XjrUser;
+import com.xjrsoft.module.teacher.service.IBaseTeacherService;
 import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
 import com.xjrsoft.module.teacher.vo.XjrUserPageVo;
-import com.xjrsoft.module.workflow.constant.WorkflowConstant;
-import com.xjrsoft.module.workflow.entity.WorkflowExtra;
 import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
-import com.xjrsoft.module.workflow.entity.WorkflowSchema;
-import com.xjrsoft.module.workflow.service.IWorkflowExtraService;
-import com.xjrsoft.module.workflow.utils.WorkFlowUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
-import org.camunda.bpm.engine.HistoryService;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.camunda.bpm.engine.history.HistoricProcessInstance;
-import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery;
+import org.camunda.bpm.engine.history.JobState;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
@@ -50,8 +66,16 @@ import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.Period;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
-import java.util.*;
+import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
@@ -65,109 +89,73 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class DatadetailController {
 
-    private final HistoryService historyService;
-    private final IWorkflowExtraService extraService;
     private final ITeacherbaseManagerService teacherService;
+    private final IBaseTeacherService baseTeacherService;
     private final IBaseStudentService studentService;
     private final IWfSubscriptionService subscriptionService;
+    private final BaseSemesterMapper baseSemesterMapper;
 
     @GetMapping(value = "/process-statistics")
     @ApiOperation(value = "流程统计详情")
     @SaCheckPermission("datadetail:detail")
     @XjrLog(value = "流程统计详情", saveResponseData = true)
     public RT<ProcessStatisticsDetailVo> processStatistics(@Valid StatisticsDetailDto dto) {
-        HistoricProcessInstanceQuery instanceQuery = historyService.createHistoricProcessInstanceQuery();
-        if (dto.getUserId() != null) {
-            instanceQuery.variableValueEquals(WorkflowConstant.PROCESS_START_USER_ID_KEY, dto.getUserId());
-        }
-        LocalDateTime startTime = null;
-        LocalDateTime endTime = null;
-        if (dto.getStartDate() != null) {
-            startTime = dto.getStartDate().atStartOfDay();
-        }
-        if (dto.getEndDate() != null) {
-            endTime = dto.getEndDate().atStartOfDay().plusDays(1).plusNanos(-1);
-        }
-        if (!ObjectUtil.isNull(dto.getStartDate())) {
-            instanceQuery.startedAfter(WorkFlowUtil.getStartOfDay(dto.getStartDate()));
-        }
-        if (!ObjectUtil.isNull(dto.getEndDate())) {
-            instanceQuery.startedBefore(WorkFlowUtil.getEndOfDay(dto.getEndDate()));
+        ProcessStatisticsDetailVo result = new ProcessStatisticsDetailVo();
+        String sql = "SELECT DISTINCT t1.id,t2.schema_name,t1.start_time,t1.end_time,t1.current_state FROM xjr_workflow_form_relation t1" +
+                " INNER JOIN xjr_workflow_extra t2 ON t1.process_id = t2.process_id" +
+                " WHERE 1 = 1";
+        if (dto.getStartDate() != null && dto.getEndDate() != null) {
+            sql += " and DATE_FORMAT(t1.start_time, '%Y-%m-%d') BETWEEN '" + dto.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "'"
+                + " and '" + dto.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "'";
+        }
+        List<Map<String, Object>> dataList = SqlRunnerAdapter.db().selectList(sql);
+        result.setAllCount(dataList.stream().count());
+        Long uncompleteCount = 0L;
+        Long completeCount = 0L;
+
+        for (Map<String, Object> objectMap : dataList) {
+            String currentState = objectMap.get("current_state").toString();
+            if(HistoricProcessInstance.STATE_ACTIVE.equals(currentState)){
+                uncompleteCount ++;
+            }else{
+                completeCount ++;
+            }
         }
+        result.setCompleteCount(completeCount);
+        result.setUncompleteCount(uncompleteCount);
 
-        List<WorkflowExtra> workflowExtras = extraService.list(
-                new MPJLambdaWrapper<WorkflowExtra>()
-                        .between((startTime != null && endTime != null), WorkflowExtra::getLaunchTime, startTime, endTime)
-                        .select(WorkflowExtra::getId)
-                        .select(WorkflowExtra.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowExtra.class).contains(x.getProperty()))
-                        .leftJoin(WorkflowSchema.class, WorkflowSchema::getId, WorkflowExtra::getSchemaId)
-                        .leftJoin(DictionaryDetail.class, DictionaryDetail::getId, WorkflowSchema::getCategory)
-        );
+        Set<String> itemSet = dataList.stream().map(x -> x.get("schema_name").toString()).collect(Collectors.toSet());
 
+        Map<String, Long> finishedMap = dataList.stream()
+                .filter(x -> !HistoricProcessInstance.STATE_ACTIVE.equals(x.get("current_state").toString()))
+                .collect(Collectors.groupingBy(x -> x.get("schema_name").toString(), Collectors.counting()));
+        Map<String, Long> unfinishedMap = dataList.stream()
+                .filter(x -> HistoricProcessInstance.STATE_ACTIVE.equals(x.get("current_state").toString()))
+                .collect(Collectors.groupingBy(x -> x.get("schema_name").toString(), Collectors.counting()));
 
-        ProcessStatisticsDetailVo result = new ProcessStatisticsDetailVo();
-        List<HistoricProcessInstance> list = instanceQuery.list();
-        List<WorkflowExtra> allCountList = new ArrayList<>();
-        for (HistoricProcessInstance historicProcessInstance : list) {
-            workflowExtras.stream()
-                    .filter(e -> e.getProcessId().equals(historicProcessInstance.getId()))
-                    .max(Comparator.comparing(WorkflowExtra::getStartTime))
-                    .ifPresent(e -> {
-                        allCountList.add(e);
-                    });
-        }
-        result.setAllCount(Long.parseLong(allCountList.size() + ""));
-
-        List<HistoricProcessInstance> finished = historyService.createHistoricProcessInstanceQuery().finished().list();
-        List<WorkflowExtra> completeCountList = new ArrayList<>();
-        for (HistoricProcessInstance historicProcessInstance : finished) {
-            workflowExtras.stream()
-                    .filter(e -> e.getProcessId().equals(historicProcessInstance.getId()) && e.getEndTime() != null)
-                    .max(Comparator.comparing(WorkflowExtra::getStartTime))
-                    .ifPresent(e -> {
-                        completeCountList.add(e);
-                    });
-        }
-        result.setCompleteCount(Long.parseLong(completeCountList.size() + ""));
-
-        List<HistoricProcessInstance> unfinished = historyService.createHistoricProcessInstanceQuery().unfinished().list();
-        List<WorkflowExtra> uncompleteCountList = new ArrayList<>();
-        for (HistoricProcessInstance historicProcessInstance : unfinished) {
-            workflowExtras.stream()
-                    .filter(e -> e.getProcessId().equals(historicProcessInstance.getId()))
-                    .max(Comparator.comparing(WorkflowExtra::getStartTime))
-                    .ifPresent(e -> {
-                        uncompleteCountList.add(e);
-                    });
-        }
-        result.setUncompleteCount(Long.parseLong(uncompleteCountList.size() + ""));
-
-        Map<String, Long> finishedMap = completeCountList.stream()
-                .collect(Collectors.groupingBy(WorkflowExtra::getSchemaName, Collectors.counting()));
-        Map<String, Long> unfinishedMap = uncompleteCountList.stream()
-                .collect(Collectors.groupingBy(WorkflowExtra::getSchemaName, Collectors.counting()));
-
-        Set<String> itemSet = new HashSet<>();
-        itemSet.addAll(finishedMap.keySet());
-        itemSet.addAll(unfinishedMap.keySet());
-        List<DistributionVo> distributionList = new ArrayList();
+        List<DistributionVo> distributionList = new ArrayList<>();
         for (String item : itemSet) {
-            Long uncompleteCount = unfinishedMap.get(item) == null ? 0L : unfinishedMap.get(item);
-            Long completeCount = finishedMap.get(item) == null ? 0L : finishedMap.get(item);
+            Long unfinishedCount = unfinishedMap.get(item) == null ? 0L : unfinishedMap.get(item);
+            Long finishedCount = finishedMap.get(item) == null ? 0L : finishedMap.get(item);
             distributionList.add(
                     new DistributionVo() {{
                         setItem(item);
-                        setCompleteCount(completeCount);
-                        setUncompleteCount(uncompleteCount);
+                        setCompleteCount(finishedCount);
+                        setUncompleteCount(unfinishedCount);
+                        setAllCount(unfinishedCount + finishedCount);
                     }}
             );
         }
+        distributionList.sort(Comparator.comparingLong(DistributionVo::getAllCount).reversed());
         result.setDistributionList(distributionList);
         List<DurationVo> durationList = new ArrayList<>();
 
         List<Long> secondList = new ArrayList<>();
-        completeCountList.stream().filter(el -> el.getEndTime() != null && el.getStartTime() != null).forEach(el -> {
-            Duration diff = Duration.between(el.getStartTime(), el.getEndTime());
+        List<Map<String, Object>> completeCountList = dataList.stream()
+                .filter(x -> HistoricProcessInstance.STATE_COMPLETED.equals(x.get("current_state").toString()))
+                .collect(Collectors.toList());
+        completeCountList.stream().forEach(el -> {
+            Duration diff = Duration.between((LocalDateTime)el.get("start_time"), (LocalDateTime)el.get("end_time"));
             secondList.add(diff.getSeconds());
         });
 
@@ -301,7 +289,6 @@ public class DatadetailController {
         return RT.ok(result);
     }
 
-
     @GetMapping(value = "/person-statistics")
     @ApiOperation(value = "教职工详情数据统计")
     @SaCheckPermission("datadetail:detail")
@@ -449,6 +436,148 @@ public class DatadetailController {
         return RT.ok(result);
     }
 
+    @GetMapping(value = "/person-statistics-tea-change")
+    @ApiOperation(value = "教职工详情数据统计之教职工变动情况")
+    @SaCheckPermission("datadetail:detail")
+    @XjrLog(value = "教职工详情数据统计之教职工变动情况", saveResponseData = true)
+    public RT<TeacherChangeStatisticsDetailVo> teacherChangeStatisticsDetail(@Valid TeacherChangeStatisticsDetailDto dto){
+        TeacherChangeStatisticsDetailVo teacherChangeStatisticsDetailVo = new TeacherChangeStatisticsDetailVo();
+
+        // 处理时间范围
+        if(ObjectUtils.isNotEmpty(dto.getStatus()) && dto.getStatus() == 1 && StringUtils.isNotEmpty(dto.getYearMonth())){
+            String yearMonthStr = dto.getYearMonth() + "-01";
+            LocalDate yearMonthLocalDate = LocalDate.parse(yearMonthStr);
+
+            // 上个月的最后一天
+            LocalDate lastDayOfPreviousMonth = yearMonthLocalDate.minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
+            LocalDateTime startTime = lastDayOfPreviousMonth.atTime(23, 59, 59);
+
+            // 下个月的第一天
+            LocalDate firstDayOfNextMonth = yearMonthLocalDate.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
+            LocalDateTime endTime = firstDayOfNextMonth.atStartOfDay();
+
+            dto.setStartTime(startTime);
+            dto.setEndTime(endTime);
+        }
+
+        if(ObjectUtils.isNotEmpty(dto.getStatus()) && dto.getStatus() == 2 && ObjectUtils.isNotEmpty(dto.getBaseSemesterId())){
+            // 获取学期
+            BaseSemester baseSemester = baseSemesterMapper.selectById(dto.getBaseSemesterId());
+            LocalDateTime startTime = baseSemester.getStartDate().toInstant()
+                    .atZone(ZoneId.systemDefault()) // 使用系统默认时区
+                    .toLocalDateTime();
+            LocalDateTime endTime = baseSemester.getEndDate().toInstant()
+                    .atZone(ZoneId.systemDefault()) // 使用系统默认时区
+                    .toLocalDateTime();
+
+            dto.setStartTime(startTime);
+            dto.setEndTime(endTime);
+        }
+
+        if(ObjectUtils.isNotEmpty(dto.getStatus()) && dto.getStatus() == 3 && ObjectUtils.isNotEmpty(dto.getYear())){
+            LocalDate yearLocalDate = LocalDate.of(dto.getYear(), 1, 1);
+            LocalDate lastDayOfLastYear = yearLocalDate.minusYears(1).with(TemporalAdjusters.lastDayOfYear());
+            LocalDateTime startTime = lastDayOfLastYear.atTime(23, 59, 59);
+
+            LocalDate firstDayOfNextYear = yearLocalDate.plusYears(1).with(TemporalAdjusters.firstDayOfYear());
+            LocalDateTime endTime = firstDayOfNextYear.atStartOfDay();
+
+            dto.setStartTime(startTime);
+            dto.setEndTime(endTime);
+        }
+
+        if(ObjectUtils.isEmpty(dto.getStatus())){
+            LocalDate yearLocalDate = LocalDate.now();
+            LocalDate lastDayOfLastYear = yearLocalDate.minusYears(1).with(TemporalAdjusters.lastDayOfYear());
+            LocalDateTime startTime = lastDayOfLastYear.atTime(23, 59, 59);
+
+            LocalDate firstDayOfNextYear = yearLocalDate.plusYears(1).with(TemporalAdjusters.firstDayOfYear());
+            LocalDateTime endTime = firstDayOfNextYear.atStartOfDay();
+
+            dto.setStartTime(startTime);
+            dto.setEndTime(endTime);
+        }
+
+        // 教职工异动统计数据
+        // 获取每个教职工异动最后一条数据
+        String sql = "select t.user_id,\n" +
+                "       t.new_job_state,\n" +
+                "       t1.employ_type\n" +
+                "from base_teacher_change_record t\n" +
+                "         inner join (SELECT user_id,\n" +
+                "                            MAX(id) AS max_id\n" +
+                "                     FROM base_teacher_change_record a\n" +
+                "                     where a.delete_mark = 0\n" +
+                "                       and a.create_date between '" + dto.getStartTime() + "' and '" + dto.getEndTime()+ "'\n" +
+                "                     GROUP BY user_id) t2 on t2.max_id = t.id\n" +
+                "         left join base_teacher t1 on t1.user_id = t.user_id\n" +
+                "where t.delete_mark = 0\n" +
+                "  and t1.delete_mark = 0"
+                ;
+        List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
+        Map<String, Map<String, Object>> statics = new LinkedHashMap<>();
+        for (Map<String, Object> oneRecord : list){
+            String jobState = oneRecord.get("new_job_state").toString();
+            if(jobState.equals("在职")){
+                continue;
+            }
+
+            String employType = oneRecord.get("employ_type").toString();
+            if(!employType.equals("FB1601") && !employType.equals("FB1605")){
+                continue;
+            }
+
+            if(statics.containsKey(jobState)){
+                Map<String, Object> oneMap = statics.get(jobState);
+                if(employType.equals("FB1601")){
+                    oneMap.put("count", (int)oneMap.get("count") + 1);
+                }
+                if(employType.equals("FB1605")){
+                    oneMap.put("count1", (int)oneMap.get("count1") + 1);
+                }
+            }else {
+                Map<String, Object> oneMap = new LinkedHashMap<>();
+                oneMap.put("item", jobState);
+                oneMap.put("count", 0);
+                oneMap.put("count1", 0);
+                if(employType.equals("FB1601")){
+                    oneMap.put("count", (int)oneMap.get("count") + 1);
+                }
+                if(employType.equals("FB1605")){
+                    oneMap.put("count1", (int)oneMap.get("count1") + 1);
+                }
+                statics.put(jobState, oneMap);
+            }
+        }
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        // 处理入职人数
+        LambdaQueryWrapper<BaseTeacher> baseTeacherLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        baseTeacherLambdaQueryWrapper
+                .ge(BaseTeacher::getJoinTime, formatter.format(dto.getStartTime()))
+                .le(BaseTeacher::getJoinTime, formatter.format(dto.getEndTime()))
+                .eq(BaseTeacher::getDeleteMark, DeleteMark.NODELETE.getCode())
+                ;
+        List<BaseTeacher> baseTeacherList = baseTeacherService.list(baseTeacherLambdaQueryWrapper);
+        if(CollectionUtils.isNotEmpty(baseTeacherList)){
+            for (BaseTeacher baseTeacher : baseTeacherList){
+                Map<String, Object> oneMap = new LinkedHashMap<>();
+                oneMap.put("item", "入职人数");
+                oneMap.put("count", 0);
+                oneMap.put("count1", 0);
+                if("FB1601".equals(baseTeacher.getEmployType())){
+                    oneMap.put("count", (int)oneMap.get("count") + 1);
+                }
+                if("FB1605".equals(baseTeacher.getEmployType())){
+                    oneMap.put("count1", (int)oneMap.get("count1") + 1);
+                }
+                statics.put("入职人数", oneMap);
+            }
+        }
+
+        teacherChangeStatisticsDetailVo.setTeacherChangeItemVoList(new ArrayList<>(statics.values()));
+        return RT.ok(teacherChangeStatisticsDetailVo);
+    }
+
     @GetMapping(value = "/student-statistics")
     @ApiOperation(value = "学生详情数据统计")
     @SaCheckPermission("datadetail:detail")
@@ -495,7 +624,6 @@ public class DatadetailController {
         }
         result.setStudentTypeList(studentTypeList);
 
-
         List<BaseStudentUserPageVo> studentList = studentService.getStudentList(new BaseStudentUserPageDto());
         Set<String> studentStayMaleSet = studentList.stream()
                 .filter(x -> (
@@ -590,6 +718,7 @@ public class DatadetailController {
             );
         }
         result.setDeptList(deptList);
+
         return RT.ok(result);
     }
 
@@ -688,15 +817,29 @@ public class DatadetailController {
     @SaCheckPermission("datadetail:detail")
     @XjrLog(value = "课表详情数据统计", saveResponseData = true)
     public RT<CourseStatisticsDetailVo> courseStatistics(@Valid StatisticsDetailDto dto) {
+        String startDate = null;
+        String endDate = null;
+        if(dto.getStartDate() != null &&  dto.getEndDate() != null){
+            startDate = dto.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+            endDate = dto.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+        }
         CourseStatisticsDetailVo result = new CourseStatisticsDetailVo();
-        String sql = "SELECT t1.id, t1.name,t4.name AS dept_name," +
-                " (SELECT GROUP_CONCAT(DISTINCT(course_name)) FROM course_table WHERE teacher_id like concat('%', t1.id,'%') ) AS course_names," +
-                " (SELECT COUNT(*) FROM course_table WHERE teacher_id like concat('%', t1.id,'%')) AS course_count FROM xjr_user t1" +
-                " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
-                " INNER JOIN xjr_user_dept_relation t3 ON t1.id = t3.user_id" +
-                " INNER JOIN xjr_department t4 ON t3.dept_id = t4.id" +
-                " WHERE t1.delete_mark = 0 AND t4.is_major = 1" +
-                " ORDER BY course_count DESC LIMIT 5";
+        String sql = "SELECT t1.id, t1.name,t4.name AS dept_name,( " +
+                " SELECT GROUP_CONCAT(DISTINCT(course_name)) FROM course_table WHERE FIND_IN_SET(t1.id, teacher_id) > 0 ";
+        if(startDate != null){
+            sql += " and schedule_date between '" + startDate + "' and '" + endDate + "'";
+        }
+        sql += " ) AS course_names,(" +
+                "SELECT COUNT(*) FROM course_table WHERE FIND_IN_SET(t1.id, teacher_id) > 0 ";
+        if(startDate != null){
+            sql += " and schedule_date between '" + startDate + "' and '" + endDate + "'";
+        }
+        sql += " ) AS course_count FROM xjr_user t1" +
+            " INNER JOIN base_teacher t2 ON t1.id = t2.user_id" +
+            " INNER JOIN xjr_user_dept_relation t3 ON t1.id = t3.user_id" +
+            " INNER JOIN xjr_department t4 ON t3.dept_id = t4.id" +
+            " WHERE t1.delete_mark = 0 AND t4.is_major = 1";
+        sql += " ORDER BY course_count DESC LIMIT 5";
         List<Map<String, Object>> list = SqlRunnerAdapter.db().selectList(sql);
         List<CourseCountListVo> courseCountList = new ArrayList<>();
         for (Map<String, Object> objectMap : list) {
@@ -706,18 +849,26 @@ public class DatadetailController {
         result.setCourseCountList(courseCountList);
 
         sql = "SELECT count(*) FROM course_table t1" +
-                " INNER JOIN base_teacher t2 ON t1.teacher_id like concat('%', t2.user_id,'%')" +
-                " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
-                " INNER JOIN xjr_department t4 ON t4.id = t3.dept_id" +
-                " WHERE t4.delete_mark = 0 AND t2.delete_mark = 0" +
-                " AND t4.is_major = 1";
+            " INNER JOIN base_teacher t2 ON FIND_IN_SET(t2.user_id, t1.teacher_id) > 0" +
+            " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
+            " INNER JOIN xjr_department t4 ON t4.id = t3.dept_id" +
+            " WHERE t4.delete_mark = 0 AND t2.delete_mark = 0" +
+            " AND t4.is_major = 1";
+        if(startDate != null){
+            sql += " and t1.schedule_date between '" + startDate + "' and '" + endDate + "'";
+        }
         long allCourseCount = SqlRunnerAdapter.db().selectCount(sql);
+
+
         sql = "SELECT name,(" +
-                " SELECT COUNT(*) FROM course_table t1" +
-                " INNER JOIN base_teacher t2 ON t1.teacher_id like concat('%', t2.user_id,'%')" +
-                " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
-                " WHERE t3.dept_id = xjr_department.id" +
-                " ) AS course_count FROM xjr_department WHERE is_major = 1";
+            " SELECT COUNT(*) FROM course_table t1" +
+            " INNER JOIN base_teacher t2 ON FIND_IN_SET(t2.user_id, t1.teacher_id) > 0" +
+            " INNER JOIN xjr_user_dept_relation t3 ON t2.user_id = t3.user_id" +
+            " WHERE t3.dept_id = xjr_department.id";
+        if(startDate != null){
+            sql += " and t1.schedule_date between '" + startDate + "' and '" + endDate + "'";
+        }
+        sql += " ) AS course_count FROM xjr_department WHERE is_major = 1";
         list = SqlRunnerAdapter.db().selectList(sql);
         List<ItemCountRatioVo> deptCourseList = new ArrayList<>();
         for (Map<String, Object> objectMap : list) {

+ 36 - 0
src/main/java/com/xjrsoft/module/databoard/dto/TeacherChangeStatisticsDetailDto.java

@@ -0,0 +1,36 @@
+package com.xjrsoft.module.databoard.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import io.swagger.models.auth.In;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+
+
+/**
+ * @title: 数据看板-流程统计入参
+ * @Author dzx
+ * @Date: 2024年8月2日
+ * @Version 1.0
+ */
+@Data
+public class TeacherChangeStatisticsDetailDto {
+    @ApiModelProperty("时间范围,1:月,2:学期,3:年")
+    private Integer status;
+
+    @ApiModelProperty("年月")
+    private String yearMonth;
+
+    @ApiModelProperty("学期主键id")
+    private Long baseSemesterId;
+
+    @ApiModelProperty("年")
+    private Integer year;
+
+    @ApiModelProperty(hidden = true)
+    private LocalDateTime startTime;
+    @ApiModelProperty(hidden = true)
+    private LocalDateTime endTime;
+}

+ 4 - 0
src/main/java/com/xjrsoft/module/databoard/vo/DistributionVo.java

@@ -1,5 +1,6 @@
 package com.xjrsoft.module.databoard.vo;
 
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
@@ -26,4 +27,7 @@ public class DistributionVo {
     @ApiModelProperty("未完成数量")
     private Long uncompleteCount;
 
+    @ApiModelProperty("总数")
+    private Long allCount;
+
 }

+ 19 - 0
src/main/java/com/xjrsoft/module/databoard/vo/TeacherChangeStatisticsDetailVo.java

@@ -0,0 +1,19 @@
+package com.xjrsoft.module.databoard.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @title: 教职工数据
+ * @Author dzx
+ * @Date: 2024年8月2日
+ * @Version 1.0
+ */
+@Data
+public class TeacherChangeStatisticsDetailVo {
+    @ApiModelProperty("教职工异动统计数据")
+    private List<Map<String, Object>> teacherChangeItemVoList;
+}

+ 0 - 1
src/main/java/com/xjrsoft/module/databoard/vo/TeacherStatisticsDetailVo.java

@@ -29,5 +29,4 @@ public class TeacherStatisticsDetailVo {
 
     @ApiModelProperty("部门统计数据")
     private List<ItemCountVo> deptList;
-
 }

+ 2 - 2
src/main/java/com/xjrsoft/module/job/BaseNewStudentTask.java

@@ -122,7 +122,7 @@ public class BaseNewStudentTask {
         List<BaseNewStudent> insertList = new ArrayList<>();
         for (PbCseFeeobjupdate feeobjupdate : dataList) {
             BaseNewStudent existsNewStudent = existsNewStudentMap.get(feeobjupdate.getPersonalid());
-
+            Long planId = planMap.get(feeobjupdate.getEnteryear() + feeobjupdate.getUserdef6());
             if (existsNewStudent != null) {
                 existsNewStudent.setName(feeobjupdate.getFeeobjname());
                 existsNewStudent.setPaymnystate(feeobjupdate.getPaymnystate());
@@ -155,12 +155,12 @@ public class BaseNewStudentTask {
                 existsNewStudent.setModifyDate(new Date());
                 existsNewStudent.setStatus(0);
                 existsNewStudent.setIsCanBanding(1);
+                existsNewStudent.setEnrollmentPlanId(planId);
 
                 updateList.add(existsNewStudent);
                 continue;
             }
 
-            Long planId = planMap.get(feeobjupdate.getEnteryear() + feeobjupdate.getUserdef6());
             insertList.add(
                     new BaseNewStudent() {{
                         setCredentialNumber(feeobjupdate.getPersonalid());

+ 25 - 17
src/main/java/com/xjrsoft/module/job/JianyuekbScheduleTask.java

@@ -26,7 +26,9 @@ import com.xjrsoft.module.courseTable.entity.CourseTable;
 import com.xjrsoft.module.courseTable.service.ICourseTableService;
 import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
 import com.xjrsoft.module.organization.entity.Department;
+import com.xjrsoft.module.organization.entity.Role;
 import com.xjrsoft.module.organization.entity.User;
+import com.xjrsoft.module.organization.entity.UserRoleRelation;
 import com.xjrsoft.module.organization.service.IDepartmentService;
 import com.xjrsoft.module.organization.service.IUserService;
 import com.xjrsoft.module.organization.service.IWeChatService;
@@ -138,10 +140,10 @@ public class JianyuekbScheduleTask {
 
     public void doExecute() {
         String active = SpringUtil.getActiveProfile();
-//        if(!"prod".equals(active)){
-//            log.info("非正式环境,无法执行获取课表数据");
-//            return;
-//        }
+        if(!"prod".equals(active)){
+            log.info("非正式环境,无法执行获取课表数据");
+            return;
+        }
         String sql = "SELECT * FROM course_receive_msg WHERE delete_mark = 0 AND is_callback IS NULL";
         List<Map<String, Object>> receiveMsgs = SqlRunnerAdapter.db().selectList(sql);
         if (receiveMsgs.isEmpty()) {
@@ -176,7 +178,7 @@ public class JianyuekbScheduleTask {
         LocalDate today = LocalDate.now();
 
         DataUtil dataUtil = new DataUtil();
-        Set<String> ongoing = redisUtil.get(taskKey, new TypeReference<Set<String>>() {
+        Set<String> ongoing = redisUtil.get(taskKey, new TypeReference<>() {
         });//正在进行中的
         if (ongoing == null) {
             ongoing = new HashSet<>();
@@ -185,7 +187,6 @@ public class JianyuekbScheduleTask {
         Map<String, Map<String, String>> dataMap = initDataMap();
         for (Map<String, Object> receiveMsg : receiveMsgs) {
             String eduYearSerialNo = receiveMsg.get("edu_year_serial_no").toString();
-            Long courseReceiveMsgId = Long.parseLong(receiveMsg.get("id").toString());
             if (ongoing.contains(eduYearSerialNo)) {
                 continue;
             }
@@ -239,7 +240,7 @@ public class JianyuekbScheduleTask {
 
                 ongoing.remove(eduYearSerialNo);
                 redisUtil.set(taskKey, ongoing);
-                insertCourse(allScheduleInfo, dataMap, dataUtil, courseReceiveMsgId, startDateStr, endDateStr);
+                insertCourse(allScheduleInfo, dataMap, dataUtil, receiveMsg, startDateStr, endDateStr);
                 //恢复挂起的流程
                 restoreCourseAdjust(processIds);
                 //处理该日期内已经审批通过的调课和顶课申请
@@ -253,7 +254,7 @@ public class JianyuekbScheduleTask {
         }
     }
 
-    void insertCourse(JsonArray scheduleInfo, Map<String, Map<String, String>> dataMap, DataUtil dataUtil, Long courseReceiveMsgId, String startDate, String endDate) {
+    void insertCourse(JsonArray scheduleInfo, Map<String, Map<String, String>> dataMap, DataUtil dataUtil, Map<String, Object> receiveMsg, String startDate, String endDate) {
         //获取年级
         String tableName = "base_grade";
 //            Map<String, Long> gradeMap = dataMap.get(tableName);
@@ -274,27 +275,34 @@ public class JianyuekbScheduleTask {
         Map<String, String> classroomMap = dataMap.get(tableName);
 
         Set<String> techerIds = dataUtil.insertCourseTableEntiy(scheduleInfo, classroomMap, courseMap, semesterMap,
-                teacherMap, classMap, courseReceiveMsgId, startDate, endDate);
-        sendMsg(techerIds, courseReceiveMsgId);
+                teacherMap, classMap, receiveMsg.get("id").toString(), startDate, endDate);
+        sendMsg(techerIds, receiveMsg);
         dataUtil.insertClassTime(scheduleInfo);
     }
 
-    void sendMsg(Set<String> techerIds, Long courseReceiveMsgId) {
-        ActiveSpan.tag("params[ JianyuekbScheduleTaskSendMsg ]", "sendMsg");
+    void sendMsg(Set<String> techerIds, Map<String, Object> receiveMsg) {
         try {
-            CourseReceiveMsg receiveMsg = receiveMsgService.getById(courseReceiveMsgId);
             JianyueData jianyueData = jianyueDataService.getOne(
                     new QueryWrapper<JianyueData>().lambda()
-                            .eq(JianyueData::getJianyueId, receiveMsg.getEduYearSerialNo())
+                            .eq(JianyueData::getJianyueId, receiveMsg.get("edu_year_serial_no").toString())
             );
             String[] sourceId = jianyueData.getSourceId().split("_");
             Department department = departmentService.getById(sourceId[0]);
 
             BaseGrade grade = gradeService.getById(sourceId[1]);
-
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             //通知对应教师
             List<User> userList = userService.listByIds(new ArrayList<>(techerIds));
+            List<User> userList1 = userService.list(
+                    new MPJLambdaWrapper<User>()
+                            .distinct()
+                            .select(User::getId)
+                            .select(User.class, x -> VoToColumnUtil.fieldsToColumns(User.class).contains(x.getProperty()))
+                            .innerJoin(UserRoleRelation.class, UserRoleRelation::getUserId, User::getId)
+                            .innerJoin(Role.class, Role::getId, UserRoleRelation::getRoleId)
+                            .eq(Role::getCode, "KEBIAOGX")
+            );
+            userList.addAll(userList1);
+
             for (User user : userList) {
                 WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
                 weChatSendMessageDto.setTemplateId(noticeTeacherTemplate);
@@ -313,7 +321,7 @@ public class JianyuekbScheduleTask {
                 paramJson.put("thing6", thing6);
 
                 JSONObject time3 = new JSONObject();
-                time3.put("value", sdf.format(receiveMsg.getCreateDate()));
+                time3.put("value", receiveMsg.get("create_date").toString());
                 paramJson.put("time3", time3);
 
                 weChatSendMessageDto.setContent(paramJson);

+ 6 - 0
src/main/java/com/xjrsoft/module/liteflow/node/StudentDropOutNode.java

@@ -7,6 +7,7 @@ import com.xjrsoft.common.enums.ArchivesStatusEnum;
 import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.StudentChangeTypeEnum;
 import com.xjrsoft.common.enums.WorkflowApproveType;
+import com.xjrsoft.module.room.mapper.RoomBedMapper;
 import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
 import com.xjrsoft.module.student.entity.StudentDropOut;
 import com.xjrsoft.module.student.mapper.StudentDropOutMapper;
@@ -47,6 +48,9 @@ public class StudentDropOutNode extends NodeComponent {
     @Autowired
     private IStudentChangeRecordService changeRecordService;
 
+    @Autowired
+    private RoomBedMapper roomBedMapper;
+
 
     @Override
     public void process() throws Exception {
@@ -96,6 +100,8 @@ public class StudentDropOutNode extends NodeComponent {
                                         .eq(BaseStudentSchoolRoll::getUserId, studentDropOut.getStudentUserId())
                                         .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
                         );
+                        //清除床位信息
+                        roomBedMapper.clearBedInfoByStudentUserId(studentDropOut.getStudentUserId(), studentDropOut.getCreateUserId());
                         if(schoolRoll != null){
                             //记录异动
                             changeRecordService.insertData(

+ 12 - 1
src/main/java/com/xjrsoft/module/liteflow/node/WfMeetingApplyNode.java

@@ -5,8 +5,11 @@ import com.xjrsoft.module.oa.service.IWfMeetingApplyService;
 import com.yomahub.liteflow.core.NodeComponent;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
 
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 /**
  * 会议通知
@@ -25,7 +28,15 @@ public class WfMeetingApplyNode extends NodeComponent {
         Long formId = Convert.toLong(value);
         if (formId != null) {
             // 数据处理
-            meetingApplyService.noticeParticipants(formId);
+            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+                @Override
+                public void afterCommit() {
+                    CompletableFuture.runAsync(() -> {
+                        meetingApplyService.noticeParticipants(formId);
+                    });
+                }
+            });
+
         }
     }
 }

+ 7 - 1
src/main/java/com/xjrsoft/module/liteflow/node/WfRoomApplicantNode.java

@@ -10,6 +10,7 @@ import com.xjrsoft.module.hikvision.entity.HikvisionData;
 import com.xjrsoft.module.hikvision.mapper.HikvisionDataMapper;
 import com.xjrsoft.module.hikvision.util.DataUtil;
 import com.xjrsoft.module.room.entity.WfRoomApplicant;
+import com.xjrsoft.module.room.mapper.RoomBedMapper;
 import com.xjrsoft.module.room.service.IWfRoomApplicantService;
 import com.xjrsoft.module.student.entity.BaseStudentSchoolRoll;
 import com.xjrsoft.module.student.service.IBaseStudentSchoolRollService;
@@ -48,7 +49,8 @@ public class WfRoomApplicantNode extends NodeComponent {
     private WorkflowRecordMapper workflowRecordMapper;
     @Autowired
     private IStudentChangeRecordService changeRecordService;
-
+    @Autowired
+    private RoomBedMapper roomBedMapper;
 
     @Override
     public void process() throws Exception {
@@ -102,6 +104,8 @@ public class WfRoomApplicantNode extends NodeComponent {
                             schoolRoll.setStduyStatus(StudyStatusEnum.InResidence.getCode());
                         } else if (RoomApplicantTypeEnum.ToBeDayPupil.getCode().equals(wfRoomApplicant.getRecedeType())) {
                             schoolRoll.setStduyStatus(StudyStatusEnum.AttendDaySchool.getCode());
+                            //清除床位信息
+                            roomBedMapper.clearBedInfoByStudentUserId(wfRoomApplicant.getApplicantUserId(), wfRoomApplicant.getCreateUserId());
                         }
                         //修改学生班级
                         studentSchoolRollService.updateById(schoolRoll);
@@ -117,6 +121,8 @@ public class WfRoomApplicantNode extends NodeComponent {
                             throw new RuntimeException(e);
                         }
                         //wfRoomApplicantService.noticeParents(formId);
+
+
                     });
                 }
             });

+ 41 - 0
src/main/java/com/xjrsoft/module/liteflow/node/WfTeacherDepartNode.java

@@ -0,0 +1,41 @@
+package com.xjrsoft.module.liteflow.node;
+
+import cn.hutool.core.convert.Convert;
+import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
+import com.xjrsoft.module.textbook.service.IWfTextbookRecedeService;
+import com.yomahub.liteflow.core.NodeComponent;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.support.TransactionSynchronization;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * 教职工离职流程规则节点
+ */
+@Component("wf_teacher_depart_node")
+public class WfTeacherDepartNode extends NodeComponent {
+    @Autowired
+    private ITeacherbaseManagerService teacherbaseManagerService;
+
+    @Override
+    public void process() throws Exception {
+        // 获取表单中数据编号
+        Map<String, Object> params = this.getFirstContextBean();
+        Object value = util.getFormDatKey(params, "id");
+        Long formId = Convert.toLong(value);
+        if (formId != null) {
+            // 数据处理
+            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+                @Override
+                public void afterCommit() {
+                    CompletableFuture.runAsync(() -> {
+                        teacherbaseManagerService.teacherDepartDataHandle(formId);
+                    });
+                }
+            });
+        }
+    }
+}

+ 30 - 6
src/main/java/com/xjrsoft/module/material/controller/MaterialTaskController.java

@@ -10,6 +10,7 @@ import com.alibaba.excel.support.ExcelTypeEnum;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.xjrsoft.common.annotation.XjrLog;
+import com.xjrsoft.common.constant.GlobalConstant;
 import com.xjrsoft.common.model.result.R;
 import com.xjrsoft.common.model.result.RT;
 import com.xjrsoft.common.page.ConventPage;
@@ -18,14 +19,29 @@ import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.module.app.dto.UpdateEnableMarkDto;
 import com.xjrsoft.module.form.dto.FormExecuteInfoDto;
 import com.xjrsoft.module.form.service.IFormExecuteService;
-import com.xjrsoft.module.material.dto.*;
+import com.xjrsoft.module.material.dto.AddMaterialTaskAssignDto;
+import com.xjrsoft.module.material.dto.AddMaterialTaskDto;
+import com.xjrsoft.module.material.dto.FormDataExportQueryDto;
+import com.xjrsoft.module.material.dto.MaterialTaskAssignAppendixDto;
+import com.xjrsoft.module.material.dto.MaterialTaskAssignApprovedDto;
+import com.xjrsoft.module.material.dto.MaterialTaskAssignListDto;
+import com.xjrsoft.module.material.dto.MaterialTaskAssignPageDto;
+import com.xjrsoft.module.material.dto.MaterialTaskPageDto;
+import com.xjrsoft.module.material.dto.MaterialTaskWaitPageDto;
+import com.xjrsoft.module.material.dto.UpdateMaterialTaskDto;
+import com.xjrsoft.module.material.dto.ViewContentDto;
 import com.xjrsoft.module.material.entity.MaterialTask;
 import com.xjrsoft.module.material.entity.MaterialTaskAssign;
 import com.xjrsoft.module.material.entity.MaterialType;
 import com.xjrsoft.module.material.entity.MaterialTypeAssign;
 import com.xjrsoft.module.material.service.IMaterialTaskAssignService;
 import com.xjrsoft.module.material.service.IMaterialTaskService;
-import com.xjrsoft.module.material.vo.*;
+import com.xjrsoft.module.material.vo.MaterialTaskAssignListVo;
+import com.xjrsoft.module.material.vo.MaterialTaskAssignVo;
+import com.xjrsoft.module.material.vo.MaterialTaskExcelVo;
+import com.xjrsoft.module.material.vo.MaterialTaskPageVo;
+import com.xjrsoft.module.material.vo.MaterialTaskVo;
+import com.xjrsoft.module.material.vo.MaterialTaskWaitPageVo;
 import com.xjrsoft.module.organization.entity.Department;
 import com.xjrsoft.module.organization.entity.UserDeptRelation;
 import com.xjrsoft.module.teacher.entity.XjrUser;
@@ -33,7 +49,14 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
@@ -64,7 +87,7 @@ public class MaterialTaskController {
     @SaCheckPermission("materialtask:detail")
     @XjrLog(value = "材料提交任务列表(分页 我发布的)")
     public RT<PageOutput<MaterialTaskPageVo>> page(@Valid MaterialTaskPageDto dto) {
-
+        List<Long> roleIds = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
         MPJLambdaWrapper<MaterialTask> queryWrapper = new MPJLambdaWrapper<>();
         queryWrapper
                 .orderByDesc(MaterialTask::getId)
@@ -72,8 +95,9 @@ public class MaterialTaskController {
                 .like(StrUtil.isNotBlank(dto.getName()), MaterialTask::getName, dto.getName())
                 .eq((ObjectUtil.isNotEmpty(dto.getMaterialTypeId())) && dto.getMaterialTypeId() > 0, MaterialTask::getMaterialTypeId, dto.getMaterialTypeId())
                 .eq((ObjectUtil.isNotEmpty(dto.getStatus())) && dto.getStatus() > 0, MaterialTask::getStatus, dto.getStatus())
-                .gt(dto.getCreateDateStart() != null && !dto.getCreateDateStart().equals(""), MaterialTask::getCreateDate, dto.getCreateDateStart())
-                .lt(dto.getCreateDateEnd() != null && !dto.getCreateDateEnd().equals(""), MaterialTask::getCreateDate, dto.getCreateDateEnd())
+                .eq(!roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID), MaterialTask::getCreateUserId, StpUtil.getLoginIdAsLong())
+                .gt(dto.getCreateDateStart() != null, MaterialTask::getCreateDate, dto.getCreateDateStart())
+                .lt(dto.getCreateDateEnd() != null, MaterialTask::getCreateDate, dto.getCreateDateEnd())
                 .select(MaterialTask::getId)
                 .selectAs(MaterialType::getName, MaterialTaskPageVo::getMaterialTypeIdCn)
                 .selectAs(MaterialType::getCreateDate, MaterialTaskPageVo::getCreateDate)

+ 5 - 0
src/main/java/com/xjrsoft/module/material/service/impl/MaterialTypeServiceImpl.java

@@ -1,5 +1,6 @@
 package com.xjrsoft.module.material.service.impl;
 
+import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -7,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.constant.GlobalConstant;
 import com.xjrsoft.common.enums.MaterialCategoryEnum;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
@@ -29,6 +31,7 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -107,11 +110,13 @@ public class MaterialTypeServiceImpl extends MPJBaseServiceImpl<MaterialTypeMapp
 
     @Override
     public PageOutput<MaterialTypePageVo> getPage(MaterialTypePageDto dto) {
+        List<Long> roleIds = StpUtil.getTokenSession().get(GlobalConstant.LOGIN_USER_ROLE_ID_KEY, new ArrayList<>());
         LambdaQueryWrapper<MaterialType> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper
                 .orderByDesc(MaterialType::getId)
                 .select(MaterialType.class, x -> VoToColumnUtil.fieldsToColumns(MaterialTypePageVo.class).contains(x.getProperty()))
                 .like(dto.getName() != null && !dto.getName().equals(""), MaterialType::getName, dto.getName())
+                .eq(!roleIds.contains(GlobalConstant.SUPER_ADMIN_ROLE_ID), MaterialType::getCreateUserId, StpUtil.getLoginIdAsLong())
                 .eq(dto.getMaterialCategory() != null && !dto.getMaterialCategory().equals(""), MaterialType::getMaterialCategory, dto.getMaterialCategory());
         IPage<MaterialType> page = this.page(ConventPage.getPage(dto), queryWrapper);
         PageOutput<MaterialTypePageVo> pageOutput = ConventPage.getPageOutput(page, MaterialTypePageVo.class);

+ 1 - 1
src/main/java/com/xjrsoft/module/oa/controller/NewsController.java

@@ -82,7 +82,7 @@ public class NewsController {
 
     @GetMapping("/manage-box")
     @ApiOperation(value = "获取管理新闻分页")
-    @XjrLog(value = "获取管理新闻分页")
+    @XjrLog(value = "获取管理新闻分页", saveRequestData = false)
     public RT<PageOutput<NewsPageVo>> manageBox(NewsPageDto dto) {
         IPage<NewsPageVo> page = newsService.manageBox(dto);
         PageOutput<NewsPageVo> pageOutput = ConventPage.getPageOutput(page, NewsPageVo.class);

+ 250 - 0
src/main/java/com/xjrsoft/module/oa/controller/WfMeetingApplyController.java

@@ -0,0 +1,250 @@
+package com.xjrsoft.module.oa.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.xjrsoft.common.annotation.XjrLog;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.utils.QrCodeUtil;
+import com.xjrsoft.config.CommonPropertiesConfig;
+import com.xjrsoft.module.oa.dto.*;
+import com.xjrsoft.module.oa.entity.WfMeetingApply;
+import com.xjrsoft.module.oa.service.IWfMeetingApplyService;
+import com.xjrsoft.module.oa.vo.*;
+import com.xjrsoft.module.system.entity.File;
+import com.xjrsoft.module.system.service.IFileService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+* @title: 
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@RestController
+@RequestMapping("/oa" + "/wfMeetingApply")
+@Api(value = "/oa"  + "/wfMeetingApply",tags = "会议申请")
+@AllArgsConstructor
+public class WfMeetingApplyController {
+
+    private final IWfMeetingApplyService wfMeetingApplyService;
+
+    private final IFileService fileService;
+
+    private final CommonPropertiesConfig commonPropertiesConfig;
+
+    @GetMapping(value = "/list_meeting_room")
+    @ApiOperation(value="会议室列表(不分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "会议室列表(分页)")
+    public RT<List<MeetingRoomListVo>> listMeetingRoom(@Valid MeetingRoomListDto dto){
+        List<MeetingRoomListVo> meetingRoomListVoList = wfMeetingApplyService.listMeetingRoom(dto);
+        return RT.ok(meetingRoomListVoList);
+    }
+
+    @GetMapping(value = "/page")
+    @ApiOperation(value="列表(分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "列表(分页)")
+    public RT<PageOutput<WfMeetingApplyPageVo>> page(@Valid WfMeetingApplyPageDto dto){
+        IPage<WfMeetingApplyPageVo> page = wfMeetingApplyService.pageRabAndHand(dto);
+        PageOutput<WfMeetingApplyPageVo> pageOutput = ConventPage.getPageOutput(page, WfMeetingApplyPageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @GetMapping(value = "/page-today-meeting-mobile")
+    @ApiOperation(value="移动端今日会议列表(分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "移动端今日会议列表(分页)")
+    public RT<PageOutput<TodayMeetingMobilePageVo>> todayMeetingMobilePage(@Valid TodayMeetingMobilePageDto dto){
+        IPage<TodayMeetingMobilePageVo> page = wfMeetingApplyService.todayMeetingMobilePage(dto);
+        PageOutput<TodayMeetingMobilePageVo> pageOutput = ConventPage.getPageOutput(page, TodayMeetingMobilePageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @GetMapping(value = "/page-sponsor-meeting-mobile")
+    @ApiOperation(value="移动端我发起的会议列表(分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "移动端我发起的会议列表(分页)")
+    public RT<PageOutput<SponsorMeetingMobilePageVo>> sponsorMeetingMobilePage(@Valid SponsorMeetingMobilePageDto dto){
+        IPage<SponsorMeetingMobilePageVo> page = wfMeetingApplyService.sponsorMeetingMobilePage(dto);
+        PageOutput<SponsorMeetingMobilePageVo> pageOutput = ConventPage.getPageOutput(page, SponsorMeetingMobilePageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @GetMapping(value = "/page-history-meeting-mobile")
+    @ApiOperation(value="移动端历史会议列表(分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "移动端历史会议列表(分页)")
+    public RT<PageOutput<HistoryMeetingMobilePageVo>> historyMeetingMobilePage(@Valid HistoryMeetingMobilePageDto dto){
+        IPage<HistoryMeetingMobilePageVo> page = wfMeetingApplyService.historyMeetingMobilePage(dto);
+        PageOutput<HistoryMeetingMobilePageVo> pageOutput = ConventPage.getPageOutput(page, HistoryMeetingMobilePageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @GetMapping(value = "/mobile-info")
+    @ApiOperation(value="移动端会议信息会议的详情")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "移动端会议信息会议的详情")
+    public RT<MeetingMobileInfoVo> mobileInfo(@RequestParam Long id){
+        MeetingMobileInfoVo meetingMobileInfoVo = wfMeetingApplyService.mobileInfo(id);
+        if (meetingMobileInfoVo == null) {
+           return RT.error("找不到此数据!");
+        }
+        return RT.ok(meetingMobileInfoVo);
+    }
+
+    @GetMapping(value = "/info_in_workflow")
+    @ApiOperation(value="按照流程查看详情")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "按照流程查看详情")
+    public RT<WfMeetingApplyInWorkflowVo> infoInWorkflow(@RequestParam Long id){
+        WfMeetingApplyInWorkflowVo wfMeetingApplyInWorkflowVo = wfMeetingApplyService.infoInWorkflow(id);
+        if (wfMeetingApplyInWorkflowVo == null) {
+           return RT.error("找不到此数据!");
+        }
+        return RT.ok(wfMeetingApplyInWorkflowVo);
+    }
+
+    @GetMapping(value = "/meeting_conferee_list")
+    @ApiOperation(value="参会人员列表(不分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "参会人员列表(分页)")
+    public RT<List<MeetingConfereeListVo>> listMeetingConferee(@Valid MeetingConfereeListDto dto){
+        List<MeetingConfereeListVo> meetingConfereeListVoList = wfMeetingApplyService.listMeetingConferee(dto);
+        return RT.ok(meetingConfereeListVoList);
+    }
+
+    @GetMapping(value = "/meeting_conferee_opinion_list")
+    @ApiOperation(value="参会意见列表(不分页)")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "参会人员列表(分页)")
+    public RT<List<MeetingConfereeOpinionListVo>> listMeetingConfereeOpinion(@Valid MeetingConfereeOpinionListDto dto){
+        List<MeetingConfereeOpinionListVo> meetingConfereeOpinionListVos = wfMeetingApplyService.listMeetingConfereeOpinion(dto);
+        return RT.ok(meetingConfereeOpinionListVos);
+    }
+
+    @PutMapping(value = "/update_meetingSummary")
+    @ApiOperation(value = "编辑会议纪要")
+    @SaCheckPermission("wfmeetingapply:edit")
+    @XjrLog(value = "编辑会议纪要")
+    public RT<Boolean> updateMeetingSummary(@Valid @RequestBody UpdateMeetingSummaryDto dto){
+        WfMeetingApply wfMeetingApply = new WfMeetingApply();
+        wfMeetingApply.setId(dto.getId());
+        wfMeetingApply.setMeetingSummary(dto.getMeetingSummary());
+        wfMeetingApply.setMeetingSummaryFileId(dto.getMeetingSummaryFileId());
+        return RT.ok(wfMeetingApplyService.updateById(wfMeetingApply));
+    }
+
+    @GetMapping(value = "/meetingSummary_info")
+    @ApiOperation(value="获取会议纪要")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "获取会议纪要")
+    public RT<MeetingSummaryVo> meetingSummaryInfo(@RequestParam Long id){
+        WfMeetingApply wfMeetingApply = wfMeetingApplyService.getById(id);
+        if (wfMeetingApply == null) {
+           return RT.error("找不到此数据!");
+        }
+
+        MeetingSummaryVo meetingSummaryVo = new MeetingSummaryVo();
+        meetingSummaryVo.setId(wfMeetingApply.getId());
+        meetingSummaryVo.setMeetingSummary(wfMeetingApply.getMeetingSummary());
+        meetingSummaryVo.setMeetingSummaryFileId(wfMeetingApply.getMeetingSummaryFileId());
+        List<File> fileList = fileService.list(Wrappers.<File>query().lambda().eq(File::getFolderId, wfMeetingApply.getMeetingSummaryFileId()));
+        meetingSummaryVo.setFileInfos(fileList);
+
+        return RT.ok(meetingSummaryVo);
+    }
+
+    @PutMapping(value = "/update_revocation_meeting")
+    @ApiOperation(value = "撤销会议申请")
+    @SaCheckPermission("wfmeetingapply:edit")
+    @XjrLog(value = "撤销会议申请")
+    public RT<Boolean> updateRevocationMeeting(@Valid @RequestBody UpdateRevocationMeetingDto dto){
+        return RT.ok(wfMeetingApplyService.updateRevocationMeeting(dto));
+    }
+
+    @PutMapping(value = "/update_meeting_check_in")
+    @ApiOperation(value = "签到")
+    @SaCheckPermission("wfmeetingapply:edit")
+    @XjrLog(value = "签到")
+    public RT<Boolean> updateMeetingCheckIn(@Valid @RequestBody UpdateMeetingCheckInDto dto){
+        return RT.ok(wfMeetingApplyService.updateMeetingCheckIn(dto));
+    }
+
+    @PostMapping(value = "/add_meeting_conferee_opinion")
+    @ApiOperation(value = "参会意见提交")
+    @SaCheckPermission("wfmeetingapply:add")
+    @XjrLog(value = "参会意见提交")
+    public RT<Boolean> addMeetingConfereeOpinion(@Valid @RequestBody AddMeetingConfereeOpinionDto dto){
+        boolean isSuccess = wfMeetingApplyService.addMeetingConfereeOpinion(dto);
+        return RT.ok(isSuccess);
+    }
+
+    @GetMapping(value = "/meeting-check-in-qrcode")
+    @ApiOperation(value = "会议签到二维码-生成二维码")
+    @SaCheckPermission("wfmeetingapply:detail")
+    @XjrLog(value = "会议签到二维码-生成二维码")
+    public RT<String> qrcode(@RequestParam Long id) throws Exception {
+        String url = commonPropertiesConfig.getDomainApp() + "/pages/material/grant?id=" + id + "&userId=" + StpUtil.getLoginIdAsLong();
+        int width = 200;
+        int height = 200;
+        int margin = 1;
+
+        String base64 = QrCodeUtil.createBase64(url, width, height, margin);
+        return RT.ok(base64);
+    }
+
+//    @GetMapping(value = "/info")
+//    @ApiOperation(value="根据id查询信息")
+//    @SaCheckPermission("wfmeetingapply:detail")
+//    @XjrLog(value = "根据id查询信息")
+//    public RT<WfMeetingApplyVo> info(@RequestParam Long id){
+//        WfMeetingApply wfMeetingApply = wfMeetingApplyService.getById(id);
+//        if (wfMeetingApply == null) {
+//           return RT.error("找不到此数据!");
+//        }
+//        return RT.ok(BeanUtil.toBean(wfMeetingApply, WfMeetingApplyVo.class));
+//    }
+//
+//
+//    @PostMapping
+//    @ApiOperation(value = "新增")
+//    @SaCheckPermission("wfmeetingapply:add")
+//    @XjrLog(value = "新增")
+//    public RT<Boolean> add(@Valid @RequestBody AddWfMeetingApplyDto dto){
+//        WfMeetingApply wfMeetingApply = BeanUtil.toBean(dto, WfMeetingApply.class);
+//        boolean isSuccess = wfMeetingApplyService.save(wfMeetingApply);
+//    return RT.ok(isSuccess);
+//    }
+//
+//    @PutMapping
+//    @ApiOperation(value = "修改")
+//    @SaCheckPermission("wfmeetingapply:edit")
+//    @XjrLog(value = "修改")
+//    public RT<Boolean> update(@Valid @RequestBody UpdateWfMeetingApplyDto dto){
+//
+//        WfMeetingApply wfMeetingApply = BeanUtil.toBean(dto, WfMeetingApply.class);
+//        return RT.ok(wfMeetingApplyService.updateById(wfMeetingApply));
+//
+//    }
+//
+//    @DeleteMapping
+//    @ApiOperation(value = "删除")
+//    @SaCheckPermission("wfmeetingapply:delete")
+//    @XjrLog(value = "删除")
+//    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
+//        return RT.ok(wfMeetingApplyService.removeBatchByIds(ids));
+//
+//    }
+
+}

+ 42 - 0
src/main/java/com/xjrsoft/module/oa/dto/AddMeetingConfereeOpinionDto.java

@@ -0,0 +1,42 @@
+package com.xjrsoft.module.oa.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+
+/**
+* @title: 会议参会人员意见
+* @Author phoenix
+* @Date: 2025-03-27
+* @Version 1.0
+*/
+@Data
+public class AddMeetingConfereeOpinionDto implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 会议申请主键id(wf_meeting_apply)
+    */
+    @ApiModelProperty("会议申请主键id(wf_meeting_apply)")
+    private Long wfMeetingApplyId;
+    /**
+    * 用户主键id(xjr_user)
+    */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private Long userId;
+    /**
+    * 意见
+    */
+    @ApiModelProperty("意见")
+    private String opinion;
+}

+ 29 - 0
src/main/java/com/xjrsoft/module/oa/dto/HistoryMeetingMobilePageDto.java

@@ -0,0 +1,29 @@
+package com.xjrsoft.module.oa.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+
+/**
+* @title: 分页查询入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class HistoryMeetingMobilePageDto extends PageInput {
+
+    @ApiModelProperty("会议日期开始")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate startMeetingApplyDate;
+
+    @ApiModelProperty("会议日期结束")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate endMeetingApplyDate;
+}

+ 22 - 0
src/main/java/com/xjrsoft/module/oa/dto/MeetingConfereeListDto.java

@@ -0,0 +1,22 @@
+package com.xjrsoft.module.oa.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+/**
+* @title: 会议参会人员列表(不分页)入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingConfereeListDto {
+    /**
+     * 会议申请主键id(wf_meeting_apply)
+     */
+    @ApiModelProperty("会议申请主键id(wf_meeting_apply)")
+    private Long wfMeetingApplyId;
+}

+ 19 - 0
src/main/java/com/xjrsoft/module/oa/dto/MeetingConfereeOpinionListDto.java

@@ -0,0 +1,19 @@
+package com.xjrsoft.module.oa.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+* @title: 会议参会人员意见表单(不分页)入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingConfereeOpinionListDto {
+    /**
+     * 会议申请主键id(wf_meeting_apply)
+     */
+    @ApiModelProperty("会议申请主键id(wf_meeting_apply)")
+    private Long wfMeetingApplyId;
+}

+ 46 - 0
src/main/java/com/xjrsoft/module/oa/dto/MeetingRoomListDto.java

@@ -0,0 +1,46 @@
+package com.xjrsoft.module.oa.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+* @title: 会议室列表(不分页)入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingRoomListDto {
+
+    /**
+     * 会议日期
+     */
+    @ApiModelProperty("会议日期")
+    private String meetingApplyDate;
+    /**
+     * 会议开始时间
+     */
+    @ApiModelProperty("会议开始时间")
+    private String meetingApplyS;
+    /**
+     * 会议结束时间
+     */
+    @ApiModelProperty("会议结束时间")
+    private String meetingApplyE;
+    /**
+     * 会议室名称
+     */
+    @ApiModelProperty("会议室名称")
+    private String name;
+    /**
+     * 楼栋(base_office_build)
+     */
+    @ApiModelProperty("楼栋(base_office_build)")
+    private String officeBuildIdCn;
+}

+ 29 - 0
src/main/java/com/xjrsoft/module/oa/dto/SponsorMeetingMobilePageDto.java

@@ -0,0 +1,29 @@
+package com.xjrsoft.module.oa.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+
+/**
+* @title: 分页查询入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class SponsorMeetingMobilePageDto extends PageInput {
+
+    @ApiModelProperty("会议日期开始")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate startMeetingApplyDate;
+
+    @ApiModelProperty("会议日期结束")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate endMeetingApplyDate;
+}

+ 27 - 0
src/main/java/com/xjrsoft/module/oa/dto/TodayMeetingMobilePageDto.java

@@ -0,0 +1,27 @@
+package com.xjrsoft.module.oa.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+
+/**
+* @title: 分页查询入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class TodayMeetingMobilePageDto extends PageInput {
+
+    /**
+     * 会议日期
+     */
+    @ApiModelProperty("会议日期")
+    private LocalDate meetingApplyDate;
+}

+ 21 - 0
src/main/java/com/xjrsoft/module/oa/dto/UpdateMeetingCheckInDto.java

@@ -0,0 +1,21 @@
+package com.xjrsoft.module.oa.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+* @title: 编辑会议纪要
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class UpdateMeetingCheckInDto {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private Long id;
+}

+ 34 - 0
src/main/java/com/xjrsoft/module/oa/dto/UpdateMeetingSummaryDto.java

@@ -0,0 +1,34 @@
+package com.xjrsoft.module.oa.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+* @title: 编辑会议纪要
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class UpdateMeetingSummaryDto {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private Long id;
+
+    /**
+     * 会议纪要
+     */
+    @ApiModelProperty("会议纪要")
+    private String meetingSummary;
+    /**
+     * 会议纪要附件
+     */
+    @ApiModelProperty("会议纪要附件")
+    private Long meetingSummaryFileId;
+}

+ 22 - 0
src/main/java/com/xjrsoft/module/oa/dto/UpdateRevocationMeetingDto.java

@@ -0,0 +1,22 @@
+package com.xjrsoft.module.oa.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+* @title: 撤销会议申请
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class UpdateRevocationMeetingDto {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private Long id;
+
+}

+ 45 - 0
src/main/java/com/xjrsoft/module/oa/dto/WfMeetingApplyPageDto.java

@@ -0,0 +1,45 @@
+package com.xjrsoft.module.oa.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+* @title: 分页查询入参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class WfMeetingApplyPageDto extends PageInput {
+
+    @ApiModelProperty("会议日期开始")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate startMeetingApplyDate;
+
+    @ApiModelProperty("会议日期结束")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate endMeetingApplyDate;
+
+    @ApiModelProperty("主持人")
+    private String meetingApplyHostCn;
+
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+
+    @ApiModelProperty("会议状态(0:未开始 1:已经撤销,2:已结束,3:进行中)")
+    private Integer meetingStatus;
+}

+ 98 - 0
src/main/java/com/xjrsoft/module/oa/entity/MeetingConferee.java

@@ -0,0 +1,98 @@
+package com.xjrsoft.module.oa.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.github.yulichang.annotation.EntityMapping;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 会议参会人员
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+@TableName("meeting_conferee")
+@ApiModel(value = "meeting_conferee", description = "会议参会人员")
+public class MeetingConferee 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 Date createDate;
+    /**
+    * 修改人
+    */
+    @ApiModelProperty("修改人")
+    @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(wf_meeting_apply)
+    */
+    @ApiModelProperty("会议申请主键id(wf_meeting_apply)")
+    private Long wfMeetingApplyId;
+    /**
+    * 用户主键id(xjr_user)
+    */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private Long userId;
+    /**
+    * 签到时间
+    */
+    @ApiModelProperty("签到时间")
+    private Date checkInDate;
+    /**
+    * 签到状态(0:未签到,1:已签到)
+    */
+    @ApiModelProperty("签到状态(0:未签到,1:已签到)")
+    private Integer checkInStatus;
+
+
+}

+ 93 - 0
src/main/java/com/xjrsoft/module/oa/entity/MeetingConfereeOpinion.java

@@ -0,0 +1,93 @@
+package com.xjrsoft.module.oa.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.github.yulichang.annotation.EntityMapping;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 会议参会人员意见
+* @Author phoenix
+* @Date: 2025-03-27
+* @Version 1.0
+*/
+@Data
+@TableName("meeting_conferee_opinion")
+@ApiModel(value = "meeting_conferee_opinion", description = "会议参会人员意见")
+public class MeetingConfereeOpinion 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 Date createDate;
+    /**
+    * 修改人
+    */
+    @ApiModelProperty("修改人")
+    @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(wf_meeting_apply)
+    */
+    @ApiModelProperty("会议申请主键id(wf_meeting_apply)")
+    private Long wfMeetingApplyId;
+    /**
+    * 用户主键id(xjr_user)
+    */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private Long userId;
+    /**
+    * 意见
+    */
+    @ApiModelProperty("意见")
+    private String opinion;
+
+
+}

+ 121 - 0
src/main/java/com/xjrsoft/module/oa/entity/MeetingRoom.java

@@ -0,0 +1,121 @@
+package com.xjrsoft.module.oa.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.github.yulichang.annotation.EntityMapping;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 会议室管理
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+@TableName("meeting_room")
+@ApiModel(value = "meeting_room", description = "会议室管理")
+public class MeetingRoom 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 Date createDate;
+    /**
+    * 修改人
+    */
+    @ApiModelProperty("修改人")
+    @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;
+    /**
+    * 会议室名称
+    */
+    @ApiModelProperty("会议室名称")
+    private String name;
+    /**
+    * 楼栋(base_office_build)
+    */
+    @ApiModelProperty("楼栋(base_office_build)")
+    private Long officeBuildId;
+    /**
+    * 楼层
+    */
+    @ApiModelProperty("楼层")
+    private Integer floorNum;
+    /**
+    * 门牌号
+    */
+    @ApiModelProperty("门牌号")
+    private String number;
+    /**
+    * 容量(最大人数)
+    */
+    @ApiModelProperty("容量(最大人数)")
+    private Integer capacity;
+    /**
+    * 会议室面积(平米)
+    */
+    @ApiModelProperty("会议室面积(平米)")
+    private Double square;
+    /**
+    * 会议室管理员(多人)(xjr_user)
+    */
+    @ApiModelProperty("会议室管理员(多人)(xjr_user)")
+    private String userId;
+    /**
+    * 管理员联系方式
+    */
+    @ApiModelProperty("管理员联系方式")
+    private String userPhone;
+    /**
+    * 状态(1:启用 0:停用)
+    */
+    @ApiModelProperty("状态(1:启用 0:停用)")
+    private Integer status;
+}

+ 86 - 49
src/main/java/com/xjrsoft/module/oa/entity/WfMeetingApply.java

@@ -7,81 +7,118 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.time.LocalDateTime;
+import java.time.LocalDate;
 import java.time.LocalTime;
 
 
 /**
- * @title: 会议申请
- * @Author dzx
- * @Date: 2024-09-04
- * @Version 1.0
- */
+* @title: 
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
 @Data
 @TableName("wf_meeting_apply")
-@ApiModel(value = "wf_meeting_apply", description = "会议申请")
+@ApiModel(value = "wf_meeting_apply", description = "")
 public class WfMeetingApply implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
     /**
-     *
-     */
-    @ApiModelProperty("")
+    * 主键id
+    */
+    @ApiModelProperty("主键id")
     @TableId
     private Long id;
-
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private Long sponsorId;
+    /**
+    * 会议日期
+    */
     @ApiModelProperty("会议日期")
-    private LocalDateTime meetingApplyDate;
-
+    private LocalDate meetingApplyDate;
+    /**
+    * 会议开始时间
+    */
     @ApiModelProperty("会议开始时间")
     private LocalTime meetingApplyS;
-
+    /**
+    * 会议结束时间
+    */
     @ApiModelProperty("会议结束时间")
     private LocalTime meetingApplyE;
-
-    @ApiModelProperty("会议地点")
-    private String meetingApplyAddress;
-
-    @ApiModelProperty("会议形式")
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
     private String meetingApplyFormat;
-
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+    * 参会人员
+    */
     @ApiModelProperty("参会人员")
     private String meetingApplyParticipants;
-
+    /**
+    * 主持人
+    */
     @ApiModelProperty("主持人")
-    private String meetingApplyHost;
-
+    private Long meetingApplyHost;
+    /**
+    * 会议主题
+    */
     @ApiModelProperty("会议主题")
     private String meetingApplyTheme;
-
+    /**
+    * 会议议题
+    */
     @ApiModelProperty("会议议题")
     private String meetingApplyTopics;
-
-    @ApiModelProperty("是否准备座牌、会标")
-    private String isMonogram;
-
+    /**
+    * 是否准备座牌、会标(1:是,0:否)
+    */
+    @ApiModelProperty("是否准备座牌、会标(1:是,0:否)")
+    private Integer isMonogram;
+    /**
+    * 会标主题
+    */
     @ApiModelProperty("会标主题")
-    private String monogram;
-
-    @ApiModelProperty("会前消息提醒")
-    private String meetingApplyTip;
-
-    @ApiModelProperty("会前资料")
-    private String meetingApplyPmm;
-
-    @ApiModelProperty("会议签到签退")
-    private String meetingApplySignIn;
-
-    @ApiModelProperty("上传权限")
-    private Integer meetingApplyUp;
-
-    @ApiModelProperty("为参会人员创建工作任务")
-    private Integer meetingApplyMission;
-
-    @ApiModelProperty("下载权限")
-    private Integer meetingApplyDown;
+    private String monogramTheme;
+    /**
+    * 会议纪要
+    */
+    @ApiModelProperty("会议纪要")
+    private String meetingSummary;
+    /**
+     * 会议纪要附件
+     */
+    @ApiModelProperty("会议纪要附件")
+    private Long meetingSummaryFileId;
+    /**
+    * 会前资料文件上传主键id
+    */
+    @ApiModelProperty("会前资料文件上传主键id")
+    private Long preMeetingInfoFileId;
+    /**
+    * 会议状态(0:未开始 1:已经撤销,2:已结束)
+    */
+    @ApiModelProperty("会议状态(0:未开始 1:已经撤销,2:已结束)")
+    private Integer meetingStatus;
 
-    @ApiModelProperty("状态(0:未通过 1:通过)")
-    private Integer status;
+    /**
+     * 会议申请流程状态(0:未结束,1:已经结束,正常通过,2:已经结束,未正常通过)
+     */
+    @ApiModelProperty("会议申请流程状态(0:未结束,1:已经结束,正常通过,2:已经结束,未正常通过)")
+    private Integer workflowStatus;
 }

+ 17 - 0
src/main/java/com/xjrsoft/module/oa/mapper/MeetingConfereeMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.oa.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.oa.entity.MeetingConferee;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 会议参会人员
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Mapper
+public interface MeetingConfereeMapper extends MPJBaseMapper<MeetingConferee> {
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/oa/mapper/MeetingConfereeOpinionMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.oa.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.oa.entity.MeetingConfereeOpinion;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 会议参会人员意见
+* @Author phoenix
+* @Date: 2025-03-27
+* @Version 1.0
+*/
+@Mapper
+public interface MeetingConfereeOpinionMapper extends MPJBaseMapper<MeetingConfereeOpinion> {
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/oa/mapper/MeetingRoomMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.oa.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.oa.entity.MeetingRoom;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 会议室管理
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Mapper
+public interface MeetingRoomMapper extends MPJBaseMapper<MeetingRoom> {
+
+}

+ 6 - 6
src/main/java/com/xjrsoft/module/oa/mapper/WfMeetingApplyMapper.java

@@ -1,17 +1,17 @@
 package com.xjrsoft.module.oa.mapper;
 
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.github.yulichang.base.MPJBaseMapper;
 import com.xjrsoft.module.oa.entity.WfMeetingApply;
 import org.apache.ibatis.annotations.Mapper;
 
 /**
- * @title: 物品申购
- * @Author dzx
- * @Date: 2024-02-19
- * @Version 1.0
- */
+* @title: 
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
 @Mapper
 public interface WfMeetingApplyMapper extends MPJBaseMapper<WfMeetingApply> {
 
 }
-

+ 29 - 0
src/main/java/com/xjrsoft/module/oa/service/IWfMeetingApplyService.java

@@ -1,7 +1,12 @@
 package com.xjrsoft.module.oa.service;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.oa.dto.*;
 import com.xjrsoft.module.oa.entity.WfMeetingApply;
+import com.xjrsoft.module.oa.vo.*;
+
+import java.util.List;
 
 /**
  * @title: 会议申请
@@ -12,5 +17,29 @@ import com.xjrsoft.module.oa.entity.WfMeetingApply;
 
 public interface IWfMeetingApplyService extends MPJBaseService<WfMeetingApply> {
 
+    List<MeetingRoomListVo> listMeetingRoom(MeetingRoomListDto dto);
+
+    IPage<WfMeetingApplyPageVo> pageRabAndHand(WfMeetingApplyPageDto dto);
+
+    IPage<TodayMeetingMobilePageVo> todayMeetingMobilePage(TodayMeetingMobilePageDto dto);
+
+    IPage<SponsorMeetingMobilePageVo> sponsorMeetingMobilePage(SponsorMeetingMobilePageDto dto);
+
+    IPage<HistoryMeetingMobilePageVo> historyMeetingMobilePage(HistoryMeetingMobilePageDto dto);
+
+    MeetingMobileInfoVo mobileInfo(Long id);
+
+    WfMeetingApplyInWorkflowVo infoInWorkflow(Long id);
+
+    List<MeetingConfereeListVo> listMeetingConferee(MeetingConfereeListDto dto);
+
+    List<MeetingConfereeOpinionListVo> listMeetingConfereeOpinion(MeetingConfereeOpinionListDto dto);
+
     void noticeParticipants(Long id);
+
+    Boolean updateRevocationMeeting(UpdateRevocationMeetingDto dto);
+
+    Boolean updateMeetingCheckIn(UpdateMeetingCheckInDto dto);
+
+    Boolean addMeetingConfereeOpinion(AddMeetingConfereeOpinionDto dto);
 }

+ 692 - 44
src/main/java/com/xjrsoft/module/oa/service/impl/WfMeetingApplyServiceImpl.java

@@ -1,27 +1,57 @@
 package com.xjrsoft.module.oa.service.impl;
 
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.IdUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.enums.MeetingTypeEnum;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.utils.VoToColumnUtil;
-import com.xjrsoft.module.oa.entity.WfMeetingApply;
+import com.xjrsoft.module.base.entity.BaseOfficeBuild;
+import com.xjrsoft.module.ledger.vo.WorkflowRecordVo;
+import com.xjrsoft.module.oa.dto.*;
+import com.xjrsoft.module.oa.entity.*;
+import com.xjrsoft.module.oa.mapper.MeetingConfereeMapper;
+import com.xjrsoft.module.oa.mapper.MeetingConfereeOpinionMapper;
+import com.xjrsoft.module.oa.mapper.MeetingRoomMapper;
 import com.xjrsoft.module.oa.mapper.WfMeetingApplyMapper;
 import com.xjrsoft.module.oa.service.IWfMeetingApplyService;
+import com.xjrsoft.module.oa.vo.*;
 import com.xjrsoft.module.organization.dto.WeChatSendMessageDto;
 import com.xjrsoft.module.organization.entity.User;
 import com.xjrsoft.module.organization.service.IUserService;
 import com.xjrsoft.module.organization.service.IWeChatService;
+import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.system.entity.File;
+import com.xjrsoft.module.system.mapper.FileMapper;
+import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.workflow.entity.WorkflowExtra;
 import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
+import com.xjrsoft.module.workflow.entity.WorkflowRecord;
+import com.xjrsoft.module.workflow.mapper.WorkflowExtraMapper;
+import com.xjrsoft.module.workflow.mapper.WorkflowFormRelationMapper;
+import com.xjrsoft.module.workflow.mapper.WorkflowRecordMapper;
 import com.xjrsoft.module.workflow.service.IWorkflowExtraService;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * @title: 物品申购
@@ -39,57 +69,675 @@ public class WfMeetingApplyServiceImpl extends MPJBaseServiceImpl<WfMeetingApply
 
     private final IWorkflowExtraService extraService;
 
+    private final MeetingRoomMapper meetingRoomMapper;
+
+    private final WorkflowFormRelationMapper workflowFormRelationMapper;
+
+    private final MeetingConfereeMapper meetingConfereeMapper;
+
+    private final MeetingConfereeOpinionMapper meetingConfereeOpinionMapper;
+
+    private final WorkflowRecordMapper workflowRecordMapper;
+
+    private final WorkflowExtraMapper workflowExtraMapper;
+
+    private final FileMapper fileMapper;
+
+    @Override
+    public List<MeetingRoomListVo> listMeetingRoom(MeetingRoomListDto dto) {
+        List<MeetingRoomListVo> usableResult = new ArrayList<>();
+        if (ObjectUtils.isEmpty(dto.getMeetingApplyDate())
+                || ObjectUtils.isEmpty(dto.getMeetingApplyS())
+                || ObjectUtils.isEmpty(dto.getMeetingApplyE())
+        ) {
+            return usableResult;
+        }
+
+        // 处理时间
+        LocalDate meetingApplyDate = LocalDate.parse(dto.getMeetingApplyDate());
+        LocalTime startTime = LocalTime.parse(dto.getMeetingApplyS());
+        LocalTime endTime = LocalTime.parse(dto.getMeetingApplyE());
+
+        // 获取所有的教室
+        MPJLambdaWrapper<MeetingRoom> meetingRoomMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        meetingRoomMPJLambdaWrapper
+                .select(MeetingRoom::getId)
+                .selectAs(MeetingRoom::getName, MeetingRoomListVo::getName)
+                .selectAs(MeetingRoom::getFloorNum, MeetingRoomListVo::getFloorNum)
+                .selectAs(MeetingRoom::getCapacity, MeetingRoomListVo::getCapacity)
+                .selectAs(BaseOfficeBuild::getName, MeetingRoomListVo::getOfficeBuildIdCn)
+                .leftJoin(BaseOfficeBuild.class, BaseOfficeBuild::getId, MeetingRoom::getOfficeBuildId)
+                .eq(MeetingRoom::getStatus, 1)
+        ;
+        List<MeetingRoomListVo> result = meetingRoomMapper.selectJoinList(MeetingRoomListVo.class, meetingRoomMPJLambdaWrapper);
+
+        // 获取会议申请日期已经预约的会议
+        List<WfMeetingApply> wfMeetingApplyList = this.list(Wrappers.lambdaQuery(WfMeetingApply.class)
+                .eq(WfMeetingApply::getMeetingApplyDate, meetingApplyDate)
+                .eq(WfMeetingApply::getMeetingApplyFormat, MeetingTypeEnum.HMT0002.getCode())// 线下会议
+                .ne(WfMeetingApply::getMeetingStatus, 1)
+                .ne(WfMeetingApply::getWorkflowStatus, 2)
+        );
+
+        // 根据会议室id分组
+        Map<Long, List<WfMeetingApply>> mapByMeetingRoomId = wfMeetingApplyList.stream()
+                .collect(Collectors.groupingBy(WfMeetingApply::getMeetingRoomId));
+
+        // 处理已经预约的会议室
+        Map<Long, MeetingRoomListVo> reservationMap = new LinkedHashMap<>();
+        MeetingRoomListVo meetingRoomListVo;
+        for (Map.Entry<Long, List<WfMeetingApply>> entry : mapByMeetingRoomId.entrySet()) {
+            Long key = entry.getKey();
+            List<WfMeetingApply> value = entry.getValue();
+            StringBuilder reservationDetail = new StringBuilder();
+            boolean isReservation = false;
+            meetingRoomListVo = new MeetingRoomListVo();
+            for (WfMeetingApply wfMeetingApply : value) {
+                // 会议时间是否重叠
+                if (!(startTime.isBefore(wfMeetingApply.getMeetingApplyS()) || endTime.isAfter(wfMeetingApply.getMeetingApplyE()))) {
+                    isReservation = true;
+                }
+                reservationDetail.append(wfMeetingApply.getMeetingApplyS()).append("-").append(wfMeetingApply.getMeetingApplyE()).append("\r\n");
+            }
+            meetingRoomListVo.setReservationDetail(reservationDetail.toString());
+            meetingRoomListVo.setStatus(isReservation ? 1 : 0);
+
+            reservationMap.put(key, meetingRoomListVo);
+        }
+
+        for (MeetingRoomListVo vo : result) {
+            vo.setStatus(0);
+            MeetingRoomListVo reservationRoom = reservationMap.get(vo.getId());
+            if (ObjectUtils.isEmpty(reservationRoom)) {
+                usableResult.add(vo);
+            }
+            if (ObjectUtils.isNotEmpty(reservationRoom) && reservationRoom.getStatus() == 0) {
+                usableResult.add(vo);
+            }
+        }
+
+        // 根据可用排序
+        usableResult.sort(Comparator.comparing(MeetingRoomListVo::getName));
+        return usableResult;
+    }
+
+    @Override
+    public IPage<WfMeetingApplyPageVo> pageRabAndHand(WfMeetingApplyPageDto dto) {
+        // 权限设置
+        Long loginId = StpUtil.getLoginIdAsLong();
+        int permission = 1;
+        if (StpUtil.hasRole("Conference") || StpUtil.hasRole("ADMIN")) {
+            permission = 2;
+        }
+
+        // 当前时间
+        LocalDate nowLocalDate = LocalDate.now();
+        LocalTime nowLocalTime = LocalTime.now();
+
+        MPJLambdaWrapper<WfMeetingApply> wfMeetingApplyPageVoMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        wfMeetingApplyPageVoMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(WfMeetingApplyPageVo.class).contains(x.getProperty()))
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfMeetingApply::getMeetingApplyFormat,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, WfMeetingApplyPageVo::getMeetingApplyFormatCn)
+                )
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingRoom::getName, WfMeetingApplyPageVo::getMeetingRoomIdCn)
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getMeetingApplyHost,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, WfMeetingApplyPageVo::getMeetingApplyHostCn)
+                                .like(StringUtils.isNotEmpty(dto.getMeetingApplyHostCn()), XjrUser::getName, dto.getMeetingApplyHostCn())
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getSponsorId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, WfMeetingApplyPageVo::getSponsorIdCn)
+                )
+                .eq(permission == 1, WfMeetingApply::getSponsorId, loginId)
+                .eq(WfMeetingApply::getWorkflowStatus, 1)
+                .ge(ObjectUtils.isNotEmpty(dto.getStartMeetingApplyDate()), WfMeetingApply::getMeetingApplyDate, dto.getStartMeetingApplyDate())
+                .le(ObjectUtils.isNotEmpty(dto.getEndMeetingApplyDate()), WfMeetingApply::getMeetingApplyDate, dto.getEndMeetingApplyDate())
+                .eq(StringUtils.isNotEmpty(dto.getMeetingApplyFormat()), WfMeetingApply::getMeetingApplyFormat, dto.getMeetingApplyFormat())
+                .like(StringUtils.isNotEmpty(dto.getMeetingApplyTheme()), WfMeetingApply::getMeetingApplyTheme, dto.getMeetingApplyTheme())
+        ;
+        if (ObjectUtils.isNotEmpty(dto.getMeetingStatus()) && dto.getMeetingStatus() == 0) {
+            wfMeetingApplyPageVoMPJLambdaWrapper
+                    .ge(WfMeetingApply::getMeetingApplyDate, nowLocalDate)
+                    .gt(WfMeetingApply::getMeetingApplyS, nowLocalTime)
+            ;
+        }
+
+        if (ObjectUtils.isNotEmpty(dto.getMeetingStatus()) && dto.getMeetingStatus() == 1) {
+            wfMeetingApplyPageVoMPJLambdaWrapper
+                    .eq(WfMeetingApply::getMeetingStatus, 1)
+            ;
+        }
+
+        if (ObjectUtils.isNotEmpty(dto.getMeetingStatus()) && dto.getMeetingStatus() == 2) {
+            wfMeetingApplyPageVoMPJLambdaWrapper
+                    .le(WfMeetingApply::getMeetingApplyDate, nowLocalDate)
+                    .lt(WfMeetingApply::getMeetingApplyE, nowLocalTime)
+            ;
+        }
+
+        if (ObjectUtils.isNotEmpty(dto.getMeetingStatus()) && dto.getMeetingStatus() == 3) {
+            wfMeetingApplyPageVoMPJLambdaWrapper
+                    .eq(WfMeetingApply::getMeetingApplyDate, nowLocalDate)
+                    .le(WfMeetingApply::getMeetingApplyS, nowLocalTime)
+                    .ge(WfMeetingApply::getMeetingApplyE, nowLocalTime)
+            ;
+        }
+
+        IPage<WfMeetingApplyPageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), WfMeetingApplyPageVo.class, wfMeetingApplyPageVoMPJLambdaWrapper);
+
+        // 判断会议状态
+        for (WfMeetingApplyPageVo vo : page.getRecords()) {
+            if (vo.getMeetingStatus() != 1) {
+                if (vo.getMeetingApplyDate().isBefore(nowLocalDate)) {
+                    vo.setMeetingStatus(2);
+                } else if (vo.getMeetingApplyDate().isAfter(nowLocalDate)) {
+                    vo.setMeetingStatus(0);
+                } else {
+                    if (vo.getMeetingApplyE().isBefore(nowLocalTime)) {
+                        vo.setMeetingStatus(2);
+                    } else if (vo.getMeetingApplyS().isAfter(nowLocalTime)) {
+                        vo.setMeetingStatus(0);
+                    } else {
+                        vo.setMeetingStatus(3);
+                    }
+                }
+            }
+        }
+
+        return page;
+    }
+
+    @Override
+    public IPage<TodayMeetingMobilePageVo> todayMeetingMobilePage(TodayMeetingMobilePageDto dto) {
+        LocalTime nowLocalTime = LocalTime.now();
+        if(ObjectUtils.isEmpty(dto.getMeetingApplyDate())){
+            dto.setMeetingApplyDate(LocalDate.now());
+        }
+        Long loginId = StpUtil.getLoginIdAsLong();
+
+        MPJLambdaWrapper<WfMeetingApply> wfMeetingApplyPageVoMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        wfMeetingApplyPageVoMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(TodayMeetingMobilePageVo.class).contains(x.getProperty()))
+                .innerJoin(MeetingConferee.class, MeetingConferee::getWfMeetingApplyId, WfMeetingApply::getId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingConferee::getCheckInStatus, TodayMeetingMobilePageVo::getCheckInStatus)
+                )
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfMeetingApply::getMeetingApplyFormat,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, TodayMeetingMobilePageVo::getMeetingApplyFormatCn)
+                )
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingRoom::getName, TodayMeetingMobilePageVo::getMeetingRoomIdCn)
+                )
+                .eq(WfMeetingApply::getMeetingApplyDate, dto.getMeetingApplyDate())
+                .eq(MeetingConferee::getUserId, loginId)
+                .eq(WfMeetingApply::getWorkflowStatus, 1)
+                .orderByAsc(WfMeetingApply::getMeetingApplyS)
+        ;
+        IPage<TodayMeetingMobilePageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), TodayMeetingMobilePageVo.class, wfMeetingApplyPageVoMPJLambdaWrapper);
+        List<TodayMeetingMobilePageVo> record = page.getRecords();
+
+        // 分割并重组列表
+        List<TodayMeetingMobilePageVo> futureVo = new ArrayList<>(); // 当前时间之后的事件
+        List<TodayMeetingMobilePageVo> pastVo = new ArrayList<>();   // 当前时间之前的事件
+
+        // 处理状态
+        for (TodayMeetingMobilePageVo vo : record){
+            if (vo.getMeetingStatus() != 1) {
+                if (vo.getMeetingApplyE().isBefore(nowLocalTime)) {
+                    if(vo.getCheckInStatus() == 0){
+                        vo.setMeetingStatus(4);
+                    }
+                    if(vo.getCheckInStatus() == 1){
+                        vo.setMeetingStatus(2);
+                    }
+                } else if (vo.getMeetingApplyS().isAfter(nowLocalTime)) {
+                    vo.setMeetingStatus(0);
+                } else {
+                    vo.setMeetingStatus(3);
+                }
+            }
+
+            if (vo.getMeetingApplyS().isBefore(nowLocalTime)) {
+                pastVo.add(vo); // 过去的事件
+            } else {
+                futureVo.add(vo); // 未来的事件
+            }
+        }
+        List<TodayMeetingMobilePageVo> result = new ArrayList<>();
+        result.addAll(futureVo);
+        result.addAll(pastVo);
+
+        page.setRecords(result);
+
+        return page;
+    }
+
+    @Override
+    public IPage<SponsorMeetingMobilePageVo> sponsorMeetingMobilePage(SponsorMeetingMobilePageDto dto) {
+        Long loginId = StpUtil.getLoginIdAsLong();
+
+        // 当前时间
+        LocalDate nowLocalDate = LocalDate.now();
+        LocalTime nowLocalTime = LocalTime.now();
+
+        MPJLambdaWrapper<WfMeetingApply> wfMeetingApplyPageVoMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        wfMeetingApplyPageVoMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(SponsorMeetingMobilePageVo.class).contains(x.getProperty()))
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfMeetingApply::getMeetingApplyFormat,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, SponsorMeetingMobilePageVo::getMeetingApplyFormatCn)
+                )
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingRoom::getName, SponsorMeetingMobilePageVo::getMeetingRoomIdCn)
+                )
+                .eq(WfMeetingApply::getSponsorId, loginId)
+                .ge(ObjectUtils.isNotEmpty(dto.getStartMeetingApplyDate()), WfMeetingApply::getMeetingApplyDate, dto.getStartMeetingApplyDate())
+                .le(ObjectUtils.isNotEmpty(dto.getEndMeetingApplyDate()), WfMeetingApply::getMeetingApplyDate, dto.getEndMeetingApplyDate())
+                .eq(WfMeetingApply::getWorkflowStatus, 1)
+                .orderByAsc("meeting_apply_date", "meeting_apply_s")
+        ;
+
+        IPage<SponsorMeetingMobilePageVo> page = this.selectJoinListPage(ConventPage.getPage(dto), SponsorMeetingMobilePageVo.class, wfMeetingApplyPageVoMPJLambdaWrapper);
+
+        // 判断会议状态
+        for (SponsorMeetingMobilePageVo vo : page.getRecords()) {
+            if (vo.getMeetingStatus() != 1) {
+                if (vo.getMeetingApplyDate().isBefore(nowLocalDate)) {
+                    vo.setMeetingStatus(2);
+                } else if (vo.getMeetingApplyDate().isAfter(nowLocalDate)) {
+                    vo.setMeetingStatus(0);
+                } else {
+                    if (vo.getMeetingApplyE().isBefore(nowLocalTime)) {
+                        vo.setMeetingStatus(2);
+                    } else if (vo.getMeetingApplyS().isAfter(nowLocalTime)) {
+                        vo.setMeetingStatus(0);
+                    } else {
+                        vo.setMeetingStatus(3);
+                    }
+                }
+            }
+        }
+
+        return page;
+    }
+
     @Override
+    public IPage<HistoryMeetingMobilePageVo> historyMeetingMobilePage(HistoryMeetingMobilePageDto dto) {
+        Long loginId = StpUtil.getLoginIdAsLong();
+
+        if(ObjectUtils.isEmpty(dto.getEndMeetingApplyDate())){
+            dto.setEndMeetingApplyDate(LocalDate.now().minusDays(1));
+        }
+
+        MPJLambdaWrapper<WfMeetingApply> wfMeetingApplyPageVoMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        wfMeetingApplyPageVoMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(HistoryMeetingMobilePageVo.class).contains(x.getProperty()))
+                .innerJoin(MeetingConferee.class, MeetingConferee::getWfMeetingApplyId, WfMeetingApply::getId)
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfMeetingApply::getMeetingApplyFormat,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, HistoryMeetingMobilePageVo::getMeetingApplyFormatCn)
+                )
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingRoom::getName, HistoryMeetingMobilePageVo::getMeetingRoomIdCn)
+                )
+                .eq(MeetingConferee::getUserId, loginId)
+                .ge(ObjectUtils.isNotEmpty(dto.getStartMeetingApplyDate()), WfMeetingApply::getMeetingApplyDate, dto.getStartMeetingApplyDate())
+                .le(ObjectUtils.isNotEmpty(dto.getEndMeetingApplyDate()), WfMeetingApply::getMeetingApplyDate, dto.getEndMeetingApplyDate())
+                .eq(WfMeetingApply::getWorkflowStatus, 1)
+                .orderByAsc("meeting_apply_date", "meeting_apply_s")
+        ;
+
+        return this.selectJoinListPage(ConventPage.getPage(dto), HistoryMeetingMobilePageVo.class, wfMeetingApplyPageVoMPJLambdaWrapper);
+    }
+
+    @Override
+    public MeetingMobileInfoVo mobileInfo(Long id) {
+        MPJLambdaWrapper<WfMeetingApply> wfMeetingApplyPageVoMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        wfMeetingApplyPageVoMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .select(" (SELECT GROUP_CONCAT(a.name) FROM xjr_user a" +
+                        " LEFT JOIN meeting_conferee b ON b.user_id = a.id" +
+                        " WHERE b.delete_mark = 0 AND b.wf_meeting_apply_id = t.id) as meetingApplyParticipantsCn")
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(MeetingMobileInfoVo.class).contains(x.getProperty()))
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfMeetingApply::getMeetingApplyFormat,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, MeetingMobileInfoVo::getMeetingApplyFormatCn)
+                )
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingRoom::getName, MeetingMobileInfoVo::getMeetingRoomIdCn)
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getMeetingApplyHost,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, MeetingMobileInfoVo::getMeetingApplyHostCn)
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getSponsorId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, MeetingMobileInfoVo::getSponsorIdCn)
+                )
+                .eq(WfMeetingApply::getId, id)
+        ;
+
+        MeetingMobileInfoVo info = this.selectJoinOne(MeetingMobileInfoVo.class, wfMeetingApplyPageVoMPJLambdaWrapper);
+
+        if (ObjectUtils.isNotEmpty(info)) {
+            List<File> fileList = fileMapper.selectList(Wrappers.<File>query().lambda().eq(File::getFolderId, info.getPreMeetingInfoFileId()));
+            info.setFileInfos(fileList);
+        }
+
+        return info;
+    }
+
+    @Override
+    public WfMeetingApplyInWorkflowVo infoInWorkflow(Long id) {
+        MPJLambdaWrapper<WfMeetingApply> wfMeetingApplyPageVoMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        wfMeetingApplyPageVoMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .select(" (SELECT GROUP_CONCAT(a.name) FROM xjr_user a" +
+                        " LEFT JOIN meeting_conferee b ON b.user_id = a.id" +
+                        " WHERE b.delete_mark = 0 AND b.wf_meeting_apply_id = t.id) as meetingApplyParticipantsCn")
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(WfMeetingApplyInWorkflowVo.class).contains(x.getProperty()))
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfMeetingApply::getMeetingApplyFormat,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, WfMeetingApplyInWorkflowVo::getMeetingApplyFormatCn)
+                )
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId,
+                        wrapper -> wrapper
+                                .selectAs(MeetingRoom::getName, WfMeetingApplyInWorkflowVo::getMeetingRoomIdCn)
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getMeetingApplyHost,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, WfMeetingApplyInWorkflowVo::getMeetingApplyHostCn)
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getSponsorId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, WfMeetingApplyInWorkflowVo::getSponsorIdCn)
+                )
+                .eq(WfMeetingApply::getId, id)
+        ;
+
+        WfMeetingApplyInWorkflowVo info = this.selectJoinOne(WfMeetingApplyInWorkflowVo.class, wfMeetingApplyPageVoMPJLambdaWrapper);
+
+        if (ObjectUtils.isNotEmpty(info)) {
+            List<File> fileList = fileMapper.selectList(Wrappers.<File>query().lambda().eq(File::getFolderId, info.getPreMeetingInfoFileId()));
+            info.setFileInfos(fileList);
+
+            List<WorkflowRecord> recordList = workflowRecordMapper.selectList(
+                    new MPJLambdaWrapper<WorkflowRecord>()
+                            .select(WorkflowRecord.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowRecordVo.class).contains(x.getProperty()))
+                            .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getProcessId, WorkflowRecord::getProcessId)
+                            .eq(WorkflowFormRelation::getFormKeyValue, id)
+            );
+            info.setWorkflowRecordList(BeanUtil.copyToList(recordList, WorkflowRecordVo.class));
+            List<WorkflowFormRelation> relations = workflowFormRelationMapper.selectList(new QueryWrapper<WorkflowFormRelation>().lambda().eq(WorkflowFormRelation::getFormKeyValue, id.toString()));
+
+            if (!relations.isEmpty()) {
+                info.setProcessId(relations.get(0).getProcessId());
+            }
+
+            //查询最后一个节点的taskId
+            List<WorkflowExtra> taskList = workflowExtraMapper.selectList(
+                    new QueryWrapper<WorkflowExtra>().lambda()
+                            .eq(WorkflowExtra::getProcessId, info.getProcessId())
+                            .orderByDesc(WorkflowExtra::getStartTime)
+            );
+            if (!taskList.isEmpty()) {
+                info.setTaskId(taskList.get(0).getTaskId());
+            }
+        }
+
+        return info;
+    }
+
+    @Override
+    public List<MeetingConfereeListVo> listMeetingConferee(MeetingConfereeListDto dto) {
+        MPJLambdaWrapper<MeetingConferee> meetingConfereeMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        meetingConfereeMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(MeetingConferee::getId)
+                .select(MeetingConferee.class, x -> VoToColumnUtil.fieldsToColumns(MeetingConfereeListVo.class).contains(x.getProperty()))
+                .leftJoin(XjrUser.class, XjrUser::getId, MeetingConferee::getUserId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, MeetingConfereeListVo::getUserIdCn)
+                                .selectAs(XjrUser::getUserName, MeetingConfereeListVo::getUserName)
+                )
+                .eq(MeetingConferee::getWfMeetingApplyId, dto.getWfMeetingApplyId())
+        ;
+
+        return meetingConfereeMapper.selectJoinList(MeetingConfereeListVo.class, meetingConfereeMPJLambdaWrapper);
+    }
+
+    @Override
+    public List<MeetingConfereeOpinionListVo> listMeetingConfereeOpinion(MeetingConfereeOpinionListDto dto) {
+        MPJLambdaWrapper<MeetingConfereeOpinion> meetingConfereeOpinionMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        meetingConfereeOpinionMPJLambdaWrapper
+                .disableSubLogicDel()
+                .select(MeetingConfereeOpinion::getId)
+                .select(MeetingConfereeOpinion.class, x -> VoToColumnUtil.fieldsToColumns(MeetingConfereeOpinionListVo.class).contains(x.getProperty()))
+                .leftJoin(XjrUser.class, XjrUser::getId, MeetingConfereeOpinion::getUserId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, MeetingConfereeOpinionListVo::getUserIdCn)
+                )
+                .eq(MeetingConfereeOpinion::getWfMeetingApplyId, dto.getWfMeetingApplyId())
+        ;
+        return meetingConfereeOpinionMapper.selectJoinList(MeetingConfereeOpinionListVo.class, meetingConfereeOpinionMPJLambdaWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
     public void noticeParticipants(Long id) {
-        WfMeetingApply meetingApply = this.getById(id);
-        if (meetingApply.getMeetingApplyParticipants() == null || meetingApply.getMeetingApplyParticipants().isEmpty()) {
-            return;
-        }
-        List<String> userIds = Arrays.asList(meetingApply.getMeetingApplyParticipants().split(","));
-
-        List<User> userList = userService.list(new QueryWrapper<User>().lambda().in(User::getId, userIds).isNotNull(User::getOpenId));
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
-        String startTime = meetingApply.getMeetingApplyS().format(formatter);
-        String endTime = meetingApply.getMeetingApplyE().format(formatter);
-
-        List<WorkflowExtra> list = extraService.list(
-                new MPJLambdaWrapper<WorkflowExtra>()
-                        .select(WorkflowExtra.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowExtra.class).contains(x.getProperty()))
-                        .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getProcessId, WorkflowExtra::getProcessId)
-                        .eq(WorkflowFormRelation::getFormId, id)
-                        .orderByAsc(WorkflowExtra::getStartTime)
+        MPJLambdaWrapper<WfMeetingApply> wrapper = new MPJLambdaWrapper<>();
+        wrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .selectAs(MeetingRoom::getName, WfMeetingApply::getMeetingSummary) // 将会议室的名称暂时放在会议纪要字段中
+                .selectAs(XjrUser::getName, WfMeetingApply::getMonogramTheme) // 将会议发起人名称暂时放在会标主题字段中
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(WfMeetingApply.class).contains(x.getProperty()))
+                .leftJoin(MeetingRoom.class, MeetingRoom::getId, WfMeetingApply::getMeetingRoomId)
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getSponsorId)
+                .eq(WfMeetingApply::getId, id)
+        ;
+        WfMeetingApply meetingApply = this.selectJoinOne(WfMeetingApply.class, wrapper);
+
+        // 根据数据id找到所在流程得状态
+        WorkflowFormRelation workflowFormRelation = workflowFormRelationMapper.selectOne(
+                Wrappers.lambdaQuery(WorkflowFormRelation.class)
+                        .eq(WorkflowFormRelation::getFormKeyValue, id)
         );
-        String startUserName = list.get(0).getStartUserName();
 
-        for (User user : userList) {
-            WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
-            weChatSendMessageDto.setUserId(user.getOpenId());
-            weChatSendMessageDto.setTemplateId("Hign0b3e4WSXe__YmBKyDsBgAjkfNYC7c6yIUHjk3Hg");
-            weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
-            JSONObject paramJson = new JSONObject();
+        if (ObjectUtils.isNotEmpty(meetingApply)
+                && ObjectUtils.isNotEmpty(workflowFormRelation)
+                && HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState())
+        ) {
+            // 修改会议申请流程状态为正常通过结束
+            WfMeetingApply updateWorkflowStatus = new WfMeetingApply();
+            updateWorkflowStatus.setId(meetingApply.getId());
+            updateWorkflowStatus.setWorkflowStatus(1);
+            this.updateById(updateWorkflowStatus);
+
+            if (meetingApply.getMeetingApplyParticipants() == null || meetingApply.getMeetingApplyParticipants().isEmpty()) {
+                return;
+            }
+
+            List<String> userIds = Arrays.asList(meetingApply.getMeetingApplyParticipants().split(","));
+
+            // 处理会议时间
+            List<User> userList = userService.list(new QueryWrapper<User>().lambda().in(User::getId, userIds));
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            LocalDateTime startLocalDateTime = LocalDateTime.of(meetingApply.getMeetingApplyDate(), meetingApply.getMeetingApplyS());
+            LocalDateTime endLocalDateTime = LocalDateTime.of(meetingApply.getMeetingApplyDate(), meetingApply.getMeetingApplyE());
+            String startTime = startLocalDateTime.format(formatter);
+            String endTime = endLocalDateTime.format(formatter);
+
+//             获取申请人
+//            List<WorkflowExtra> list = extraService.list(
+//                    new MPJLambdaWrapper<WorkflowExtra>()
+//                            .select(WorkflowExtra.class, x -> VoToColumnUtil.fieldsToColumns(WorkflowExtra.class).contains(x.getProperty()))
+//                            .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getProcessId, WorkflowExtra::getProcessId)
+//                            .eq(WorkflowFormRelation::getFormId, id)
+//                            .orderByAsc(WorkflowExtra::getStartTime)
+//            );
+//            String startUserName = list.get(0).getStartUserName();
+
+            MeetingConferee meetingConferee;
 
-            JSONObject thing2 = new JSONObject();
-            thing2.put("value", meetingApply.getMeetingApplyTheme());
-            paramJson.put("thing2", thing2);
+            // 添加参会人员到参会人员表
+            for (User user : userList) {
+                meetingConferee = new MeetingConferee();
+                meetingConferee.setWfMeetingApplyId(id);
+                meetingConferee.setUserId(user.getId());
+                meetingConferee.setCheckInStatus(0);
 
-            JSONObject time5 = new JSONObject();
-            time5.put("value", startTime);
-            paramJson.put("time5", time5);
+                meetingConfereeMapper.insert(meetingConferee);
+            }
 
-            JSONObject time6 = new JSONObject();
-            time6.put("value", endTime);
-            paramJson.put("time6", time6);
+            // 发送微信通知,和添加到记录分开是预防添加出现异常只通知一部人。
+            for (User user : userList) {
+                if (ObjectUtils.isNotEmpty(user.getOpenId())) {
+                    WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
+                    weChatSendMessageDto.setUserId(user.getOpenId());
+                    weChatSendMessageDto.setTemplateId("Hign0b3e4WSXe__YmBKyDsBgAjkfNYC7c6yIUHjk3Hg");
+                    weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
+                    JSONObject paramJson = new JSONObject();
 
-            JSONObject thing7 = new JSONObject();
-            thing7.put("value", meetingApply.getMeetingApplyAddress());
-            paramJson.put("thing7", thing7);
+                    JSONObject thing2 = new JSONObject();
+                    thing2.put("value", meetingApply.getMeetingApplyTheme());
+                    paramJson.put("thing2", thing2);
 
-            JSONObject thing8 = new JSONObject();
-            thing8.put("value", startUserName);
-            paramJson.put("thing8", thing8);
+                    JSONObject time5 = new JSONObject();
+                    time5.put("value", startTime);
+                    paramJson.put("time5", time5);
 
-            weChatSendMessageDto.setContent(paramJson);
-            weChatService.sendTemplateMessage(weChatSendMessageDto);
+                    JSONObject time6 = new JSONObject();
+                    time6.put("value", endTime);
+                    paramJson.put("time6", time6);
+
+                    JSONObject thing7 = new JSONObject();
+                    thing7.put("value", meetingApply.getMeetingSummary());
+                    paramJson.put("thing7", thing7);
+
+                    JSONObject thing8 = new JSONObject();
+                    thing8.put("value", meetingApply.getMonogramTheme());
+                    paramJson.put("thing8", thing8);
+
+                    weChatSendMessageDto.setContent(paramJson);
+                    weChatService.sendTemplateMessage(weChatSendMessageDto);
+                }
+            }
         }
+
+        if (ObjectUtils.isNotEmpty(meetingApply)
+                && ObjectUtils.isNotEmpty(workflowFormRelation)
+                && !HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState())
+                && !HistoricProcessInstance.STATE_ACTIVE.equals(workflowFormRelation.getCurrentState())
+        ) {
+            // 修改会议申请流程状态为不正常的结束
+            WfMeetingApply updateWorkflowStatus = new WfMeetingApply();
+            updateWorkflowStatus.setId(meetingApply.getId());
+            updateWorkflowStatus.setWorkflowStatus(2);
+            this.updateById(updateWorkflowStatus);
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateRevocationMeeting(UpdateRevocationMeetingDto dto) {
+        MPJLambdaWrapper<WfMeetingApply> wrapper = new MPJLambdaWrapper<>();
+        wrapper
+                .disableSubLogicDel()
+                .select(WfMeetingApply::getId)
+                .selectAs(XjrUser::getName, WfMeetingApply::getMonogramTheme) // 将会议发起人名称暂时放在会标主题字段中
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(WfMeetingApply.class).contains(x.getProperty()))
+                .leftJoin(XjrUser.class, XjrUser::getId, WfMeetingApply::getSponsorId)
+                .eq(WfMeetingApply::getId, dto.getId())
+        ;
+        WfMeetingApply oldWfMeetingApply = this.selectJoinOne(WfMeetingApply.class, wrapper);
+
+        WfMeetingApply updateWfMeetingApply = new WfMeetingApply();
+        updateWfMeetingApply.setId(dto.getId());
+        updateWfMeetingApply.setMeetingStatus(1);
+        this.updateById(updateWfMeetingApply);
+
+        if (StringUtils.isNotEmpty(oldWfMeetingApply.getMeetingApplyParticipants())) {
+            List<String> userIds = Arrays.asList(oldWfMeetingApply.getMeetingApplyParticipants().split(","));
+            List<User> userList = userService.list(new QueryWrapper<User>().lambda().in(User::getId, userIds).isNotNull(User::getOpenId));
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+            LocalDateTime startLocalDateTime = LocalDateTime.of(oldWfMeetingApply.getMeetingApplyDate(), oldWfMeetingApply.getMeetingApplyS());
+            String startTime = startLocalDateTime.format(formatter);
+            // 发送消息通知
+            for (User user : userList) {
+                WeChatSendMessageDto weChatSendMessageDto = new WeChatSendMessageDto();
+                weChatSendMessageDto.setUserId(user.getOpenId());
+                weChatSendMessageDto.setTemplateId("sZcnORXfcQZf8zy5K16N3dsPgQomyQALqUeEzYvTwxo");
+                weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
+                JSONObject paramJson = new JSONObject();
+
+                JSONObject thing1 = new JSONObject();
+                thing1.put("value", oldWfMeetingApply.getMeetingApplyTheme());
+                paramJson.put("thing1", thing1);
+
+                JSONObject time6 = new JSONObject();
+                time6.put("value", startTime);
+                paramJson.put("time6", time6);
+
+                JSONObject thing8 = new JSONObject();
+                thing8.put("value", oldWfMeetingApply.getMonogramTheme());
+                paramJson.put("thing8", thing8);
+
+                weChatSendMessageDto.setContent(paramJson);
+                weChatService.sendTemplateMessage(weChatSendMessageDto);
+            }
+        }
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateMeetingCheckIn(UpdateMeetingCheckInDto dto) {
+        LambdaUpdateWrapper<MeetingConferee> meetingConfereeLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+        meetingConfereeLambdaUpdateWrapper
+                .eq(MeetingConferee::getWfMeetingApplyId, dto.getId())
+                .eq(MeetingConferee::getUserId, StpUtil.getLoginIdAsLong())
+                ;
+        MeetingConferee meetingConferee = new MeetingConferee();
+        meetingConferee.setCheckInStatus(1);
+        meetingConferee.setCheckInDate(new Date());
+        meetingConferee.setModifyDate(new Date());
+        meetingConferee.setModifyUserId(StpUtil.getLoginIdAsLong());
+        meetingConfereeMapper.update(meetingConferee, meetingConfereeLambdaUpdateWrapper);
+        return true;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean addMeetingConfereeOpinion(AddMeetingConfereeOpinionDto dto) {
+        MeetingConfereeOpinion insert = new MeetingConfereeOpinion();
+        insert.setWfMeetingApplyId(dto.getWfMeetingApplyId());
+        insert.setUserId(StpUtil.getLoginIdAsLong());
+        insert.setOpinion(dto.getOpinion());
+        insert.setCreateDate(new Date());
+        insert.setCreateUserId(StpUtil.getLoginIdAsLong());
+        meetingConfereeOpinionMapper.insert(insert);
+        return true;
     }
 }

+ 68 - 0
src/main/java/com/xjrsoft/module/oa/vo/HistoryMeetingMobilePageVo.java

@@ -0,0 +1,68 @@
+package com.xjrsoft.module.oa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+* @title: 移动端今日会议列表(分页)出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class HistoryMeetingMobilePageVo {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private String id;
+    /**
+     * 会议日期
+     */
+    @ApiModelProperty("会议日期")
+    private LocalDate meetingApplyDate;
+    /**
+    * 会议开始时间
+    */
+    @ApiModelProperty("会议开始时间")
+    private LocalTime meetingApplyS;
+    /**
+    * 会议结束时间
+    */
+    @ApiModelProperty("会议结束时间")
+    private LocalTime meetingApplyE;
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+    /**
+     * 会议形式(xjr_dictionary_item(meeting_type))
+     */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormatCn;
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+     * 会议室管理主键id(meeting_room)
+     */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private String meetingRoomIdCn;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+    * 会议主题
+    */
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+}

+ 47 - 0
src/main/java/com/xjrsoft/module/oa/vo/MeetingConfereeListVo.java

@@ -0,0 +1,47 @@
+package com.xjrsoft.module.oa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+* @title: 会议参会人员列表(不分页)出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingConfereeListVo {
+
+    /**
+     * 主键编号
+     */
+    @ApiModelProperty("主键编号")
+    private Long id;
+    /**
+     * 用户主键id(xjr_user)
+     */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private Long userId;
+    /**
+     * 用户主键id(xjr_user)
+     */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private String userIdCn;
+    /**
+     * 账户
+     */
+    @ApiModelProperty("账户")
+    private String userName;
+    /**
+     * 签到状态(0:未签到,1:已签到)
+     */
+    @ApiModelProperty("签到状态(0:未签到,1:已签到,2:请假)")
+    private Integer checkInStatus;
+    /**
+     * 签到时间
+     */
+    @ApiModelProperty("签到时间")
+    private LocalDateTime checkInDate;
+}

+ 50 - 0
src/main/java/com/xjrsoft/module/oa/vo/MeetingConfereeOpinionListVo.java

@@ -0,0 +1,50 @@
+package com.xjrsoft.module.oa.vo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+* @title: 会议参会人员意见表单出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingConfereeOpinionListVo {
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+    /**
+     * 会议申请主键id(wf_meeting_apply)
+     */
+    @ApiModelProperty("会议申请主键id(wf_meeting_apply)")
+    private Long wfMeetingApplyId;
+    /**
+     * 用户主键id(xjr_user)
+     */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private Long userId;
+    /**
+     * 用户主键id(xjr_user)
+     */
+    @ApiModelProperty("用户主键id(xjr_user)")
+    private String userIdCn;
+    /**
+    * 意见
+    */
+    @ApiModelProperty("意见")
+    private String opinion;
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createDate;
+}

+ 118 - 0
src/main/java/com/xjrsoft/module/oa/vo/MeetingMobileInfoVo.java

@@ -0,0 +1,118 @@
+package com.xjrsoft.module.oa.vo;
+
+import com.xjrsoft.module.system.entity.File;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+* @title: 表单出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingMobileInfoVo {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private Long id;
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private Long sponsorId;
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private String sponsorIdCn;
+    /**
+    * 会议日期
+    */
+    @ApiModelProperty("会议日期")
+    private Date meetingApplyDate;
+    /**
+    * 会议开始时间
+    */
+    @ApiModelProperty("会议开始时间")
+    private LocalTime meetingApplyS;
+    /**
+    * 会议结束时间
+    */
+    @ApiModelProperty("会议结束时间")
+    private LocalTime meetingApplyE;
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+    /**
+     * 会议形式(xjr_dictionary_item(meeting_type))
+     */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormatCn;
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+     * 会议室管理主键id(meeting_room)
+     */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private String meetingRoomIdCn;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+    * 主持人
+    */
+    @ApiModelProperty("主持人")
+    private String meetingApplyHost;
+    /**
+     * 主持人
+     */
+    @ApiModelProperty("主持人")
+    private String meetingApplyHostCn;
+    /**
+    * 会议主题
+    */
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+    /**
+    * 会议议题
+    */
+    @ApiModelProperty("会议议题")
+    private String meetingApplyTopics;
+    /**
+    * 是否准备座牌、会标(1:是,0:否)
+    */
+    @ApiModelProperty("是否准备座牌、会标(1:是,0:否)")
+    private Integer isMonogram;
+    /**
+    * 会标主题
+    */
+    @ApiModelProperty("会标主题")
+    private String monogramTheme;
+    /**
+    * 会议纪要
+    */
+    @ApiModelProperty("会议纪要")
+    private String meetingSummary;
+    /**
+    * 会前资料文件上传主键id
+    */
+    @ApiModelProperty("会前资料文件上传主键id")
+    private Long preMeetingInfoFileId;
+
+    @ApiModelProperty("附件列表")
+    private List<File> fileInfos;
+}

+ 50 - 0
src/main/java/com/xjrsoft/module/oa/vo/MeetingRoomListVo.java

@@ -0,0 +1,50 @@
+package com.xjrsoft.module.oa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+* @title: 会议室列表(不分页)出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingRoomListVo {
+
+    @ApiModelProperty("主键id")
+    private Long id;
+    /**
+     * 会议室名称
+     */
+    @ApiModelProperty("会议室名称")
+    private String name;
+    /**
+     * 预约情况
+     */
+    @ApiModelProperty("预约情况")
+    private String reservationDetail;
+    /**
+     * 楼栋(base_office_build)
+     */
+    @ApiModelProperty("楼栋(base_office_build)")
+    private String officeBuildIdCn;
+    /**
+     * 楼层
+     */
+    @ApiModelProperty("楼层")
+    private Integer floorNum;
+    /**
+     * 容量(最大人数)
+     */
+    @ApiModelProperty("容量(最大人数)")
+    private Integer capacity;
+    /**
+     * 会议室名称
+     */
+    @ApiModelProperty("会议室在时间段内的状态,0:可以正常使用,1:在当前时间端已经预约")
+    private Integer status;
+}

+ 36 - 0
src/main/java/com/xjrsoft/module/oa/vo/MeetingSummaryVo.java

@@ -0,0 +1,36 @@
+package com.xjrsoft.module.oa.vo;
+
+import com.xjrsoft.module.system.entity.File;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+* @title: 会会议纪要出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class MeetingSummaryVo {
+
+    /**
+     * 主键编号
+     */
+    @ApiModelProperty("主键编号")
+    private Long id;
+    /**
+     * 会议纪要
+     */
+    @ApiModelProperty("会议纪要")
+    private String meetingSummary;
+    /**
+     * 会议纪要附件
+     */
+    @ApiModelProperty("会议纪要附件")
+    private Long meetingSummaryFileId;
+
+    @ApiModelProperty("附件列表")
+    private List<File> fileInfos;
+}

+ 73 - 0
src/main/java/com/xjrsoft/module/oa/vo/SponsorMeetingMobilePageVo.java

@@ -0,0 +1,73 @@
+package com.xjrsoft.module.oa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+* @title: 移动端今日会议列表(分页)出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class SponsorMeetingMobilePageVo {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private String id;
+    /**
+     * 会议日期
+     */
+    @ApiModelProperty("会议日期")
+    private LocalDate meetingApplyDate;
+    /**
+    * 会议开始时间
+    */
+    @ApiModelProperty("会议开始时间")
+    private LocalTime meetingApplyS;
+    /**
+    * 会议结束时间
+    */
+    @ApiModelProperty("会议结束时间")
+    private LocalTime meetingApplyE;
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+    /**
+     * 会议形式(xjr_dictionary_item(meeting_type))
+     */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormatCn;
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+     * 会议室管理主键id(meeting_room)
+     */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private String meetingRoomIdCn;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+    * 会议主题
+    */
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+    /**
+    * 会议状态(0:未开始 1:已经撤销,2:已结束,3:进行中,4:未参与)
+    */
+    @ApiModelProperty("会议状态(0:未开始 1:已经撤销,2:已结束,3:进行中,4:未参与)")
+    private Integer meetingStatus;
+}

+ 73 - 0
src/main/java/com/xjrsoft/module/oa/vo/TodayMeetingMobilePageVo.java

@@ -0,0 +1,73 @@
+package com.xjrsoft.module.oa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+* @title: 移动端今日会议列表(分页)出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class TodayMeetingMobilePageVo {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private String id;
+    /**
+    * 会议开始时间
+    */
+    @ApiModelProperty("会议开始时间")
+    private LocalTime meetingApplyS;
+    /**
+    * 会议结束时间
+    */
+    @ApiModelProperty("会议结束时间")
+    private LocalTime meetingApplyE;
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+    /**
+     * 会议形式(xjr_dictionary_item(meeting_type))
+     */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormatCn;
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+     * 会议室管理主键id(meeting_room)
+     */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private String meetingRoomIdCn;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+    * 会议主题
+    */
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+    /**
+    * 会议状态(0:未开始 1:已经撤销,2:已结束)
+    */
+    @ApiModelProperty("会议状态(0:未开始 1:已经撤销,2:已结束,3:进行中,4:未参与)")
+    private Integer meetingStatus;
+    /**
+     * 签到状态(0:未签到,1:已签到)
+     */
+    @ApiModelProperty("签到状态(0:未签到,1:已签到)")
+    private Integer checkInStatus;
+}

+ 144 - 0
src/main/java/com/xjrsoft/module/oa/vo/WfMeetingApplyInWorkflowVo.java

@@ -0,0 +1,144 @@
+package com.xjrsoft.module.oa.vo;
+
+import com.xjrsoft.module.ledger.vo.WorkflowRecordVo;
+import com.xjrsoft.module.system.entity.File;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalTime;
+import java.util.Date;
+import java.util.List;
+
+/**
+* @title: 表单出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class WfMeetingApplyInWorkflowVo {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private Long id;
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private Long sponsorId;
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private String sponsorIdCn;
+    /**
+    * 会议日期
+    */
+    @ApiModelProperty("会议日期")
+    private Date meetingApplyDate;
+    /**
+    * 会议开始时间
+    */
+    @ApiModelProperty("会议开始时间")
+    private LocalTime meetingApplyS;
+    /**
+    * 会议结束时间
+    */
+    @ApiModelProperty("会议结束时间")
+    private LocalTime meetingApplyE;
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+    /**
+     * 会议形式(xjr_dictionary_item(meeting_type))
+     */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormatCn;
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+     * 会议室管理主键id(meeting_room)
+     */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private String meetingRoomIdCn;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+    * 参会人员
+    */
+    @ApiModelProperty("参会人员")
+    private String meetingApplyParticipants;
+    /**
+     * 参会人员
+     */
+    @ApiModelProperty("参会人员")
+    private String meetingApplyParticipantsCn;
+    /**
+    * 主持人
+    */
+    @ApiModelProperty("主持人")
+    private String meetingApplyHost;
+    /**
+     * 主持人
+     */
+    @ApiModelProperty("主持人")
+    private String meetingApplyHostCn;
+    /**
+    * 会议主题
+    */
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+    /**
+    * 会议议题
+    */
+    @ApiModelProperty("会议议题")
+    private String meetingApplyTopics;
+    /**
+    * 是否准备座牌、会标(1:是,0:否)
+    */
+    @ApiModelProperty("是否准备座牌、会标(1:是,0:否)")
+    private Integer isMonogram;
+    /**
+    * 会标主题
+    */
+    @ApiModelProperty("会标主题")
+    private String monogramTheme;
+    /**
+    * 会议纪要
+    */
+    @ApiModelProperty("会议纪要")
+    private String meetingSummary;
+    /**
+    * 会前资料文件上传主键id
+    */
+    @ApiModelProperty("会前资料文件上传主键id")
+    private Long preMeetingInfoFileId;
+
+    @ApiModelProperty("附件列表")
+    private List<File> fileInfos;
+
+    /**
+    * 会议状态(0:未开始 1:已经撤销,2:已结束)
+    */
+    @ApiModelProperty("会议状态(0:未开始 1:已经撤销,2:已结束)")
+    private Integer meetingStatus;
+
+    @ApiModelProperty("流程信息")
+    private List<WorkflowRecordVo> workflowRecordList;
+
+    @ApiModelProperty("流程id")
+    private String processId;
+
+    @ApiModelProperty("任务id")
+    private String taskId;
+}

+ 108 - 0
src/main/java/com/xjrsoft/module/oa/vo/WfMeetingApplyPageVo.java

@@ -0,0 +1,108 @@
+package com.xjrsoft.module.oa.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+* @title: 分页列表出参
+* @Author phoenix
+* @Date: 2025-03-26
+* @Version 1.0
+*/
+@Data
+public class WfMeetingApplyPageVo {
+
+    /**
+    * 
+    */
+    @ApiModelProperty("")
+    private String id;
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private Long sponsorId;
+    /**
+     * 会议发起人主键id(xjr_user
+     */
+    @ApiModelProperty("会议发起人主键id(xjr_user")
+    private String sponsorIdCn;
+    /**
+    * 会议日期
+    */
+    @ApiModelProperty("会议日期")
+    private LocalDate meetingApplyDate;
+    /**
+    * 会议开始时间
+    */
+    @ApiModelProperty("会议开始时间")
+    private LocalTime meetingApplyS;
+    /**
+    * 会议结束时间
+    */
+    @ApiModelProperty("会议结束时间")
+    private LocalTime meetingApplyE;
+    /**
+    * 会议形式(xjr_dictionary_item(meeting_type))
+    */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormat;
+    /**
+     * 会议形式(xjr_dictionary_item(meeting_type))
+     */
+    @ApiModelProperty("会议形式(xjr_dictionary_item(meeting_type))")
+    private String meetingApplyFormatCn;
+    /**
+    * 会议室管理主键id(meeting_room)
+    */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private Long meetingRoomId;
+    /**
+     * 会议室管理主键id(meeting_room)
+     */
+    @ApiModelProperty("会议室管理主键id(meeting_room)")
+    private String meetingRoomIdCn;
+    /**
+    * 线上会议链接
+    */
+    @ApiModelProperty("线上会议链接")
+    private String meetingApplyUrl;
+    /**
+     * 主持人
+     */
+    @ApiModelProperty("主持人")
+    private Long meetingApplyHost;
+    /**
+    * 主持人
+    */
+    @ApiModelProperty("主持人")
+    private String meetingApplyHostCn;
+    /**
+    * 会议主题
+    */
+    @ApiModelProperty("会议主题")
+    private String meetingApplyTheme;
+    /**
+    * 会议议题
+    */
+    @ApiModelProperty("会议议题")
+    private String meetingApplyTopics;
+    /**
+    * 是否准备座牌、会标(1:是,0:否)
+    */
+    @ApiModelProperty("是否准备座牌、会标(1:是,0:否)")
+    private Integer isMonogram;
+    /**
+    * 会标主题
+    */
+    @ApiModelProperty("会标主题")
+    private String monogramTheme;
+    /**
+    * 会议状态(0:未开始 1:已经撤销,2:已结束)
+    */
+    @ApiModelProperty("会议状态(0:未开始 1:已经撤销,2:已结束,3:进行中)")
+    private Integer meetingStatus;
+}

+ 12 - 5
src/main/java/com/xjrsoft/module/organization/controller/UserController.java

@@ -716,18 +716,25 @@ public class UserController {
         return R.error("该用户不存在!");
     }
 
+//    @PostMapping("/bind-openid")
+//    @ApiOperation(value = "绑定微信 Openid")
+//    @XjrLog(value = "绑定微信 Openid", saveResponseData = true)
+//    public R bindOpenid(@RequestBody BindOpenidDto dto) {
+//        return R.ok(userService.bindOpenid(dto));
+//    }
+
     @PostMapping("/bind-openid")
     @ApiOperation(value = "绑定微信 Openid")
     @XjrLog(value = "绑定微信 Openid", saveResponseData = true)
-    public R bindOpenid(@RequestBody BindOpenidDto dto) {
-        return R.ok(userService.bindOpenid(dto));
+    public RT<BindOpenidVo> bindOpenid(@RequestBody BindOpenidDto dto) {
+        return RT.ok(userService.bindOpenid(dto));
     }
 
-    @GetMapping("/unbind-openid")
+    @PostMapping("/unbind-openid")
     @ApiOperation(value = "取消绑定微信 UnionId")
     @XjrLog(value = "取消绑定微信 UnionId", saveResponseData = true)
-    public R unbindOpenid(@RequestParam Long id) {
-        return R.ok(userService.unbindOpenid(id));
+    public R unbindOpenid(@RequestBody UnbindOpenidDto dto) {
+        return R.ok(userService.unbindOpenid(dto));
     }
 
     @PostMapping("/register")

+ 17 - 0
src/main/java/com/xjrsoft/module/organization/dto/UnbindOpenidDto.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.organization.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class UnbindOpenidDto {
+
+    private Long id;
+
+    private String openid;
+
+    @ApiModelProperty("手机号")
+    private String mobile;
+
+    private String code;
+}

+ 4 - 2
src/main/java/com/xjrsoft/module/organization/service/IUserService.java

@@ -49,14 +49,16 @@ public interface IUserService extends MPJBaseService<User> {
      * @param dto
      * @return
      */
-    boolean bindOpenid(BindOpenidDto dto);
+//    boolean bindOpenid(BindOpenidDto dto);
+    BindOpenidVo bindOpenid(BindOpenidDto dto);
 
     /**
      * 取消绑定微信 UnionId
      *
      * @return
      */
-    boolean unbindOpenid(Long id);
+//    boolean unbindOpenid(Long id);
+    boolean unbindOpenid(UnbindOpenidDto dto);
 
     /**
      * 批量获取用户信息

+ 68 - 16
src/main/java/com/xjrsoft/module/organization/service/impl/UserServiceImpl.java

@@ -23,6 +23,7 @@ import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.sms.SmsCtcc;
 import com.xjrsoft.common.utils.RedisUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.config.CommonPropertiesConfig;
@@ -48,6 +49,7 @@ import org.springframework.transaction.annotation.Transactional;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
@@ -79,6 +81,8 @@ public class UserServiceImpl extends MPJBaseServiceImpl<UserMapper, User> implem
 
     private HikvisionDataMapper hikvisionDataMapper;
 
+    private SmsCtcc smsCtcc;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean add(AddUserDto dto) {
@@ -279,42 +283,90 @@ public class UserServiceImpl extends MPJBaseServiceImpl<UserMapper, User> implem
     }
 
     @Override
-    public boolean bindOpenid(BindOpenidDto dto) {
-        User user = this.getOne(Wrappers.<User>query().lambda().select(User::getId, User::getOpenId, User::getUnionId).eq(User::getId, dto.getId()), false);
+    @Transactional(rollbackFor = Exception.class)
+//    public boolean bindOpenid(BindOpenidDto dto) {
+    public BindOpenidVo bindOpenid(BindOpenidDto dto) {
+        BindOpenidVo result = new BindOpenidVo();
+        result.setStatus(0);
+        User user = this.getOne(
+                Wrappers.<User>query().lambda()
+                        .select(User::getId, User::getUserName, User::getOpenId, User::getUnionId, User::getMobile)
+                        .eq(User::getId, dto.getId()), false);
         if (user != null) {
-            if (StrUtil.isNotBlank(user.getOpenId())) {
-                throw new MyException("该用户已经绑定微信");
+//            if (StrUtil.isNotBlank(user.getOpenId())) {
+//                throw new MyException("该用户已经绑定微信");
+//            }
+//            long count = this.count(Wrappers.<User>query().lambda().eq(User::getOpenId, dto.getOpenid()));
+//            if (count > 0) {
+//                throw new MyException("该用户已经绑定微信!");
+//            }
+            result.setUserId(user.getId().toString());
+            result.setName(user.getName());
+            result.setUserName(user.getUserName());
+            result.setMobile(user.getMobile());
+
+            if (StrUtil.isNotBlank(user.getOpenId()) && Objects.equals(user.getOpenId(), dto.getOpenid())) {
+                result.setStatus(1);
+                return result;
+            }
+
+            if (StrUtil.isNotBlank(user.getOpenId()) && !Objects.equals(user.getOpenId(), dto.getOpenid())) {
+                result.setStatus(2);
+                return result;
             }
-            long count = this.count(Wrappers.<User>query().lambda().eq(User::getOpenId, dto.getOpenid()));
-            if (count > 0) {
-                throw new MyException("该用户已经绑定微信!");
+
+            User openId2user = this.getOne(
+                    Wrappers.<User>query().lambda()
+                            .select(User::getId, User::getUserName, User::getOpenId, User::getUnionId, User::getMobile)
+                            .eq(User::getOpenId, dto.getOpenid()), false);
+
+            if (ObjectUtil.isNotEmpty(openId2user)) {
+                result.setUserId(openId2user.getId().toString());
+                result.setName(openId2user.getName());
+                result.setUserName(openId2user.getUserName());
+                result.setMobile(openId2user.getMobile());
+                result.setStatus(3);
+                return result;
             }
+
             User updateUser = new User();
             updateUser.setId(dto.getId());
             updateUser.setOpenId(dto.getOpenid());
             updateUser.setUnionId(dto.getUnionid());
-            boolean result = this.updateById(updateUser);
+//            boolean result = this.updateById(updateUser);
+            boolean flag = this.updateById(updateUser);
             // 用户绑定微信后,更新缓存
-            if (result) {
+            if (flag) {
+                result.setStatus(1);
                 CompletableFuture.runAsync(() -> {
                     List<User> list = list();
                     redisUtil.set(GlobalConstant.USER_CACHE_KEY, list);
                 });
             }
             return result;
-        } else {
-            long count = this.count(Wrappers.<User>query().lambda().eq(User::getOpenId, dto.getOpenid()));
-            if (count > 0) {
-                throw new MyException("该用户已经绑定微信!");
-            }
         }
+//        else {
+//            long count = this.count(Wrappers.<User>query().lambda().eq(User::getOpenId, dto.getOpenid()));
+//            if (count > 0) {
+//                throw new MyException("当前微信已经绑定其他用户!");
+//            }
+//        }
         throw new MyException("该用户不存在!");
     }
 
     @Override
-    public boolean unbindOpenid(Long id) {
+    @Transactional(rollbackFor = Exception.class)
+//    public boolean unbindOpenid(Long id) {
+    public boolean unbindOpenid(UnbindOpenidDto dto) {
+        // 验证手机验证码
+        boolean verifyResult = smsCtcc.captchaVerify(dto.getMobile(), dto.getCode());
+
+        if(!verifyResult){
+            throw new MyException("验证码错误");
+        }
+
         User updateUser = new User();
-        updateUser.setId(id);
+        updateUser.setId(dto.getId());
         updateUser.setOpenId("");
         updateUser.setUnionId("");
         boolean result = updateById(updateUser);

+ 32 - 0
src/main/java/com/xjrsoft/module/organization/vo/BindOpenidVo.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.module.organization.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @title: RoleListVo
+ * @Author tzx
+ * @Date: 2022/4/4 18:24
+ * @Version 1.0
+ */
+@Data
+public class BindOpenidVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String userId;
+
+    @ApiModelProperty("用户名")
+    private String userName;
+
+    @ApiModelProperty("名字")
+    private String name;
+
+    @ApiModelProperty("手机号")
+    private String mobile;
+
+    @ApiModelProperty("修改状态,0:修改失败,1:修改成功,2:该用户已经绑定了其他微信,3:该微信已经绑定其他用户")
+    private Integer status;
+}

+ 3 - 0
src/main/java/com/xjrsoft/module/room/dto/RoomBedPageDto.java

@@ -42,4 +42,7 @@ public class RoomBedPageDto extends PageInput {
 
     @ApiModelProperty("入住身份")
     public String identity;
+
+    @ApiModelProperty("床位号")
+    public String bedNumber;
 }

+ 25 - 23
src/main/java/com/xjrsoft/module/room/mapper/RoomBedMapper.java

@@ -2,11 +2,30 @@ package com.xjrsoft.module.room.mapper;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.yulichang.base.MPJBaseMapper;
-import com.xjrsoft.module.room.dto.*;
+import com.xjrsoft.module.room.dto.AdjustBedPageDto;
+import com.xjrsoft.module.room.dto.AdjustClassPageDto;
+import com.xjrsoft.module.room.dto.DistributeClassPageDto;
+import com.xjrsoft.module.room.dto.DistributeRoomBedDto;
+import com.xjrsoft.module.room.dto.DistributeRoomBedPageDto;
+import com.xjrsoft.module.room.dto.RoomBedPageDto;
 import com.xjrsoft.module.room.entity.RoomBed;
-import com.xjrsoft.module.room.vo.*;
+import com.xjrsoft.module.room.vo.AdjustBedClassPageVo;
+import com.xjrsoft.module.room.vo.AdjustBedClassStudentPageVo;
+import com.xjrsoft.module.room.vo.AdjustBedStudentPageVo;
+import com.xjrsoft.module.room.vo.ClassStudentCountVo;
+import com.xjrsoft.module.room.vo.DistributeClassPageVo;
+import com.xjrsoft.module.room.vo.DistributeResultListVo;
+import com.xjrsoft.module.room.vo.DistributeRoomBedPageVo;
+import com.xjrsoft.module.room.vo.NoBedStudentPageVo;
+import com.xjrsoft.module.room.vo.RoomBedExcelVo;
+import com.xjrsoft.module.room.vo.RoomBedInfoVo;
+import com.xjrsoft.module.room.vo.RoomBedPageVo;
+import com.xjrsoft.module.room.vo.RoomBedVo;
+import com.xjrsoft.module.room.vo.StudentPayStatusVo;
+import com.xjrsoft.module.room.vo.TeacherRoomListVo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
 
 import java.util.List;
 
@@ -20,17 +39,12 @@ import java.util.List;
 public interface RoomBedMapper extends MPJBaseMapper<RoomBed> {
     /**
      * 返回最大的序号
-     *
-     * @return
      */
     Integer getMaxSortCode();
 
     /**
      * 分页查询
      *
-     * @param page
-     * @param dto
-     * @return
      */
     Page<RoomBedPageVo> getPage(Page<RoomBedPageVo> page, RoomBedPageDto dto);
 
@@ -45,34 +59,24 @@ public interface RoomBedMapper extends MPJBaseMapper<RoomBed> {
     /**
      * 返回分配的结果
      *
-     * @param dto
-     * @return
      */
     List<DistributeResultListVo> getDistributeResult(@Param("dto") DistributeRoomBedDto dto);
 
     /**
      * 调整床位,左边的班级学生信息
      *
-     * @param dto
-     * @return
      */
     List<AdjustBedClassStudentPageVo> getClassStudetBed(@Param("dto") AdjustClassPageDto dto);
 
     /**
      * 调整床位,右边的床位学生信息
      *
-     * @param dto
-     * @return
      */
     List<AdjustBedStudentPageVo> getBedStudentInfo(@Param("dto") AdjustBedPageDto dto);
 
 
     /**
      * 未分配床位的学生信息
-     *
-     * @param page
-     * @param dto
-     * @return
      */
     Page<NoBedStudentPageVo> getNoBedStudent(Page<AdjustBedPageDto> page, AdjustBedPageDto dto);
 
@@ -115,24 +119,18 @@ public interface RoomBedMapper extends MPJBaseMapper<RoomBed> {
     /**
      * 根据用户id查询床位信息
      *
-     * @param id
-     * @return
      */
     RoomBedInfoVo getBedInfoByUserId(Long id);
 
     /**
      * 查询学生的住宿费缴费状态
      *
-     * @param dto
-     * @return
      */
     List<StudentPayStatusVo> getStudentPayStatus(@Param("dto") DistributeRoomBedDto dto);
 
     /**
      * 查询班级id、名称和班主任信息
      *
-     * @param dto
-     * @return
      */
     List<AdjustBedClassPageVo> getClassTeacherInfo(@Param("dto") AdjustClassPageDto dto);
 
@@ -140,4 +138,8 @@ public interface RoomBedMapper extends MPJBaseMapper<RoomBed> {
 
     List<TeacherRoomListVo> getTeacherRoomList(@Param("dto") AdjustBedPageDto dto);
 
+
+    @Update("UPDATE room_bed SET student_user_id = NULL,is_check_in = 0,modify_user_id = #{updateUserId}, modify_date = NOW() WHERE student_user_id = #{studentUserId}")
+    void clearBedInfoByStudentUserId(@Param("studentUserId") Long studentUserId, @Param("updateUserId") Long updateUserId);
+
 }

+ 1 - 1
src/main/java/com/xjrsoft/module/schedule/controller/ScheduleController.java

@@ -103,7 +103,7 @@ public class ScheduleController {
     @GetMapping(value = "/course-table")
     @ApiOperation(value = "课表接口(PC端)")
     @SaCheckPermission("schedule:detail")
-    @XjrLog(value = "课表接口(PC端)", saveResponseData = true)
+    @XjrLog(value = "课表接口(PC端)", saveRequestData = false)
     public RT<CourseTableVo> courseInfo(CourseTableDto dto) {
         if (dto.getSemesterId() == null) {
             BaseSemester semester = semesterService.getCurrentSemester();

+ 72 - 0
src/main/java/com/xjrsoft/module/schedule/controller/TodayScheduleController.java

@@ -0,0 +1,72 @@
+package com.xjrsoft.module.schedule.controller;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpUtil;
+import com.xjrsoft.common.annotation.XjrLog;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.utils.LocalDateTimeUtil;
+import com.xjrsoft.module.schedule.dto.TodaySchedulePageDto;
+import com.xjrsoft.module.schedule.service.ITodayScheduleService;
+import com.xjrsoft.module.schedule.vo.TodayScheduleVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @title: 今日安排
+ * @Author dzx
+ * @Date: 2025年3月27日
+ * @Version 1.0
+ */
+@RestController
+@RequestMapping("/todaySchedule" + "/todaySchedule")
+@Api(value = "/todaySchedule" + "/todaySchedule", tags = "今日安排查询代码")
+@AllArgsConstructor
+public class TodayScheduleController {
+
+
+    private final ITodayScheduleService todayScheduleService;
+
+    @GetMapping(value = "/list")
+    @ApiOperation(value = "今日安排查询")
+    @SaCheckPermission("schedule:detail")
+    @XjrLog(value = "今日安排查询", saveResponseData = true)
+    public RT<List<TodayScheduleVo>> receiveMsg(@Valid TodaySchedulePageDto dto){
+        if(dto.getUserId() == null){
+            dto.setUserId(StpUtil.getLoginIdAsLong());
+        }
+        List<TodayScheduleVo> list = todayScheduleService.getList(dto);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        Map<Long, LocalDateTime> startTimeMap = list.stream().collect(Collectors.toMap(TodayScheduleVo::getId, x -> LocalDateTime.parse(x.getStartTime(), formatter)));
+        Map<Long, LocalDateTime> endTimeMap = list.stream().collect(Collectors.toMap(TodayScheduleVo::getId, x -> LocalDateTime.parse(x.getEndTime(), formatter)));
+        for (TodayScheduleVo todayScheduleVo : list) {
+            String adjustType = null;
+            LocalDateTime startDateTime = LocalDateTime.parse(todayScheduleVo.getStartTime(), formatter);
+            LocalDateTime endDateTime = LocalDateTime.parse(todayScheduleVo.getEndTime(), formatter);
+            for (Long id : startTimeMap.keySet()) {
+                if(todayScheduleVo.getId().equals(id)){
+                    continue;
+                }
+                LocalDateTime startTime = startTimeMap.get(id);
+                LocalDateTime endTime = endTimeMap.get(id);
+                if(LocalDateTimeUtil.isDateTimeInRange(startDateTime, startTime, endTime) || LocalDateTimeUtil.isDateTimeInRange(endDateTime, startTime, endTime)){
+                    adjustType = "冲突";
+                }
+            }
+            todayScheduleVo.setAdjustType(adjustType);
+        }
+
+        return RT.ok(list);
+    }
+
+}

+ 19 - 0
src/main/java/com/xjrsoft/module/schedule/dto/TodaySchedulePageDto.java

@@ -0,0 +1,19 @@
+package com.xjrsoft.module.schedule.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+
+/**
+ * @title: 今日安排
+ * @Author dzx
+ * @Date: 2025年3月27日
+ * @Version 1.0
+ */
+@Data
+public class TodaySchedulePageDto{
+
+    @ApiModelProperty("用户id")
+    private Long userId;
+}

+ 54 - 0
src/main/java/com/xjrsoft/module/schedule/entity/TodaySchedule.java

@@ -0,0 +1,54 @@
+package com.xjrsoft.module.schedule.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * @title: 简约系统对照表
+ * @Author dzx
+ * @Date: 2024-01-23
+ * @Version 1.0
+ */
+@Data
+@TableName("today_schedule")
+@ApiModel(value = "今日安排", description = "今日安排")
+public class TodaySchedule implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableField(fill = FieldFill.INSERT)
+    private Long id;
+
+    @ApiModelProperty("开始时间")
+    private String startTime;
+
+    @ApiModelProperty("结束时间")
+    private String endTime;
+
+    @ApiModelProperty("调整类别")
+    private String adjustType;
+
+    @ApiModelProperty("类别")
+    private String title;
+
+    @ApiModelProperty("地点")
+    private String place;
+
+    @ApiModelProperty("名称")
+    private String scheduleName;
+
+    @ApiModelProperty("类别")
+    private String category;
+
+    @ApiModelProperty("用户id")
+    private String userId;
+
+}

+ 20 - 0
src/main/java/com/xjrsoft/module/schedule/mapper/TodayScheduleMapper.java

@@ -0,0 +1,20 @@
+package com.xjrsoft.module.schedule.mapper;
+
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.schedule.dto.TodaySchedulePageDto;
+import com.xjrsoft.module.schedule.entity.TodaySchedule;
+import com.xjrsoft.module.schedule.vo.TodayScheduleVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @Author dzx
+ * @Date: 2025年3月27日
+ */
+@Mapper
+public interface TodayScheduleMapper extends MPJBaseMapper<TodaySchedule> {
+
+    List<TodayScheduleVo> getList(@Param("dto") TodaySchedulePageDto dto);
+}

+ 21 - 0
src/main/java/com/xjrsoft/module/schedule/service/ITodayScheduleService.java

@@ -0,0 +1,21 @@
+package com.xjrsoft.module.schedule.service;
+
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.schedule.dto.TodaySchedulePageDto;
+import com.xjrsoft.module.schedule.entity.TodaySchedule;
+import com.xjrsoft.module.schedule.vo.TodayScheduleVo;
+
+import java.util.List;
+
+/**
+ * @title: 今日安排
+ * @Author dzx
+ * @Date: 2025年3月27日
+ * @Version 1.0
+ */
+
+public interface ITodayScheduleService extends MPJBaseService<TodaySchedule> {
+
+    List<TodayScheduleVo> getList(TodaySchedulePageDto dto);
+
+}

+ 50 - 0
src/main/java/com/xjrsoft/module/schedule/service/impl/TodayScheduleServiceImpl.java

@@ -0,0 +1,50 @@
+package com.xjrsoft.module.schedule.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.common.enums.CourseAdjustTypeEnum;
+import com.xjrsoft.common.enums.EnabledMark;
+import com.xjrsoft.module.courseTable.entity.CourseTable;
+import com.xjrsoft.module.courseTable.service.ICourseTableService;
+import com.xjrsoft.module.organization.entity.User;
+import com.xjrsoft.module.organization.service.IUserService;
+import com.xjrsoft.module.schedule.dto.TodaySchedulePageDto;
+import com.xjrsoft.module.schedule.dto.WfCourseAdjustDto;
+import com.xjrsoft.module.schedule.entity.CourseTableBak;
+import com.xjrsoft.module.schedule.entity.TodaySchedule;
+import com.xjrsoft.module.schedule.entity.WfCourseAdjust;
+import com.xjrsoft.module.schedule.mapper.TodayScheduleMapper;
+import com.xjrsoft.module.schedule.mapper.WfCourseAdjustMapper;
+import com.xjrsoft.module.schedule.service.ICourseTableBakService;
+import com.xjrsoft.module.schedule.service.ITodayScheduleService;
+import com.xjrsoft.module.schedule.service.IWfCourseAdjustService;
+import com.xjrsoft.module.schedule.vo.TodayScheduleVo;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @Author dzx
+ * @Date: 2025年3月27日
+ * @Version 1.0
+ */
+@Service
+@AllArgsConstructor
+public class TodayScheduleServiceImpl extends MPJBaseServiceImpl<TodayScheduleMapper, TodaySchedule> implements ITodayScheduleService {
+
+    @Override
+    public List<TodayScheduleVo> getList(TodaySchedulePageDto dto) {
+        return this.baseMapper.getList(dto);
+    }
+}

+ 4 - 4
src/main/java/com/xjrsoft/module/schedule/util/DataUtil.java

@@ -625,7 +625,7 @@ public class DataUtil {
 
             String sql = "INSERT INTO course_table(id,base_semester_id,teacher_id,teacher_name,teacher_serial_no,course_id,course_name," +
                     "class_id, class_name,weeks,weeks_cn,time_period,time_number,site_id,site_name,status," +
-                    "create_date,schedule_date,jianyue_id) select " + id + String.format("%04d", count) + ","
+                    "create_date,schedule_date,jianyue_id, start_time, end_time) select " + id + String.format("%04d", count) + ","
                     + semesterMap.get(asJsonObject.get("semesterSerialNo").getAsString()) + ",";
             if (teachers.size() > 0) {
                 JsonObject teacherJson = teachers.get(0).getAsJsonObject();
@@ -647,8 +647,8 @@ public class DataUtil {
                     + (classroomMap.get(asJsonObject.get("classRoomSerialNo").getAsString()) == null ? 0 : classroomMap.get(asJsonObject.get("classRoomSerialNo").getAsString())) + ","
                     + "'" + asJsonObject.get("classRoomName").getAsString() + "',1,now(),"
                     + "'" + asJsonObject.get("scheduleDate").getAsString() + "',"
-                    + "'" + asJsonObject.get("id").getAsString() + "' FROM DUAL"
-                    + " WHERE NOT EXISTS(SELECT * FROM course_table WHERE jianyue_id = '" + asJsonObject.get("id").getAsString() + "' and status = 1)";
+                    + "'" + asJsonObject.get("id").getAsString() + "', '" + asJsonObject.get("startTime").getAsString() + "', '" + asJsonObject.get("endTime").getAsString() +"' FROM DUAL"
+                    + " WHERE NOT EXISTS(SELECT 1 FROM course_table WHERE jianyue_id = '" + asJsonObject.get("id").getAsString() + "' and status = 1)";
 //            sqls.add(updateSql);
 //            sqls.add(sql);
             SqlRunnerAdapter.db().insert(sql);
@@ -658,7 +658,7 @@ public class DataUtil {
 
     public Set<String> insertCourseTableEntiy(JsonArray data, Map<String, String> classroomMap, Map<String, String> coureseMap,
                                               Map<String, String> semesterMap, Map<String, String> teacherMap, Map<String, String> classMap
-            , Long courseReceiveMsgId, String startDate, String endDate) {
+            , String courseReceiveMsgId, String startDate, String endDate) {
         String sql = "SELECT jianyue_id FROM course_table" +
                 " where schedule_date between '" + startDate + "' and '" + endDate + "'";
         List<Map<String, Object>> oldDataList = SqlRunnerAdapter.db().selectList(sql);

+ 43 - 0
src/main/java/com/xjrsoft/module/schedule/vo/TodayScheduleVo.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.module.schedule.vo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+/**
+ * 周课表导出
+ */
+@Data
+public class TodayScheduleVo {
+
+    @TableField(fill = FieldFill.INSERT)
+    private Long id;
+
+    @ApiModelProperty("开始时间")
+    private String startTime;
+
+    @ApiModelProperty("结束时间")
+    private String endTime;
+
+    @ApiModelProperty("调整类别")
+    private String adjustType;
+
+    @ApiModelProperty("类别(冲突、调课、顶课)")
+    private String title;
+
+    @ApiModelProperty("地点")
+    private String place;
+
+    @ApiModelProperty("名称")
+    private String scheduleName;
+
+    @ApiModelProperty("类别(0:课表 1:思政德育活动 2:党建活动 3:社团活动表 4:校企合作活动 5:赛事活动 6:会议)")
+    private Integer category;
+
+    @ApiModelProperty("用户id")
+    private String userId;
+
+}

+ 4 - 0
src/main/java/com/xjrsoft/module/student/controller/BaseStudentAssessmentInspectionController.java

@@ -57,6 +57,10 @@ public class BaseStudentAssessmentInspectionController {
         if (roleList.size() == 2 && roleList.contains("TEACHER") && roleList.contains("CLASSTE")) {
             dto.setTeacherId(StpUtil.getLoginIdAsLong());
         }
+        if(!roleList.contains("BJKHGLY")){
+            dto.setCreateUserId(StpUtil.getLoginIdAsLong());
+        }
+
         Page<BaseStudentAssessmentInspectionPageVo> page = inspectionService.getPage(new Page<>(dto.getLimit(), dto.getSize()), dto);
         return RT.ok(ConventPage.getPageOutput(page, BaseStudentAssessmentInspectionPageVo.class));
     }

+ 3 - 0
src/main/java/com/xjrsoft/module/student/dto/BaseStudentAssessmentInspectionPageDto.java

@@ -42,4 +42,7 @@ public class BaseStudentAssessmentInspectionPageDto extends PageInput {
 
     @ApiModelProperty("教师id")
     private Long teacherId;
+
+    @ApiModelProperty("创建人id")
+    private Long createUserId;
 }

+ 5 - 0
src/main/java/com/xjrsoft/module/student/service/impl/BaseStudentGraduateServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.github.yulichang.base.MPJBaseServiceImpl;
 import com.xjrsoft.common.enums.ArchivesStatusEnum;
+import com.xjrsoft.module.room.mapper.RoomBedMapper;
 import com.xjrsoft.module.student.dto.AddBaseStudentGraduateDto;
 import com.xjrsoft.module.student.dto.BaseStudentGraduatePageDto;
 import com.xjrsoft.module.student.entity.BaseStudentGraduate;
@@ -40,6 +41,8 @@ public class BaseStudentGraduateServiceImpl extends MPJBaseServiceImpl<BaseStude
 
     private final IFileService fileService;
 
+    private final RoomBedMapper roomBedMapper;
+
     @Override
     public Page<BaseStudentGraduatePageVo> getPage(Page<BaseStudentGraduatePageDto> page, BaseStudentGraduatePageDto dto) {
         Page<BaseStudentGraduatePageVo> voPage = baseStudentGraduateMapper.getPage(page, dto);
@@ -79,6 +82,8 @@ public class BaseStudentGraduateServiceImpl extends MPJBaseServiceImpl<BaseStude
             setArchivesStatus(ArchivesStatusEnum.FB2907.getCode());
         }}, baseStudentSchoolRollLambdaQueryWrapper);
 
+        //清空该学生的床位信息
+        roomBedMapper.clearBedInfoByStudentUserId(dto.getUserId(), StpUtil.getLoginIdAsLong());
         //保存毕业信息
         this.save(baseStudentGraduate);
         return true;

+ 4 - 1
src/main/java/com/xjrsoft/module/student/service/impl/BaseStudentSchoolRollServiceImpl.java

@@ -331,7 +331,10 @@ public class BaseStudentSchoolRollServiceImpl extends MPJBaseServiceImpl<BaseStu
 
         //将学籍信息改为在读
         BaseStudentSchoolRoll schoolRoll = this.getOne(
-                new QueryWrapper<BaseStudentSchoolRoll>().lambda()
+                new MPJLambdaWrapper<BaseStudentSchoolRoll>()
+                        .disableLogicDel()
+                        .select(BaseStudentSchoolRoll::getId)
+                        .select(BaseStudentSchoolRoll.class, x -> VoToColumnUtil.fieldsToColumns(BaseStudentSchoolRoll.class).contains(x.getProperty()))
                         .eq(BaseStudentSchoolRoll::getUserId, userId)
         );
         UpdateWrapper<BaseStudentSchoolRoll> updateRoll = new UpdateWrapper<>();

+ 137 - 0
src/main/java/com/xjrsoft/module/teacher/controller/BaseTeacherChangeRecordController.java

@@ -0,0 +1,137 @@
+package com.xjrsoft.module.teacher.controller;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import com.xjrsoft.common.constant.GlobalConstant;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.xjrsoft.common.page.ConventPage;
+import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.model.result.RT;
+import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.teacher.dto.AddBaseTeacherChangeRecordDto;
+import com.xjrsoft.module.teacher.dto.UpdateBaseTeacherChangeRecordDto;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.xjrsoft.common.annotation.XjrLog;
+
+import com.xjrsoft.module.teacher.dto.BaseTeacherChangeRecordPageDto;
+import com.xjrsoft.module.teacher.entity.BaseTeacherChangeRecord;
+import com.xjrsoft.module.teacher.entity.XjrUser;
+import com.xjrsoft.module.teacher.service.IBaseTeacherChangeRecordService;
+import com.xjrsoft.module.teacher.vo.BaseTeacherChangeRecordPageVo;
+
+import com.xjrsoft.module.teacher.vo.BaseTeacherChangeRecordVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@RestController
+@RequestMapping("/teacher" + "/baseTeacherChangeRecord")
+@Api(value = "/teacher"  + "/baseTeacherChangeRecord",tags = "教职工异动记录代码")
+@AllArgsConstructor
+public class BaseTeacherChangeRecordController {
+
+
+    private final IBaseTeacherChangeRecordService baseTeacherChangeRecordService;
+
+    @GetMapping(value = "/page")
+    @ApiOperation(value="教职工异动记录列表(分页)")
+    @SaCheckPermission("baseteacherchangerecord:detail")
+    @XjrLog(value = "教职工异动记录列表(分页)")
+    public RT<PageOutput<BaseTeacherChangeRecordPageVo>> page(@Valid BaseTeacherChangeRecordPageDto dto) {
+        MPJLambdaWrapper<BaseTeacherChangeRecord> queryWrapper = new MPJLambdaWrapper<>();
+        queryWrapper
+                .select(BaseTeacherChangeRecord::getId)
+                .select(BaseTeacherChangeRecord.class, x -> VoToColumnUtil.fieldsToColumns(BaseTeacherChangeRecordPageVo.class).contains(x.getProperty()))
+                .leftJoin(XjrUser.class, XjrUser::getId, BaseTeacherChangeRecord::getUserId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, BaseTeacherChangeRecordPageVo::getName)
+                                .selectAs(XjrUser::getCredentialNumber, BaseTeacherChangeRecordPageVo::getCredentialNumber)
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getGender,
+                                        wrap -> wrap
+                                                .selectAs(DictionaryDetail::getName, BaseTeacherChangeRecordPageVo::getGenderCn)
+                                )
+                                .like(StringUtils.isNotEmpty(dto.getName()), XjrUser::getName, dto.getName())
+                                .eq(StringUtils.isNotEmpty(dto.getCredentialNumber()), XjrUser::getCredentialNumber, dto.getCredentialNumber())
+                )
+                .leftJoin(XjrUser.class, XjrUser::getId, BaseTeacherChangeRecord::getCreateUserId,
+                        wrapper -> wrapper
+                                .selectAs(XjrUser::getName, BaseTeacherChangeRecordPageVo::getCreateUserIdCn)
+                                .like(StringUtils.isNotEmpty(dto.getCreateUserIdCn()), XjrUser::getName, dto.getCreateUserIdCn())
+                )
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacherChangeRecord::getChangeType,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, BaseTeacherChangeRecordPageVo::getChangeTypeCn)
+                )
+                .eq(StringUtils.isNotEmpty(dto.getChangeType()), BaseTeacherChangeRecord::getChangeType, dto.getChangeType())
+                .ge(ObjectUtils.isNotEmpty(dto.getStartCreateDate()), BaseTeacherChangeRecord::getCreateDate, dto.getStartCreateDate())
+                .le(ObjectUtils.isNotEmpty(dto.getEndCreateDate()), BaseTeacherChangeRecord::getCreateDate, dto.getEndCreateDate())
+                .orderByDesc(BaseTeacherChangeRecord::getCreateDate)
+        ;
+        IPage<BaseTeacherChangeRecordPageVo> page = baseTeacherChangeRecordService.selectJoinListPage(ConventPage.getPage(dto), BaseTeacherChangeRecordPageVo.class, queryWrapper);
+        PageOutput<BaseTeacherChangeRecordPageVo> pageOutput = ConventPage.getPageOutput(page, BaseTeacherChangeRecordPageVo.class);
+        return RT.ok(pageOutput);
+    }
+
+    @GetMapping(value = "/info")
+    @ApiOperation(value="根据id查询教职工异动记录信息")
+    @SaCheckPermission("baseteacherchangerecord:detail")
+    @XjrLog(value = "根据id查询教职工异动记录信息")
+    public RT<BaseTeacherChangeRecordVo> info(@RequestParam Long id){
+        BaseTeacherChangeRecord baseTeacherChangeRecord = baseTeacherChangeRecordService.getById(id);
+        if (baseTeacherChangeRecord == null) {
+           return RT.error("找不到此数据!");
+        }
+        return RT.ok(BeanUtil.toBean(baseTeacherChangeRecord, BaseTeacherChangeRecordVo.class));
+    }
+
+
+    @PostMapping
+    @ApiOperation(value = "新增教职工异动记录")
+    @SaCheckPermission("baseteacherchangerecord:add")
+    @XjrLog(value = "新增教职工异动记录")
+    public RT<Boolean> add(@Valid @RequestBody AddBaseTeacherChangeRecordDto dto){
+        BaseTeacherChangeRecord baseTeacherChangeRecord = BeanUtil.toBean(dto, BaseTeacherChangeRecord.class);
+        boolean isSuccess = baseTeacherChangeRecordService.save(baseTeacherChangeRecord);
+    return RT.ok(isSuccess);
+    }
+
+    @PutMapping
+    @ApiOperation(value = "修改教职工异动记录")
+    @SaCheckPermission("baseteacherchangerecord:edit")
+    @XjrLog(value = "修改教职工异动记录")
+    public RT<Boolean> update(@Valid @RequestBody UpdateBaseTeacherChangeRecordDto dto){
+
+        BaseTeacherChangeRecord baseTeacherChangeRecord = BeanUtil.toBean(dto, BaseTeacherChangeRecord.class);
+        return RT.ok(baseTeacherChangeRecordService.updateById(baseTeacherChangeRecord));
+
+    }
+
+    @DeleteMapping
+    @ApiOperation(value = "删除教职工异动记录")
+    @SaCheckPermission("baseteacherchangerecord:delete")
+    @XjrLog(value = "删除教职工异动记录")
+    public RT<Boolean> delete(@Valid @RequestBody List<Long> ids){
+        return RT.ok(baseTeacherChangeRecordService.removeBatchByIds(ids));
+
+    }
+
+}

+ 62 - 6
src/main/java/com/xjrsoft/module/teacher/controller/TeacherbaseManagerController.java

@@ -5,6 +5,7 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.excel.EasyExcel;
+import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -23,11 +24,13 @@ import com.xjrsoft.module.organization.entity.UserPostRelation;
 import com.xjrsoft.module.organization.service.IUserDeptRelationService;
 import com.xjrsoft.module.organization.service.IUserPostRelationService;
 import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.system.entity.DictionaryItem;
 import com.xjrsoft.module.system.service.IDictionarydetailService;
 import com.xjrsoft.module.teacher.dto.AddXjrUserDto;
 import com.xjrsoft.module.teacher.dto.UpdateXjrUserDto;
 import com.xjrsoft.module.teacher.dto.XjrUserPageDto;
 import com.xjrsoft.module.teacher.entity.BaseTeacher;
+import com.xjrsoft.module.teacher.entity.BaseTeacherRegular;
 import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
 import com.xjrsoft.module.teacher.vo.XjrUserPageVo;
@@ -35,12 +38,16 @@ import com.xjrsoft.module.teacher.vo.XjrUserVo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.validation.Valid;
 import java.io.IOException;
 import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -59,16 +66,15 @@ public class TeacherbaseManagerController {
 
 
     private final ITeacherbaseManagerService teacherbaseManagerService;
-    private final IDictionarydetailService dictionarydetailService;
     private final IUserDeptRelationService userDeptRelationService;
     private final IUserPostRelationService userPostRelationService;
+    private final IDictionarydetailService dictionarydetailService;
 
     @GetMapping(value = "/page")
     @ApiOperation(value = "XjrUser列表(分页)")
     @SaCheckPermission("teacherbasemanager:detail")
     @XjrLog(value = "XjrUser列表(分页)")
     public R page(@Valid XjrUserPageDto dto) {
-
         MPJLambdaWrapper<XjrUser> queryWrapper = MPJWrappers.<XjrUser>lambdaJoin()
                 .disableSubLogicDel()
                 .like(StrUtil.isNotBlank(dto.getUserName()), XjrUser::getUserName, dto.getUserName())
@@ -77,12 +83,30 @@ public class TeacherbaseManagerController {
                 .like(StrUtil.isNotBlank(dto.getEmail()), XjrUser::getEmail, dto.getEmail())
 
                 .orderByDesc(XjrUser::getId)
+
                 .select(XjrUser::getId)
                 .select(XjrUser.class, x -> VoToColumnUtil.fieldsToColumns(XjrUserPageVo.class).contains(x.getProperty()))
-                .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId)
-                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getJobState, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getJobState))
-                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getCredentialType, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getCredentialType))
-                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getEmployWay, ext -> ext.selectAs(DictionaryDetail::getName, XjrUserPageVo::getEmployWay))
+
+                .innerJoin(BaseTeacher.class, BaseTeacher::getUserId, XjrUser::getId,
+                        wra -> wra
+                                .selectAs(BaseTeacher::getJoinTime, XjrUserPageVo::getJoinTime)
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getJobState,
+                                        ext -> ext
+                                                .selectAs(DictionaryDetail::getName, XjrUserPageVo::getJobStateCn)
+                                )
+                                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, BaseTeacher::getEmployType,
+                                        ext -> ext
+                                                .selectAs(DictionaryDetail::getName, XjrUserPageVo::getEmployTypeCn)
+                                )
+                        )
+                .leftJoin(BaseTeacherRegular.class, BaseTeacherRegular::getUserId, XjrUser::getId,
+                        ext -> ext
+                                .selectAs(BaseTeacherRegular::getTeachingStatus, XjrUserPageVo::getTeachingStatus)
+                )
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, XjrUser::getCredentialType,
+                        ext -> ext
+                                .selectAs(DictionaryDetail::getName, XjrUserPageVo::getCredentialType)
+                )
 
                 .selectAsClass(BaseTeacher.class, XjrUserPageVo.class);
 
@@ -96,8 +120,40 @@ public class TeacherbaseManagerController {
 
         PageOutput<XjrUserPageVo> pageOutput = ConventPage.getPageOutput(page, XjrUserPageVo.class);
 
+        // 处理任课状况字典值
+        List<DictionaryDetail> detailList = dictionarydetailService.list(
+                new MPJLambdaWrapper<DictionaryDetail>()
+                        .select(DictionaryDetail::getId)
+                        .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryDetail.class).contains(x.getProperty()))
+                        .leftJoin(DictionaryItem.class, DictionaryItem::getId, DictionaryDetail::getItemId)
+                        .eq(DictionaryItem::getCode, "teaching_status")
+        );
+
+        Map<String, String> dictionaryDetailMap = new HashMap<>();
+        for (DictionaryDetail dictionaryDetail : detailList) {
+            dictionaryDetailMap.put(dictionaryDetail.getCode(), dictionaryDetail.getName());
+        }
+
         for (XjrUserPageVo record : pageOutput.getList()) {
             record.setGenderCn(GenderDictionaryEnum.getValue(record.getGender()));
+            // 处理任课状况
+            if(ObjectUtils.isNotEmpty(record.getTeachingStatus()) && ObjectUtils.isNotEmpty(dictionaryDetailMap)){
+                JSONArray teachingStatus = record.getTeachingStatus();
+
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < teachingStatus.size(); i++) {
+                    String code = teachingStatus.getString(i);
+                    if(StringUtils.isEmpty(code)){
+                        continue;
+                    }
+                    String name = dictionaryDetailMap.get(code);
+                    sb.append(name).append(",");
+                }
+                if(sb.length() > 0){
+                    sb.setLength(sb.length() - 1);
+                }
+                record.setTeachingStatusCn(sb.toString());
+            }
         }
 
         return R.ok(pageOutput);

+ 48 - 0
src/main/java/com/xjrsoft/module/teacher/dto/AddBaseTeacherChangeRecordDto.java

@@ -0,0 +1,48 @@
+package com.xjrsoft.module.teacher.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+public class AddBaseTeacherChangeRecordDto implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 变更教职工主键id
+    */
+    @ApiModelProperty("变更教职工主键id")
+    private Long userId;
+    /**
+    * 异动类型(xjr_dictionary_item[tea_change_type])
+    */
+    @ApiModelProperty("异动类型(xjr_dictionary_item[tea_change_type])")
+    private String changeType;
+    /**
+    * 新的在职状态
+    */
+    @ApiModelProperty("新的在职状态")
+    private String newJobState;
+    /**
+    * 旧的在职状态
+    */
+    @ApiModelProperty("旧的在职状态")
+    private String oldJobState;
+
+}

+ 43 - 0
src/main/java/com/xjrsoft/module/teacher/dto/BaseTeacherChangeRecordPageDto.java

@@ -0,0 +1,43 @@
+package com.xjrsoft.module.teacher.dto;
+
+import com.xjrsoft.common.page.PageInput;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+
+/**
+* @title: 教职工异动记录分页查询入参
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class BaseTeacherChangeRecordPageDto extends PageInput {
+
+    @ApiModelProperty("证件号码")
+    private String credentialNumber;
+
+    @ApiModelProperty("姓名")
+    private String name;
+
+    @ApiModelProperty("异动类型(xjr_dictionary_item[tea_change_type])")
+    private String changeType;
+
+    @ApiModelProperty("异动时间")
+    private LocalDate startCreateDate;
+
+    @ApiModelProperty("异动时间")
+    private LocalDate endCreateDate;
+
+    @ApiModelProperty("操作人")
+    private String createUserIdCn;
+}

+ 32 - 0
src/main/java/com/xjrsoft/module/teacher/dto/UpdateBaseTeacherChangeRecordDto.java

@@ -0,0 +1,32 @@
+package com.xjrsoft.module.teacher.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.List;
+import java.util.Date;
+
+
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+public class UpdateBaseTeacherChangeRecordDto extends AddBaseTeacherChangeRecordDto {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+}

+ 98 - 0
src/main/java/com/xjrsoft/module/teacher/entity/BaseTeacherChangeRecord.java

@@ -0,0 +1,98 @@
+package com.xjrsoft.module.teacher.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.github.yulichang.annotation.EntityMapping;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+@TableName("base_teacher_change_record")
+@ApiModel(value = "base_teacher_change_record", description = "教职工异动记录")
+public class BaseTeacherChangeRecord 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 Date createDate;
+    /**
+    * 修改人
+    */
+    @ApiModelProperty("修改人")
+    @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
+    */
+    @ApiModelProperty("变更教职工主键id")
+    private Long userId;
+    /**
+    * 异动类型(xjr_dictionary_item[tea_change_type])
+    */
+    @ApiModelProperty("异动类型(xjr_dictionary_item[tea_change_type])")
+    private String changeType;
+    /**
+    * 新的在职状态
+    */
+    @ApiModelProperty("新的在职状态")
+    private String newJobState;
+    /**
+    * 旧的在职状态
+    */
+    @ApiModelProperty("旧的在职状态")
+    private String oldJobState;
+
+
+}

+ 0 - 2
src/main/java/com/xjrsoft/module/teacher/entity/BaseTeacherRegular.java

@@ -116,6 +116,4 @@ public class BaseTeacherRegular implements Serializable {
      */
     @ApiModelProperty("任教学科(base_course_subject)")
     private Long courseSubjectId;
-
-
 }

+ 178 - 0
src/main/java/com/xjrsoft/module/teacher/entity/WfTeacherDepart.java

@@ -0,0 +1,178 @@
+package com.xjrsoft.module.teacher.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.github.yulichang.annotation.EntityMapping;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import java.io.Serializable;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+
+/**
+* @title: 教职工离职
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+@TableName("wf_teacher_depart")
+@ApiModel(value = "wf_teacher_depart", description = "教职工离职")
+public class WfTeacherDepart 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 Date createDate;
+    /**
+    * 修改人
+    */
+    @ApiModelProperty("修改人")
+    @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;
+    /**
+    * 序号
+    */
+    @ApiModelProperty("序号")
+    private Integer sortCode;
+    /**
+    * 申请人
+    */
+    @ApiModelProperty("申请人")
+    private Long applicantUserId;
+    /**
+    * 性别 男, 女
+    */
+    @ApiModelProperty("性别 男, 女")
+    private String sex;
+    /**
+    * 部门名称
+    */
+    @ApiModelProperty("部门名称")
+    private String deptName;
+    /**
+    * 编制性质(编内、编外)
+    */
+    @ApiModelProperty("编制性质(编内、编外)")
+    private String natureOrganization;
+    /**
+    * 是否工会会员(xjr_dictionary_item[judgment_method_1])
+    */
+    @ApiModelProperty("是否工会会员(xjr_dictionary_item[judgment_method_1])")
+    private String isUnionMember;
+    /**
+    * 工作岗位(xjr_dictionary_item[depart_post])
+    */
+    @ApiModelProperty("工作岗位(xjr_dictionary_item[depart_post])")
+    private String job;
+    /**
+    * 是否班主任(xjr_dictionary_item[judgment_method_1])
+    */
+    @ApiModelProperty("是否班主任(xjr_dictionary_item[judgment_method_1])")
+    private String isHeadTeacher;
+    /**
+    * 专业部-办公室钥匙移交(已交接、未交接、未借用)
+    */
+    @ApiModelProperty("专业部-办公室钥匙移交(已交接、未交接、未借用)")
+    private String hPdOfficeKey;
+    /**
+    * 专业部-教具、设施等移交(已交接、未交接、未借用)
+    */
+    @ApiModelProperty("专业部-教具、设施等移交(已交接、未交接、未借用)")
+    private String hPdFacilities;
+    /**
+    * 专业部-其它
+    */
+    @ApiModelProperty("专业部-其它")
+    private String hPdOther;
+    /**
+    * 教务处-借阅图书归还(已交接、未交接、未借用)
+    */
+    @ApiModelProperty("教务处-借阅图书归还(已交接、未交接、未借用)")
+    private String hDoBooks;
+    /**
+    * 教务处-借用教室钥匙(已交接、未交接、未借用)
+    */
+    @ApiModelProperty("教务处-借用教室钥匙(已交接、未交接、未借用)")
+    private String hDoClassroomKey;
+    /**
+    * 教务处-其它
+    */
+    @ApiModelProperty("教务处-其它")
+    private String hDoOther;
+    /**
+    * 德育处-借用军训服装(已交接、未交接、未借用)
+    */
+    @ApiModelProperty("德育处-借用军训服装(已交接、未交接、未借用)")
+    private String hMeMilitaryUniform;
+    /**
+    * 德育处-其它
+    */
+    @ApiModelProperty("德育处-其它")
+    private String hMeOther;
+    /**
+    * 财务后勤处-办公电脑(已交接、未交接、未借用)
+    */
+    @ApiModelProperty("财务后勤处-办公电脑(已交接、未交接、未借用)")
+    private String hFlComputer;
+    /**
+    * 安保处-其它
+    */
+    @ApiModelProperty("安保处-其它")
+    private String hSdOther;
+    /**
+    * 附件文件id
+    */
+    @ApiModelProperty("附件文件id")
+    private Long fileId;
+    /**
+    * 状态(1:结束 0:未结束)
+    */
+    @ApiModelProperty("状态(1:结束 0:未结束)")
+    private Integer status;
+
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/teacher/mapper/BaseTeacherChangeRecordMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.teacher.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.teacher.entity.BaseTeacherChangeRecord;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Mapper
+public interface BaseTeacherChangeRecordMapper extends MPJBaseMapper<BaseTeacherChangeRecord> {
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/teacher/mapper/WfTeacherDepartMapper.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.teacher.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.github.yulichang.base.MPJBaseMapper;
+import com.xjrsoft.module.teacher.entity.WfTeacherDepart;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+* @title: 教职工离职
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Mapper
+public interface WfTeacherDepartMapper extends MPJBaseMapper<WfTeacherDepart> {
+
+}

+ 17 - 0
src/main/java/com/xjrsoft/module/teacher/service/IBaseTeacherChangeRecordService.java

@@ -0,0 +1,17 @@
+package com.xjrsoft.module.teacher.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.github.yulichang.base.MPJBaseService;
+import com.xjrsoft.module.teacher.entity.BaseTeacherChangeRecord;
+import lombok.Data;
+import java.util.List;
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+
+public interface IBaseTeacherChangeRecordService extends MPJBaseService<BaseTeacherChangeRecord> {
+}

+ 2 - 0
src/main/java/com/xjrsoft/module/teacher/service/ITeacherbaseManagerService.java

@@ -43,4 +43,6 @@ public interface ITeacherbaseManagerService extends MPJBaseService<XjrUser> {
     Boolean importData(List<Map<Integer, Object>> excelDataList);
 
     void changeIsNormal(String jobState, Integer isNormal);
+
+    void teacherDepartDataHandle(Long formId);
 }

+ 25 - 0
src/main/java/com/xjrsoft/module/teacher/service/impl/BaseTeacherChangeRecordServiceImpl.java

@@ -0,0 +1,25 @@
+package com.xjrsoft.module.teacher.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.github.yulichang.base.MPJBaseServiceImpl;
+import com.xjrsoft.module.teacher.entity.BaseTeacherChangeRecord;
+import com.xjrsoft.module.teacher.mapper.BaseTeacherChangeRecordMapper;
+import com.xjrsoft.module.teacher.service.IBaseTeacherChangeRecordService;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+
+/**
+* @title: 教职工异动记录
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Service
+@AllArgsConstructor
+public class BaseTeacherChangeRecordServiceImpl extends MPJBaseServiceImpl<BaseTeacherChangeRecordMapper, BaseTeacherChangeRecord> implements IBaseTeacherChangeRecordService {
+}

+ 165 - 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.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.convert.Convert;
@@ -14,21 +15,33 @@ import com.xjrsoft.common.constant.GlobalConstant;
 import com.xjrsoft.common.enums.DeleteMark;
 import com.xjrsoft.common.enums.GenderDictionaryEnum;
 import com.xjrsoft.common.enums.RoleEnum;
+import com.xjrsoft.common.enums.TeaChangeTypeEnum;
+import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.utils.RedisUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.config.CommonPropertiesConfig;
+import com.xjrsoft.module.liteflow.node.WfTeacherDepartNode;
 import com.xjrsoft.module.organization.entity.*;
 import com.xjrsoft.module.organization.mapper.UserDeptRelationMapper;
 import com.xjrsoft.module.organization.mapper.UserRoleRelationMapper;
 import com.xjrsoft.module.organization.service.*;
 import com.xjrsoft.module.system.entity.DictionaryDetail;
+import com.xjrsoft.module.system.entity.DictionaryItem;
 import com.xjrsoft.module.system.service.IDictionarydetailService;
 import com.xjrsoft.module.teacher.dto.AddXjrUserDto;
 import com.xjrsoft.module.teacher.dto.UpdateXjrUserDto;
 import com.xjrsoft.module.teacher.entity.*;
 import com.xjrsoft.module.teacher.mapper.*;
+import com.xjrsoft.module.teacher.service.IBaseTeacherChangeRecordService;
 import com.xjrsoft.module.teacher.service.ITeacherbaseManagerService;
+import com.xjrsoft.module.textbook.entity.WfTextbookRecede;
+import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
+import com.xjrsoft.module.workflow.mapper.WorkflowFormRelationMapper;
 import lombok.AllArgsConstructor;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.camunda.bpm.engine.history.HistoricProcessInstance;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -65,8 +78,15 @@ public class TeacherbaseManagerServiceImpl extends MPJBaseServiceImpl<XjrUserMap
     private final IDictionarydetailService dictionaryService;
     private final IDepartmentService departmentService;
     private final IPostService postService;
+    private final BaseTeacherMapper baseTeacherMapper;
     private IDictionarydetailService dictionarydetailService;
 
+    private WfTeacherDepartMapper wfTeacherDepartMapper;
+
+    private BaseTeacherChangeRecordMapper baseTeacherChangeRecordMapper;
+
+    private WorkflowFormRelationMapper workflowFormRelationMapper;
+
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -181,6 +201,64 @@ public class TeacherbaseManagerServiceImpl extends MPJBaseServiceImpl<XjrUserMap
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Boolean update(UpdateXjrUserDto dto) {
+        XjrUser old = this.getByIdDeep(dto.getId());
+        if(ObjectUtils.isEmpty(old)){
+            throw new MyException("教职工信息不存在");
+        }
+
+        // 处理在职状态
+        // 获取字典值
+        List<DictionaryDetail> detailList = dictionarydetailService.list(
+                new MPJLambdaWrapper<DictionaryDetail>()
+                        .select(DictionaryDetail::getId)
+                        .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryDetail.class).contains(x.getProperty()))
+                        .leftJoin(DictionaryItem.class, DictionaryItem::getId, DictionaryDetail::getItemId)
+                        .eq(DictionaryItem::getCode, "job_state")
+        );
+
+        Map<String, String> dictionaryDetailMap = detailList.stream()
+                .collect(Collectors.toMap(DictionaryDetail::getCode, DictionaryDetail::getName));
+
+        // 定义常量
+        final String NO_JOB_STATE = "无在职状态";
+
+        // 获取新旧在职状态
+        String oldJobState = null;
+        String newJobState = null;
+
+        if (CollectionUtils.isNotEmpty(old.getBaseTeacherList()) && StringUtils.isNotEmpty(old.getBaseTeacherList().get(0).getJobState())) {
+            oldJobState = old.getBaseTeacherList().get(0).getJobState();
+        }
+
+        if (CollectionUtils.isNotEmpty(dto.getBaseTeacherList()) && StringUtils.isNotEmpty(dto.getBaseTeacherList().get(0).getJobState())) {
+            newJobState = dto.getBaseTeacherList().get(0).getJobState();
+        }
+
+        // 只有在职状态被修改时,才触发 insert
+        if (!Objects.equals(oldJobState, newJobState)) {
+            BaseTeacherChangeRecord insetBaseTeacherChangeRecord = new BaseTeacherChangeRecord();
+            insetBaseTeacherChangeRecord.setCreateUserId(StpUtil.getLoginIdAsLong());
+            insetBaseTeacherChangeRecord.setCreateDate(new Date());
+            insetBaseTeacherChangeRecord.setUserId(dto.getId());
+            insetBaseTeacherChangeRecord.setChangeType(TeaChangeTypeEnum.TCT0001.getCode());
+
+            // 设置旧状态
+            if (StringUtils.isNotEmpty(oldJobState)) {
+                insetBaseTeacherChangeRecord.setOldJobState(dictionaryDetailMap.getOrDefault(oldJobState, oldJobState));
+            } else {
+                insetBaseTeacherChangeRecord.setOldJobState(NO_JOB_STATE);
+            }
+
+            // 设置新状态
+            if (StringUtils.isNotEmpty(newJobState)) {
+                insetBaseTeacherChangeRecord.setNewJobState(dictionaryDetailMap.getOrDefault(newJobState, newJobState));
+            } else {
+                insetBaseTeacherChangeRecord.setNewJobState(NO_JOB_STATE);
+            }
+
+            // 插入变更记录
+            baseTeacherChangeRecordMapper.insert(insetBaseTeacherChangeRecord);
+        }
 
         XjrUser xjrUser = BeanUtil.toBean(dto, XjrUser.class);
 
@@ -645,4 +723,91 @@ public class TeacherbaseManagerServiceImpl extends MPJBaseServiceImpl<XjrUserMap
         }
 
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void teacherDepartDataHandle(Long formId) {
+        WfTeacherDepart wfTextbookRecede = wfTeacherDepartMapper.selectById(formId);
+
+        Date nowDate = new Date();
+
+        // 根据数据id找到所在流程得状态
+        WorkflowFormRelation workflowFormRelation = workflowFormRelationMapper.selectOne(
+                Wrappers.lambdaQuery(WorkflowFormRelation.class)
+                        .eq(WorkflowFormRelation::getFormKeyValue, formId)
+        );
+
+        if (ObjectUtils.isNotEmpty(wfTextbookRecede)
+                && ObjectUtils.isNotEmpty(workflowFormRelation)
+                && HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState())
+        ) {
+            XjrUser old = this.getByIdDeep(wfTextbookRecede.getApplicantUserId());
+            if(ObjectUtils.isEmpty(old)){
+                throw new MyException("教职工信息不存在");
+            }
+
+            // 处理在职状态
+            // 更新教职工在职状态
+            List<BaseTeacher> baseTeacherList = old.getBaseTeacherList();
+            BaseTeacher updateBaseTeacher;
+            for (BaseTeacher baseTeacher : baseTeacherList){
+                updateBaseTeacher = new BaseTeacher();
+                updateBaseTeacher.setId(baseTeacher.getId());
+                updateBaseTeacher.setJobState("JOB_LZ");
+                baseTeacherMapper.updateById(updateBaseTeacher);
+            }
+
+            // 处理变更记录
+            // 获取字典值
+            List<DictionaryDetail> detailList = dictionarydetailService.list(
+                    new MPJLambdaWrapper<DictionaryDetail>()
+                            .select(DictionaryDetail::getId)
+                            .select(DictionaryDetail.class, x -> VoToColumnUtil.fieldsToColumns(DictionaryDetail.class).contains(x.getProperty()))
+                            .leftJoin(DictionaryItem.class, DictionaryItem::getId, DictionaryDetail::getItemId)
+                            .eq(DictionaryItem::getCode, "job_state")
+            );
+
+            Map<String, String> dictionaryDetailMap = detailList.stream()
+                    .collect(Collectors.toMap(DictionaryDetail::getCode, DictionaryDetail::getName));
+
+            // 定义常量
+            final String NO_JOB_STATE = "无在职状态";
+
+            // 获取新旧在职状态
+            String oldJobState = null;
+            String newJobState = null;
+
+            if (CollectionUtils.isNotEmpty(old.getBaseTeacherList()) && StringUtils.isNotEmpty(old.getBaseTeacherList().get(0).getJobState())) {
+                oldJobState = old.getBaseTeacherList().get(0).getJobState();
+            }
+
+            newJobState = "JOB_LZ";
+
+            // 只有在职状态被修改时,才触发 insert
+            if (!Objects.equals(oldJobState, newJobState)) {
+                BaseTeacherChangeRecord insetBaseTeacherChangeRecord = new BaseTeacherChangeRecord();
+                insetBaseTeacherChangeRecord.setCreateUserId(StpUtil.getLoginIdAsLong());
+                insetBaseTeacherChangeRecord.setCreateDate(new Date());
+                insetBaseTeacherChangeRecord.setUserId(wfTextbookRecede.getApplicantUserId());
+                insetBaseTeacherChangeRecord.setChangeType(TeaChangeTypeEnum.TCT0001.getCode());
+
+                // 设置旧状态
+                if (StringUtils.isNotEmpty(oldJobState)) {
+                    insetBaseTeacherChangeRecord.setOldJobState(dictionaryDetailMap.getOrDefault(oldJobState, oldJobState));
+                } else {
+                    insetBaseTeacherChangeRecord.setOldJobState(NO_JOB_STATE);
+                }
+
+                // 设置新状态
+                if (StringUtils.isNotEmpty(newJobState)) {
+                    insetBaseTeacherChangeRecord.setNewJobState(dictionaryDetailMap.getOrDefault(newJobState, newJobState));
+                } else {
+                    insetBaseTeacherChangeRecord.setNewJobState(NO_JOB_STATE);
+                }
+
+                // 插入变更记录
+                baseTeacherChangeRecordMapper.insert(insetBaseTeacherChangeRecord);
+            }
+        }
+    }
 }

+ 73 - 0
src/main/java/com/xjrsoft/module/teacher/vo/BaseTeacherChangeRecordPageVo.java

@@ -0,0 +1,73 @@
+package com.xjrsoft.module.teacher.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import com.xjrsoft.common.annotation.Trans;
+import com.xjrsoft.common.enums.TransType;
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+* @title: 教职工异动记录分页列表出参
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+public class BaseTeacherChangeRecordPageVo {
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private String id;
+
+    /**
+    * 变更教职工主键id
+    */
+    @ApiModelProperty("变更教职工主键id")
+    private Long userId;
+
+    @ApiModelProperty("姓名")
+    private String name;
+
+    @ApiModelProperty("性别")
+    private String genderCn;
+
+    @ApiModelProperty("证件号码")
+    private String credentialNumber;
+
+    @ApiModelProperty("异动时间")
+    private Date createDate;
+
+    @ApiModelProperty("操作人")
+    private Long createUserId;
+
+    @ApiModelProperty("操作人")
+    private String createUserIdCn;
+
+    /**
+    * 异动类型(xjr_dictionary_item[tea_change_type])
+    */
+    @ApiModelProperty("异动类型(xjr_dictionary_item[tea_change_type])")
+    private String changeType;
+    /**
+     * 异动类型(xjr_dictionary_item[tea_change_type])
+     */
+    @ApiModelProperty("异动类型(xjr_dictionary_item[tea_change_type])")
+    private String changeTypeCn;
+    /**
+    * 新的在职状态
+    */
+    @ApiModelProperty("新的在职状态")
+    private String newJobState;
+    /**
+    * 旧的在职状态
+    */
+    @ApiModelProperty("旧的在职状态")
+    private String oldJobState;
+}

+ 49 - 0
src/main/java/com/xjrsoft/module/teacher/vo/BaseTeacherChangeRecordVo.java

@@ -0,0 +1,49 @@
+package com.xjrsoft.module.teacher.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalTime;
+import java.time.LocalDateTime;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Date;
+
+/**
+* @title: 教职工异动记录表单出参
+* @Author phoenix
+* @Date: 2025-03-24
+* @Version 1.0
+*/
+@Data
+public class BaseTeacherChangeRecordVo {
+
+    /**
+    * 主键编号
+    */
+    @ApiModelProperty("主键编号")
+    private Long id;
+    /**
+    * 变更教职工主键id
+    */
+    @ApiModelProperty("变更教职工主键id")
+    private Long userId;
+    /**
+    * 异动类型(xjr_dictionary_item[tea_change_type])
+    */
+    @ApiModelProperty("异动类型(xjr_dictionary_item[tea_change_type])")
+    private String changeType;
+    /**
+    * 新的在职状态
+    */
+    @ApiModelProperty("新的在职状态")
+    private String newJobState;
+    /**
+    * 旧的在职状态
+    */
+    @ApiModelProperty("旧的在职状态")
+    private String oldJobState;
+
+
+
+}

+ 34 - 2
src/main/java/com/xjrsoft/module/teacher/vo/XjrUserPageVo.java

@@ -1,8 +1,13 @@
 package com.xjrsoft.module.teacher.vo;
 
+import com.alibaba.fastjson.JSONArray;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.Date;
+
 /**
  * @title: 分页列表出参
  * @Author 管理员
@@ -79,14 +84,41 @@ public class XjrUserPageVo {
     @ApiModelProperty("在职状态")
     private String jobState;
     /**
-     * 聘用方式
+     * 在职状态
      */
-    @ApiModelProperty("聘用方式")
+    @ApiModelProperty("在职状态")
+    private String jobStateCn;
+    /**
+     * 聘用方式(xjr_dictionary_item[employ_type])上级聘用类型
+     */
+    @ApiModelProperty("聘用方式(xjr_dictionary_item[employ_type])上级聘用类型")
     private String employWay;
+    /**
+     * 聘用类型(xjr_dictionary_item[employ_type])
+     */
+    @ApiModelProperty("聘用类型(xjr_dictionary_item[employ_type])")
+    private String employType;
+    /**
+     * 聘用方式(xjr_dictionary_item[employ_type])上级聘用类型
+     */
+    @ApiModelProperty("聘用方式(xjr_dictionary_item[employ_type])上级聘用类型")
+    private String employTypeCn;
     /**
      * 手机号
      */
     @ApiModelProperty("手机号")
     private String mobile;
+    /**
+     * 来校年月
+     */
+    @ApiModelProperty("来校年月")
+    private Date joinTime;
+    /**
+     * 任课状况(xjr_dictionary_item[teaching_status])多选
+     */
+    @ApiModelProperty("任课状况(xjr_dictionary_item[teaching_status])多选")
+    @TableField(typeHandler = FastjsonTypeHandler.class)
+    private JSONArray teachingStatus;
 
+    private String teachingStatusCn;
 }

+ 4 - 9
src/main/java/com/xjrsoft/module/textbook/controller/WfTextbookClaimController.java

@@ -162,20 +162,15 @@ public class WfTextbookClaimController {
     @GetMapping(value = "/info-qrcode")
     @ApiOperation(value = "教材领取-生成二维码")
     @SaCheckPermission("wfstudenttextbookclaim:detail")
-    @XjrLog(value = "教材领取-生成二维码", saveResponseData = true)
+    @XjrLog(value = "教材领取-生成二维码")
     public RT<String> qrcode(@RequestParam Long id) throws Exception {
-        String url = commonPropertiesConfig.getDomainApp() + "/pages/material/grant?id=" + id + "&userId=" + StpUtil.getLoginIdAsLong();
+        String url = commonPropertiesConfig.getDomainApp() + "/pages/meeting/detail?id=" + id + "&userId=" + StpUtil.getLoginIdAsLong();
         int width = 200;
         int height = 200;
         int margin = 1;
 
-        try {
-            String base64 = QrCodeUtil.createBase64(url, width, height, margin);
-            return RT.ok(base64);
-        } catch (Exception e) {
-            throw e;
-        }
-
+        String base64 = QrCodeUtil.createBase64(url, width, height, margin);
+        return RT.ok(base64);
     }
 
     @PostMapping("/claim-records-export-query")

+ 1 - 1
src/main/java/com/xjrsoft/module/workflow/controller/WorkflowExecuteController.java

@@ -57,7 +57,7 @@ public class WorkflowExecuteController {
 
     @GetMapping("/approve-process-info")
     @ApiOperation(value = "审批流程所需要的信息")
-    @XjrLog(value = "审批流程所需要的信息", saveResponseData = true)
+    @XjrLog(value = "审批流程所需要的信息", saveRequestData = false, saveResponseData = false)
     public R approveProcessInfo(@RequestParam String taskId) {
         return R.ok(workflowExecuteService.getApproveProcessInfo(taskId));
     }

+ 42 - 0
src/main/java/com/xjrsoft/module/workflow/service/impl/WorkflowExecuteServiceImpl.java

@@ -13,6 +13,7 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.db.Session;
 import cn.hutool.extra.spring.SpringUtil;
 import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -33,8 +34,10 @@ import com.xjrsoft.common.exception.MyException;
 import com.xjrsoft.common.mybatis.SqlRunnerAdapter;
 import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
+import com.xjrsoft.common.utils.LocalDateTimeUtil;
 import com.xjrsoft.common.utils.RedisUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.common.utils.WeChatUtil;
 import com.xjrsoft.config.CommonPropertiesConfig;
 import com.xjrsoft.module.form.dto.FormExecuteWorkflowAddDto;
 import com.xjrsoft.module.form.dto.FormExecuteWorkflowUpdateDto;
@@ -5492,6 +5495,7 @@ public class WorkflowExecuteServiceImpl implements IWorkflowExecuteService {
 //            addProcessRecord(task, schemaId, message);
         } else {
             List<WorkflowCirculated> newList = new ArrayList<>();
+
             for (Long userId : appendUserTaskCirculated) {
                 WorkflowCirculated workflowCirculated = BeanUtil.toBean(circulatedList.get(0), WorkflowCirculated.class);
                 workflowCirculated.setCirculatedUserId(userId);
@@ -5511,6 +5515,44 @@ public class WorkflowExecuteServiceImpl implements IWorkflowExecuteService {
                 circulateMessage = "【" + user.getName() + "】添加了传阅人【" + circulatedName + "】,当前传阅人【" + addCirculatedName + "】";
             }
         }
+        if(!appendUserTaskCirculated.isEmpty()){
+            WeChatUtil weChatUtil = SpringUtil.getBean(WeChatUtil.class);
+            CommonPropertiesConfig cpConfig = SpringUtil.getBean(CommonPropertiesConfig.class);
+            Map<Long, User> userMap = userService.listByIds(appendUserTaskCirculated).stream().filter(x -> StrUtil.isNotEmpty(x.getOpenId())).collect(Collectors.toMap(User::getId, x -> x));
+            for (Long userId : appendUserTaskCirculated) {
+                if(!userMap.containsKey(userId)){
+                    continue;
+                }
+
+                User appendUser = userMap.get(userId);
+                JSONObject data = new JSONObject();
+                // 任务名称
+                data.put("thing8", new JSONObject() {{
+                    put("value", "传阅消息");
+                }});
+                // 事项名称
+                data.put("thing2", new JSONObject() {{
+                    put("value", workflowSchemaConfig.getProcessConfig().getName());
+                }});
+                // 申请人
+                data.put("thing6", new JSONObject() {{
+                    put("value", appendUser.getName());
+                }});
+                // 时间
+                data.put("time3", new JSONObject() {{
+                    put("value", LocalDateTimeUtil.format(LocalDateTime.now(), LocalDateTimeUtil.LOCAL_DATE_TIME_FORMAT));
+                }});
+
+                JSONObject object = new JSONObject();
+                object.put("touser", appendUser.getOpenId());
+                object.put("template_id", "sHsmz7LRj7HLd7GSTS3r2jCLvK-4Wp19iGzEvYK8n_I");
+                object.put("url", StrUtil.format("{}/xjrsoft/pages/workflow/approval?taskId={}&processId={}&type=todo", cpConfig.getDomainApp(), task.getId(), task.getProcessInstanceId()));
+                object.put("client_msg_id", task.getId());
+                object.put("data", data);
+                weChatUtil.sendTemplateMessage(object);
+            }
+        }
+
         return circulateMessage;
     }
 

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

@@ -96,6 +96,7 @@
         <if test="dto.enrollType != null and dto.enrollType != ''">
             and t1.enroll_type = #{dto.enrollType}
         </if>
+        order by t1.name desc
     </select>
 
     <select id="getStudentClass" resultType="com.xjrsoft.module.base.vo.StudentClassVo">

+ 3 - 0
src/main/resources/mapper/room/RoomBedMapper.xml

@@ -42,6 +42,9 @@
         <if test="dto.identity != null and dto.identity != ''">
             and t2.check_in_status like concat('%',#{dto.identity},'%')
         </if>
+        <if test="dto.bedNumber != null and dto.bedNumber != ''">
+            and t1.bed_number like concat('%',#{dto.bedNumber},'%')
+        </if>
         ORDER BY t1.sort_code
     </select>
 

+ 9 - 0
src/main/resources/mapper/schedule/TodayScheduleMapper.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.xjrsoft.module.schedule.mapper.TodayScheduleMapper">
+    <select id="getList" parameterType="com.xjrsoft.module.schedule.dto.TodaySchedulePageDto" resultType="com.xjrsoft.module.schedule.vo.TodayScheduleVo">
+        SELECT * FROM today_schedule WHERE FIND_IN_SET(#{dto.userId}, user_id) > 0 ORDER BY start_time
+    </select>
+</mapper>

+ 3 - 0
src/main/resources/mapper/student/BaseStudentAssessmentInspectionMapper.xml

@@ -43,6 +43,9 @@
         <if test="dto.teacherId != null">
             and t7.teacher_id = #{dto.teacherId}
         </if>
+        <if test="dto.createUserId != null">
+            and t.create_user_id = #{dto.createUserId}
+        </if>
         order by t.id desc
     </select>
 

+ 1 - 1
src/main/resources/mapper/student/PbVXsxxsfytbMapper.xml

@@ -65,7 +65,7 @@
         GROUP BY t2.name
     </select>
     <select id="getClassQfPage" parameterType="com.xjrsoft.module.student.dto.PbVXsxxsfytbStatDto" resultType="com.xjrsoft.module.student.vo.ClassQfPageVo">
-        SELECT t1.id, t1.name AS grade_name,t2.name AS class_name,t3.name AS teacher_name,
+        SELECT t1.id, t1.name AS class_name,t2.name AS grade_name,t3.name AS teacher_name,
         (
         SELECT SUM(qfje) FROM pb_v_xsxxsfytb a1
         INNER JOIN xjr_user a2 ON a1.studentcode = a2.credential_number

+ 169 - 0
src/main/resources/sqlScript/20250324_sql.sql

@@ -0,0 +1,169 @@
+-- ----------------------------
+-- 教职工异动记录
+-- ----------------------------
+DROP TABLE IF EXISTS `base_teacher_change_record`;
+CREATE TABLE `base_teacher_change_record`
+(
+    id             bigint       not null comment '主键编号'
+        primary key,
+    create_user_id BIGINT       NULL COMMENT '创建人',
+    create_date    DATETIME     NULL COMMENT '创建时间',
+    modify_user_id BIGINT       NULL COMMENT '修改人',
+    modify_date    DATETIME     NULL COMMENT '修改时间',
+    delete_mark    INT          NOT NULL COMMENT '删除标记',
+    enabled_mark   INT          NOT NULL COMMENT '有效标志',
+
+    user_id        bigint       NOT NULL COMMENT '变更教职工主键id',
+    change_type    varchar(64)  NOT NULL COMMENT '异动类型(xjr_dictionary_item[tea_change_type])',
+    new_job_state  varchar(256) NOT NULL COMMENT '新的在职状态',
+    old_job_state  varchar(256) NOT NULL COMMENT '旧的在职状态'
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT = '教职工异动记录';
+
+-- ----------------------------
+-- 会议室管理
+-- ----------------------------
+DROP TABLE IF EXISTS `meeting_room`;
+CREATE TABLE `meeting_room`
+(
+    id              bigint      not null comment '主键编号'
+        primary key,
+    create_user_id  BIGINT      NULL COMMENT '创建人',
+    create_date     DATETIME    NULL COMMENT '创建时间',
+    modify_user_id  BIGINT      NULL COMMENT '修改人',
+    modify_date     DATETIME    NULL COMMENT '修改时间',
+    delete_mark     INT         NOT NULL COMMENT '删除标记',
+    enabled_mark    INT         NOT NULL COMMENT '有效标志',
+
+    name            varchar(64) not null comment '会议室名称',
+    office_build_id bigint      not null comment '楼栋(base_office_build)',
+    floor_num       int         not null comment '楼层',
+    number          varchar(32) null comment '门牌号',
+    capacity        int         null comment '容量(最大人数)',
+    square          double      null comment '会议室面积(平米)',
+    user_id         longtext    null comment '会议室管理员(多人)(xjr_user)',
+    user_phone      longtext    null comment '管理员联系方式',
+    status          int         not null comment '状态(1:启用 0:停用)'
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT = '会议室管理';
+
+
+alter table wf_meeting_apply
+    modify meeting_apply_date date not null comment '会议日期';
+
+alter table wf_meeting_apply
+    modify meeting_apply_s time not null comment '会议开始时间';
+
+alter table wf_meeting_apply
+    modify meeting_apply_e time not null comment '会议结束时间';
+
+alter table wf_meeting_apply
+    modify meeting_apply_format varchar(64) not null comment '会议形式(xjr_dictionary_item(meeting_type))';
+
+alter table wf_meeting_apply
+    change meeting_apply_address meeting_room_id BIGINT null comment '会议室管理主键id(meeting_room)' after meeting_apply_format;
+
+alter table wf_meeting_apply
+    add meeting_apply_url varchar(1024) null comment '线上会议链接' after meeting_room_id;
+
+alter table wf_meeting_apply
+    modify meeting_apply_theme varchar(512) null comment '会议主题';
+
+alter table wf_meeting_apply
+    modify meeting_apply_topics varchar(512) null comment '会议议题';
+
+alter table wf_meeting_apply
+    modify is_monogram int default 0 null comment '是否准备座牌、会标(1:是,0:否)';
+
+alter table wf_meeting_apply
+    change monogram monogram_theme varchar(512) null comment '会标主题';
+
+alter table wf_meeting_apply
+    drop column meeting_apply_tip;
+
+alter table wf_meeting_apply
+    drop column meeting_apply_pmm;
+
+alter table wf_meeting_apply
+    add `meeting_summary` longtext null comment '会议纪要' after monogram_theme;
+
+alter table wf_meeting_apply
+    drop column meeting_apply_sign_in;
+
+alter table wf_meeting_apply
+    add pre_meeting_Info_file_id bigint null comment '会前资料文件上传主键id' after `meeting_summary`;
+
+alter table wf_meeting_apply
+    drop column meeting_apply_up;
+
+alter table wf_meeting_apply
+    drop column meeting_apply_mission;
+
+alter table wf_meeting_apply
+    drop column meeting_apply_down;
+
+alter table wf_meeting_apply
+    change status meeting_status int default 0 null comment '会议状态(0:未开始 1:已经撤销,2:已结束)';
+
+alter table wf_meeting_apply
+    modify meeting_apply_host bigint null comment '主持人';
+
+alter table wf_meeting_apply
+    add sponsor_id bigint not null comment '会议发起人主键id(xjr_user)' after id;
+
+alter table wf_meeting_apply
+    add workflow_status int default 0 not null comment '会议申请流程状态(0:未结束,1:已经结束,正常通过,2:已经结束,未正常通过)';
+
+alter table wf_meeting_apply
+    modify workflow_status int default 0 null comment '会议申请流程状态(0:未结束,1:已经结束,正常通过,2:已经结束,未正常通过)';
+
+alter table wf_meeting_apply
+    add meeting_summary_file_id BIGINT null comment '会议纪要附件' after meeting_summary;
+
+alter table wf_meeting_apply
+    add meeting_room_name varchar(128) null comment '会议室管理名称' after meeting_room_id;
+
+-- ----------------------------
+-- 会议参会人员
+-- ----------------------------
+DROP TABLE IF EXISTS `meeting_conferee`;
+CREATE TABLE `meeting_conferee`
+(
+    id                  bigint   not null comment '主键编号'
+        primary key,
+    create_user_id      BIGINT   NULL COMMENT '创建人',
+    create_date         DATETIME NULL COMMENT '创建时间',
+    modify_user_id      BIGINT   NULL COMMENT '修改人',
+    modify_date         DATETIME NULL COMMENT '修改时间',
+    delete_mark         INT      NOT NULL COMMENT '删除标记',
+    enabled_mark        INT      NOT NULL COMMENT '有效标志',
+
+    wf_meeting_apply_id bigint   not null comment '会议申请主键id(wf_meeting_apply)',
+    user_id             bigint   not null comment '用户主键id(xjr_user)',
+    check_in_date       DATETIME NULL COMMENT '签到时间',
+    check_in_status     int      not null default 0 comment '签到状态(0:未签到,1:已签到)'
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT = '会议参会人员';
+
+-- ----------------------------
+-- 会议参会人员意见
+-- ----------------------------
+DROP TABLE IF EXISTS `meeting_conferee_opinion`;
+CREATE TABLE `meeting_conferee_opinion`
+(
+    id                  bigint   not null comment '主键编号'
+        primary key,
+    create_user_id      BIGINT   NULL COMMENT '创建人',
+    create_date         DATETIME NULL COMMENT '创建时间',
+    modify_user_id      BIGINT   NULL COMMENT '修改人',
+    modify_date         DATETIME NULL COMMENT '修改时间',
+    delete_mark         INT      NOT NULL COMMENT '删除标记',
+    enabled_mark        INT      NOT NULL COMMENT '有效标志',
+
+    wf_meeting_apply_id bigint   not null comment '会议申请主键id(wf_meeting_apply)',
+    user_id             bigint   not null comment '用户主键id(xjr_user)',
+    opinion             text     not null comment '意见'
+) ENGINE = InnoDB
+  DEFAULT CHARSET = utf8mb4 COMMENT = '会议参会人员意见';
+
+

Some files were not shown because too many files changed in this diff