/**
 * Copyright (C), 2015-2018, XXX有限公司
 * FileName: ExamQuestionApiController
 * Author:   phone
 * Date:     2018/3/30 11:20
 * Description: 考试试题
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.yizhi.application.exam.controller;


import com.yizhi.application.exam.controller.constant.ExamConstant;
import com.yizhi.application.point.constant.MQqueuesEnum;
import com.yizhi.application.point.constant.PointEventEnum;
import com.yizhi.core.application.context.ContextHolder;
import com.yizhi.core.application.context.RequestContext;
import com.yizhi.core.application.event.EventWrapper;
import com.yizhi.core.application.publish.CloudEventPublisher;
import com.yizhi.core.application.task.AbstractTaskHandler;
import com.yizhi.core.application.task.TaskExecutor;
import com.yizhi.exam.application.feign.ExamQuestionApiClient;
import com.yizhi.exam.application.vo.exam.*;
import com.yizhi.exam.application.vo.report.ExamPcAnswerVO;
import com.yizhi.point.application.feign.PointRedisFeignClients;
import com.yizhi.point.application.vo.PointParamVO;
import com.yizhi.util.application.constant.QueueConstant;
import com.yizhi.util.application.constant.ReturnCode;
import com.yizhi.util.application.domain.Response;
import com.yizhi.util.application.enums.i18n.Constants;
import com.yizhi.util.application.event.TrainingProjectEvent;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 〈一句话功能简述〉<br>
 * 〈考试试题〉
 *
 * @author fanchunhui
 * @create 2018/3/30
 * @since 1.0.0
 */

@Api(tags = "学员端", description = "学员端接口")
@RestController
@RequestMapping("/api/exam")
public class ExamQuestionApiController {

    private static final Logger LOG = LoggerFactory.getLogger(ExamQuestionApiController.class);

    @Autowired
    ExamQuestionApiClient examQuestionApiClient;

    @Autowired
    PointRedisFeignClients pointRedisFeignClients;
/*
    @Autowired
    AmqpTemplate amqpTemplate;*/

    @Autowired
    private TaskExecutor taskExecutor;
    @Autowired
    private CloudEventPublisher cloudEventPublisher;

    @ApiOperation(value = "开始考试", notes = "开始考试", response = StudentExamPaperVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/make")
    public Response<StudentExamPaperVO> makeExamQuestion(@RequestBody StudentExamPaperVO studentExamPaperVO) {
        Map<String, Integer> page = null;
        RequestContext requestContext = ContextHolder.get();
        studentExamPaperVO.setAccountId(requestContext.getAccountId());
        studentExamPaperVO.setAccountName(requestContext.getAccountName());
        studentExamPaperVO.setCompanyId(requestContext.getCompanyId());
        studentExamPaperVO.setOrgId(requestContext.getOrgId());
        studentExamPaperVO.setSiteId(requestContext.getSiteId());
//        studentExamPaperVO.setCompanyId(91L);
//        studentExamPaperVO.setOrgId(134991L);
//        studentExamPaperVO.setSiteId(3L);
        StudentExamPaperVO studentExamPaperVO1 = examQuestionApiClient.makeExamQuestion(studentExamPaperVO);
     /*   if (map.containsKey("list")){
            list = (List<StudentExamPaperVO>) map.get("list");
        }
        if (map.containsKey("page")){
            page = (Map<String, Integer>) map.get("page");
        }*/
//        Pair<List<StudentExamPaperVO>,Map<String,Integer>> pair = new MutablePair<List<StudentExamPaperVO>,Map<String,Integer>>(list, page);

        if (studentExamPaperVO1 == null) {
            Response.ok(new ArrayList<Object>());
        }
        //没有考试次数了,不能开始考试
        if (null != studentExamPaperVO1.getIsExamAnswerGoOn() && studentExamPaperVO1.getIsExamAnswerGoOn() == 1) {
            return Response.fail("4023", "该考试没有考试次数了");
        }
        if (null != studentExamPaperVO1.getIsExamAnswerGoOn() && studentExamPaperVO1.getIsExamAnswerGoOn() == 3) {
            return Response.fail("4024", "本场考试未开始");
        }

        return Response.ok(studentExamPaperVO1);
    }

    @ApiOperation(value = "pc端开始/继续 考试", notes = "pc端开始/继续 考试", response = PcStudentExamPaperVo.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/pcMake")
    public Response<PcStudentExamPaperVo> pcMakeExamQuestion(@RequestBody StudentExamPaperVO studentExamPaperVO) {
        try {
            Map<String, Integer> pageMap = new HashMap<>();
            RequestContext requestContext = ContextHolder.get();
            studentExamPaperVO.setAccountId(requestContext.getAccountId());
            studentExamPaperVO.setAccountName(requestContext.getAccountName());
            studentExamPaperVO.setCompanyId(requestContext.getCompanyId());
            studentExamPaperVO.setOrgId(requestContext.getOrgId());
            studentExamPaperVO.setSiteId(requestContext.getSiteId());

            PcStudentExamPaperVo studentExamPaperVO1 = examQuestionApiClient.makePcExamQuestion(studentExamPaperVO);
            if (null == studentExamPaperVO1){
                LOG.error("start or continue exam has an exception! companyId = {},sitId = {}," +
                                " orgId = {}, accountId = {}, accountName = {}, examId = {}, answerId = {}"
                        ,studentExamPaperVO.getCompanyId(),studentExamPaperVO.getSiteId()
                        ,studentExamPaperVO.getOrgId(),studentExamPaperVO.getAccountId()
                        ,studentExamPaperVO.getAccountName(),studentExamPaperVO.getExamId(),studentExamPaperVO.getAnswerId());
                return Response.fail(Constants.EXAM_MSG_BIZ_ERROR);
            }
            //没有考试次数了不能开始考试
            if (null != studentExamPaperVO1.getIsExamAnswerGoOn()
                    && studentExamPaperVO1.getIsExamAnswerGoOn() == 1) {
                return Response.fail(Constants.EXAM_MSG_NO_EXAM_TIMES);
            }
            //该场考试已经提交了,不能继续考试
            if (null != studentExamPaperVO1.getIsExamAnswerGoOn()
                    && studentExamPaperVO1.getIsExamAnswerGoOn() == 2) {
                return Response.fail(Constants.EXAM_MSG_SUBMITED);
            }
            if (null != studentExamPaperVO1.getIsExamAnswerGoOn()
                    && studentExamPaperVO1.getIsExamAnswerGoOn() == 3) {
                return Response.fail(Constants.EXAM_MSG_EXAM_NOT_BEGIN);
            }
            Integer pageNo = studentExamPaperVO.getPageNo();
            Integer pageSize = studentExamPaperVO.getPageSize();

            pageMap.put("pageNo", pageNo);
            pageMap.put("pageSize", pageSize);
            if (null != studentExamPaperVO1) {
                pageMap.put("pageRecords", studentExamPaperVO1.getPageTotal());
            }
            return Response.ok(studentExamPaperVO1, pageMap);

        } catch (Exception e) {
            LOG.error("start or continue exam has an exeception : ", e);
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    @ApiOperation(value = "pc/微信端学员答卷答题卡", notes = "pc/微信端学员答卷答题卡）", response = CardVO.class)
    @GetMapping("/answerCard")
    public Response<CardVO> getMyExamAnswerCards(
            @ApiParam(name = "answerId", value = "答卷ID") @RequestParam("answerId") Long answerId) {
        try {

            return Response.ok(examQuestionApiClient.getMyExamAnswerCards(answerId));
        } catch (Exception e) {
            LOG.error("exam接口出现异常", e);
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    @ApiOperation(value = "获取一场考试剩余考试时间", notes = "获取一场考试剩余考试时间")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "answerId", value = "答卷ID"),
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/getRemainderTime")
    public Response<Object> getRemainderTime(@RequestBody ExamAnswerVO vo) {
        try {
            return Response.ok(examQuestionApiClient.getRemainderTime(vo));
        } catch (Exception e) {
            LOG.error("获取考试剩余考试时间:", e);
            return Response.fail(ReturnCode.BIZ_FAIL.getCode(),ReturnCode.BIZ_FAIL.getMsg());
        }
    }

    /**
     * 根据考试ID，学号查询已有的试卷
     *
     * @return 返回考生考试试卷
     */
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @ApiOperation(value = "继续考试", notes = "继续考试", response = StudentExamPaperVO.class)
    @PostMapping("/continue")
    public Response<StudentExamPaperVO> examContinue(@RequestBody ExamPaperVO examPaperVO) {
        RequestContext requestContext = ContextHolder.get();
        examPaperVO.setAccountId(requestContext.getAccountId());
        examPaperVO.setAccountName(requestContext.getAccountName());
        examPaperVO.setCompanyId(requestContext.getCompanyId());
        examPaperVO.setOrgId(requestContext.getOrgId());
        examPaperVO.setSiteId(requestContext.getSiteId());
        StudentExamPaperVO studentExamPaperVo = examQuestionApiClient.examContinue(examPaperVO);
        //该场考试已经提交过了,不能继续考试
        if (null != studentExamPaperVo.getIsExamAnswerGoOn() && studentExamPaperVo.getIsExamAnswerGoOn() == 2) {
            return Response.fail("4024", "该场考试已经提交,不能继续考试");
        }
        return Response.ok(studentExamPaperVo);
    }

    @ApiOperation(value = "保存考试进展", notes = "返回成功与否")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "answerId", value = "答卷ID"),
            @ApiImplicitParam(name = "examId", value = "考试ID"),
            @ApiImplicitParam(name = "sub", value = "主观题答案"),
            @ApiImplicitParam(name = "epList", value = "考试进展", dataType = "List<ExamProgressVO>"),
            @ApiImplicitParam(name = "epList.ansQId", value = "答案题目ID"),
            @ApiImplicitParam(name = "epList.type", value = "题型，1单选题、2多选题、3判断题、4问答题"),
            @ApiImplicitParam(name = "epList.ops", value = "选项", dataType = "List<StudentOptionVO>"),
            @ApiImplicitParam(name = "epList.ops.optionId", value = "选项_ID主键"),
            @ApiImplicitParam(name = "epList.ops.answer", value = "用户答案标识 0未选择 1选择")
    })
    @PostMapping("/save")
    public Response<String> saveExamAnswer(@RequestBody ExamAnswerVO vo) {
        boolean boo = false;
        try {
            RequestContext requestContext = ContextHolder.get();
            vo.setAccountId(requestContext.getAccountId());
            vo.setAccountName(requestContext.getAccountName());
            vo.setCompanyId(requestContext.getCompanyId());
            vo.setOrgId(requestContext.getOrgId());
            vo.setSiteId(requestContext.getSiteId());
            boo = examQuestionApiClient.saveExamAnswer(vo);
            return Response.ok(boo);
        } catch (Exception e) {
            LOG.error("保存考试进展:", e);
            return Response.fail(ReturnCode.BIZ_FAIL.getCode(),ReturnCode.BIZ_FAIL.getMsg());
        }
    }

    @ApiOperation(value = "pc端保存考试进展", notes = "返回成功与否")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "answerId", value = "答卷ID"),
            @ApiImplicitParam(name = "examId", value = "考试ID"),
            @ApiImplicitParam(name = "epList.sub", value = "主观题答案"),
            @ApiImplicitParam(name = "epList", value = "考试进展", dataType = "List<ExamProgressVO>"),
            @ApiImplicitParam(name = "epList.ansQId", value = "答案题目ID"),
            @ApiImplicitParam(name = "epList.type", value = "题型，1单选题、2多选题、3判断题、4问答题"),
            @ApiImplicitParam(name = "epList.ops", value = "选项", dataType = "List<StudentOptionVO>"),
            @ApiImplicitParam(name = "epList.ops.optionId", value = "选项_ID主键"),
            @ApiImplicitParam(name = "epList.ops.answer", value = "用户答案标识 0未选择 1选择")
    })
    @PostMapping("/pcSave")
    public Response<String> savePcExamAnswer(@RequestBody ExamPcAnswerVO vo) {
        boolean boo = false;
        try {
            ExamAnswerVO param = new ExamAnswerVO();
            List<ExamProgressVO> examProgressVOList = new ArrayList<>();
            RequestContext requestContext = ContextHolder.get();
            param.setAccountId(requestContext.getAccountId());
            param.setAccountName(requestContext.getAccountName());
            param.setCompanyId(requestContext.getCompanyId());
            param.setOrgId(requestContext.getOrgId());
            param.setSiteId(requestContext.getSiteId());
            param.setAnswerId(vo.getAnswerId());
            param.setExamId(vo.getExamId());
            if (!CollectionUtils.isEmpty(vo.getEpList())) {
                for (QuestionListVO questionListVO : vo.getEpList()) {
                    ExamProgressVO examProgressVO = new ExamProgressVO();
                    List<StudentOptionVO> optionVOS = new ArrayList<>();
                    examProgressVO.setAnsQId(questionListVO.getAnswerQuestionId());
                    examProgressVO.setType(questionListVO.getType());
                    examProgressVO.setSub(questionListVO.getSub());
                    examProgressVO.setMark(questionListVO.getFlag());
                    if (!CollectionUtils.isEmpty(questionListVO.getQuestionOptions())) {
                        for (QuestionOptionListVO listVO : questionListVO.getQuestionOptions()) {
                            StudentOptionVO optionVO = new StudentOptionVO();
                            optionVO.setOptionId(listVO.getOptionId());
                            optionVO.setAnswer(listVO.getAnswer());
                            optionVO.setSort(listVO.getSort());
                            optionVOS.add(optionVO);
                        }
                    }
                    examProgressVO.setOps(optionVOS);
                    examProgressVOList.add(examProgressVO);
                }
            }
            param.setEpList(examProgressVOList);
            System.out.println(param.toString());
            boo = examQuestionApiClient.saveExamAnswer(param);
            return Response.ok(boo);
        } catch (Exception e) {
            LOG.error("pc端保存考试进展:", e);
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }


    @ApiOperation(value = "交卷", notes = "返回考试结果", response = ExamResultVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "answerId", value = "答卷ID"),
            @ApiImplicitParam(name = "examId", value = "考试ID"),
            @ApiImplicitParam(name = "sub", value = "主观题答案"),
            @ApiImplicitParam(name = "epList", value = "考试进展", dataType = "List<ExamProgressVO>"),
            @ApiImplicitParam(name = "epList.ansQId", value = "答案题目ID"),
            @ApiImplicitParam(name = "epList.type", value = "题型，1单选题、2多选题、3判断题、4问答题"),
            @ApiImplicitParam(name = "epList.ops", value = "选项", dataType = "List<StudentOptionVO>"),
            @ApiImplicitParam(name = "epList.ops.optionId", value = "选项_ID主键"),
            @ApiImplicitParam(name = "epList.ops.answer", value = "用户答案标识 0未选择 1选择")
    })
    @PostMapping("/submit")
    public Response<ExamResultVO> submitExamPage(@RequestBody ExamAnswerVO vo) {
        ExamResultVO result = null;
        RequestContext requestContext = ContextHolder.get();
        Date time = new Date();
        try {
            vo.setAccountId(requestContext.getAccountId());
            vo.setAccountName(requestContext.getAccountName());
            vo.setCompanyId(requestContext.getCompanyId());
            vo.setSiteId(requestContext.getSiteId());
            vo.setOrgId(requestContext.getOrgId());
            result = examQuestionApiClient.submitExamPage(vo);
            vo.setExamId(result.getExamId());
            //没有考试次数了不能提交
            if (null != result.getIsExamAnswerGoOn() && result.getIsExamAnswerGoOn() == 1) {
                return Response.fail("4021", "该考试没有考试次数了,不能提交");
            }
            //该场考试已经提交过了,不能提交
            if (null != result.getIsExamAnswerGoOn() && result.getIsExamAnswerGoOn() == 2) {
                return Response.fail("4022", "该考试已经提交过了,不能重复提交");
            }

            //考试交卷后积分发放
            try {
                Integer point = result.getPoint();
                if (result.getIsres() == 0) {
                    PointParamVO pointParamVO = new PointParamVO();
                    pointParamVO.setEventName(PointEventEnum.POINTEXAM.getKey());    //事件名称
                    pointParamVO.setActivityType("考试通过积分发放");                //事件类型
                    pointParamVO.setActivitySource("考试");                            //学习活动来源
                    pointParamVO.setActivityName(result.getExamName());                //学习活动名称
                    pointParamVO.setReleaseCondition("范围发放");                    //发放条件
                    pointParamVO.setReleaseRules("按照范围取积分");                    //发放规则
                    pointParamVO.setCreatePointTime(time);                            //积分创建时间
                    pointParamVO.setSourceId(vo.getExamId());                        //积分来源ID，（业务ID主键）
                    pointParamVO.setOperatingPoint(result.getPoint());                //积分数量，  正数 加积分，  负数减积分
                    pointParamVO.setAccountId(requestContext.getAccountId());        //学员ID
                    pointParamVO.setAccountName(requestContext.getAccountName());    //学员名称
                    pointParamVO.setCompanyId(requestContext.getCompanyId());        //企业ID
                    pointParamVO.setSiteId(requestContext.getSiteId());                //站点ID
                    pointParamVO.setOrgId(requestContext.getOrgId());                //组织ID
                    LOG.info("###############score:{}", result.getScore().intValue());
                    pointParamVO.setScore(result.getScore().intValue());
                    String sitePointId = null;
                    if (null != point && point > 0) {
                        sitePointId = pointRedisFeignClients.addPointRedis(pointParamVO);//调用积分接口添加积分
                    }
                    String sitePointId1 = pointRedisFeignClients.addPointRedis(pointParamVO);//调用积分接口添加经验
                    if (null != sitePointId) {
                       // amqpTemplate.convertAndSend(MQqueuesEnum.EXAM.getKey(), sitePointId);    //发送积分获取消息
                    }
                    if (null != sitePointId1) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXPERIENCEEXAM.getKey(), sitePointId1);    //发送经验获取消息
                    }
                }
            } catch (Exception e) {
                LOG.error("student交卷exam积分发放失败：", e);
            }

            // 考试提交，向培训项目发送消息，告知业务已经完成
            try {
                boolean isFinished = false;
                //如果没有主观题,判断是否合格
                if (result.getIsres() == 0 && result.getScore() != null
                        && result.getScoreSuccess() != null) {
                    if (result.getScore().compareTo(new BigDecimal(result.getScoreSuccess())) != -1) {
                        isFinished = true;
                    }
                }

                LOG.info("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject");
                Float value = null;
                if (result.getIsres() == 0) {
                    value = result.getScore().floatValue();
                }
                boolean finalIsFinished = isFinished;
                Float finalValue = value;
                taskExecutor.asynExecute(new AbstractTaskHandler() {
                    @Override
                    public void handle() {
                        try {
                            cloudEventPublisher.publish(QueueConstant.TRAINING_PROJECT_EVENT_QUEUE,
                                    new EventWrapper<TrainingProjectEvent>(vo.getExamId(),
                                            TrainingProjectEvent.getInstance(vo.getExamId(), ExamConstant.EXAM_TRANINNING_TYPE,
                                                    requestContext.getAccountId(), time,
                                                    requestContext.getSiteId(), finalValue, finalIsFinished)));
                        } catch (Exception e) {
                            e.printStackTrace();
                            LOG.error("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject异常：", e);
                        }
                    }
                });

            } catch (Exception e) {
                LOG.error("student交卷，给trainingProject发送消息失败：", e);
            }

            return Response.ok(result);
        } catch (Exception e) {
            LOG.error("student交卷", e);
            return Response.fail(ReturnCode.BIZ_FAIL.getCode(),ReturnCode.BIZ_FAIL.getMsg());
        }
    }

    @ApiOperation(value = "pc端交卷", notes = "返回考试结果", response = ExamResultVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "answerId", value = "答卷ID"),
            @ApiImplicitParam(name = "examId", value = "考试ID"),
            @ApiImplicitParam(name = "sub", value = "主观题答案"),
            @ApiImplicitParam(name = "epList", value = "考试进展", dataType = "List<ExamProgressVO>"),
            @ApiImplicitParam(name = "epList.ansQId", value = "答案题目ID"),
            @ApiImplicitParam(name = "epList.type", value = "题型，1单选题、2多选题、3判断题、4问答题"),
            @ApiImplicitParam(name = "epList.ops", value = "选项", dataType = "List<StudentOptionVO>"),
            @ApiImplicitParam(name = "epList.ops.optionId", value = "选项_ID主键"),
            @ApiImplicitParam(name = "epList.ops.answer", value = "用户答案标识 0未选择 1选择")
    })
    @PostMapping("/pcSubmit")
    public Response<ExamResultVO> submitPcExamPage(@RequestBody ExamPcAnswerVO vo) {
        ExamResultVO result = null;
        RequestContext requestContext = ContextHolder.get();
        Date time = new Date();
        try {
            ExamAnswerVO examAnswerVO = new ExamAnswerVO();
            List<ExamProgressVO> examProgressVOList = new ArrayList<>();
            examAnswerVO.setAccountId(requestContext.getAccountId());
            examAnswerVO.setAccountName(requestContext.getAccountName());
            examAnswerVO.setCompanyId(requestContext.getCompanyId());
            examAnswerVO.setSiteId(requestContext.getSiteId());
            examAnswerVO.setOrgId(requestContext.getOrgId());
            examAnswerVO.setExamId(vo.getExamId());
            examAnswerVO.setAnswerId(vo.getAnswerId());
            if (!CollectionUtils.isEmpty(vo.getEpList())) {
                for (QuestionListVO questionListVO : vo.getEpList()) {
                    ExamProgressVO examProgressVO = new ExamProgressVO();
                    List<StudentOptionVO> optionVOS = new ArrayList<>();
                    examProgressVO.setAnsQId(questionListVO.getAnswerQuestionId());
                    examProgressVO.setType(questionListVO.getType());
                    examProgressVO.setSub(questionListVO.getSub());
                    examProgressVO.setMark(questionListVO.getFlag());
                    if (!CollectionUtils.isEmpty(questionListVO.getQuestionOptions())) {
                        for (QuestionOptionListVO listVO : questionListVO.getQuestionOptions()) {
                            StudentOptionVO optionVO = new StudentOptionVO();
                            optionVO.setOptionId(listVO.getOptionId());
                            optionVO.setAnswer(listVO.getAnswer());
                            optionVO.setSort(listVO.getSort());
                            optionVOS.add(optionVO);
                        }
                    }
                    examProgressVO.setOps(optionVOS);
                    examProgressVOList.add(examProgressVO);
                }
            }
            examAnswerVO.setEpList(examProgressVOList);
            result = examQuestionApiClient.submitExamPage(examAnswerVO);
            vo.setExamId(result.getExamId());
            if (null != result.getIsExamAnswerGoOn() && result.getIsExamAnswerGoOn() == 1) {
                return Response.fail(Constants.EXAM_MSG_NO_EXAM_TIMES);
            }
            if (null != result.getIsExamAnswerGoOn() && result.getIsExamAnswerGoOn() == 2) {
                return Response.fail(Constants.EXAM_MSG_SUBMIT_REPEATITION);
            }
            //考试交卷后积分发放
            try {
                Integer point = result.getPoint();
                if (result.getIsres() == 0) {
                    PointParamVO pointParamVO = new PointParamVO();
                    pointParamVO.setEventName(PointEventEnum.POINTEXAM.getKey());    //事件名称
                    pointParamVO.setActivityType("考试通过积分发放");                //事件类型
                    pointParamVO.setActivitySource("考试");                            //学习活动来源
                    pointParamVO.setActivityName(result.getExamName());                //学习活动名称
                    pointParamVO.setReleaseCondition("范围发放");                    //发放条件
                    pointParamVO.setReleaseRules("按照范围取积分");                    //发放规则
                    pointParamVO.setCreatePointTime(time);                            //积分创建时间
                    pointParamVO.setSourceId(vo.getExamId());                        //积分来源ID，（业务ID主键）
                    pointParamVO.setOperatingPoint(result.getPoint());                //积分数量，  正数 加积分，  负数减积分
                    pointParamVO.setAccountId(requestContext.getAccountId());        //学员ID
                    pointParamVO.setAccountName(requestContext.getAccountName());    //学员名称
                    pointParamVO.setCompanyId(requestContext.getCompanyId());        //企业ID
                    pointParamVO.setSiteId(requestContext.getSiteId());                //站点ID
                    pointParamVO.setOrgId(requestContext.getOrgId());                //组织ID
//                    pointParamVO.setScore(Integer.valueOf(String.valueOf(result.getScore())));
                    pointParamVO.setScore(result.getScore().intValue());
                    String sitePointId = null;
                    if (null != point && point > 0) {
                        sitePointId = pointRedisFeignClients.addPointRedis(pointParamVO);//调用积分接口添加积分
                    }
                    String sitePointId1 = pointRedisFeignClients.addPointRedis(pointParamVO);    //调用积分接口添加积分
                    if (null != sitePointId) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXAM.getKey(), sitePointId);    //发送积分获取消息
                    }
                    if (null != sitePointId1) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXPERIENCEEXAM.getKey(), sitePointId1);    //发送积分获取消息
                    }
                }
            } catch (Exception e) {
                LOG.error("student交卷exam积分发放失败：", e);
            }

            // 考试提交，向培训项目发送消息，告知业务已经完成
            try {
                boolean isFinished = false;
                //如果没有主观题,判断是否合格
                if (result.getIsres() == 0 && result.getScore() != null
                        && result.getScoreSuccess() != null) {
                    if (result.getScore().compareTo(new BigDecimal(result.getScoreSuccess())) != -1) {
                        isFinished = true;
                    }
                }

                LOG.info("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject");
                Float value = null;
                if (result.getIsres() == 0) {
                    value = result.getScore().floatValue();
                }
                boolean finalIsFinished = isFinished;
                Float finalValue = value;
                taskExecutor.asynExecute(new AbstractTaskHandler() {
                    @Override
                    public void handle() {
                        try {
                            cloudEventPublisher.publish(QueueConstant.TRAINING_PROJECT_EVENT_QUEUE,
                                    new EventWrapper<TrainingProjectEvent>(vo.getExamId(),
                                            TrainingProjectEvent.getInstance(vo.getExamId(), ExamConstant.EXAM_TRANINNING_TYPE,
                                                    requestContext.getAccountId(), time,
                                                    requestContext.getSiteId(), finalValue, finalIsFinished)));
                        } catch (Exception e) {
                            e.printStackTrace();
                            LOG.error("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject异常：", e);
                        }
                    }
                });
            } catch (Exception e) {
                LOG.error("student交卷，给trainingProject发送消息失败：", e);
            }

            return Response.ok(result);
        } catch (Exception e) {
            LOG.error("student交卷", e);
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    @ApiOperation(value = "考试时间失效，提交考试", notes = "考试时间失效，提交考试", response = ExamResultVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "answerId", value = "答卷id")
    })
    @PostMapping("/lose/pcSubmit")
    public Response<ExamResultVO> pcSubmitExamLose(@RequestBody ExamAnswerVO vo) {
        try {
            RequestContext requestContext = ContextHolder.get();
            vo.setAccountId(requestContext.getAccountId());
            vo.setAccountName(requestContext.getAccountName());
            vo.setCompanyId(requestContext.getCompanyId());
            vo.setSiteId(requestContext.getSiteId());
            vo.setOrgId(requestContext.getOrgId());
            ExamResultVO result = examQuestionApiClient.submitExamLose(vo);
            vo.setExamId(result.getExamId());

            Date time = new Date();

            //考试交卷后积分发放
            try {
                Integer point = result.getPoint();
                if (result.getIsres() == 0) {
                    PointParamVO pointParamVO = new PointParamVO();
                    pointParamVO.setEventName(PointEventEnum.POINTEXAM.getKey());    //事件名称
                    pointParamVO.setActivityType("考试通过积分发放");                //事件类型
                    pointParamVO.setActivitySource("考试");                            //学习活动来源
                    pointParamVO.setActivityName(result.getExamName());                //学习活动名称
                    pointParamVO.setReleaseCondition("范围发放");                    //发放条件
                    pointParamVO.setReleaseRules("按照范围取积分");                    //发放规则
                    pointParamVO.setCreatePointTime(time);                            //积分创建时间
                    pointParamVO.setSourceId(vo.getExamId());                        //积分来源ID，（业务ID主键）
                    pointParamVO.setOperatingPoint(result.getPoint());                //积分数量，  正数 加积分，  负数减积分
                    pointParamVO.setAccountId(requestContext.getAccountId());        //学员ID
                    pointParamVO.setAccountName(requestContext.getAccountName());    //学员名称
                    pointParamVO.setCompanyId(requestContext.getCompanyId());        //企业ID
                    pointParamVO.setSiteId(requestContext.getSiteId());                //站点ID
                    pointParamVO.setOrgId(requestContext.getOrgId());                //组织ID
//                    pointParamVO.setScore(Integer.valueOf(String.valueOf(result.getScore())));
                    pointParamVO.setScore(result.getScore().intValue());
                    String sitePointId = null;
                    if (null != point && point > 0) {
                        sitePointId = pointRedisFeignClients.addPointRedis(pointParamVO);//调用积分接口添加积分
                    }
                    String sitePointId1 = pointRedisFeignClients.addPointRedis(pointParamVO);    //调用积分接口添加积分
                    if (null != sitePointId) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXAM.getKey(), sitePointId);    //发送积分获取消息
                    }
                    if (null != sitePointId1) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXPERIENCEEXAM.getKey(), sitePointId1);    //发送积分获取消息
                    }
                }
            } catch (Exception e) {
                LOG.error("student交卷exam积分发放失败：", e);
            }

            try {
                boolean isFinished = false;
                //如果没有主观题,判断是否合格
                if (result.getIsres() == 0 && result.getScore() != null
                        && result.getScoreSuccess() != null) {
                    if (result.getScore().compareTo(new BigDecimal(result.getScoreSuccess())) != -1) {
                        isFinished = true;
                    }
                }

                LOG.info("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject");
                Float value = null;
                if (result.getIsres() == 0) {
                    value = result.getScore().floatValue();
                }

                boolean finalIsFinished = isFinished;
                Float finalValue = value;
                taskExecutor.asynExecute(new AbstractTaskHandler() {
                    @Override
                    public void handle() {
                        try {
                            cloudEventPublisher.publish(QueueConstant.TRAINING_PROJECT_EVENT_QUEUE,
                                    new EventWrapper<TrainingProjectEvent>(vo.getExamId(),
                                            TrainingProjectEvent.getInstance(vo.getExamId(), ExamConstant.EXAM_TRANINNING_TYPE,
                                                    requestContext.getAccountId(), time,
                                                    requestContext.getSiteId(), finalValue, finalIsFinished)));
                        } catch (Exception e) {
                            e.printStackTrace();
                            LOG.error("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject异常：", e);
                        }
                    }
                });
            } catch (Exception e) {
                LOG.error("student交卷，给trainingProject发送消息失败：", e);
            }

            return Response.ok(result);
        } catch (Exception e) {
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    @ApiOperation(value = "题目标记", notes = "题目标记")
    @PostMapping("/mark")
    public Response<String> mark(@RequestBody ExamAnswerVO examAnswerVO) {
        try {
            RequestContext requestContext = ContextHolder.get();
            examAnswerVO.setAccountId(requestContext.getAccountId());
            examAnswerVO.setAccountName(requestContext.getAccountName());
            boolean result = examQuestionApiClient.mark(examAnswerVO);
            if (result) {
                return Response.ok(ReturnCode.SUCCESS);
            } else {
                return  Response.fail(ReturnCode.SAVE_FAIL.getCode(),ReturnCode.SAVE_FAIL.getMsg());
            }
        } catch (Exception e) {
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @ApiOperation(value = "pc端题目标记", notes = "pc端题目标记")
    @PostMapping("/pcMark")
    public Response<String> pcMark(@RequestBody ExamAnswerVO examAnswerVO) {
        try {
            RequestContext requestContext = ContextHolder.get();
            examAnswerVO.setAccountId(requestContext.getAccountId());
            examAnswerVO.setAccountName(requestContext.getAccountName());
            boolean result = examQuestionApiClient.mark(examAnswerVO);
            if (result) {
                return Response.ok();
            } else {
                return Response.fail(Constants.MSG_BIZ_FAIL);
            }
        } catch (Exception e) {
            return Response.fail(Constants.MSG_BIZ_FAIL);
        }
    }

    @ApiOperation(value = "答卷历史记录", notes = "答卷历史记录")
    @GetMapping("/history")
    public Response<ExamHistoryVO> selectHistory(@RequestParam("examId") Long examId, @RequestParam("accountId") Long accountId) {
        try {
            List<ExamHistoryVO> examHistoryVOS = examQuestionApiClient.selectHistory(examId, accountId);
            if (examHistoryVOS.size() > 0) {
                return Response.ok(examHistoryVOS);
            } else {
                return Response.fail(ReturnCode.RESOURCE_NOT_FOUND.getCode(),ReturnCode.RESOURCE_NOT_FOUND.getMsg());
            }
        } catch (Exception e) {
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }

    @ApiOperation(value = "考试时间失效，提交考试", notes = "考试时间失效，提交考试", response = ExamResultVO.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "examId", value = "考试ID")
    })
    @PostMapping("/lose/submit")
    public Response<ExamResultVO> submitExamLose(@RequestBody ExamAnswerVO vo) {
        try {
            RequestContext requestContext = ContextHolder.get();
            vo.setAccountId(requestContext.getAccountId());
            vo.setAccountName(requestContext.getAccountName());
            vo.setCompanyId(requestContext.getCompanyId());
            vo.setSiteId(requestContext.getSiteId());
            vo.setOrgId(requestContext.getOrgId());
            ExamResultVO result = examQuestionApiClient.submitExamLose(vo);
            vo.setExamId(result.getExamId());

            Date time = new Date();

            //考试交卷后积分发放
            try {
                Integer point = result.getPoint();
                if (result.getIsres() == 0) {
                    PointParamVO pointParamVO = new PointParamVO();
                    pointParamVO.setEventName(PointEventEnum.POINTEXAM.getKey());    //事件名称
                    pointParamVO.setActivityType("考试通过积分发放");                //事件类型
                    pointParamVO.setActivitySource("考试");                            //学习活动来源
                    pointParamVO.setActivityName(result.getExamName());                //学习活动名称
                    pointParamVO.setReleaseCondition("范围发放");                    //发放条件
                    pointParamVO.setReleaseRules("按照范围取积分");                    //发放规则
                    pointParamVO.setCreatePointTime(time);                            //积分创建时间
                    pointParamVO.setSourceId(result.getExamId());                        //积分来源ID，（业务ID主键）
                    pointParamVO.setOperatingPoint(result.getPoint());                //积分数量，  正数 加积分，  负数减积分
                    pointParamVO.setAccountId(requestContext.getAccountId());        //学员ID
                    pointParamVO.setAccountName(requestContext.getAccountName());    //学员名称
                    pointParamVO.setCompanyId(requestContext.getCompanyId());        //企业ID
                    pointParamVO.setSiteId(requestContext.getSiteId());                //站点ID
                    pointParamVO.setOrgId(requestContext.getOrgId());                //组织ID
//                    pointParamVO.setScore(Integer.valueOf(String.valueOf(result.getScore())));
                    pointParamVO.setScore(result.getScore().intValue());
                    String sitePointId = null;
                    if (null != point && point > 0) {
                        sitePointId = pointRedisFeignClients.addPointRedis(pointParamVO);//调用积分接口添加积分
                    }
                    String sitePointId1 = pointRedisFeignClients.addPointRedis(pointParamVO);    //调用积分接口添加积分
                    if (null != sitePointId) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXAM.getKey(), sitePointId);    //发送积分获取消息
                    }
                    if (null != sitePointId1) {
                        //amqpTemplate.convertAndSend(MQqueuesEnum.EXPERIENCEEXAM.getKey(), sitePointId1);    //发送积分获取消息
                    }
                }
            } catch (Exception e) {
                LOG.error("student交卷exam积分发放失败：", e);
            }

            // 考试提交，向培训项目发送消息，告知业务已经完成
            try {
                boolean isFinished = false;
                //如果没有主观题,判断是否合格
                if (result.getIsres() == 0 && result.getScore() != null
                        && result.getScoreSuccess() != null) {
                    if (result.getScore().compareTo(new BigDecimal(result.getScoreSuccess())) != -1) {
                        isFinished = true;
                    }
                }

                LOG.info("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject");
                Float value = null;
                if (result.getIsres() == 0) {
                    value = result.getScore().floatValue();
                }

                boolean finalIsFinished = isFinished;
                Float finalValue = value;
                taskExecutor.asynExecute(new AbstractTaskHandler() {
                    @Override
                    public void handle() {
                        try {
                            cloudEventPublisher.publish(QueueConstant.TRAINING_PROJECT_EVENT_QUEUE,
                                    new EventWrapper<TrainingProjectEvent>(vo.getExamId(),
                                            TrainingProjectEvent.getInstance(vo.getExamId(), ExamConstant.EXAM_TRANINNING_TYPE,
                                                    requestContext.getAccountId(), time,
                                                    requestContext.getSiteId(), finalValue, finalIsFinished)));
                        } catch (Exception e) {
                            e.printStackTrace();
                            LOG.error("发送考试:(" + vo.getExamId() + ") 合格信息到trainingProject异常：", e);
                        }
                    }
                });
            } catch (Exception e) {
                LOG.error("student交卷，给trainingProject发送消息失败：", e);
            }
            return Response.ok(result);
        } catch (Exception e) {
            return Response.fail(ReturnCode.SERVICE_UNAVAILABLE.getCode(),ReturnCode.SERVICE_UNAVAILABLE.getMsg());
        }
    }
}
