package com.qmth.distributed.print.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.teachcloud.common.bean.marking.CardJpgResult;
import com.qmth.teachcloud.common.bean.marking.ConvertJpgStorage;
import com.qmth.distributed.print.business.bean.params.ExamCardParams;
import com.qmth.distributed.print.business.bean.params.GenericExamCardParams;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.enums.CardStatusEnum;
import com.qmth.distributed.print.business.enums.CardTypeEnum;
import com.qmth.distributed.print.business.enums.MakeMethodEnum;
import com.qmth.distributed.print.business.mapper.ExamCardMapper;
import com.qmth.distributed.print.business.service.*;
import com.qmth.distributed.print.business.util.HtmlToJpgUtil;
import com.qmth.distributed.print.business.util.PdfUtil;
import com.qmth.distributed.print.business.util.pdf.CreatePdfNewUtil;
import com.qmth.teachcloud.common.bean.dto.DataPermissionRule;
import com.qmth.teachcloud.common.bean.vo.FilePathVo;
import com.qmth.teachcloud.common.bean.vo.PaperInfoVo;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicAttachment;
import com.qmth.teachcloud.common.entity.BasicCourse;
import com.qmth.teachcloud.common.entity.BasicPrintConfig;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.CardCreateMethodEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.PageSizeEnum;
import com.qmth.teachcloud.common.enums.UploadFileEnum;
import com.qmth.teachcloud.common.service.*;
import com.qmth.teachcloud.common.util.*;
import com.qmth.teachcloud.mark.service.ScanAnswerCardService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 题卡 服务实现类
 * </p>
 *
 * @author xf
 * @since 2021-03-23
 */
@Service
public class ExamCardServiceImpl extends ServiceImpl<ExamCardMapper, ExamCard> implements ExamCardService {

    @Resource
    private BasicExamRuleService basicExamRuleService;
    @Resource
    private BasicCardRuleService basicCardRuleService;
    @Resource
    private ExamTaskDetailService examTaskDetailService;
    @Resource
    private ExamTaskService examTaskService;
    @Resource
    private BasicAttachmentService basicAttachmentService;
    @Resource
    TeachcloudCommonService teachcloudCommonService;
    @Resource
    BasicCourseService basicCourseService;
    @Resource
    HtmlToJpgUtil htmlToJpgUtil;
    @Resource
    BasicRoleDataPermissionService basicRoleDataPermissionService;
    @Resource
    CreatePdfNewUtil createPdfNewUtil;
    @Resource
    private FileUploadService fileUploadService;
    @Resource
    private ScanAnswerCardService scanAnswerCardService;
    @Resource
    private BasicPrintConfigService basicPrintConfigService;

    @Transactional
    @Override
    public Map<String, String> saveExamCard(ExamCardParams examCardParams) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser user = (SysUser) ServletUtil.getRequestUser();

        // 新增
        ExamCard examCard;
        if (examCardParams.getTitle().getBytes().length > 80) {
            throw ExceptionResultEnum.ERROR.exception("标题最长只能输入80个字符");
        }
        if (examCardParams.getId() == null) {
            validateCardData(examCardParams);

            String title = examCardParams.getPaperId() != null ? examCardParams.getTitle() + SystemConstant.generateRandomNumber(4) : examCardParams.getTitle();

            QueryWrapper<ExamCard> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ExamCard::getSchoolId, schoolId)
                    .eq(ExamCard::getCourseCode, examCardParams.getCourseCode())
                    .eq(ExamCard::getTitle, title);
            List<ExamCard> examCardList = this.list(queryWrapper);
            if (!examCardList.isEmpty()) {
                throw ExceptionResultEnum.ERROR.exception("题卡名称已存在");
            }

            examCard = new ExamCard();
            examCard.setSchoolId(schoolId);
            if (Objects.isNull(examCardParams.getTemplateId())) {
                examCard.setOrgId(basicCourseService.getOrgIdBySchoolIdAndCourseCode(schoolId, examCardParams.getCourseCode()));
            } else {
                examCard.setOrgId(user.getOrgId());
            }
            examCard.setCourseCode(examCardParams.getCourseCode());
            examCard.setCourseName(examCardParams.getCourseName());
            examCard.setTitle(title);
            examCard.setMakeMethod(examCardParams.getMakeMethod());
            examCard.setStatus(examCardParams.getStatus());
            examCard.setType(examCardParams.getType());
            examCard.setAttachmentId(examCardParams.getAttachmentId());
            examCard.setCardRuleId(examCardParams.getCardRuleId());
            examCard.setPaperId(examCardParams.getPaperId());
            examCard.insertInfo(user.getId());
        }
        // 修改
        else {
            String title = examCardParams.getTitle();
            QueryWrapper<ExamCard> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ExamCard::getSchoolId, schoolId)
                    .eq(ExamCard::getCourseCode, examCardParams.getCourseCode())
                    .eq(ExamCard::getTitle, title)
                    .ne(ExamCard::getId, examCardParams.getId());
            List<ExamCard> examCardList = this.list(queryWrapper);
            if (!examCardList.isEmpty()) {
                throw ExceptionResultEnum.ERROR.exception("题卡名称已存在");
            }

            examCard = this.getById(examCardParams.getId());
            examCard.setTitle(title);
            examCard.setStatus(examCardParams.getStatus());
            examCard.setUpdateId(user.getId());
            examCard.setUpdateTime(System.currentTimeMillis());
        }

        // 自动保存
        if (CardStatusEnum.SUBMIT.equals(examCardParams.getStatus())) {
            examCard.setContent(examCardParams.getContent());
            examCard.setStageContent(null);
            examCard.setHtmlContent(examCardParams.getHtmlContent());
            createJpgImage(examCard);
        } else {
            examCard.setStageContent(examCardParams.getContent());
        }
        this.saveOrUpdate(examCard);

        Map<String, String> map = new HashMap<>();
        map.put("id", String.valueOf(examCard.getId()));
        map.put("title", examCard.getTitle());
        return map;
    }

    @Override
    public List<ExamCard> listSelectCard(String courseCode, Long examId, String paperNumber) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        BasicPrintConfig basicPrintConfig = basicPrintConfigService.getByExamId(examId);
        Long cardRuleId = basicPrintConfig.getCardRuleId();

        // 通用题卡
        List<ExamCard> list = new ArrayList<>();
        List<ExamCard> genericCards = this.baseMapper.listGenericCard(schoolId, CardTypeEnum.GENERIC.name(), cardRuleId);
        if (!genericCards.isEmpty()) {
            list.addAll(genericCards);
        }
        // 专卡
        if (SystemConstant.ALL_CARD != cardRuleId) {
            // 只查自己创建的专卡(20230405已改为查询课程下所有题卡，允许复制，不能选择)
            List<ExamCard> customCards = this.baseMapper.listCustom(schoolId, courseCode, CardTypeEnum.CUSTOM.name(), cardRuleId);
            if (!customCards.isEmpty()) {
                list.addAll(customCards);
            }
        }

        // 命题任务未提交的任务，单独查询题卡
        List<ExamCard> customCards = this.baseMapper.listCustomByExamStage(schoolId, examId, courseCode, paperNumber, CardTypeEnum.CUSTOM.name());
        if (!customCards.isEmpty()) {
            for (ExamCard customCard : customCards) {
                long count = list.stream().filter(m -> m.getId().equals(customCard.getId())).count();
                if (count == 0) {
                    list.add(customCard);
                }
            }
        }
        list.sort(Comparator.comparing(ExamCard::getType));
        return list;
    }

    @Override
    public IPage<ExamCard> listPage(Long semesterId, Long examId, String courseCode, String paperNumber, String cardType, String title, String createMethod, Boolean enable, Long createStartTime, Long createEndTime, Integer pageNumber, Integer pageSize) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
        DataPermissionRule dpr = basicRoleDataPermissionService.findDataPermission(schoolId, requestUser.getId(), ServletUtil.getRequest().getServletPath());
        IPage<ExamCard> cardPageDtoIPage = this.baseMapper.listPage(new Page<>(pageNumber, pageSize), schoolId, semesterId, examId, courseCode, paperNumber, cardType, title, createMethod, enable, createStartTime, createEndTime, dpr);
        for (ExamCard record : cardPageDtoIPage.getRecords()) {
            if (StringUtils.isNotBlank(record.getJpgAttachment())) {
                List<JSONObject> mapList = JSON.parseArray(record.getJpgAttachment(), JSONObject.class);
                List<String> imageUrls = new ArrayList<>();
                // 组装图片访问url
                for (JSONObject object : mapList) {
                    imageUrls.add(teachcloudCommonService.filePreview(object.getLong("attachmentId")));
                }
                record.setImageUrls(imageUrls);
            }
        }
        return cardPageDtoIPage;
    }

    @Transactional
    @Override
    public Map<String, String> saveGeneric(GenericExamCardParams params) {
        Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();

        QueryWrapper<ExamCard> checkTitleQueryWrapper = new QueryWrapper<>();
        checkTitleQueryWrapper.lambda().eq(ExamCard::getSchoolId, schoolId)
                .eq(ExamCard::getType, CardTypeEnum.GENERIC)
                .eq(ExamCard::getTitle, params.getTitle().trim());
        ExamCard checkTitleExamCardList = this.getOne(checkTitleQueryWrapper);

        ExamCard examCard = new ExamCard();
        // 新增
        if (Objects.isNull(params.getId())) {
            if (checkTitleExamCardList != null) {
                throw ExceptionResultEnum.ERROR.exception("题卡名称已使用");
            }
            // 保存题卡
            examCard.setId(SystemConstant.getDbUuid());
            examCard.setSchoolId(schoolId);
            examCard.setOrgId(sysUser.getOrgId());

            examCard.setTitle(params.getTitle());
            examCard.setMakeMethod(MakeMethodEnum.SELECT); // 默认值
            // 上传题卡，状态为提交
            examCard.setStatus(CardCreateMethodEnum.UPLOAD.equals(params.getCreateMethod()) ? CardStatusEnum.SUBMIT : CardStatusEnum.valueOf(params.getStatus()));
            examCard.setType(CardTypeEnum.GENERIC); // 默认值
            examCard.setCreateMethod(params.getCreateMethod());
            examCard.setAttachmentId(params.getAttachmentId());
            examCard.setEnable(true); // 默认值
            examCard.setCardRuleId(params.getCardRuleId());
            examCard.setRemark(params.getRemark());
            examCard.setCreateId(sysUser.getId());
            examCard.setCreateTime(System.currentTimeMillis());
            this.save(examCard);

            // 方式为上传
            String htmlContent;
            if (CardCreateMethodEnum.UPLOAD.equals(params.getCreateMethod())) {
                if (params.getAttachmentId() == null) {
                    throw ExceptionResultEnum.ERROR.exception("请上传模板文件");
                }
                BasicAttachment attachment = basicAttachmentService.getById(params.getAttachmentId());
                if (attachment == null) {
                    throw ExceptionResultEnum.ERROR.exception("无模板文件记录，请重新上传");
                }
                if (!SystemConstant.HTML_PREFIX.equalsIgnoreCase(attachment.getType())) {
                    throw ExceptionResultEnum.ERROR.exception("只能上传后缀为.html文件");
                }
                htmlContent = teachcloudCommonService.readFileContent(attachment.getPath());
                examCard.setHtmlContent(htmlContent);
            }
            // 方式为自定义
            else if (CardCreateMethodEnum.STANDARD.equals(params.getCreateMethod())
                    || CardCreateMethodEnum.FREE.equals(params.getCreateMethod())) {
                if (CardStatusEnum.SUBMIT.name().equals(params.getStatus())) {
                    examCard.setContent(params.getContent());
                    examCard.setStageContent(null);
                    htmlContent = params.getHtmlContent();
                    examCard.setHtmlContent(htmlContent);
                } else {
                    examCard.setStageContent(params.getContent());
                }
            } else {
                throw ExceptionResultEnum.ERROR.exception("不存在的题卡创建方式");
            }
        }
        // 修改
        else {
            examCard = this.getById(params.getId());
            if (checkTitleExamCardList != null && !Objects.equals(params.getId(), examCard.getId())) {
                throw ExceptionResultEnum.ERROR.exception("题卡名称重复");
            }
            examCard.setTitle(params.getTitle());
            examCard.setAttachmentId(params.getAttachmentId());
            examCard.setCardRuleId(params.getCardRuleId());
            // 上传题卡，状态为提交
            examCard.setStatus(CardCreateMethodEnum.UPLOAD.equals(params.getCreateMethod()) ? CardStatusEnum.SUBMIT : CardStatusEnum.valueOf(params.getStatus()));
            examCard.setRemark(params.getRemark());
            examCard.setUpdateId(sysUser.getId());
            examCard.setUpdateTime(System.currentTimeMillis());

            String htmlContent;
            // 方式为上传
            if (CardCreateMethodEnum.UPLOAD.equals(params.getCreateMethod())) {
                if (params.getAttachmentId() == null) {
                    throw ExceptionResultEnum.ERROR.exception("请上传模板文件");
                }
                BasicAttachment attachment = basicAttachmentService.getById(params.getAttachmentId());
                if (attachment == null) {
                    throw ExceptionResultEnum.ERROR.exception("无模板文件记录，请重新上传");
                }
                if (!SystemConstant.HTML_PREFIX.equalsIgnoreCase(attachment.getType())) {
                    throw ExceptionResultEnum.ERROR.exception("只能上传后缀为.html文件");
                }
                htmlContent = teachcloudCommonService.readFileContent(attachment.getPath());
                examCard.setHtmlContent(htmlContent);
                // 上传题卡，状态为提交
                examCard.setStatus(CardStatusEnum.SUBMIT);
            }
            // 方式为自定义
            else if (CardCreateMethodEnum.STANDARD.equals(params.getCreateMethod()) || CardCreateMethodEnum.FREE.equals(params.getCreateMethod())) {
                if (CardStatusEnum.SUBMIT.name().equals(params.getStatus())) {
                    examCard.setContent(params.getContent());
                    examCard.setStageContent(null);
                    htmlContent = params.getHtmlContent();
                    examCard.setHtmlContent(htmlContent);
                } else {
                    examCard.setStageContent(params.getContent());
                }
            } else {
                throw ExceptionResultEnum.ERROR.exception("不存在的题卡创建方式");
            }
        }
        if (CardStatusEnum.SUBMIT.name().equals(params.getStatus())) {
            // 生成题卡图片
            createJpgImage(examCard);
        }
        this.saveOrUpdate(examCard);
        Map<String, String> map = new HashMap<>();
        map.put("id", String.valueOf(examCard.getId()));
        map.put("title", examCard.getTitle());
        return map;
    }

    @Override
    public Boolean deleteGeneric(Long id) {
        // 校验题卡是否被绑定
        List<ExamTaskDetail> examTaskDetails = examTaskDetailService.getExamTaskDetailByCardIdJson(id);
        if (examTaskDetails != null && examTaskDetails.size() > 0) {
            throw ExceptionResultEnum.ERROR.exception("题卡已绑定命题任务，不能删除");
        }
        return this.removeById(id);
    }

    @Transactional
    @Override
    public Long copyCard(Long id, String courseCode) {
        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();

        ExamCard examCard = this.getById(id);
        if (examCard == null) {
            throw ExceptionResultEnum.ERROR.exception("题卡不存在");
        }
        if (CardTypeEnum.CUSTOM.equals(examCard.getType()) && !courseCode.equals(examCard.getCourseCode())) {
            throw ExceptionResultEnum.ERROR.exception("复制的题卡不属于当前课程，无法复制");
        }

        // 复制题卡
        ExamCard copyExamCard = new ExamCard();
        BeanUtils.copyProperties(examCard, copyExamCard);
        copyExamCard.setTitle(checkTitle(examCard, courseCode));
        copyExamCard.insertInfo(requestUser.getId());
        if (CardTypeEnum.GENERIC.equals(examCard.getType()) && CardCreateMethodEnum.STANDARD.equals(examCard.getCreateMethod())) {
            BasicCourse basicCourse = basicCourseService.findByCourseCode(courseCode, requestUser.getSchoolId());
            copyExamCard.setCourseCode(courseCode);
            copyExamCard.setCourseName(basicCourse != null ? basicCourse.getName() : null);
            copyExamCard.setMakeMethod(MakeMethodEnum.SELF);
            copyExamCard.setCreateMethod(null);
            copyExamCard.setType(CardTypeEnum.CUSTOM);
        }
        copyExamCard.setRemark(String.format("来源题卡:%s(%s)", id, examCard.getTitle()));
        copyExamCard.setUsed(false);
        // 生成图片
        createJpgImage(copyExamCard);
        this.save(copyExamCard);
        return copyExamCard.getId();
    }

    @Override
    public void convertImage(Long id) {
        ExamCard examCard = this.getById(id);
        createJpgImage(examCard);
        if (examCard.getJpgAttachment().length() > 0) {
            UpdateWrapper<ExamCard> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda().set(ExamCard::getBlankCardPath, examCard.getBlankCardPath())
                    .set(ExamCard::getJpgAttachment, examCard.getJpgAttachment())
                    .eq(ExamCard::getId, id);
            this.update(updateWrapper);
        }
    }

    @Override
    public void downloadCard(HttpServletResponse response, String id) {
        String rootPath = null;
        try {
            // 题卡详细信息
            ExamCard examCard = this.getById(id);
            // 本地保存目录
            File tempFile = SystemConstant.getFileTempParentDirVar(SystemConstant.TEMP_PREFIX);
            rootPath = tempFile.getPath() + File.separator + SystemConstant.getNanoId();
            // 下载文件保存路径（以题卡名称命名）
            String downloadFilePath = rootPath + File.separator + examCard.getTitle();
            File downloadPathFile = new File(downloadFilePath);
            if (!downloadPathFile.exists()) {
                downloadPathFile.mkdirs();
            }

            // 通用模板
            String htmlContent = createPdfNewUtil.replaceBlankHtmlContent(examCard.getHtmlContent());
            // html文件
            File htmlFile = new File(downloadFilePath, examCard.getTitle() + SystemConstant.HTML_PREFIX);
            if (!htmlFile.exists()) {
                htmlFile.createNewFile();
            }
            // 生成html文件
            FileUtil.writeContent(htmlFile, htmlContent);

            // pdf文件
            File pdfFile = new File(downloadFilePath, examCard.getTitle() + SystemConstant.PDF_PREFIX);
            if (!pdfFile.exists()) {
                pdfFile.createNewFile();
            }
            HtmlToPdfUtil.convert(htmlFile.getPath(), pdfFile.getPath(), PageSizeEnum.A3);

            // jpg文件
            String jpgAttachmentIds = examCard.getJpgAttachment();
            if (StringUtils.isNotBlank(jpgAttachmentIds)) {
                List<ConvertJpgStorage> jsonObjectList = JSONObject.parseArray(jpgAttachmentIds, ConvertJpgStorage.class);
                for (ConvertJpgStorage convertJpgStorage : jsonObjectList) {
                    Long jpgAttachmentId = convertJpgStorage.getAttachmentId();
                    Integer index = convertJpgStorage.getIndex();
                    if (jpgAttachmentId != null) {
                        BasicAttachment attachment = basicAttachmentService.getById(jpgAttachmentId);
                        if (attachment != null) {
                            String fileName = downloadFilePath + File.separator + examCard.getTitle() + SystemConstant.HYPHEN + index + attachment.getType();
                            fileUploadService.downloadFile(attachment.getPath(), fileName);
                        }
                    }
                }
            }

            // json文件
            String content = examCard.getContent();
            if (StringUtils.isNotBlank(content)) {
                String jsonPath = downloadFilePath + File.separator + examCard.getTitle() + SystemConstant.JSON_PREFIX;
                FileUtil.writeContent(new File(jsonPath), content);
            }

            String zipFileName = examCard.getTitle() + SystemConstant.ZIP_PREFIX;
//            teachcloudCommonService.downloadFileAndZip(response, rootPath, rootPath, zipFileName);
            FileUtil.downloadEncryptZip(response, downloadPathFile, zipFileName);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (Objects.nonNull(rootPath)) {
                FileUtil.deleteDirectory(rootPath);
            }
        }
    }

    @Override
    public List<CardJpgResult> listCardImage(Long examId, String paperNumber, String paperType) {
        ExamTask examTask = examTaskService.getOne(new QueryWrapper<ExamTask>().lambda()
                .eq(ExamTask::getExamId, examId)
                .eq(ExamTask::getPaperNumber, paperNumber));
        if (examTask == null) {
            return scanAnswerCardService.listPageImage(examId, paperNumber, paperType);
        }
        Long examTaskId = examTask.getId();
        ExamTaskDetail examTaskDetail = examTaskDetailService.getOne(new QueryWrapper<ExamTaskDetail>().lambda()
                .eq(ExamTaskDetail::getExamTaskId, examTaskId));
        List<CardJpgResult> cardJpgResultList = new ArrayList<>();
        if (Objects.nonNull(examTaskDetail) && Objects.nonNull(examTaskDetail.getPaperAttachmentIds())) {
            List<PaperInfoVo> paperInfoVoList = ExamTaskUtil.parsePaperAttachmentPath(examTaskDetail.getPaperAttachmentIds());
            for (PaperInfoVo paperInfoVo : paperInfoVoList) {
                if (!paperType.equals(paperInfoVo.getName())) {
                    // 试卷类型不匹配跳过
                    continue;
                }
                String jpgAttachmentInfo = this.getOne(new QueryWrapper<ExamCard>().lambda()
                        .eq(ExamCard::getId, paperInfoVo.getCardId())).getJpgAttachment();
                if (StringUtils.isBlank(jpgAttachmentInfo)) {
                    return new ArrayList<>();
                }

                List<ConvertJpgStorage> convertJpgStorageList = JSONObject.parseArray(jpgAttachmentInfo, ConvertJpgStorage.class);

                cardJpgResultList.addAll(convertJpgStorageList.stream().flatMap(e -> {
                    BasicAttachment basicAttachment = basicAttachmentService.getById(e.getAttachmentId());

                    CardJpgResult cardJpgResult = new CardJpgResult();
                    cardJpgResult.setName(basicAttachment.getName());
                    cardJpgResult.setIndex(e.getIndex());
                    cardJpgResult.setPath(teachcloudCommonService.filePreview(basicAttachment.getPath()));
                    return Stream.of(cardJpgResult);
                }).collect(Collectors.toList()));
            }
        } else {
            return scanAnswerCardService.listPageImage(examId, paperNumber, paperType);
        }
        return cardJpgResultList;
    }

    /**
     * 生成新的title
     *
     * @param examCard 题卡对象
     */
    private String checkTitle(ExamCard examCard, String courseCode) {
        String title;
        int i = 1;
        ExamCard newExamCard;
        do {
            title = examCard.getTitle() + "副本" + i;
            QueryWrapper<ExamCard> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(ExamCard::getSchoolId, examCard.getSchoolId())
                    .eq(ExamCard::getCourseCode, courseCode)
                    .eq(ExamCard::getTitle, title);
            newExamCard = this.getOne(queryWrapper);
            i++;
        } while (newExamCard != null);
        return title;
    }

    /**
     * 数据验证
     *
     * @param examCardParams
     */
    private void validateCardData(ExamCardParams examCardParams) {
        BasicExamRule basicExamRule = basicExamRuleService.getBySchoolId();
        if (basicExamRule == null) {
            throw ExceptionResultEnum.ERROR.exception("通用规则未设置");
        }

//        if (Objects.isNull(examCardParams.getMakeMethod())) {
//            throw ExceptionResultEnum.ERROR.exception("题卡制作方式不能为空");
//        }
        if (examCardParams.getStatus() == null) {
            throw ExceptionResultEnum.ERROR.exception("提交方式不能为空");
        }
        if (CardTypeEnum.CUSTOM.name().equals(examCardParams.getType().name())) {
//            if (examCardParams.getExamTaskId() == null) {
//                throw ExceptionResultEnum.ERROR.exception("命题任务ID不能为空");
//            }
            if (StringUtils.isBlank(examCardParams.getCourseCode())) {
                throw ExceptionResultEnum.ERROR.exception("课程代码不能为空");
            }
            if (StringUtils.isBlank(examCardParams.getCourseName())) {
                throw ExceptionResultEnum.ERROR.exception("课程名称不能为空");
            }
            if (MakeMethodEnum.SELECT.name().equals(examCardParams.getMakeMethod().name())) {
                if (examCardParams.getId() == null) {
                    throw ExceptionResultEnum.ERROR.exception("选择已有题卡时，题卡ID不能为空");
                }
                // 当前选择题卡是否已绑定（不再校验是否使用  2023-06-20）
            } else if (MakeMethodEnum.SELF.name().equals(examCardParams.getMakeMethod().name())) {
                if (StringUtils.isBlank(examCardParams.getTitle())) {
                    throw ExceptionResultEnum.ERROR.exception("题卡标题不能为空");
                }
                if (StringUtils.isBlank(examCardParams.getContent())) {
                    throw ExceptionResultEnum.ERROR.exception("题卡内容不能为空");
                }
                if (CardStatusEnum.SUBMIT.name().equals(examCardParams.getStatus().name())) {
                    if (StringUtils.isBlank(examCardParams.getHtmlContent())) {
                        throw ExceptionResultEnum.ERROR.exception("提交题卡时，html内容不能为空");
                    }
                }
            } else {
                throw ExceptionResultEnum.ERROR.exception("不支持的题卡制作方式");
            }
        }
    }

    @Override
    public ExamCard createJpgImage(ExamCard examCard) {
        BasicCardRule basicCardRule = basicCardRuleService.getById(examCard.getCardRuleId());
        String replaceBackupCardHtmlContent = createPdfNewUtil.replaceBackupCardHtmlParam(examCard.getHtmlContent(), null, basicCardRule, null);
        File pdfFile = PdfUtil.htmlToPdf(replaceBackupCardHtmlContent);
        try {
            String fileName = PdfUtil.md5FileName("BLANK" + examCard.getId()) + SystemConstant.PDF_PREFIX;
            FilePathVo filePathVo = fileUploadService.uploadFile(pdfFile, UploadFileEnum.PDF, fileName);
            examCard.setBlankCardPath(JSON.toJSONString(filePathVo));
            List<ConvertJpgStorage> convertJpgStorageList = htmlToJpgUtil.convertPdfToJpg(examCard.getId(), pdfFile, examCard.getCreateId());
            if (convertJpgStorageList.size() > 0) {
                examCard.setJpgAttachment(JSON.toJSONString(convertJpgStorageList));
            } else {
                examCard.setJpgAttachment(null);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (pdfFile.exists()) {
                FileUtil.deleteFile(pdfFile);
            }
        }
        return examCard;
    }

    @Override
    public void downloadCardJson(HttpServletResponse response, String id) {
        File tempParentFile = null;
        try {
            // 题卡详细信息
            ExamCard examCard = this.getById(id);
            // json文件
            String content = examCard.getContent();
            if (StringUtils.isNotBlank(content)) {
                // 本地保存目录
                tempParentFile = SystemConstant.getFileTempDirVar(SystemConstant.JSON_PREFIX);
                // todo 2024-03-02 处理content卡格式填涂点信息
                FileUtil.writeContent(tempParentFile, content);
                FileUtil.outputFile(response, tempParentFile, examCard.getTitle() + SystemConstant.JSON_PREFIX);
            } else {
                throw ExceptionResultEnum.ERROR.exception("没有可下载的卡格式文件");
            }
        } catch (Exception e) {
            throw ExceptionResultEnum.ERROR.exception("下载卡格式文件失败");
        } finally {
            if (Objects.nonNull(tempParentFile)) {
                FileUtil.deleteFile(tempParentFile);
            }
        }
    }
}
