Browse Source

Merge branch 'pre'

大数据与最优化研究所 1 week ago
parent
commit
d71654c179

+ 22 - 7
src/main/java/com/xjrsoft/module/oa/service/impl/WfMeetingApplyServiceImpl.java

@@ -3,6 +3,7 @@ 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 cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -16,6 +17,7 @@ import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.page.PageOutput;
 import com.xjrsoft.common.utils.LocalDateTimeUtil;
 import com.xjrsoft.common.utils.VoToColumnUtil;
+import com.xjrsoft.config.CommonPropertiesConfig;
 import com.xjrsoft.module.base.entity.BaseOfficeBuild;
 import com.xjrsoft.module.ledger.vo.WorkflowRecordVo;
 import com.xjrsoft.module.oa.dto.*;
@@ -87,6 +89,8 @@ public class WfMeetingApplyServiceImpl extends MPJBaseServiceImpl<WfMeetingApply
 
     private final FileMapper fileMapper;
 
+    private final CommonPropertiesConfig propertiesConfig;
+
     @Override
     public List<MeetingRoomListVo> listMeetingRoom(MeetingRoomListDto dto) {
         List<MeetingRoomListVo> usableResult = new ArrayList<>();
@@ -629,9 +633,9 @@ public class WfMeetingApplyServiceImpl extends MPJBaseServiceImpl<WfMeetingApply
         wrapper
                 .disableSubLogicDel()
                 .select(WfMeetingApply::getId)
+                .select(WfMeetingApply.class, x -> VoToColumnUtil.fieldsToColumns(WfMeetingApply.class).contains(x.getProperty()))
                 .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)
@@ -697,11 +701,14 @@ public class WfMeetingApplyServiceImpl extends MPJBaseServiceImpl<WfMeetingApply
                     weChatSendMessageDto.setUserId(user.getOpenId());
                     weChatSendMessageDto.setTemplateId("Hign0b3e4WSXe__YmBKyDsBgAjkfNYC7c6yIUHjk3Hg");
                     weChatSendMessageDto.setMsgId(IdUtil.getSnowflakeNextId() + "");
+                    weChatSendMessageDto.setUrl(StrUtil.format("{}pages/meeting/detail?id={}&type=0", propertiesConfig.getDomainApp(), meetingApply.getId()));
                     JSONObject paramJson = new JSONObject();
 
-                    JSONObject thing2 = new JSONObject();
-                    thing2.put("value", meetingApply.getMeetingApplyTheme());
-                    paramJson.put("thing2", thing2);
+                    if(StringUtils.isNotEmpty(meetingApply.getMeetingApplyTheme())){
+                        JSONObject thing2 = new JSONObject();
+                        thing2.put("value", meetingApply.getMeetingApplyTheme());
+                        paramJson.put("thing2", thing2);
+                    }
 
                     JSONObject time5 = new JSONObject();
                     time5.put("value", startTime);
@@ -711,9 +718,17 @@ public class WfMeetingApplyServiceImpl extends MPJBaseServiceImpl<WfMeetingApply
                     time6.put("value", endTime);
                     paramJson.put("time6", time6);
 
-                    JSONObject thing7 = new JSONObject();
-                    thing7.put("value", meetingApply.getMeetingSummary());
-                    paramJson.put("thing7", thing7);
+                    if("HMT0001".equals(meetingApply.getMeetingApplyFormat())){
+                        JSONObject thing7 = new JSONObject();
+                        thing7.put("value", meetingApply.getMeetingApplyUrl());
+                        paramJson.put("thing7", thing7);
+                    }
+
+                    if("HMT0002".equals(meetingApply.getMeetingApplyFormat())){
+                        JSONObject thing7 = new JSONObject();
+                        thing7.put("value", meetingApply.getMeetingSummary());
+                        paramJson.put("thing7", thing7);
+                    }
 
                     JSONObject thing8 = new JSONObject();
                     thing8.put("value", meetingApply.getMonogramTheme());

+ 2 - 2
src/main/java/com/xjrsoft/module/textbook/entity/TextbookStudentClaim.java

@@ -91,9 +91,9 @@ public class TextbookStudentClaim implements Serializable {
     @ApiModelProperty("教材管理编号")
     private Long textbookId;
     /**
-     * 是否领取(1:已领取 0:未领取)
+     * 是否领取(1:已领取 0:未领取 2:领取后退还教务处了
      */
-    @ApiModelProperty("是否领取(1:已领取 0:未领取)")
+    @ApiModelProperty("是否领取(1:已领取 0:未领取 2:领取后退还教务处了)")
     private Integer isClaim;
     /**
      * 备注

+ 5 - 0
src/main/java/com/xjrsoft/module/textbook/entity/WfTextbookClaim.java

@@ -122,6 +122,11 @@ public class WfTextbookClaim implements Serializable {
      */
     @ApiModelProperty("状态(1:结束 0:未结束)")
     private Integer status;
+    /**
+     * 流程状态(0:未结束,1:已结束,正常通过,2:已结束,未通过)
+     */
+    @ApiModelProperty("流程状态(0:未结束,1:已结束,正常通过,2:已结束,未通过)")
+    private Integer workflowStatus;
     /**
      * 当前申领项发放次数
      */

+ 164 - 44
src/main/java/com/xjrsoft/module/textbook/service/impl/TextbookStudentClaimServiceImpl.java

@@ -39,9 +39,11 @@ import com.xjrsoft.module.textbook.mapper.WfTextbookClaimItemMapper;
 import com.xjrsoft.module.textbook.mapper.WfTextbookClaimMapper;
 import com.xjrsoft.module.textbook.service.ITextbookStudentClaimService;
 import com.xjrsoft.module.textbook.vo.*;
+import com.xjrsoft.module.workflow.entity.WorkflowFormRelation;
 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.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -196,6 +198,7 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
         Long loginId = StpUtil.getLoginIdAsLong();
 
         dto.setStudentUserId(loginId);
+
         // 获取当前学生的信息
         MPJLambdaWrapper<BaseStudentSchoolRoll> baseStudentSchoolRollMPJLambdaWrapper = new MPJLambdaWrapper<>();
         baseStudentSchoolRollMPJLambdaWrapper
@@ -219,6 +222,30 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
             result.setBaseSemesterCN(baseSemester.getName());
         }
 
+        // 学生教材应该以班级课程管理所维护的教材为基础
+        MPJLambdaWrapper<BaseClassAdminCourse> courseMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        courseMPJLambdaWrapper
+                .disableSubLogicDel()
+                .selectAs(WfTextbookClaimItem::getTextbookId, HeadTeaLookClassBookCategoryDetailVo::getTextbookId)
+                .selectAs(Textbook::getBookName, HeadTeaLookClassBookCategoryDetailVo::getBookName)
+                .selectAs(Textbook::getPrice, HeadTeaLookClassBookCategoryDetailVo::getPrice)
+                .selectAs(Textbook::getTextbookType, HeadTeaLookClassBookCategoryDetailVo::getTextbookType)
+                .innerJoin(BaseClassCourse.class, BaseClassCourse::getClassId, BaseClassAdminCourse::getId)
+                .innerJoin(Textbook.class, Textbook::getId, BaseClassCourse::getTextbookId)
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Textbook::getTextbookType,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, HeadTeaLookClassBookCategoryDetailVo::getTextbookTypeCn)
+                )
+                .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, WfTextbookClaim::getClaimType,
+                        wrapper -> wrapper
+                                .selectAs(DictionaryDetail::getName, HeadTeaLookClassBookCategoryDetailVo::getClaimTypeCn)
+                )
+                .eq(WfTextbookClaim::getBaseSemesterId, dto.getBaseSemesterId())
+                .eq(WfTextbookClaim::getClassId, result.getClassId())
+        ;
+        List<HeadTeaLookClassBookCategoryDetailVo> courselList = baseClassAdminCourseMapper.selectJoinList(HeadTeaLookClassBookCategoryDetailVo.class, courseMPJLambdaWrapper);
+
+
         // 学生查看自己的教材来源于两个方面,一个是班级申领教材,一个是个人申领的教材
         // 班级申领教材
         MPJLambdaWrapper<WfTextbookClaimItem> classMPJLambdaWrapper = new MPJLambdaWrapper<>();
@@ -232,6 +259,8 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
                 .selectAs(WfTextbookClaim::getClaimType, HeadTeaLookClassBookCategoryDetailVo::getClaimType)
                 .select("1 as claim_num")
                 .innerJoin(WfTextbookClaim.class, WfTextbookClaim::getId, WfTextbookClaimItem::getWfTextbookClaimId)
+                .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfTextbookClaim::getId)
+                .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
                 .innerJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId)
                 .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Textbook::getTextbookType,
                         wrapper -> wrapper
@@ -259,6 +288,8 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
                 .selectAs(WfTextbookClaim::getClaimType, HeadTeaLookClassBookCategoryDetailVo::getClaimType)
                 .select("1 as claim_num")
                 .innerJoin(WfTextbookClaim.class, WfTextbookClaim::getId, WfTextbookClaimItem::getWfTextbookClaimId)
+                .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfTextbookClaim::getId)
+                .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
                 .innerJoin(Textbook.class, Textbook::getId, WfTextbookClaimItem::getTextbookId)
                 .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Textbook::getTextbookType,
                         wrapper -> wrapper
@@ -275,7 +306,7 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
         List<HeadTeaLookClassBookCategoryDetailVo> personalList = wfTextbookClaimItemMapper.selectJoinList(HeadTeaLookClassBookCategoryDetailVo.class, personalMPJLambdaWrapper);
 
         // 合并两个列表,如果有个人领取记录,应该保留个人的,移除班级的
-        List<HeadTeaLookClassBookCategoryDetailVo> mergedList = new ArrayList<>(Stream.concat(classList.stream(), personalList.stream())
+        List<HeadTeaLookClassBookCategoryDetailVo> mergedDistinctList = new ArrayList<>(Stream.concat(classList.stream(), personalList.stream())
                 .collect(Collectors.toMap(
                         // 使用唯一标识作为 key
                         HeadTeaLookClassBookCategoryDetailVo::getTextbookId,
@@ -285,15 +316,6 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
                 ))
                 .values()); // 转换回 List
 
-        // 根据 textbookId 去重
-        List<HeadTeaLookClassBookCategoryDetailVo> distinctList = new ArrayList<>(mergedList.stream()
-                .collect(Collectors.toMap(
-                        HeadTeaLookClassBookCategoryDetailVo::getTextbookId, // 以 textbookId 作为去重依据
-                        vo -> vo, // 保留原始对象
-                        (existing, replacement) -> existing // 如果重复,保留已存在的对象
-                ))
-                .values());
-
         // 获取当前学生当前学期所有已经领取的数据
         LambdaQueryWrapper<TextbookStudentClaim> textbookStudentClaimLambdaQueryWrapper = new LambdaQueryWrapper<>();
         textbookStudentClaimLambdaQueryWrapper
@@ -306,10 +328,10 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
         Map<Long, TextbookStudentClaim> byTextbookId = textbookStudentClaimList.stream()
                 .collect(Collectors.toMap(TextbookStudentClaim::getTextbookId, t -> t, (t1, t2) -> t1));
 
-        if (ObjectUtils.isNotEmpty(distinctList)) {
+        if (ObjectUtils.isNotEmpty(mergedDistinctList)) {
             // 处理数据
             // 根据类型分组
-            Map<String, List<HeadTeaLookClassBookCategoryDetailVo>> detailByCategoryMap = distinctList.stream()
+            Map<String, List<HeadTeaLookClassBookCategoryDetailVo>> detailByCategoryMap = mergedDistinctList.stream()
                     .filter(detail -> StringUtils.isNotEmpty(detail.getTextbookType())) // Exclude entries where textbookType is null
                     .collect(Collectors.groupingBy(HeadTeaLookClassBookCategoryDetailVo::getTextbookType));
 
@@ -357,67 +379,165 @@ public class TextbookStudentClaimServiceImpl extends MPJBaseServiceImpl<Textbook
 
     @Override
     public List<TextbookStudentSemesterVo> getStudentSemesterList() {
+        Long loginId = StpUtil.getLoginIdAsLong();
         // 获取当前学生的信息
         BaseStudentSchoolRoll baseStudentSchoolRoll = baseStudentSchoolRollMapper.selectOne(
                 Wrappers.lambdaQuery(BaseStudentSchoolRoll.class)
                         .eq(BaseStudentSchoolRoll::getDeleteMark, DeleteMark.NODELETE.getCode())
-                        .eq(BaseStudentSchoolRoll::getUserId, StpUtil.getLoginIdAsLong())
+                        .eq(BaseStudentSchoolRoll::getUserId, loginId)
         );
 
         if (ObjectUtils.isEmpty(baseStudentSchoolRoll)) {
             throw new MyException("用户信息错误,请重新登录");
         }
 
-        // 学生查看自己的教材来源于两个方面,一个是班级申领教材,一个是个人申领的教材
+        // 学生教材应该以班级课程管理所维护的教材为基础,当有申领记录应该修改领取状态
+        MPJLambdaWrapper<BaseClassAdminCourse> courseMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        courseMPJLambdaWrapper
+                .selectAs(BaseClassAdminCourse::getBaseSemesterId, TextbookStudentSemesterVo::getBaseSemesterId)
+                .selectAs(BaseSemester::getName, TextbookStudentSemesterVo::getBaseSemesterIdCN)
+                .select("3 as status")
+                .leftJoin(BaseSemester.class, BaseSemester::getId, BaseClassAdminCourse::getBaseSemesterId)
+                .eq(BaseClassAdminCourse::getClassId, baseStudentSchoolRoll.getClassId())
+        ;
+        List<TextbookStudentSemesterVo> courselList = baseClassAdminCourseMapper.selectJoinList(TextbookStudentSemesterVo.class, courseMPJLambdaWrapper);
+
+        // 根据申领情况和确认领取确认学期教材的状态
+        // 获取已经领取的教材
+        MPJLambdaWrapper<TextbookStudentClaim> textbookStudentClaimMPJLambdaWrapper = new MPJLambdaWrapper<>();
+        textbookStudentClaimMPJLambdaWrapper
+                .selectAs(TextbookStudentClaim::getBaseSemesterId, StudentSemesterTextbookVo::getBaseSemesterId)
+                .selectAs(TextbookStudentClaim::getTextbookId, StudentSemesterTextbookVo::getTextbookId)
+                .eq(TextbookStudentClaim::getStudentUserId, loginId)
+                .ne(TextbookStudentClaim::getIsClaim, 0)
+                .eq(TextbookStudentClaim::getDeleteMark, DeleteMark.NODELETE.getCode())
+        ;
+        List<StudentSemesterTextbookVo> studentClaimList = textbookStudentClaimMapper.selectJoinList(StudentSemesterTextbookVo.class, textbookStudentClaimMPJLambdaWrapper);
+        // 根据学期 ID 分组,再根据教材 ID 映射
+        Map<Long, Map<Long, StudentSemesterTextbookVo>> studentClaimMap = studentClaimList.stream()
+                .collect(Collectors.groupingBy(
+                        StudentSemesterTextbookVo::getBaseSemesterId, // 第一层分组:按学期 ID 分组
+                        Collectors.toMap(
+                                StudentSemesterTextbookVo::getTextbookId, // 第二层映射:按教材 ID 作为键
+                                claim -> claim,                      // 值为 TextbookStudentClaim 对象本身
+                                (existing, replacement) -> existing   // 如果有重复键,保留现有的值
+                        )
+                ));
+
+        // 发起申请流程了,属于是待领取;当所有申请的教材都领取了,属于是已确认
+        // 首先是申请的教材:学生查看自己的教材来源于两个方面,一个是班级申领教材,一个是个人申领的教材
         // 班级申领教材
         MPJLambdaWrapper<WfTextbookClaim> classMPJLambdaWrapper = new MPJLambdaWrapper<>();
         classMPJLambdaWrapper
-                .selectAs(WfTextbookClaim::getBaseSemesterId, TextbookStudentSemesterVo::getBaseSemesterId)
-                .selectAs(BaseSemester::getName, TextbookStudentSemesterVo::getBaseSemesterIdCN)
+                .selectAs(WfTextbookClaim::getBaseSemesterId, StudentSemesterTextbookVo::getBaseSemesterId)
+                .selectAs(BaseSemester::getName, StudentSemesterTextbookVo::getBaseSemesterIdCN)
+                .selectAs(WfTextbookClaimItem::getTextbookId, StudentSemesterTextbookVo::getTextbookId)
+                .innerJoin(WfTextbookClaimItem.class, WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaim::getId)
+                .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfTextbookClaim::getId)
                 .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookClaim::getBaseSemesterId)
+                .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
                 .eq(WfTextbookClaim::getClassId, baseStudentSchoolRoll.getClassId())
                 .eq(WfTextbookClaim::getClaimType, ClaimTypeEnum.ClaimClass.getCode())
-        ;
-        List<TextbookStudentSemesterVo> classList = wfTextbookClaimMapper.selectJoinList(TextbookStudentSemesterVo.class, classMPJLambdaWrapper);
+               ;
+        List<StudentSemesterTextbookVo> classList = wfTextbookClaimMapper.selectJoinList(StudentSemesterTextbookVo.class, classMPJLambdaWrapper);
+        // 根据学期 ID 分组,再根据教材 ID 映射
+        Map<Long, Map<Long, StudentSemesterTextbookVo>> classMap = classList.stream()
+                .collect(Collectors.groupingBy(
+                        StudentSemesterTextbookVo::getBaseSemesterId, // 第一层分组:按学期 ID 分组
+                        Collectors.toMap(
+                                StudentSemesterTextbookVo::getTextbookId, // 第二层映射:按教材 ID 作为键
+                                claim -> claim,                      // 值为 TextbookStudentClaim 对象本身
+                                (existing, replacement) -> existing   // 如果有重复键,保留现有的值
+                        )
+                ));
 
         // 个人申领的教材
         MPJLambdaWrapper<WfTextbookClaim> personalMPJLambdaWrapper = new MPJLambdaWrapper<>();
         personalMPJLambdaWrapper
-                .selectAs(WfTextbookClaim::getBaseSemesterId, TextbookStudentSemesterVo::getBaseSemesterId)
-                .selectAs(BaseSemester::getName, TextbookStudentSemesterVo::getBaseSemesterIdCN)
+                .selectAs(WfTextbookClaim::getBaseSemesterId, StudentSemesterTextbookVo::getBaseSemesterId)
+                .selectAs(BaseSemester::getName, StudentSemesterTextbookVo::getBaseSemesterIdCN)
+                .selectAs(WfTextbookClaimItem::getTextbookId, StudentSemesterTextbookVo::getTextbookId)
+                .innerJoin(WfTextbookClaimItem.class, WfTextbookClaimItem::getWfTextbookClaimId, WfTextbookClaim::getId)
+                .innerJoin(WorkflowFormRelation.class, WorkflowFormRelation::getFormKeyValue, WfTextbookClaim::getId)
                 .leftJoin(BaseSemester.class, BaseSemester::getId, WfTextbookClaim::getBaseSemesterId)
-                .eq(WfTextbookClaim::getApplicantUserId, baseStudentSchoolRoll.getUserId())
+                .eq(WorkflowFormRelation::getCurrentState, HistoricProcessInstance.STATE_COMPLETED)
+                .eq(WfTextbookClaim::getApplicantUserId, loginId)
                 .eq(WfTextbookClaim::getClaimType, ClaimTypeEnum.ClaimStudent.getCode())
         ;
-        List<TextbookStudentSemesterVo> personalList = wfTextbookClaimMapper.selectJoinList(TextbookStudentSemesterVo.class, personalMPJLambdaWrapper);
+        List<StudentSemesterTextbookVo> personalList = wfTextbookClaimMapper.selectJoinList(StudentSemesterTextbookVo.class, personalMPJLambdaWrapper);
+        // 根据学期 ID 分组,再根据教材 ID 映射
+        Map<Long, Map<Long, StudentSemesterTextbookVo>> personalMap = personalList.stream()
+                .collect(Collectors.groupingBy(
+                        StudentSemesterTextbookVo::getBaseSemesterId, // 第一层分组:按学期 ID 分组
+                        Collectors.toMap(
+                                StudentSemesterTextbookVo::getTextbookId, // 第二层映射:按教材 ID 作为键
+                                claim -> claim,                      // 值为 TextbookStudentClaim 对象本身
+                                (existing, replacement) -> existing   // 如果有重复键,保留现有的值
+                        )
+                ));
+
+        // 合并两个列表,获取所有的学期
+        List<StudentSemesterTextbookVo> mergedDistinctList = new ArrayList<>(Stream.concat(classList.stream(), personalList.stream())
+                .collect(Collectors.toMap(
+                        // 使用唯一标识作为 key
+                        StudentSemesterTextbookVo::getBaseSemesterId,
+                        // 如果有重复,保留后面的值(即优先保留 personalList 的记录)
+                        vo -> vo,
+                        (classVo, personalVo) -> personalVo // 解决冲突时,优先选择 personalList 的记录
+                ))
+                .values()); // 转换回 List
 
-        // 合并两个列表
-        List<TextbookStudentSemesterVo> mergedList = Stream.concat(classList.stream(), personalList.stream())
-                .collect(Collectors.toList());
+        // 处理所有学期教材的情况
+        List<TextbookStudentSemesterVo> resultList = new ArrayList<>();
+        TextbookStudentSemesterVo result;
+        List<Long> mergedKeyList;
+        int status = 2;
+        for(StudentSemesterTextbookVo vo : mergedDistinctList){
+            result = new TextbookStudentSemesterVo();
+            Long semester = vo.getBaseSemesterId();
+            result.setBaseSemesterId(semester);
+            result.setBaseSemesterIdCN(vo.getBaseSemesterIdCN());
+            Map<Long, StudentSemesterTextbookVo> classSemesterMap = classMap.get(semester);
+            Map<Long, StudentSemesterTextbookVo> personalSemesterMap = personalMap.get(semester);
+            Map<Long, StudentSemesterTextbookVo> studentClaimSemesterMap = studentClaimMap.get(semester);
+
+            // 取出所有的教材
+            // 获取两个 Map 的键集合
+            Set<Long> classKeys = (classSemesterMap != null) ? classSemesterMap.keySet() : Collections.emptySet();
+            Set<Long> personalKeys = (personalSemesterMap != null) ? personalSemesterMap.keySet() : Collections.emptySet();
+
+            // 合并两个键集合并去重
+            mergedKeyList = Stream.concat(classKeys.stream(), personalKeys.stream())
+                    .distinct() // 去重
+                    .collect(Collectors.toList()); // 转换为 List
+
+            for(Long textbookId : mergedKeyList){
+                StudentSemesterTextbookVo studentClaimVo = studentClaimSemesterMap.get(textbookId);
+                // 当教材没有确认领取记录的时候当前学期状态应该是待领取
+                if(ObjectUtils.isEmpty(studentClaimVo)){
+                    status = 1;
+                    break;
+                }
+            }
+            result.setStatus(status);
+            resultList.add(result);
+        }
 
-        // 根据 baseSemesterId 去重
-        List<TextbookStudentSemesterVo> distinctList = new ArrayList<>(mergedList.stream()
+        // 合并两个列表,获取所有的学期
+        List<TextbookStudentSemesterVo> lastMergedDistinctList = new ArrayList<>(Stream.concat(courselList.stream(), resultList.stream())
                 .collect(Collectors.toMap(
-                        TextbookStudentSemesterVo::getBaseSemesterId, // 以 baseSemesterId 作为去重依据
-                        vo -> vo, // 保留原始对象
-                        (existing, replacement) -> existing // 如果重复,保留已存在的对象
+                        // 使用唯一标识作为 key
+                        TextbookStudentSemesterVo::getBaseSemesterId,
+                        // 如果有重复,保留后面的值(即优先保留 personalList 的记录)
+                        vo -> vo,
+                        (courseVo, resultVo) -> resultVo // 解决冲突时,优先选择 personalList 的记录
                 ))
-                .values());
+                .values()); // 转换回 List
 
         // 根据 baseSemesterIdCN 排序
-        distinctList.sort(Comparator.comparing(TextbookStudentSemesterVo::getBaseSemesterIdCN));
-
-//        //为每个学期添加未领取人数
-//        for (TextbookStudentSemesterVo textbookStudentSemesterVo : textbookStudentSemesterVoList) {
-//            LambdaQueryWrapper<TextbookStudentClaim> queryWrapperNotClaimNum = new LambdaQueryWrapper<>();
-//            queryWrapperNotClaimNum
-//                    .eq(TextbookStudentClaim::getStudentUserId, StpUtil.getLoginIdAsLong())
-//                    .eq(TextbookStudentClaim::getBaseSemesterId, textbookStudentSemesterVo.getBaseSemesterId())
-//                    .eq(TextbookStudentClaim::getIsClaim, 0);
-//            Long notClaimNum = this.count(queryWrapperNotClaimNum);
-//            textbookStudentSemesterVo.setNotClaimNum(notClaimNum);
-//        }
-        return distinctList;
+        lastMergedDistinctList.sort(Comparator.comparing(TextbookStudentSemesterVo::getBaseSemesterIdCN));
+
+        return lastMergedDistinctList;
     }
 
     @Override

+ 20 - 0
src/main/java/com/xjrsoft/module/textbook/service/impl/WfTextbookClaimServiceImpl.java

@@ -16,6 +16,7 @@ import com.xjrsoft.common.page.ConventPage;
 import com.xjrsoft.common.utils.VoToColumnUtil;
 import com.xjrsoft.module.base.entity.BaseClass;
 import com.xjrsoft.module.base.entity.BaseSemester;
+import com.xjrsoft.module.oa.entity.WfMeetingApply;
 import com.xjrsoft.module.system.entity.DictionaryDetail;
 import com.xjrsoft.module.teacher.entity.XjrUser;
 import com.xjrsoft.module.teacher.mapper.XjrUserMapper;
@@ -567,7 +568,26 @@ public class WfTextbookClaimServiceImpl extends MPJBaseServiceImpl<WfTextbookCla
             for (TextbookClaimUser textbookClaimUser : textbookClaimUserList) {
                 textbookClaimUserMapper.insert(textbookClaimUser);
             }
+
+            // 修改流程结束状态
+            WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim();
+            updateWfTextbookClaim.setId(wfTextbookClaim.getId());
+            updateWfTextbookClaim.setWorkflowStatus(1);
+            this.updateById(updateWfTextbookClaim);
         }
+
+        if (ObjectUtils.isNotEmpty(wfTextbookClaim)
+                && ObjectUtils.isNotEmpty(workflowFormRelation)
+                && !HistoricProcessInstance.STATE_COMPLETED.equals(workflowFormRelation.getCurrentState())
+                && !HistoricProcessInstance.STATE_ACTIVE.equals(workflowFormRelation.getCurrentState())
+        ) {
+            // 修改教材申领流程状态为不正常的结束
+            WfTextbookClaim updateWfTextbookClaim = new WfTextbookClaim();
+            updateWfTextbookClaim.setId(wfTextbookClaim.getId());
+            updateWfTextbookClaim.setWorkflowStatus(2);
+            this.updateById(updateWfTextbookClaim);
+        }
+
         return true;
     }
 

+ 1 - 1
src/main/java/com/xjrsoft/module/textbook/vo/HeadTeaLookClassBookCategoryDetailVo.java

@@ -9,7 +9,7 @@ import java.time.LocalDateTime;
 @Data
 public class HeadTeaLookClassBookCategoryDetailVo {
 
-    @ApiModelProperty("书名")
+    @ApiModelProperty("学生领取主键编号")
     private Long textbookStudentClaimId;
 
     @ApiModelProperty("书名")

+ 23 - 0
src/main/java/com/xjrsoft/module/textbook/vo/StudentSemesterTextbookVo.java

@@ -0,0 +1,23 @@
+package com.xjrsoft.module.textbook.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * @title: 一个学生一个学期的一本书
+ * @Author szs
+ * @Date: 2023-12-26
+ * @Version 1.0
+ */
+@Data
+public class StudentSemesterTextbookVo {
+
+    @ApiModelProperty("学期ID")
+    private Long baseSemesterId;
+
+    @ApiModelProperty("学期ID(base_semester)")
+    private String baseSemesterIdCN;
+
+    @ApiModelProperty("教材ID")
+    private Long textbookId;
+}

+ 3 - 4
src/main/java/com/xjrsoft/module/textbook/vo/TextbookStudentSemesterVo.java

@@ -23,9 +23,8 @@ public class TextbookStudentSemesterVo {
     @ApiModelProperty("学期ID(base_semester)")
     private String baseSemesterIdCN;
     /**
-     * 该学生该学期未领取数量
+     * 该学期教材的状态(1:待确认,2:已确认,3:下学期教材)
      */
-    @ApiModelProperty("该学生该学期未领取数量")
-    private Long notClaimNum;
-
+    @ApiModelProperty("该学期教材的状态(1:待确认,2:已确认,3:下学期教材)")
+    private Integer status;
 }

+ 4 - 1
src/main/resources/sqlScript/20250409_sql.sql

@@ -48,4 +48,7 @@ create table `feedback_item`
     `reply_time`        datetime     default null comment '回复时间',
     `reply_read_status` int          default 0 comment '回复阅读状态(0:未读,1:已读)'
 ) engine = innodb
-  default charset = utf8mb4 comment = '意见反馈-具体反馈单项';
+  default charset = utf8mb4 comment = '意见反馈-具体反馈单项';
+
+alter table wf_textbook_claim
+    add workflow_status int default 0 null comment '流程状态(0:未结束,1:已结束,正常通过,2:已结束,未通过)' after status;

+ 1 - 1
src/test/java/com/xjrsoft/module/oa/service/impl/WfMeetingApplyServiceImplTest.java

@@ -16,6 +16,6 @@ class WfMeetingApplyServiceImplTest {
 
     @Test
     void noticeParticipants() {
-        wfMeetingApplyService.noticeParticipants(1905133329842712576L);
+        wfMeetingApplyService.noticeParticipants(1910658069004095488L);
     }
 }