package com.yunzhupaas.service.impl;

import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.dto.*;
import com.yunzhupaas.entity.*;
import com.yunzhupaas.mapper.TrainExamRecordsMapper;
import com.yunzhupaas.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunzhupaas.model.trainexamrecords.*;
import org.springframework.stereotype.Service;
import com.yunzhupaas.base.service.SuperServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import com.yunzhupaas.util.GeneraterSwapUtil;

import java.sql.Connection;
import java.sql.SQLException;

import lombok.Cleanup;
import com.yunzhupaas.database.plugins.DynamicSourceGeneratorInterface;
import com.yunzhupaas.database.util.DynamicDataSourceUtil;
import org.apache.commons.collections4.CollectionUtils;
import com.yunzhupaas.i18n.util.I18nUtil;
import com.yunzhupaas.exception.DataException;

import java.math.BigDecimal;

import cn.hutool.core.util.ObjectUtil;

import java.lang.reflect.Field;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;

import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.yunzhupaas.base.model.ColumnDataModel;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.yunzhupaas.model.QueryAllModel;

import java.text.SimpleDateFormat;

import com.yunzhupaas.util.*;

import java.util.*;

import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.permission.entity.UserEntity;
import com.github.pagehelper.PageHelper;

/**
 * 考试记录
 * 版本： V5.2.0
 * 版权： Copyright @ 2025
 * 作者： 浙江尖峰集团股份有限公司
 * 日期： 2024-11-06
 */
@Service
public class TrainExamRecordsServiceImpl extends SuperServiceImpl<TrainExamRecordsMapper, TrainExamRecordsEntity>
        implements TrainExamRecordsService {
    @Autowired
    private GeneraterSwapUtil generaterSwapUtil;
    @Autowired
    private TrainExamRecordsService trainExamRecordsService;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private TrainTestPaperLibraryService trainTestPaperLibraryService;
    @Autowired
    private TrainLibrarySingleService trainLibrarySingleService;
    @Autowired
    private TrainLibraryMoreService trainLibraryMoreService;
    @Autowired
    private TrainLibraryJudgmentService trainLibraryJudgmentService;
    @Autowired
    private TrainLibraryEssayQuestionService trainLibraryEssayQuestionService;

    @Override
    public List<TrainExamRecordsEntity> getList(TrainExamRecordsPagination trainExamRecordsPagination) {
        return getTypeList(trainExamRecordsPagination, trainExamRecordsPagination.getDataType());
    }

    /**
     * 列表查询
     */
    @Override
    public List<TrainExamRecordsEntity> getTypeList(TrainExamRecordsPagination trainExamRecordsPagination,
            String dataType) {
        String userId = userProvider.get().getUserId();
        Map<String, Class> tableClassMap = new HashMap<>();
        tableClassMap.put("make_train_exam_records", TrainExamRecordsEntity.class);
        tableClassMap.put("make_train_library_essay_question", TrainLibraryEssayQuestionEntity.class);
        tableClassMap.put("make_train_library_judgment", TrainLibraryJudgmentEntity.class);
        tableClassMap.put("make_train_library_more", TrainLibraryMoreEntity.class);
        tableClassMap.put("make_train_library_single", TrainLibrarySingleEntity.class);

        MPJLambdaWrapper<TrainExamRecordsEntity> wrapper = JoinWrappers
                .lambda("make_train_exam_records", TrainExamRecordsEntity.class)
                .selectCollection(TrainLibraryEssayQuestionEntity.class,
                        TrainExamRecordsEntity::getTrainLibraryEssayQuestion)
                .leftJoin(TrainLibraryEssayQuestionEntity.class, "make_train_library_essay_question",
                        TrainLibraryEssayQuestionEntity::getFbankId, TrainExamRecordsEntity::getId)
                .selectCollection(TrainLibraryJudgmentEntity.class, TrainExamRecordsEntity::getTrainLibraryJudgment)
                .leftJoin(TrainLibraryJudgmentEntity.class, "make_train_library_judgment",
                        TrainLibraryJudgmentEntity::getFbankId, TrainExamRecordsEntity::getId)
                .selectCollection(TrainLibraryMoreEntity.class, TrainExamRecordsEntity::getTrainLibraryMore)
                .leftJoin(TrainLibraryMoreEntity.class, "make_train_library_more", TrainLibraryMoreEntity::getFbankId,
                        TrainExamRecordsEntity::getId)
                .selectCollection(TrainLibrarySingleEntity.class, TrainExamRecordsEntity::getTrainLibrarySingle)
                .leftJoin(TrainLibrarySingleEntity.class, "make_train_library_single",
                        TrainLibrarySingleEntity::getFbankId, TrainExamRecordsEntity::getId)
                .selectAll(TrainExamRecordsEntity.class);
        MPJLambdaWrapper<TrainExamRecordsEntity> wrapper2 = JoinWrappers
                .lambda("make_train_exam_records", TrainExamRecordsEntity.class)
                .leftJoin(TrainLibraryEssayQuestionEntity.class, "make_train_library_essay_question",
                        TrainLibraryEssayQuestionEntity::getFbankId, TrainExamRecordsEntity::getId)
                .leftJoin(TrainLibraryJudgmentEntity.class, "make_train_library_judgment",
                        TrainLibraryJudgmentEntity::getFbankId, TrainExamRecordsEntity::getId)
                .leftJoin(TrainLibraryMoreEntity.class, "make_train_library_more", TrainLibraryMoreEntity::getFbankId,
                        TrainExamRecordsEntity::getId)
                .leftJoin(TrainLibrarySingleEntity.class, "make_train_library_single",
                        TrainLibrarySingleEntity::getFbankId, TrainExamRecordsEntity::getId)
                .distinct().select(TrainExamRecordsEntity::getId);

        QueryAllModel queryAllModel = new QueryAllModel();
        queryAllModel.setWrapper(wrapper);
        queryAllModel.setClassMap(tableClassMap);
        queryAllModel.setDbLink(TrainExamRecordsConstant.DBLINKID);
        // 数据过滤
        boolean isPc = ServletUtil.getHeader("yunzhupaas-origin").equals("pc");
        String columnData = !isPc ? TrainExamRecordsConstant.getAppColumnData()
                : TrainExamRecordsConstant.getColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        String ruleJson = !isPc ? JsonUtil.getObjectToString(columnDataModel.getRuleListApp())
                : JsonUtil.getObjectToString(columnDataModel.getRuleList());
        queryAllModel.setRuleJson(ruleJson);
        // 高级查询
        boolean hasSuperQuery = true;
        if (hasSuperQuery) {
            queryAllModel.setSuperJson(trainExamRecordsPagination.getSuperQueryJson());
        }
        // 数据权限
        boolean pcPermission = true;
        boolean appPermission = false;
        if (isPc && pcPermission && !userProvider.get().getIsAdministrator()) {
            queryAllModel.setModuleId(trainExamRecordsPagination.getMenuId());
            queryAllModel.setModuleId(trainExamRecordsPagination.getMenuId());
        }
        if (!isPc && appPermission && !userProvider.get().getIsAdministrator()) {
            queryAllModel.setModuleId(trainExamRecordsPagination.getMenuId());
        }
        // 拼接复杂条件
        wrapper = generaterSwapUtil.getConditionAllTable(queryAllModel);
        queryAllModel.setWrapper(wrapper2);
        wrapper2 = generaterSwapUtil.getConditionAllTable(queryAllModel);
        // 其他条件拼接
        otherConditions(trainExamRecordsPagination, wrapper, isPc);
        otherConditions(trainExamRecordsPagination, wrapper2, isPc);

        if ("0".equals(dataType)) {
            com.github.pagehelper.Page<Object> objects = PageHelper.startPage(
                    (int) trainExamRecordsPagination.getCurrentPage(), (int) trainExamRecordsPagination.getPageSize(),
                    true);
            List<TrainExamRecordsEntity> userIPage = this.selectJoinList(TrainExamRecordsEntity.class, wrapper2);
            List<Object> collect = userIPage.stream().map(t -> t.getId()).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                wrapper.in(TrainExamRecordsEntity::getId, collect);
            }
            List<TrainExamRecordsEntity> result = this.selectJoinList(TrainExamRecordsEntity.class, wrapper);
            return trainExamRecordsPagination.setData(result, objects.getTotal());
        } else {
            List<TrainExamRecordsEntity> list = this.selectJoinList(TrainExamRecordsEntity.class, wrapper);
            if ("2".equals(dataType)) {
                List<String> selectIds = Arrays.asList(trainExamRecordsPagination.getSelectIds());
                return list.stream().filter(t -> selectIds.contains(t.getId().toString())).collect(Collectors.toList());
            } else {
                return list;
            }
        }

    }

    /**
     * 其他条件拼接
     */
    private void otherConditions(TrainExamRecordsPagination trainExamRecordsPagination,
            MPJLambdaWrapper<TrainExamRecordsEntity> wrapper, boolean isPc) {
        String databaseName;
        try {
            @Cleanup
            Connection cnn = DynamicDataSourceUtil.getCurrentConnection();
            databaseName = cnn.getMetaData().getDatabaseProductName().trim();
        } catch (SQLException e) {
            throw new DataException(e.getMessage());
        }
        wrapper.isNull(TrainExamRecordsEntity::getFlowId);
        // 关键词
        if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getYunzhupaasKeyword())) {
        }
        // 普通查询
        if (isPc) {
            if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getFexaminers())) {
                List<String> idList = new ArrayList<>();
                try {
                    String[][] fexaminers = JsonUtil.getJsonToBean(trainExamRecordsPagination.getFexaminers(),
                            String[][].class);
                    for (int i = 0; i < fexaminers.length; i++) {
                        if (fexaminers[i].length > 0) {
                            idList.add(JsonUtil.getObjectToString(Arrays.asList(fexaminers[i])));
                        }
                    }
                } catch (Exception e1) {
                    try {
                        List<String> fexaminers = JsonUtil.getJsonToList(trainExamRecordsPagination.getFexaminers(),
                                String.class);
                        if (fexaminers.size() > 0) {
                            idList.addAll(fexaminers);
                        }
                    } catch (Exception e2) {
                        idList.add(String.valueOf(trainExamRecordsPagination.getFexaminers()));
                    }
                }
                wrapper.and(t -> {
                    idList.forEach(tt -> {
                        if (StringUtil.isNotEmpty(tt) && "Microsoft SQL Server".equalsIgnoreCase(databaseName)) {
                            tt = tt.replaceFirst("\\[", "[[]");
                        }
                        t.like(TrainExamRecordsEntity::getFexaminers, tt).or();
                    });
                });
            }

            if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getFresultScore())) {
                List FresultScoreList = JsonUtil.getJsonToList(trainExamRecordsPagination.getFresultScore(),
                        String.class);
                for (int i = 0; i < FresultScoreList.size(); i++) {
                    String id = String.valueOf(FresultScoreList.get(i));
                    boolean idAll = StringUtil.isNotEmpty(id) && !id.equals("null");
                    if (idAll) {
                        Object b = new BigDecimal(id);
                        if (i == 0) {
                            wrapper.ge(TrainExamRecordsEntity::getFresultScore, b);
                        } else {
                            wrapper.le(TrainExamRecordsEntity::getFresultScore, b);
                        }
                    }
                }
            }

            if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getFfullName())) {
                String value = trainExamRecordsPagination.getFfullName() instanceof List
                        ? JsonUtil.getObjectToString(trainExamRecordsPagination.getFfullName())
                        : String.valueOf(trainExamRecordsPagination.getFfullName());
                wrapper.like(TrainExamRecordsEntity::getFfullName, value);
            }

            if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getFsort())) {
                List<String> idList = new ArrayList<>();
                try {
                    String[][] fsort = JsonUtil.getJsonToBean(trainExamRecordsPagination.getFsort(), String[][].class);
                    for (int i = 0; i < fsort.length; i++) {
                        if (fsort[i].length > 0) {
                            idList.add(JsonUtil.getObjectToString(Arrays.asList(fsort[i])));
                        }
                    }
                } catch (Exception e1) {
                    try {
                        List<String> fsort = JsonUtil.getJsonToList(trainExamRecordsPagination.getFsort(),
                                String.class);
                        if (fsort.size() > 0) {
                            idList.addAll(fsort);
                        }
                    } catch (Exception e2) {
                        idList.add(String.valueOf(trainExamRecordsPagination.getFsort()));
                    }
                }
                wrapper.and(t -> {
                    idList.forEach(tt -> {
                        if (StringUtil.isNotEmpty(tt) && "Microsoft SQL Server".equalsIgnoreCase(databaseName)) {
                            tt = tt.replaceFirst("\\[", "[[]");
                        }
                        t.like(TrainExamRecordsEntity::getFsort, tt).or();
                    });
                });
            }

            if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getFcreatorTime())) {
                List FcreatorTimeList = JsonUtil.getJsonToList(trainExamRecordsPagination.getFcreatorTime(),
                        String.class);
                for (int i = 0; i < FcreatorTimeList.size(); i++) {
                    String id = String.valueOf(FcreatorTimeList.get(i));
                    boolean idAll = StringUtil.isNotEmpty(id) && !id.equals("null");
                    if (idAll) {
                        Object b = new Date(Long.valueOf(id));
                        if (i == 0) {
                            wrapper.ge(TrainExamRecordsEntity::getFcreatorTime, b);
                        } else {
                            wrapper.le(TrainExamRecordsEntity::getFcreatorTime, b);
                        }
                    }
                }
            }

            if (ObjectUtil.isNotEmpty(trainExamRecordsPagination.getFquestionStatus())) {
                List<String> idList = new ArrayList<>();
                try {
                    String[][] fquestionStatus = JsonUtil.getJsonToBean(trainExamRecordsPagination.getFquestionStatus(),
                            String[][].class);
                    for (int i = 0; i < fquestionStatus.length; i++) {
                        if (fquestionStatus[i].length > 0) {
                            idList.add(JsonUtil.getObjectToString(Arrays.asList(fquestionStatus[i])));
                        }
                    }
                } catch (Exception e1) {
                    try {
                        List<String> fquestionStatus = JsonUtil
                                .getJsonToList(trainExamRecordsPagination.getFquestionStatus(), String.class);
                        if (fquestionStatus.size() > 0) {
                            idList.addAll(fquestionStatus);
                        }
                    } catch (Exception e2) {
                        idList.add(String.valueOf(trainExamRecordsPagination.getFquestionStatus()));
                    }
                }
                wrapper.and(t -> {
                    idList.forEach(tt -> {
                        if (StringUtil.isNotEmpty(tt) && "Microsoft SQL Server".equalsIgnoreCase(databaseName)) {
                            tt = tt.replaceFirst("\\[", "[[]");
                        }
                        t.like(TrainExamRecordsEntity::getFquestionStatus, tt).or();
                    });
                });
            }

        }
        // 排序
        if (StringUtil.isEmpty(trainExamRecordsPagination.getSidx())) {
            wrapper.orderByDesc(TrainExamRecordsEntity::getId);
        } else {
            try {
                String[] split = trainExamRecordsPagination.getSidx().split(",");
                for (String sidx : split) {
                    TrainExamRecordsEntity trainExamRecordsEntity = new TrainExamRecordsEntity();
                    String oderTableField = trainExamRecordsEntity.getClass().getAnnotation(TableName.class).value();
                    if (sidx.startsWith("-")) {
                        Field declaredField = trainExamRecordsEntity.getClass().getDeclaredField(sidx.substring(1));
                        declaredField.setAccessible(true);
                        oderTableField = oderTableField + "." + declaredField.getAnnotation(TableField.class).value();
                        wrapper.select(oderTableField);
                        wrapper.orderByDesc(oderTableField);
                    } else {
                        Field declaredField = trainExamRecordsEntity.getClass().getDeclaredField(sidx);
                        declaredField.setAccessible(true);
                        oderTableField = oderTableField + "." + declaredField.getAnnotation(TableField.class).value();
                        wrapper.select(oderTableField);
                        wrapper.orderByAsc(oderTableField);
                    }
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public TrainExamRecordsEntity getInfo(String id) {
        MPJLambdaWrapper<TrainExamRecordsEntity> wrapper = JoinWrappers
                .lambda("make_train_exam_records", TrainExamRecordsEntity.class)
                .selectCollection(TrainLibraryEssayQuestionEntity.class,
                        TrainExamRecordsEntity::getTrainLibraryEssayQuestion)
                .leftJoin(TrainLibraryEssayQuestionEntity.class, "make_train_library_essay_question",
                        TrainLibraryEssayQuestionEntity::getFbankId, TrainExamRecordsEntity::getId)
                .selectCollection(TrainLibraryJudgmentEntity.class, TrainExamRecordsEntity::getTrainLibraryJudgment)
                .leftJoin(TrainLibraryJudgmentEntity.class, "make_train_library_judgment",
                        TrainLibraryJudgmentEntity::getFbankId, TrainExamRecordsEntity::getId)
                .selectCollection(TrainLibraryMoreEntity.class, TrainExamRecordsEntity::getTrainLibraryMore)
                .leftJoin(TrainLibraryMoreEntity.class, "make_train_library_more", TrainLibraryMoreEntity::getFbankId,
                        TrainExamRecordsEntity::getId)
                .selectCollection(TrainLibrarySingleEntity.class, TrainExamRecordsEntity::getTrainLibrarySingle)
                .leftJoin(TrainLibrarySingleEntity.class, "make_train_library_single",
                        TrainLibrarySingleEntity::getFbankId, TrainExamRecordsEntity::getId)
                .selectAll(TrainExamRecordsEntity.class);
        wrapper.and(
                t -> t.eq(TrainExamRecordsEntity::getId, id)
                        .or().eq(TrainExamRecordsEntity::getFlowTaskId, id));
        return this.selectJoinOne(TrainExamRecordsEntity.class, wrapper);
    }

    @Override
    public void create(TrainExamRecordsEntity entity) {
        this.save(entity);
    }

    @Override
    public boolean update(String id, TrainExamRecordsEntity entity) {
        return this.updateById(entity);
    }

    @Override
    public void delete(TrainExamRecordsEntity entity) {
        if (entity != null) {
            this.removeById(entity.getId());
        }
    }

    /**
     * 验证表单唯一字段，正则，非空 i-0新增-1修改
     */
    @Override
    public String checkForm(TrainExamRecordsForm form, int i) {
        boolean isUp = StringUtil.isNotEmpty(form.getId()) && !form.getId().equals("0");
        Object id = null;
        String countRecover = "";
        String fieldTipName = "";
        String canNotNull = I18nUtil.getMessageStr("sys.validate.textRequiredSuffix", "不能为空");
        String canNotRepeated = I18nUtil.getMessageStr("EXIST103", "不能重复");
        if (isUp) {
            id = form.getId();
        }
        // 主表字段验证
        fieldTipName = "试卷名称";
        if (StringUtil.isEmpty(form.getFfullName())) {
            return fieldTipName + canNotNull;
        }
        fieldTipName = "试题分类";
        fieldTipName = "考试人员";
        fieldTipName = "考试成绩";
        fieldTipName = "总分数";
        fieldTipName = "总题数";
        fieldTipName = "每题分数";
        fieldTipName = "是否存在问答题";
        fieldTipName = "阅卷状态";
        fieldTipName = "创建用户";
        fieldTipName = "完成时间";
        fieldTipName = "修改用户";
        fieldTipName = "修改时间";
        fieldTipName = "所属组织";
        // 子表字段验证
        if (form.getTrainLibrarySingleList() != null) {

            fieldTipName = "单选题"
                    + "-" + "题目难度";

            fieldTipName = "单选题"
                    + "-" + "分类";

            fieldTipName = "单选题"
                    + "-" + "题目名称";

            fieldTipName = "单选题"
                    + "-" + "解析";

            fieldTipName = "单选题"
                    + "-" + "答案";

            fieldTipName = "单选题"
                    + "-" + "题目类型";

            fieldTipName = "单选题"
                    + "-" + "选项A";

            fieldTipName = "单选题"
                    + "-" + "选项B";

            fieldTipName = "单选题"
                    + "-" + "选项C";

            fieldTipName = "单选题"
                    + "-" + "选项D";

            fieldTipName = "单选题"
                    + "-" + "所属组织";

            fieldTipName = "单选题"
                    + "-" + "修改时间";

            fieldTipName = "单选题"
                    + "-" + "修改用户";

            fieldTipName = "单选题"
                    + "-" + "创建时间";

            fieldTipName = "单选题"
                    + "-" + "创建用户";

        }
        if (form.getTrainLibraryMoreList() != null) {

            fieldTipName = "多选题"
                    + "-" + "题目难度";

            fieldTipName = "多选题"
                    + "-" + "分类";

            fieldTipName = "多选题"
                    + "-" + "题目名称";

            fieldTipName = "多选题"
                    + "-" + "解析";

            fieldTipName = "多选题"
                    + "-" + "答案";

            fieldTipName = "多选题"
                    + "-" + "题目类型";

            fieldTipName = "多选题"
                    + "-" + "选项A";

            fieldTipName = "多选题"
                    + "-" + "选项B";

            fieldTipName = "多选题"
                    + "-" + "选项C";

            fieldTipName = "多选题"
                    + "-" + "选项D";

            fieldTipName = "多选题"
                    + "-" + "所属组织";

            fieldTipName = "多选题"
                    + "-" + "修改时间";

            fieldTipName = "多选题"
                    + "-" + "修改用户";

            fieldTipName = "多选题"
                    + "-" + "创建时间";

            fieldTipName = "多选题"
                    + "-" + "创建用户";

        }
        if (form.getTrainLibraryJudgmentList() != null) {

            fieldTipName = "判断题"
                    + "-" + "题目难度";

            fieldTipName = "判断题"
                    + "-" + "分类";

            fieldTipName = "判断题"
                    + "-" + "题目名称";

            fieldTipName = "判断题"
                    + "-" + "解析";

            fieldTipName = "判断题"
                    + "-" + "答案";

            fieldTipName = "判断题"
                    + "-" + "题目类型";

            fieldTipName = "判断题"
                    + "-" + "所属组织";

            fieldTipName = "判断题"
                    + "-" + "修改时间";

            fieldTipName = "判断题"
                    + "-" + "修改用户";

            fieldTipName = "判断题"
                    + "-" + "创建时间";

            fieldTipName = "判断题"
                    + "-" + "创建用户";

        }
        if (form.getTrainLibraryEssayQuestionList() != null) {

            fieldTipName = "问答题"
                    + "-" + "题目难度";

            fieldTipName = "问答题"
                    + "-" + "分类";

            fieldTipName = "问答题"
                    + "-" + "题目名称";

            fieldTipName = "问答题"
                    + "-" + "解析";

            fieldTipName = "问答题"
                    + "-" + "答案";

            fieldTipName = "问答题"
                    + "-" + "题目类型";

            fieldTipName = "问答题"
                    + "-" + "所属组织";

            fieldTipName = "问答题"
                    + "-" + "修改时间";

            fieldTipName = "问答题"
                    + "-" + "修改用户";

            fieldTipName = "问答题"
                    + "-" + "创建时间";

            fieldTipName = "问答题"
                    + "-" + "创建用户";

        }
        return countRecover;
    }

    /**
     * 新增修改数据(事务回滚)
     *
     * @param id
     * @param trainExamRecordsForm
     * @return
     */
    @Override
    @Transactional
    public void saveOrUpdate(TrainExamRecordsForm trainExamRecordsForm, String id, boolean isSave) throws Exception {
        UserInfo userInfo = userProvider.get();
        UserEntity userEntity = generaterSwapUtil.getUser(userInfo.getUserId());
        trainExamRecordsForm = JsonUtil.getJsonToBean(
                generaterSwapUtil.swapDatetime(TrainExamRecordsConstant.getFormData(), trainExamRecordsForm,
                        TrainExamRecordsConstant.TABLERENAMES),
                TrainExamRecordsForm.class);
        TrainExamRecordsEntity entity = JsonUtil.getJsonToBean(trainExamRecordsForm, TrainExamRecordsEntity.class);
        String mainUuid = StringUtil.isEmpty(id) ? RandomUtil.uuId() : id;
        if (isSave) {
            entity.setFlowTaskId(mainUuid);
            entity.setFcreatorUserId(userInfo.getUserId());
            entity.setFcreatorTime(DateUtil.getNowDate());
            entity.setFlastModifyUserId(null);
            entity.setFlastModifyTime(null);
            entity.setForganizeId(generaterSwapUtil.getCurrentOrgIds(userInfo.getOrganizeId(), "last"));
            entity.setId(mainUuid);
        } else {
            entity.setFcreatorUserId(null);
            entity.setFcreatorTime(null);
            entity.setFlastModifyUserId(userInfo.getUserId());
            entity.setFlastModifyTime(DateUtil.getNowDate());
            entity.setForganizeId(null);
        }
        this.saveOrUpdate(entity);

        // TrainLibrarySingle子表数据新增修改
        QueryWrapper<TrainLibrarySingleEntity> TrainLibrarySinglequeryWrapper = new QueryWrapper<>();
        TrainLibrarySinglequeryWrapper.lambda().eq(TrainLibrarySingleEntity::getFbankId, entity.getId());
        if (!isSave && !CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibrarySingleList())) {
            trainLibrarySingleService.remove(TrainLibrarySinglequeryWrapper);
        }
        if (CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibrarySingleList())) {
            List<TrainLibrarySingleEntity> tableField103 = JsonUtil
                    .getJsonToList(trainExamRecordsForm.getTrainLibrarySingleList(), TrainLibrarySingleEntity.class);
            // 移除的数据
            List<Object> childIds = tableField103.stream().filter(t -> t.getId() != null)
                    .map(TrainLibrarySingleEntity::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(childIds)) {
                TrainLibrarySinglequeryWrapper.lambda().notIn(TrainLibrarySingleEntity::getId, childIds);
            }
            trainLibrarySingleService.remove(TrainLibrarySinglequeryWrapper);
            for (TrainLibrarySingleEntity entitys : tableField103) {
                entitys.setFbankId(entity.getId());
                if (isSave || entitys.getId() == null) {
                    entitys.setForganizeId(generaterSwapUtil.getCurrentOrgIds(userInfo.getOrganizeId(), "last"));
                    entitys.setFlastModifyTime(null);
                    entitys.setFlastModifyUserId(null);
                    entitys.setFcreatorTime(DateUtil.getNowDate());
                    entitys.setFcreatorUserId(userInfo.getUserId());
                } else {
                    entitys.setForganizeId(null);
                    entitys.setFlastModifyTime(DateUtil.getNowDate());
                    entitys.setFlastModifyUserId(userInfo.getUserId());
                    entitys.setFcreatorTime(null);
                    entitys.setFcreatorUserId(null);
                }
                if (entitys.getId() == null) {
                    entitys.setId(RandomUtil.uuId());
                }
                trainLibrarySingleService.saveOrUpdate(entitys);
            }
        }
        // TrainLibraryMore子表数据新增修改
        QueryWrapper<TrainLibraryMoreEntity> TrainLibraryMorequeryWrapper = new QueryWrapper<>();
        TrainLibraryMorequeryWrapper.lambda().eq(TrainLibraryMoreEntity::getFbankId, entity.getId());
        if (!isSave && !CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibraryMoreList())) {
            trainLibraryMoreService.remove(TrainLibraryMorequeryWrapper);
        }
        if (CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibraryMoreList())) {
            List<TrainLibraryMoreEntity> tableField131 = JsonUtil
                    .getJsonToList(trainExamRecordsForm.getTrainLibraryMoreList(), TrainLibraryMoreEntity.class);
            // 移除的数据
            List<Object> childIds = tableField131.stream().filter(t -> t.getId() != null)
                    .map(TrainLibraryMoreEntity::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(childIds)) {
                TrainLibraryMorequeryWrapper.lambda().notIn(TrainLibraryMoreEntity::getId, childIds);
            }
            trainLibraryMoreService.remove(TrainLibraryMorequeryWrapper);
            for (TrainLibraryMoreEntity entitys : tableField131) {
                entitys.setFbankId(entity.getId());
                if (isSave || entitys.getId() == null) {
                    entitys.setForganizeId(generaterSwapUtil.getCurrentOrgIds(userInfo.getOrganizeId(), "last"));
                    entitys.setFlastModifyTime(null);
                    entitys.setFlastModifyUserId(null);
                    entitys.setFcreatorTime(DateUtil.getNowDate());
                    entitys.setFcreatorUserId(userInfo.getUserId());
                } else {
                    entitys.setForganizeId(null);
                    entitys.setFlastModifyTime(DateUtil.getNowDate());
                    entitys.setFlastModifyUserId(userInfo.getUserId());
                    entitys.setFcreatorTime(null);
                    entitys.setFcreatorUserId(null);
                }
                if (entitys.getId() == null) {
                    entitys.setId(RandomUtil.uuId());
                }
                trainLibraryMoreService.saveOrUpdate(entitys);
            }
        }
        // TrainLibraryJudgment子表数据新增修改
        QueryWrapper<TrainLibraryJudgmentEntity> TrainLibraryJudgmentqueryWrapper = new QueryWrapper<>();
        TrainLibraryJudgmentqueryWrapper.lambda().eq(TrainLibraryJudgmentEntity::getFbankId, entity.getId());
        if (!isSave && !CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibraryJudgmentList())) {
            trainLibraryJudgmentService.remove(TrainLibraryJudgmentqueryWrapper);
        }
        if (CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibraryJudgmentList())) {
            List<TrainLibraryJudgmentEntity> tableField147 = JsonUtil.getJsonToList(
                    trainExamRecordsForm.getTrainLibraryJudgmentList(), TrainLibraryJudgmentEntity.class);
            // 移除的数据
            List<Object> childIds = tableField147.stream().filter(t -> t.getId() != null)
                    .map(TrainLibraryJudgmentEntity::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(childIds)) {
                TrainLibraryJudgmentqueryWrapper.lambda().notIn(TrainLibraryJudgmentEntity::getId, childIds);
            }
            trainLibraryJudgmentService.remove(TrainLibraryJudgmentqueryWrapper);
            for (TrainLibraryJudgmentEntity entitys : tableField147) {
                entitys.setFbankId(entity.getId());
                if (isSave || entitys.getId() == null) {
                    entitys.setForganizeId(generaterSwapUtil.getCurrentOrgIds(userInfo.getOrganizeId(), "last"));
                    entitys.setFlastModifyTime(null);
                    entitys.setFlastModifyUserId(null);
                    entitys.setFcreatorTime(DateUtil.getNowDate());
                    entitys.setFcreatorUserId(userInfo.getUserId());
                } else {
                    entitys.setForganizeId(null);
                    entitys.setFlastModifyTime(DateUtil.getNowDate());
                    entitys.setFlastModifyUserId(userInfo.getUserId());
                    entitys.setFcreatorTime(null);
                    entitys.setFcreatorUserId(null);
                }
                if (entitys.getId() == null) {
                    entitys.setId(RandomUtil.uuId());
                }
                trainLibraryJudgmentService.saveOrUpdate(entitys);
            }
        }
        // TrainLibraryEssayQuestion子表数据新增修改
        QueryWrapper<TrainLibraryEssayQuestionEntity> TrainLibraryEssayQuestionqueryWrapper = new QueryWrapper<>();
        TrainLibraryEssayQuestionqueryWrapper.lambda().eq(TrainLibraryEssayQuestionEntity::getFbankId, entity.getId());
        if (!isSave && !CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibraryEssayQuestionList())) {
            trainLibraryEssayQuestionService.remove(TrainLibraryEssayQuestionqueryWrapper);
        }
        if (CollectionUtils.isNotEmpty(trainExamRecordsForm.getTrainLibraryEssayQuestionList())) {
            List<TrainLibraryEssayQuestionEntity> tableField180 = JsonUtil.getJsonToList(
                    trainExamRecordsForm.getTrainLibraryEssayQuestionList(), TrainLibraryEssayQuestionEntity.class);
            // 移除的数据
            List<Object> childIds = tableField180.stream().filter(t -> t.getId() != null)
                    .map(TrainLibraryEssayQuestionEntity::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(childIds)) {
                TrainLibraryEssayQuestionqueryWrapper.lambda().notIn(TrainLibraryEssayQuestionEntity::getId, childIds);
            }
            trainLibraryEssayQuestionService.remove(TrainLibraryEssayQuestionqueryWrapper);
            for (TrainLibraryEssayQuestionEntity entitys : tableField180) {
                entitys.setFbankId(entity.getId());
                if (isSave || entitys.getId() == null) {
                    entitys.setForganizeId(generaterSwapUtil.getCurrentOrgIds(userInfo.getOrganizeId(), "last"));
                    entitys.setFlastModifyTime(null);
                    entitys.setFlastModifyUserId(null);
                    entitys.setFcreatorTime(DateUtil.getNowDate());
                    entitys.setFcreatorUserId(userInfo.getUserId());
                } else {
                    entitys.setForganizeId(null);
                    entitys.setFlastModifyTime(DateUtil.getNowDate());
                    entitys.setFlastModifyUserId(userInfo.getUserId());
                    entitys.setFcreatorTime(null);
                    entitys.setFcreatorUserId(null);
                }
                if (entitys.getId() == null) {
                    entitys.setId(RandomUtil.uuId());
                }
                trainLibraryEssayQuestionService.saveOrUpdate(entitys);
            }
        }
    }

    @Override
    public ActionResult<OutExamRecordsDetailDTO> examRecordsDetail(String id) {
        OutExamRecordsDetailDTO outDTO = new OutExamRecordsDetailDTO();
        outDTO.setId(id);
        TrainExamRecordsEntity recordsEntity = trainExamRecordsService.getInfo(id);
        TrainTestPaperLibraryEntity libraryEntity = trainTestPaperLibraryService.getInfo(recordsEntity.getFlibraryId());
        int perQuestion = recordsEntity.getFperQuestion();
        String scoreStr = "(" + perQuestion + ")分";
        // 获取用户答案
        List<TrainLibrarySingleEntity> singleEntities = trainLibrarySingleService.getListByParentId(id);
        List<TrainLibraryMoreEntity> moreEntities = trainLibraryMoreService.getListByParentId(id);
        List<TrainLibraryJudgmentEntity> judgmentEntities = trainLibraryJudgmentService.getListByParentId(id);
        List<TrainLibraryEssayQuestionEntity> essayQuestionEntities = trainLibraryEssayQuestionService
                .getListByParentId(id);

        // 单选题
        if (!singleEntities.isEmpty()) {
            List<TrainLibrarySingleEntity> realSingleEntities = trainLibrarySingleService
                    .getListByParentId(recordsEntity.getFlibraryId());
            List<OutSingleDTO> singleList = new ArrayList<>();
            for (TrainLibrarySingleEntity singleEntity : singleEntities) {
                OutSingleDTO outSingleDTO = new OutSingleDTO();
                // 获取正确答案
                TrainLibrarySingleEntity correctEntity = realSingleEntities.stream()
                        .filter(entity -> entity.getFfullName().equals(singleEntity.getFfullName()))
                        .findFirst().orElse(null);
                if (correctEntity != null) {
                    outSingleDTO.setId(singleEntity.getId())
                            .setUserAnswer(singleEntity.getFanswer())
                            .setCorrectAnswer(correctEntity.getFanswer())
                            .setFullName(singleEntity.getFfullName() + scoreStr);
                    outSingleDTO.setResult(singleEntity.getFanswer().equals(correctEntity.getFanswer()) ? "正确" : "错误");
                }
                singleList.add(outSingleDTO);
            }
            outDTO.setSingleList(singleList);
        }
        // 多选题
        if (!moreEntities.isEmpty()) {
            List<TrainLibraryMoreEntity> realMoreEntities = trainLibraryMoreService
                    .getListByParentId(recordsEntity.getFlibraryId());
            List<OutMultipleDTO> multipleList = new ArrayList<>();
            for (TrainLibraryMoreEntity moreEntity : moreEntities) {
                OutMultipleDTO outMultipleDTO = new OutMultipleDTO();
                TrainLibraryMoreEntity correctEntity = realMoreEntities.stream()
                        .filter(entity -> entity.getFfullName().equals(moreEntity.getFfullName()))
                        .findFirst()
                        .orElse(null);
                if (correctEntity != null) {
                    outMultipleDTO.setId(moreEntity.getId())
                            .setUserAnswer(moreEntity.getFanswer())
                            .setCorrectAnswer(correctEntity.getFanswer())
                            .setFullName(moreEntity.getFfullName() + scoreStr);
                    // 判断结果
                    List<String> userAnswerList = Arrays
                            .asList(moreEntity.getFanswer().replace("[", "").replace("]", "").split(","));
                    List<String> correctAnswerList = Arrays
                            .asList(correctEntity.getFanswer().replace("[", "").replace("]", "").split(","));
                    // 将 List 转换为 Set 以去除重复项并忽略顺序
                    Set<String> userAnswerSet = new HashSet<>(userAnswerList);
                    Set<String> correctAnswerSet = new HashSet<>(correctAnswerList);
                    // 比较集合是否相等
                    boolean isCorrect = userAnswerSet.equals(correctAnswerSet);
                    outMultipleDTO.setResult(isCorrect ? "正确" : "错误");
                }
                multipleList.add(outMultipleDTO);
            }
            outDTO.setMultipleList(multipleList);
        }
        // 判断题
        if (!judgmentEntities.isEmpty()) {
            List<TrainLibraryJudgmentEntity> realJudgmentEntities = trainLibraryJudgmentService
                    .getListByParentId(recordsEntity.getFlibraryId());
            List<OutJudgeDTO> judgeList = new ArrayList<>();
            for (TrainLibraryJudgmentEntity judgmentEntity : judgmentEntities) {
                OutJudgeDTO outJudgeDTO = new OutJudgeDTO();
                TrainLibraryJudgmentEntity correctEntity = realJudgmentEntities.stream()
                        .filter(entity -> entity.getFfullName().equals(judgmentEntity.getFfullName()))
                        .findFirst()
                        .orElse(null);
                if (correctEntity != null) {
                    outJudgeDTO.setId(judgmentEntity.getId())
                            .setUserAnswer(judgmentEntity.getFanswer())
                            .setCorrectAnswer(correctEntity.getFanswer())
                            .setFullName(judgmentEntity.getFfullName() + scoreStr);
                    outJudgeDTO.setResult(judgmentEntity.getFanswer().equals(correctEntity.getFanswer()) ? "正确" : "错误");
                }
                judgeList.add(outJudgeDTO);
            }
            outDTO.setJudgeList(judgeList);
        }
        // 简答题
        if (!essayQuestionEntities.isEmpty()) {
            List<TrainLibraryEssayQuestionEntity> realEssayQuestionEntities = trainLibraryEssayQuestionService
                    .getListByParentId(recordsEntity.getFlibraryId());
            List<OutShortAnswerDTO> shortAnswerList = new ArrayList<>();
            for (TrainLibraryEssayQuestionEntity essayQuestionEntity : essayQuestionEntities) {
                System.out.println("问答题用户答案: " + essayQuestionEntity.getFanswer());
                OutShortAnswerDTO outShortAnswerDTO = new OutShortAnswerDTO();
                TrainLibraryEssayQuestionEntity correctEntity = realEssayQuestionEntities.stream()
                        .filter(entity -> entity.getFfullName().equals(essayQuestionEntity.getFfullName()))
                        .findFirst()
                        .orElse(null);
                if (correctEntity != null) {
                    outShortAnswerDTO.setId(essayQuestionEntity.getId())
                            .setUserAnswer(essayQuestionEntity.getFanswer())
                            .setCorrectAnswer(correctEntity.getFanswer())
                            .setFullName(essayQuestionEntity.getFfullName() + scoreStr);
                    if (StringUtil.isNotEmpty(essayQuestionEntity.getFresult())) {
                        outShortAnswerDTO.setResult(essayQuestionEntity.getFresult());
                    } else {
                        outShortAnswerDTO.setResult(
                                essayQuestionEntity.getFanswer().equals(correctEntity.getFanswer()) ? "正确" : "错误");
                    }
                    System.out.println("正确答案: " + correctEntity.getFanswer());
                }
                shortAnswerList.add(outShortAnswerDTO);
            }
            outDTO.setShortAnswerList(shortAnswerList);
        }

        return ActionResult.success("查询成功", outDTO);
    }

    @Override
    @Transactional
    public ActionResult readPaper(InReadPaperDTO in) {
        TrainExamRecordsEntity entity = trainExamRecordsService.getInfo(in.getId());
        if (entity == null) {
            return ActionResult.fail("记录不存在");
        }
        if (entity.getFquestionStatus().equals("已完成")) {
            return ActionResult.fail("阅卷已完成,请勿重复阅卷!");
        }
        int correctCnt = 0;
        int perQuestion = entity.getFperQuestion();// 每题分数

        List<EssayQuestionDTO> essayQuestions = in.getEssayQuestions();
        for (EssayQuestionDTO dto : essayQuestions) {
            if (dto.getResult().equals("正确")) {
                correctCnt++;
            }
        }
        int questionScore = correctCnt * perQuestion;
        int resultScore = Integer.parseInt(entity.getFresultScore()) + questionScore;
        if (resultScore > Integer.parseInt(entity.getFmark())) {
            return ActionResult.fail("阅卷失败,最终得分不能超过总分!");
        }

        entity.setFresultScore(String.valueOf(resultScore)).setFquestionStatus("已完成").setFquestionScore(questionScore);
        // 修改数据库
        trainLibraryEssayQuestionService.updateResult(in.getEssayQuestions());
        trainExamRecordsService.update(in.getId(), entity);
        return ActionResult.success("阅卷成功");
    }
}
