Jelajahi Sumber

学生确认教材领取学期

大数据与最优化研究所 9 bulan lalu
induk
melakukan
a800933780

+ 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;
     /**
      * 当前申领项发放次数
      */

+ 139 - 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;
@@ -232,6 +234,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 +263,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 +281,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 +291,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 +303,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 +354,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;
     }
 

+ 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;