浏览代码

完善云阅卷摘取数据接口相关代码,待调试

lideyin 5 年之前
父节点
当前提交
1c8d3fb11e

+ 180 - 45
examcloud-core-oe-admin-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/admin/api/provider/ExamRecordCloudServiceProvider.java

@@ -1,14 +1,28 @@
 package cn.com.qmth.examcloud.core.oe.admin.api.provider;
 package cn.com.qmth.examcloud.core.oe.admin.api.provider;
 
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordCloudService;
+import cn.com.qmth.examcloud.core.oe.admin.api.bean.*;
 import cn.com.qmth.examcloud.core.oe.admin.api.request.*;
 import cn.com.qmth.examcloud.core.oe.admin.api.request.*;
 import cn.com.qmth.examcloud.core.oe.admin.api.response.*;
 import cn.com.qmth.examcloud.core.oe.admin.api.response.*;
+import cn.com.qmth.examcloud.core.oe.admin.base.utils.Check;
+import cn.com.qmth.examcloud.core.oe.admin.dao.*;
+import cn.com.qmth.examcloud.core.oe.admin.dao.entity.*;
+import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordForMarkingService;
+import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordQuestionsService;
+import cn.com.qmth.examcloud.core.oe.admin.service.others.ExamCacheTransferHelper;
+import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
 import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionStructure;
 import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionStructure;
 import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionUnit;
 import cn.com.qmth.examcloud.question.commons.core.question.DefaultQuestionUnit;
+import cn.com.qmth.examcloud.question.commons.core.question.QuestionType;
+import cn.com.qmth.examcloud.support.cache.CacheHelper;
+import cn.com.qmth.examcloud.support.cache.bean.CourseCacheBean;
 import cn.com.qmth.examcloud.support.cache.bean.QuestionCacheBean;
 import cn.com.qmth.examcloud.support.cache.bean.QuestionCacheBean;
+import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
+import cn.com.qmth.examcloud.web.support.ControllerSupport;
+import com.mysql.cj.util.StringUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
 import org.jsoup.Jsoup;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.nodes.Element;
@@ -20,36 +34,9 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 
 
-import com.mysql.cj.util.StringUtils;
-
-import cn.com.qmth.examcloud.commons.exception.StatusException;
-import cn.com.qmth.examcloud.core.oe.admin.api.ExamRecordCloudService;
-import cn.com.qmth.examcloud.core.oe.admin.api.bean.ExamRecordForSelectScore;
-import cn.com.qmth.examcloud.core.oe.admin.api.bean.ToBeMarkExamRecordBean;
-import cn.com.qmth.examcloud.core.oe.admin.api.bean.ToBeMarkSubjectiveAnswerBean;
-import cn.com.qmth.examcloud.core.oe.admin.base.utils.Check;
-import cn.com.qmth.examcloud.core.oe.admin.dao.ExamCaptureRepo;
-import cn.com.qmth.examcloud.core.oe.admin.dao.ExamRecordDataRepo;
-import cn.com.qmth.examcloud.core.oe.admin.dao.ExamRecordQuestionsRepo;
-import cn.com.qmth.examcloud.core.oe.admin.dao.ExamScoreRepo;
-import cn.com.qmth.examcloud.core.oe.admin.dao.ExamStudentRepo;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamCaptureEntity;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamQuestionEntity;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordDataEntity;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordForMarkingEntity;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamRecordQuestionsEntity;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamScoreEntity;
-import cn.com.qmth.examcloud.core.oe.admin.dao.entity.ExamStudentEntity;
-import cn.com.qmth.examcloud.core.oe.admin.service.ExamRecordForMarkingService;
-import cn.com.qmth.examcloud.core.oe.admin.service.others.ExamCacheTransferHelper;
-import cn.com.qmth.examcloud.question.commons.core.question.AnswerType;
-import cn.com.qmth.examcloud.question.commons.core.question.QuestionType;
-import cn.com.qmth.examcloud.support.cache.CacheHelper;
-import cn.com.qmth.examcloud.support.cache.bean.CourseCacheBean;
-import cn.com.qmth.examcloud.web.helpers.GlobalHelper;
-import cn.com.qmth.examcloud.web.support.ControllerSupport;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * @author chenken
  * @author chenken
@@ -85,6 +72,9 @@ public class ExamRecordCloudServiceProvider extends ControllerSupport implements
     @Autowired
     @Autowired
     private ExamRecordQuestionsRepo examRecordQuestionsRepo;
     private ExamRecordQuestionsRepo examRecordQuestionsRepo;
 
 
+    @Autowired
+    private ExamRecordQuestionsService examRecordQuestionsService;
+
     @Override
     @Override
     @ApiOperation(value = "查询是否已经开考")
     @ApiOperation(value = "查询是否已经开考")
     @PostMapping("/checkExamIsStarted")
     @PostMapping("/checkExamIsStarted")
@@ -274,29 +264,173 @@ public class ExamRecordCloudServiceProvider extends ControllerSupport implements
      * @return
      * @return
      */
      */
     @Override
     @Override
-    @ApiOperation(value = "获取待阅卷的考试记录-供bridge调用")
-    @PostMapping("/getToBeMarkExamRecord")
+    @ApiOperation(value = "分页获取待阅卷的考试记录")
+    @PostMapping("/getPagedToBeMarkExamRecord")
     public GetPagedToBeMarkExamRecordResp getPagedToBeMarkExamRecord(@RequestBody GetPagedToBeMarkExamRecordReq req) {
     public GetPagedToBeMarkExamRecordResp getPagedToBeMarkExamRecord(@RequestBody GetPagedToBeMarkExamRecordReq req) {
-        if (null == req.getExamId()) {
-            throw new StatusException("101001", "考试id不允许为空");
+        Long examId = req.getExamId();
+        String courseCode = req.getSubjectCode();
+        Long startId = req.getStartId();
+        Integer size = req.getSize();
+
+        validateToBeMarkData(examId, courseCode, startId, size);
+
+        List<ExamStudentEntity> limitedExamStuList =
+                examStudentRepo.getLimitExamStudentList(examId, courseCode, startId, size);
+
+        GetPagedToBeMarkExamRecordResp resp = new GetPagedToBeMarkExamRecordResp();
+        Long nextId = startId;
+
+        if (null == limitedExamStuList || limitedExamStuList.isEmpty()) {
+            resp.setNextId(nextId);
+            resp.setToBeMarkExamRecordBeanList(null);
+            return resp;
+        }
+
+        List<PagedToBeMarkExamRecordBean> pagedToBeMarkList = new ArrayList<>();
+
+        CourseCacheBean course = CacheHelper.getCourse(limitedExamStuList.get(0).getCourseId());
+        for (ExamStudentEntity examStu : limitedExamStuList) {
+            //当前考生待阅卷的考试记录
+            List<ExamRecordForMarkingEntity> examRecordForMarkingList =
+                    examRecordForMarkingService.queryValidExamRecordList(examStu.getExamStudentId());
+
+            for (ExamRecordForMarkingEntity record : examRecordForMarkingList) {
+                PagedToBeMarkExamRecordBean pagedBean = new PagedToBeMarkExamRecordBean();
+                pagedBean.setExamId(examId);
+                pagedBean.setStudentName(examStu.getStudentName());
+                pagedBean.setStudentCode(examStu.getStudentCode());
+                pagedBean.setCourseCode(courseCode);
+                pagedBean.setCourseName(course.getName());
+                pagedBean.setPaperType(examStu.getPaperType());
+                pagedBean.setExamStudentId(examStu.getExamStudentId());
+                pagedBean.setExamRecordDataId(record.getExamRecordDataId());
+                pagedBean.setGrade(examStu.getGrade());
+
+                pagedBean.setSubjectiveAnswerList(
+                        getSubjectiveAnswerList(record.getExamRecordDataId(), examId, courseCode, examStu.getPaperType()));
+
+                pagedToBeMarkList.add(pagedBean);
+            }
         }
         }
 
 
-        if (StringUtils.isNullOrEmpty(req.getSubjectCode())) {
+        nextId = limitedExamStuList.get(limitedExamStuList.size() - 1).getId() + 1;
+        resp.setNextId(nextId);
+        resp.setToBeMarkExamRecordBeanList(pagedToBeMarkList);
+        return resp;
+    }
+
+    /**
+     * 获取主观题集合
+     *
+     * @param examRecordDataId
+     * @param examId
+     * @return
+     */
+    private List<PagedToBeMarkSubjectiveAnswerBean> getSubjectiveAnswerList(Long examRecordDataId,
+                                                                            Long examId, String courseCode, String paperType) {
+        List<ExamQuestionEntity> eqList = examRecordQuestionsService.querySubjectiveAnswerList(examRecordDataId);
+
+        List<PagedToBeMarkSubjectiveAnswerBean> resultList = new ArrayList<>();
+        for (ExamQuestionEntity eq : eqList) {
+            PagedToBeMarkSubjectiveAnswerBean bean = new PagedToBeMarkSubjectiveAnswerBean();
+            bean.setMainNumber(eq.getMainNumber());
+            bean.setOrder(eq.getOrder());
+            bean.setQuestionId(eq.getQuestionId());
+            bean.setStudentAnswer(eq.getStudentAnswer());
+            bean.setAnswerType(eq.getAnswerType());
+            bean.setAnswer(eq.getCorrectAnswer());
+            bean.setQuestionType(eq.getQuestionType());
+
+            //获取指定小题的题干相关信息
+            QuestionCacheBean cachedQues = CacheHelper.getQuestion(examId, courseCode, paperType, eq.getQuestionId());
+            bean.setParentBody(getParentBody(cachedQues));
+            bean.setBody(getBody(eq.getOrder(), eq.getQuestionId(), cachedQues, eqList));
+
+            resultList.add(bean);
+        }
+
+        return resultList;
+    }
+
+    /**
+     * 获取套题的主题干
+     *
+     * @param cachedQues
+     * @return
+     */
+    private String getParentBody(QuestionCacheBean cachedQues) {
+
+        DefaultQuestionStructure questionStructure = cachedQues.getDefaultQuestion().getMasterVersion();
+
+        //如果主题干不为空,则认为是套题
+        return questionStructure.getBody();
+    }
+
+    /**
+     * 获取当前小题的题干
+     *
+     * @param curSubNumber       当前小题号
+     * @param questionId         原小题id
+     * @param cachedQues         带题干的试卷结构
+     * @param subjectiveQuesList 主观题集合
+     * @return
+     */
+    private String getBody(Integer curSubNumber, String questionId,
+                           QuestionCacheBean cachedQues, List<ExamQuestionEntity> subjectiveQuesList) {
+        DefaultQuestionStructure questionStructure = cachedQues.getDefaultQuestion().getMasterVersion();
+
+        //body为空,则说明当前小题为非套题(即questionUnitList集合大小为1),可直接返回小题题干
+        if (StringUtils.isNullOrEmpty(questionStructure.getBody())) {
+            return questionStructure.getQuestionUnitList().get(0).getBody();
+        }
+
+        //同一questionId的主观题集合(不带题干)
+        List<ExamQuestionEntity> noBodySubjectiveQuesList = subjectiveQuesList.stream().
+                filter(p -> p.getQuestionId().equals(questionId)).collect(Collectors.toList());
+
+        //同一questionId的主观题集合(带题干)
+        List<DefaultQuestionUnit> haveBodySubjectiveQuesList = questionStructure.getQuestionUnitList().stream()
+                .filter(p -> QuestionType.FILL_UP == p.getQuestionType() || QuestionType.ESSAY == p.getQuestionType())
+                .collect(Collectors.toList());
+
+        for (int i = 0; i < noBodySubjectiveQuesList.size(); i++) {
+            //如果小题号相同,则根据相同索引从带题干的集合中取出对应的小题题干
+            if (noBodySubjectiveQuesList.get(i).getOrder().intValue() == curSubNumber.intValue()) {
+                return haveBodySubjectiveQuesList.get(i).getBody();
+            }
+        }
+
+        return "";
+    }
+
+    /**
+     * 校验待阅卷数据
+     *
+     * @param examId
+     * @param courseCode
+     * @param startId
+     * @param size
+     */
+    private void validateToBeMarkData(Long examId, String courseCode, Long startId, Integer size) {
+        if (null == examId) {
+            throw new StatusException("101001", "考生id不允许为空");
+        }
+
+        if (StringUtils.isNullOrEmpty(courseCode)) {
             throw new StatusException("101002", "科目代码不允许为空");
             throw new StatusException("101002", "科目代码不允许为空");
         }
         }
 
 
-        if (null == req.getStartId()) {
+        if (null == startId) {
             throw new StatusException("101003", "考试记录id不允许为空");
             throw new StatusException("101003", "考试记录id不允许为空");
         }
         }
 
 
-        if (null == req.getSize()) {
+        if (null == size) {
             throw new StatusException("101004", "数据量大小不允许为空");
             throw new StatusException("101004", "数据量大小不允许为空");
         }
         }
 
 
-
-
-        GetPagedToBeMarkExamRecordResp resp = new GetPagedToBeMarkExamRecordResp();
-        return resp;
+        if (size.intValue() > 500) {
+            throw new StatusException("101005", "数据量最大不得超过500");
+        }
     }
     }
 
 
     /**
     /**
@@ -479,4 +613,5 @@ public class ExamRecordCloudServiceProvider extends ControllerSupport implements
 
 
         return studentAnswer;
         return studentAnswer;
     }
     }
+
 }
 }

+ 2 - 0
examcloud-core-oe-admin-dao/src/main/java/cn/com/qmth/examcloud/core/oe/admin/dao/ExamRecordForMarkingRepo.java

@@ -42,4 +42,6 @@ public interface ExamRecordForMarkingRepo extends JpaRepository<ExamRecordForMar
 	@Modifying
 	@Modifying
 	@Query(value = "update ec_oe_exam_record_4_marking set batch_num=?2 where id in (?1)",nativeQuery = true)
 	@Query(value = "update ec_oe_exam_record_4_marking set batch_num=?2 where id in (?1)",nativeQuery = true)
 	void updateBatchNum(List<Long> idList, String batchNum);
 	void updateBatchNum(List<Long> idList, String batchNum);
+
+	List<ExamRecordForMarkingEntity> findByExamStudentId(Long examStudentId);
 }
 }

+ 3 - 0
examcloud-core-oe-admin-dao/src/main/java/cn/com/qmth/examcloud/core/oe/admin/dao/ExamStudentRepo.java

@@ -95,4 +95,7 @@ public interface ExamStudentRepo extends JpaRepository<ExamStudentEntity, Long>,
 
 
 	ExamStudentEntity findByStudentIdAndExamIdAndCourseId(Long studentId,Long examId,Long courseId);
 	ExamStudentEntity findByStudentIdAndExamIdAndCourseId(Long studentId,Long examId,Long courseId);
 
 
+	@Query(value = "select *  from ec_oe_exam_student where enable=1 and exam_id=?1 and course_code=?2 and exam_student_id>=?3 order by id limit ?4",nativeQuery = true)
+	List<ExamStudentEntity> getLimitExamStudentList(Long examId, String courseCode,Long startId, Integer size);
+
 }
 }

+ 7 - 0
examcloud-core-oe-admin-service/src/main/java/cn/com/qmth/examcloud/core/oe/admin/service/ExamRecordForMarkingService.java

@@ -46,4 +46,11 @@ public interface ExamRecordForMarkingService {
 	 * @param examRecordDataId
 	 * @param examRecordDataId
 	 */
 	 */
 	void saveExamRecordForMarking(Long examRecordDataId,Double objectiveScore);
 	void saveExamRecordForMarking(Long examRecordDataId,Double objectiveScore);
+
+	/**
+	 * 获取某个考生的有效考试记录
+	 * @param examStudentId 考生id集合
+	 * @return
+	 */
+	List<ExamRecordForMarkingEntity> queryValidExamRecordList(Long examStudentId);
 }
 }

+ 65 - 19
examcloud-core-oe-admin-service/src/main/java/cn/com/qmth/examcloud/core/oe/admin/service/impl/ExamRecordForMarkingServiceImpl.java

@@ -57,22 +57,15 @@ public class ExamRecordForMarkingServiceImpl implements ExamRecordForMarkingServ
 
 
     @Autowired
     @Autowired
     private JdbcTemplate jdbcTemplate;
     private JdbcTemplate jdbcTemplate;
+
     @Override
     @Override
     public List<ExamRecordForMarkingEntity> queryValidExamRecordInfoByStuIds(
     public List<ExamRecordForMarkingEntity> queryValidExamRecordInfoByStuIds(
             Long examId, Long courseId, List<Long> examStudentIds, String batchNum) {
             Long examId, Long courseId, List<Long> examStudentIds, String batchNum) {
-        GetExamReq getExamReq = new GetExamReq();
-        getExamReq.setId(examId);
-        GetExamResp getExamResp = examCloudService.getExam(getExamReq);
-        ExamType examType = ExamType.valueOf(getExamResp.getExamBean().getExamType());
+        ExamType examType = getExamType(examId);
 
 
         List<ExamRecordForMarkingEntity> examRecordForMarkingList;
         List<ExamRecordForMarkingEntity> examRecordForMarkingList;
 
 
-        GetExamPropertyReq getExamPropertyReq = new GetExamPropertyReq();
-        getExamPropertyReq.setExamId(examId);
-        getExamPropertyReq.setKey("MARKING_TYPE");
-        GetExamPropertyResp getExamPropertyResp = examCloudService.getExamProperty(getExamPropertyReq);
-
-        String markingType = getExamPropertyResp.getValue();
+        String markingType = getMarkingType(examId);
         if (StringUtils.isEmpty(batchNum)) {
         if (StringUtils.isEmpty(batchNum)) {
             examRecordForMarkingList =
             examRecordForMarkingList =
                     examRecordForMarkingRepo.findByExamIdAndCourseIdAndExamStudentIds(examId, courseId, examStudentIds);
                     examRecordForMarkingRepo.findByExamIdAndCourseIdAndExamStudentIds(examId, courseId, examStudentIds);
@@ -101,23 +94,30 @@ public class ExamRecordForMarkingServiceImpl implements ExamRecordForMarkingServ
         return null;
         return null;
     }
     }
 
 
+    /**
+     * 获取阅卷类型
+     * @param examId
+     * @return
+     */
+    private String getMarkingType(Long examId) {
+        GetExamPropertyReq getExamPropertyReq = new GetExamPropertyReq();
+        getExamPropertyReq.setExamId(examId);
+        getExamPropertyReq.setKey("MARKING_TYPE");
+        GetExamPropertyResp getExamPropertyResp = examCloudService.getExamProperty(getExamPropertyReq);
+
+        return getExamPropertyResp.getValue();
+    }
+
     @Override
     @Override
     public List<ExamRecordForMarkingEntity> queryValidExamRecordList(Long examId, Long courseId) {
     public List<ExamRecordForMarkingEntity> queryValidExamRecordList(Long examId, Long courseId) {
-        GetExamReq getExamReq = new GetExamReq();
-        getExamReq.setId(examId);
-        GetExamResp getExamResp = examCloudService.getExam(getExamReq);
-        ExamType examType = ExamType.valueOf(getExamResp.getExamBean().getExamType());
+        ExamType examType = getExamType(examId);
 
 
         List<ExamRecordForMarkingEntity> examRecordForMarkingList = examRecordForMarkingRepo.findByExamIdAndCourseId(examId, courseId);
         List<ExamRecordForMarkingEntity> examRecordForMarkingList = examRecordForMarkingRepo.findByExamIdAndCourseId(examId, courseId);
         if (examType == ExamType.OFFLINE) {
         if (examType == ExamType.OFFLINE) {
             return examRecordForMarkingList;
             return examRecordForMarkingList;
         } else if (ExamType.ONLINE == examType || ExamType.ONLINE_HOMEWORK == examType) {
         } else if (ExamType.ONLINE == examType || ExamType.ONLINE_HOMEWORK == examType) {
-            GetExamPropertyReq getExamPropertyReq = new GetExamPropertyReq();
-            getExamPropertyReq.setExamId(examId);
-            getExamPropertyReq.setKey("MARKING_TYPE");
-            GetExamPropertyResp getExamPropertyResp = examCloudService.getExamProperty(getExamPropertyReq);
+            String markingType = getMarkingType(examId);
 
 
-            String markingType = getExamPropertyResp.getValue();
             if (markingType.equals(MarkingType.ALL.name())) {
             if (markingType.equals(MarkingType.ALL.name())) {
                 return examRecordForMarkingList;
                 return examRecordForMarkingList;
             } else if (markingType.equals(MarkingType.OBJECT_SCORE_MAX.name())) {
             } else if (markingType.equals(MarkingType.OBJECT_SCORE_MAX.name())) {
@@ -129,6 +129,18 @@ public class ExamRecordForMarkingServiceImpl implements ExamRecordForMarkingServ
         return null;
         return null;
     }
     }
 
 
+    /**
+     * 获取考试类型
+     * @param examId
+     * @return
+     */
+    private ExamType getExamType(Long examId) {
+        GetExamReq getExamReq = new GetExamReq();
+        getExamReq.setId(examId);
+        GetExamResp getExamResp = examCloudService.getExam(getExamReq);
+        return ExamType.valueOf(getExamResp.getExamBean().getExamType());
+    }
+
     /**
     /**
      * 最后一次提交
      * 最后一次提交
      *
      *
@@ -319,4 +331,38 @@ public class ExamRecordForMarkingServiceImpl implements ExamRecordForMarkingServ
 
 
         examRecordForMarkingRepo.save(examRecordForMarking);
         examRecordForMarkingRepo.save(examRecordForMarking);
     }
     }
+
+    /**
+     * 获取某个考生的有效考试记录
+     *
+     * @param examStudentId 考生id集合
+     * @return
+     */
+    @Override
+    public List<ExamRecordForMarkingEntity> queryValidExamRecordList(Long examStudentId) {
+        List<ExamRecordForMarkingEntity> examRecordForMarkingList =
+                examRecordForMarkingRepo.findByExamStudentId(examStudentId);
+
+        if (null == examRecordForMarkingList || examRecordForMarkingList.isEmpty()) {
+            return null;
+        }
+
+        Long examId=examRecordForMarkingList.get(0).getExamId();
+        ExamType examType = getExamType(examId);
+
+        if (examType == ExamType.OFFLINE) {
+            return examRecordForMarkingList;
+        } else if (ExamType.ONLINE == examType || ExamType.ONLINE_HOMEWORK == examType) {
+
+            String markingType = getMarkingType(examId);
+            if (markingType.equals(MarkingType.ALL.name())) {
+                return examRecordForMarkingList;
+            } else if (markingType.equals(MarkingType.OBJECT_SCORE_MAX.name())) {
+                return queryStudentPapersByObjectScoreMax(examRecordForMarkingList);
+            } else if (markingType.equals(MarkingType.LAST_SUBMIT.name())) {
+                return queryStudentPapersByLastSubmit(examRecordForMarkingList);
+            }
+        }
+        return null;
+    }
 }
 }