package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.config.bean.SystemProperties;
import com.yiboshi.science.config.security.SecurityUserHolder;
import com.yiboshi.science.dao.ComProjectAuditDAO;
import com.yiboshi.science.entity.ComProjectAuditNote;
import com.yiboshi.science.entity.ComProjectAudit;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.*;
import com.yiboshi.science.param.query.ComProjectAuditQueryVO;
import com.yiboshi.science.service.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.yiboshi.science.utils.StringUtil.hideAllIdCardNum;

/**
 * 审核表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-26
 */
@Service
public class ComProjectAuditServiceImpl extends BaseServiceImpl<ComProjectAuditDAO, ComProjectAuditQueryVO, ComProjectAuditDTO, ComProjectAudit> implements ComProjectAuditService {

    @Autowired
    private ComProjectAuditDAO comProjectAuditDAO;

    @Autowired
    private ComUnitService comUnitService;

    @Autowired
    private ComProjectAuditNoteService comProjectAuditNoteService;

    private final SystemProperties properties;

    public ComProjectAuditServiceImpl(SystemProperties properties) {
        this.properties = properties;
    }

    @Override
    protected void setCriteriaForQuery(ComProjectAuditQueryVO vo, QueryWrapper<ComProjectAuditQueryVO> criteria) {
        if (Objects.nonNull(vo.getReportYear())) {
            criteria.eq("a.report_year", vo.getReportYear());
        }
        if (Objects.nonNull(vo.getAuditType())) {
            criteria.eq("a.audit_type", vo.getAuditType());
        }
        if (Objects.nonNull(vo.getAuditObjectId())) {
            criteria.eq("a.audit_object_id", vo.getAuditObjectId());
        }
        if (Objects.nonNull(vo.getAuditUnitId())) {
            criteria.eq("a.audit_unit_id", vo.getAuditUnitId());
        }
        if (Objects.nonNull(vo.getAuditResult())) {
            criteria.eq("a.audit_result", vo.getAuditResult());
        }
        if (Objects.nonNull(vo.getAuditMethod())) {
            criteria.eq("a.audit_method", vo.getAuditMethod());
        }
        if (Objects.nonNull(vo.getProjName())) {
            criteria.like("proj_name", vo.getProjName());
        }
        if (Objects.nonNull(vo.getAppNo())) {
            criteria.like("app_no", vo.getAppNo());
        }
        if (Objects.nonNull(vo.getProjNo())) {
            criteria.like("proj_no", vo.getProjNo());
        }
        if (Objects.nonNull(vo.getProjType())) {
            criteria.eq("proj_type", vo.getProjType());
        }
        if (Objects.nonNull(vo.getAppUnitName())) {
            criteria.like("d.unit_name", vo.getAppUnitName());
        }
        if (Objects.nonNull(vo.getTreeCode())) {
            criteria.and(qw -> qw.eq("d.tree_code", vo.getTreeCode()).or().likeRight("d.tree_code", vo.getTreeCode()));
        }
        if (Objects.nonNull(vo.getAppPersonName())) {
            criteria.like("person_name", vo.getAppPersonName());
        }
        if (Objects.nonNull(vo.getCheckYear())) {
            criteria.eq("check_year", vo.getCheckYear());
        }
        if (Objects.nonNull(vo.getKnowledgeId())) {
            criteria.eq("c.knowledge_id", vo.getKnowledgeId());
        }
        if (Objects.nonNull(vo.getKnowledgeParentId())) {
            criteria.eq("p1.id", vo.getKnowledgeParentId());
        }
        if (Objects.nonNull(vo.getKnowledgeCode())) {
            //and (p.id = #{knowledgeCode} or p1.id = #{knowledgeCode} or p2.id = #{knowledgeCode})
            criteria.and(qw -> qw.eq("p.id", vo.getKnowledgeCode()).or().eq("p1.id", vo.getKnowledgeCode()).or().eq("p2.id", vo.getKnowledgeCode()));
        }
        if (Objects.nonNull(vo.getCompleted())) {
            criteria.eq("c.completed", vo.getCompleted());
        }
        if (Objects.nonNull(vo.getAssignState())) {
            criteria.eq("c.assign_state", vo.getAssignState());
        }
        if (Objects.nonNull(vo.getScoreStart()) && Objects.isNull(vo.getScoreEnd())) {
            criteria.ge("c.average_score", vo.getScoreStart());
        }
        if (Objects.nonNull(vo.getScoreEnd()) && Objects.isNull(vo.getScoreStart())) {
            criteria.le("c.average_score", vo.getScoreEnd());
        }
        if (Objects.nonNull(vo.getScoreStart()) && Objects.nonNull(vo.getScoreEnd())) {
            criteria.and(qw -> qw.ge("c.average_score", vo.getScoreStart()).le("c.average_score", vo.getScoreEnd()));
        }
        if (Objects.nonNull(vo.getProjState())) {
            criteria.eq("c.proj_state", vo.getProjState());
        }
    }

    @Override
    public Pagination<ComProjectAuditDTO> getListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        criteria.orderByAsc("a.audit_type,a.show_index");
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    @Transactional
    public String save(@NotNull ComProjectAuditDTO dto) {
        if (Objects.nonNull(dto.getId())) {
            ComProjectAudit comProjectAudit = this.entityById(dto.getId());
            if (null == comProjectAudit)
                throw new BusinessException("审核记录不存在！");
            ComProjectAuditNote comProjectAuditNote = comProjectAuditNoteService.getAuditNote(comProjectAudit.getAuditObjectId(), comProjectAudit.getAuditUnitId(), comProjectAudit.getAuditType(), comProjectAudit.getAuditMethod(), comProjectAudit.getShowIndex());
            if (null == comProjectAuditNote)
                throw new BusinessException("审核记录不存在！");
            this.updateAudit(comProjectAudit.getId(), dto.getAuditResult(), dto.getAuditContent(), dto.getShowIndex(), null, null, dto.getReportYear(), dto.getAuditUnitId(), dto.getAuditType(), dto.getAuditMethod());
            comProjectAuditNoteService.updateAuditNote(comProjectAuditNote.getId(), dto.getAuditResult(), dto.getAuditContent(), dto.getShowIndex(), null, null, dto.getReportYear(), dto.getAuditUnitId(), dto.getAuditType(), dto.getAuditMethod());
        } else {
            this.insertAudit(dto.getReportYear(), dto.getAuditType(), dto.getAuditObjectId(), dto.getAuditMethod(), dto.getAuditUnitId(), dto.getAuditContent(), dto.getAuditResult(), new Date(), dto.getUnitLevel(), dto.getShowIndex(), SecurityUserHolder.getPersonId());
            comProjectAuditNoteService.insertAuditNote(dto.getReportYear(), dto.getAuditType(), dto.getAuditObjectId(), dto.getAuditMethod(), dto.getAuditUnitId(), dto.getAuditContent(), dto.getAuditResult(), new Date(), dto.getUnitLevel(), dto.getShowIndex(), SecurityUserHolder.getPersonId());
        }
        return "success";
    }

    @Transactional
    public String deleteRecord(String id) {
        if (Objects.nonNull(id)) {
            ComProjectAudit model = this.entityById(id);
            if (null == model)
                throw new BusinessException("审核记录不存在！");
            this.deleteById(id);
            ComProjectAuditNote comProjectAuditNote = comProjectAuditNoteService.getAuditNote(model.getAuditObjectId(), model.getAuditUnitId(), model.getAuditType(), model.getAuditMethod(), model.getShowIndex());
            if (null != comProjectAuditNote) {
                comProjectAuditNoteService.deleteById(comProjectAuditNote.getId());
            }
        }
        return id;
    }

    public Pagination<ComProjectAuditDTO> getAuditListByPage(ComProjectAuditQueryVO vo) {
        Pagination<ComProjectAuditDTO> page = new Pagination<ComProjectAuditDTO>();
        if (null != vo && null != vo.getAuditType()) {
            switch (vo.getAuditType()) {
                case 1:
                    page = this.getProjectAuditListByPage(vo);
                    break;
                case 2:
                    page = this.getTaskAuditListByPage(vo);
                    break;
                case 3:
                    page = this.getCheckAuditListByPage(vo);
                    break;
                case 4:
                case 5:
                    page = this.getConclusionAuditListByPage(vo);
                    break;
                default:
                    break;
            }
        }
        return page;
    }

    public Pagination<ComProjectAuditDTO> getStatisticListByPage(ComProjectAuditQueryVO vo) {
        Pagination<ComProjectAuditDTO> page = new Pagination<ComProjectAuditDTO>();
        if (null != vo && null != vo.getAuditType()) {
            switch (vo.getAuditType()) {
                case 1:
                    page = this.getProjectStatisticListByPage(vo);
                    break;
                case 2:
                    page = this.getTaskStatisticListByPage(vo);
                    break;
                case 3:
                    page = this.getCheckStatisticListByPage(vo);
                    break;
                default:
                    break;
            }
        }
        return page;
    }

    public void report(Integer reportYear, String auditObjectId, Integer auditType, String auditUnitId, String
            treeCode) {
        int maxIndex = this.getMaxAuditIndex(auditObjectId);
        ComProjectAudit comProjectAudit = this.getAudit(auditObjectId, auditUnitId, auditType, CommonEnum.auditMethod.audit.getCode(), null);
        if (null != comProjectAudit) {
            //更新上报表
            this.updateAudit(comProjectAudit.getId(), CommonEnum.auditResult.waitAudit.getCode(), "", maxIndex + 1, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);
        } else {
            //插入上报表
            this.insertAudit(reportYear, auditType, auditObjectId, CommonEnum.auditMethod.audit.getCode(), auditUnitId, null, CommonEnum.auditResult.waitAudit.getCode(), null, treeCode.length() / properties.getDefaultCodeLength(), maxIndex + 1, SecurityUserHolder.getPersonId());
        }
        // 插入审核记录表
        comProjectAuditNoteService.insertAuditNote(reportYear, auditType, auditObjectId, CommonEnum.auditMethod.audit.getCode(), auditUnitId, null, CommonEnum.auditResult.waitAudit.getCode(), null, treeCode.length() / properties.getDefaultCodeLength(), maxIndex + 1, SecurityUserHolder.getPersonId());
    }

    public String audit(ComProjectAudit comProjectAudit, String reportTreeCode, String auditUnitTreeCode) {
        ComProjectAudit model = this.entityById(comProjectAudit.getId());
        if (null == model)
            throw new BusinessException("审核记录不存在！");
        if (!model.getAuditResult().equals(CommonEnum.auditResult.waitAudit.getCode()))
            throw new BusinessException("项目已审核！");
        //更新上报表
        this.updateAudit(model.getId(), comProjectAudit.getAuditResult(), comProjectAudit.getAuditContent(), null, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);

        // 定义常量
        Integer reportYear = model.getReportYear();
        Integer auditType = model.getAuditType();
        String auditObjectId = model.getAuditObjectId();
        Integer auditMethod = model.getAuditMethod();
        Integer unitLevel = model.getUnitLevel();
        Integer index = model.getShowIndex();
        String auditUnitId = model.getAuditUnitId();

        ComProjectAuditNote comProjectAuditNote = comProjectAuditNoteService.getAuditNote(auditObjectId, auditUnitId, auditType, auditMethod, index);
        if (null == comProjectAuditNote)
            throw new BusinessException("审核记录不存在！");
        //更新审核记录表
        comProjectAuditNoteService.updateAuditNote(comProjectAuditNote.getId(), comProjectAudit.getAuditResult(), comProjectAudit.getAuditContent(), null, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);

        // 返回上级或下级单位Id,最高级或个人返回 null
        String unitId = null;
        String upTreeCode = null;
        // 审核通过
        if (comProjectAudit.getAuditResult().equals(CommonEnum.auditResult.pass.getCode())) {
            if (unitLevel.equals(1)) {
                if (auditMethod.equals(CommonEnum.auditMethod.audit.getCode())) {
                    // 查询上级单位上报记录
                    ComProjectAudit auditNote = this.getAudit(auditObjectId, auditUnitId, auditType, CommonEnum.auditMethod.last.getCode(), null);
                    if (null != auditNote) {
                        // 更新上级单位上报记录
                        this.updateAudit(auditNote.getId(), CommonEnum.auditResult.waitAudit.getCode(), "", index + 1, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);
                    } else {
                        //插入上报表
                        this.insertAudit(reportYear, auditType, auditObjectId, CommonEnum.auditMethod.last.getCode(), auditUnitId, null, CommonEnum.auditResult.waitAudit.getCode(), null, unitLevel, index + 1, SecurityUserHolder.getPersonId());
                    }
                    // 插入审核记录表
                    comProjectAuditNoteService.insertAuditNote(reportYear, auditType, auditObjectId, CommonEnum.auditMethod.last.getCode(), auditUnitId, null, CommonEnum.auditResult.waitAudit.getCode(), null, unitLevel, index + 1, SecurityUserHolder.getPersonId());
                    unitId = auditUnitId;
                }
            } else {
                // 获取上级单位
                if ((auditUnitTreeCode.length() / properties.getDefaultCodeLength()) > 3) {
                    upTreeCode = auditUnitTreeCode.substring(0, 10);
                } else {
                    upTreeCode = auditUnitTreeCode.substring(0, auditUnitTreeCode.length() - properties.getDefaultCodeLength());
                }
                unitLevel = upTreeCode.length() / properties.getDefaultCodeLength();
                ComUnitDTO unit = comUnitService.getByTreeCode(upTreeCode);
                if (null == unit)
                    throw new BusinessException("未找到上级单位，请联系系统管理员处理！");

                int method = CommonEnum.auditMethod.audit.getCode();

//                if (projType.equals(CommonEnum.projType.num.getCode()) && unit.getTreeCode().length() == properties.getDefaultCodeLength()) {
//                    method = CommonEnum.auditMethod.last.getCode();
//                    // 设置项目分组
//                    //comProjectGroupService.processProjectGroup(comProjectAudit.getAuditObjectId());
//                }

                // 查询上级单位上报记录
                ComProjectAudit auditNote = this.getAudit(auditObjectId, unit.getId(), auditType, method, null);
                if (null != auditNote) {
                    // 更新上级单位上报记录
                    this.updateAudit(auditNote.getId(), CommonEnum.auditResult.waitAudit.getCode(), "", index + 1, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);
                } else {
                    //插入上报表
                    this.insertAudit(reportYear, auditType, auditObjectId, method, unit.getId(), null, CommonEnum.auditResult.waitAudit.getCode(), null, unitLevel, index + 1, SecurityUserHolder.getPersonId());
                }
                // 插入审核记录表
                comProjectAuditNoteService.insertAuditNote(reportYear, auditType, auditObjectId, method, unit.getId(), null, CommonEnum.auditResult.waitAudit.getCode(), null, unitLevel, index + 1, SecurityUserHolder.getPersonId());
                unitId = unit.getId();
            }
        }
        //返回修改
        else if (comProjectAudit.getAuditResult().equals(CommonEnum.auditResult.returnModify.getCode())) {
            if (auditMethod.equals(CommonEnum.auditMethod.last.getCode()))
                throw new BusinessException("终审项目不能返回修改！");
            unitLevel = unitLevel + 1;
            // 跳过县级行政机构
            if (reportTreeCode.length() / properties.getDefaultCodeLength() > 3 && auditUnitTreeCode.length() / properties.getDefaultCodeLength() == 2) {
                unitLevel = comProjectAuditDAO.getMaxUnitLevelByObjectId(model.getAuditObjectId());
            }
            //更新上报表
            ComProjectAudit auditNote = this.getAudit(auditObjectId, null, auditType, CommonEnum.auditMethod.audit.getCode(), unitLevel);
            if (null != auditNote) {
                // 更新下级单位上报记录
                this.updateAudit(auditNote.getId(), CommonEnum.auditResult.waitAudit.getCode(), "", index + 1, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);
                // 插入审核记录表
                comProjectAuditNoteService.insertAuditNote(reportYear, auditType, auditObjectId, CommonEnum.auditMethod.audit.getCode(), auditNote.getAuditUnitId(), null, CommonEnum.auditResult.waitAudit.getCode(), null, unitLevel, index + 1, SecurityUserHolder.getPersonId());
                unitId = auditNote.getAuditUnitId();
            }
        }
        return unitId;
    }

    //项目结题/论文审核
    public void audit(ComProjectAudit comProjectAudit) {
        ComProjectAudit model = this.entityById(comProjectAudit.getId());
        if (null == model)
            throw new BusinessException("审核记录不存在！");
        if (model.getAuditResult() != CommonEnum.auditResult.waitAudit.getCode())
            throw new BusinessException("项目已审核！");

        String auditObjectId = model.getAuditObjectId();
        Integer auditMethod = model.getAuditMethod();
        Integer index = model.getShowIndex();
        String auditUnitId = model.getAuditUnitId();
        Integer auditType = model.getAuditType();

        ComProjectAuditNote comProjectAuditNote = comProjectAuditNoteService.getAuditNote(auditObjectId, auditUnitId, auditType, auditMethod, index);
        if (null == comProjectAuditNote)
            throw new BusinessException("审核记录不存在！");
        //更新上报表
        this.updateAudit(model.getId(), comProjectAudit.getAuditResult(), comProjectAudit.getAuditContent(), null, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);
        //更新审核记录表
        comProjectAuditNoteService.updateAuditNote(comProjectAuditNote.getId(), comProjectAudit.getAuditResult(), comProjectAudit.getAuditContent(), null, SecurityUserHolder.getPersonId(), new Date(), null, null, null, null);
    }

    public Pagination<ComProjectAuditDTO> getProjectAuditListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        criteria.orderByDesc("c.average_score");
        criteria.orderByAsc("p1.display_order");
        criteria.orderByAsc("p.display_order");
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getProjectAuditListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public Pagination<ComProjectAuditDTO> getTaskAuditListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getTaskAuditListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public Pagination<ComProjectAuditDTO> getCheckAuditListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getCheckAuditListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public Pagination<ComProjectAuditDTO> getConclusionAuditListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getConclusionAuditListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public Pagination<ComProjectAuditDTO> getProjectStatisticListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        vo.setAuditType(1);
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getProjectStatisticListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public Pagination<ComProjectAuditDTO> getTaskStatisticListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        vo.setAuditType(1);
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getTaskStatisticListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public Pagination<ComProjectAuditDTO> getCheckStatisticListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        vo.setAuditType(1);
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getCheckStatisticListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public int getMaxAuditIndex(String auditObjectId) {
        return comProjectAuditDAO.getMaxAuditIndex(auditObjectId);
    }

    public ComProjectAudit getAudit(String reportObjectId, String auditUnitId, Integer auditType, Integer
            auditMethod, Integer unitLevel) {
        ComProjectAudit comProjectAudit = new ComProjectAudit();
        comProjectAudit.setAuditObjectId(reportObjectId);
        comProjectAudit.setAuditUnitId(auditUnitId);
        comProjectAudit.setAuditType(auditType);
        comProjectAudit.setAuditMethod(auditMethod);
        comProjectAudit.setUnitLevel(unitLevel);
        return this.getEntity(comProjectAudit);
    }

    public void insertAudit(Integer reportYear, Integer auditType, String auditObjectId, Integer auditMethod, String auditUnitId, String auditContent, Integer auditResult, Date auditDate, Integer unitLevel, Integer showIndex,String comPerson) {
        ComProjectAudit comProjectAudit = new ComProjectAudit();
        comProjectAudit.setReportYear(reportYear);
        comProjectAudit.setAuditType(auditType);
        comProjectAudit.setAuditObjectId(auditObjectId);
        comProjectAudit.setAuditMethod(auditMethod);
        comProjectAudit.setAuditUnitId(auditUnitId);
        comProjectAudit.setAuditContent(auditContent);
        comProjectAudit.setAuditResult(auditResult);
        comProjectAudit.setAuditDate(auditDate);
        comProjectAudit.setUnitLevel(unitLevel);
        comProjectAudit.setShowIndex(showIndex);
        comProjectAudit.setComPerson(comPerson);
        this.insert(comProjectAudit);
    }

    public void updateAudit(String id, Integer auditResult, String auditContent, Integer showIndex, String comPerson, Date auditDate, Integer reportYear, String auditUnitId, Integer auditType, Integer auditMethod) {
        ComProjectAudit model = new ComProjectAudit();
        model.setId(id);
        model.setAuditResult(auditResult);
        model.setAuditContent(auditContent);
        model.setComPerson(comPerson);
        model.setAuditDate(auditDate);
        model.setShowIndex(showIndex);

        model.setReportYear(reportYear);
        model.setAuditUnitId(auditUnitId);
        model.setAuditType(auditType);
        model.setAuditMethod(auditMethod);

        this.update(model);
    }

    public DataStatisticsDTO getCount(ComProjectAuditQueryVO e) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(e, criteria);
        return comProjectAuditDAO.getCount(criteria);
    }

    public DataStatisticsDTO getConclusionAuditCount(ComProjectAuditQueryVO e) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(e, criteria);
        return comProjectAuditDAO.getConclusionAuditCount(criteria);
    }

    public DataStatisticsDTO getCountByDay(ComProjectAuditQueryVO e) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(e, criteria);
        return comProjectAuditDAO.getCountByDay(criteria);
    }

    public DataStatisticsDTO getFirstAuditPassCount(ComProjectAuditQueryVO e) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(e, criteria);
        return comProjectAuditDAO.getFirstAuditPassCount(criteria);
    }

    public DataStatisticsDTO getAssignPersonCount(Integer assignYear, Integer projType) {
        DataStatisticsDTO dto = comProjectAuditDAO.getAssignPersonCount(assignYear, projType);
        return dto;
    }

    public ComProjectAudit getByObjIdAndUnitId(String auditObjId, String auditUnitId) {
        ComProjectAudit comProjectAudit = new ComProjectAudit();
        comProjectAudit.setAuditObjectId(auditObjId);
        comProjectAudit.setAuditUnitId(auditUnitId);
        comProjectAudit = this.getEntity(comProjectAudit);
        return comProjectAudit;
    }

    public List<DataStatisticsDTO> getTreeCodeProjectCount(ComProjectAuditQueryVO v, String treeCode) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(v, criteria);
        List<DataStatisticsDTO> list = comProjectAuditDAO.getTreeCodeProjectCount(criteria, treeCode);
        return list;
    }

    public List<DataStatisticsDTO> getKnowledgeCount(ComProjectAuditQueryVO v) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(v, criteria);
        List<DataStatisticsDTO> list = comProjectAuditDAO.getKnowledgeCount(criteria);
        return list;
    }

    public List<KnowledgeStatisticsDTO> getKnowledgeStatistic(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        this.setCriteriaForQuery(vo, criteria);
        List<KnowledgeStatisticsDTO> list = comProjectAuditDAO.getKnowledgeStatistic(criteria);
        list.forEach(e -> {
            if (e.getDisplayOrder() == 1) {
                List<KnowledgeStatisticsDTO> findList = list.stream().filter(p -> e.getKnowledge1Id().equals(p.getKnowledge1Id())).collect(Collectors.toList());
                if (null == findList || findList.size() == 0)
                    e.setRowspan(0);
                else
                    e.setRowspan(findList.size());
                e.setVisiable(true);
            } else {
                e.setRowspan(0);
                e.setVisiable(false);
            }
        });

        return list;
    }

    public List<KnowledgeStatisticsDTO> getKnowledgeSelectedList(ComProjectAuditQueryVO vo) {
        List<KnowledgeStatisticsDTO> statisticsList = this.getKnowledgeStatistic(vo);
        List<ComProjectGroupDetailDTO> knowledgeList = this.getProjectGroupKnowledgeId(vo.getReportYear());
        if (null != knowledgeList && knowledgeList.size() > 0) {
            statisticsList.forEach(e -> {
                List<ComProjectGroupDetailDTO> findList = knowledgeList.stream().filter(p -> p.getKnowledgeId().equals(e.getKnowledge2Id())).collect(Collectors.toList());
                if (null != findList && findList.size() > 0) {
                    e.setDisabled(true);
                }
                //e.setVisiable(true);
            });
        }

        return statisticsList;
    }

    public List<ComProjectGroupDetailDTO> getProjectGroupKnowledgeId(Integer groupYear) {
        return comProjectAuditDAO.getProjectGroupKnowledgeId(groupYear);
    }

    public Pagination<ComProjectAuditDTO> getUnAssignProjectListByPage(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComProjectAuditQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComProjectAuditDTO> dtoList = comProjectAuditDAO.getUnAssignProjectListByPage(page, criteria, vo.getReportYear()).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public List<ComProjectAuditDTO> getAuditProjectList(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        return comProjectAuditDAO.getAuditProjectList(criteria);
    }

    public List<projectExpertGroupStatisticDTO> getProjectExpertGroupStatistic(ComProjectAuditQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        List<projectExpertGroupStatisticDTO> list = comProjectAuditDAO.getProjectExpertGroupStatistic(criteria, vo.getReportYear());

        Map<String, List<projectExpertGroupStatisticDTO>> groupedMap = list.stream()
                .collect(Collectors.groupingBy(projectExpertGroupStatisticDTO::getGroupId));

        groupedMap.forEach((k, v) -> {
            v.get(0).setTotalCount(v.stream().mapToInt(projectExpertGroupStatisticDTO::getKnowledgeCount).sum());
            List<ComPersonDTO> expertList = this.getExpertInfoByGroupId(v.get(0).getGroupId());
            if (null != expertList && expertList.size() > 0) {
                expertList.forEach(e -> {
                    if (null == v.get(0).getExpertName() || v.get(0).getExpertName().isEmpty())
                        v.get(0).setExpertName(e.getPersonName() + "/" + e.getUnitName());
                    else
                        v.get(0).setExpertName(v.get(0).getExpertName() + "|" + e.getPersonName() + "/" + e.getUnitName());
                });
            }
        });

        return list;
    }

    public List<ComPersonDTO> getExpertInfoByGroupId(String groupId) {
        return comProjectAuditDAO.getExpertInfoByGroupId(groupId);
    }

    public List<EvaluationStatisticDTO> getEvaluationStatistic(Integer reportYear) {
        return comProjectAuditDAO.getEvaluationStatistic(reportYear);
    }

    /**
     * 导出excel数据列表
     *
     * @param reportYear  年度
     * @param startRow    开始行
     * @param rowMarkList excel行标列表
     * @return
     */
    public EvaluationExportExcelDTO getEvaluationExportExcel(Integer reportYear, Integer
            startRow, List<String> rowMarkList) {
        List<EvaluationStatisticDTO> list = comProjectAuditDAO.getEvaluationStatistic(reportYear);
        //按申请编号排序
        list = list.stream().sorted(Comparator.comparing(EvaluationStatisticDTO::getAppNo)).collect(Collectors.toList());
        EvaluationExportExcelDTO dto = new EvaluationExportExcelDTO();
        dto.setEvaluationList(list);

        list.forEach(e -> {
            e.setCertId(hideAllIdCardNum(e.getCertId()));
        });

        Map<String, List<EvaluationStatisticDTO>> evaluationdMap = list.stream()
                .collect(Collectors.groupingBy(EvaluationStatisticDTO::getAppNo));
        SortedMap<String, List<EvaluationStatisticDTO>> sortedMap = new TreeMap<>(evaluationdMap);

        AtomicInteger rowCount = new AtomicInteger(startRow);
        List<String> mergeList = new ArrayList<>();
        sortedMap.forEach((k, v) -> {
            rowMarkList.forEach(e -> {
                mergeList.add(e + rowCount.get() + ":" + e + (rowCount.get() + v.size() - 1));
            });
            rowCount.set(rowCount.get() + v.size());
        });

        dto.setMergeList(mergeList);

        return dto;
    }

    public EvaluationExportExcelDTO getProjectGroupScoreOrder(Integer reportYear, Integer
            startRow, List<String> rowMarkList) {
        List<ProjectGroupScoreOrderDTO> list = comProjectAuditDAO.getProjectGroupScoreOrder(reportYear);

        Map<String, List<ProjectGroupScoreOrderDTO>> groupScoreMap1 = list.stream()
                .collect(Collectors.groupingBy(ProjectGroupScoreOrderDTO::getGroupId));

        AtomicInteger orderNo = new AtomicInteger(1);
        List<String> mergeList = new ArrayList<>();
        groupScoreMap1.forEach((k, v) -> {
            v.forEach(e -> {
                e.setOrderNo(orderNo.get());
                orderNo.incrementAndGet();
            });
            orderNo.set(1);
        });

        Map<Integer, List<ProjectGroupScoreOrderDTO>> groupScoreMap2 = list.stream()
                .collect(Collectors.groupingBy(ProjectGroupScoreOrderDTO::getDisplayOrder));

        AtomicInteger rowCount = new AtomicInteger(startRow);
        groupScoreMap2.forEach((k, v) -> {
            rowMarkList.forEach(e -> {
                mergeList.add(e + rowCount.get() + ":" + e + (rowCount.get() + v.size() - 1));
            });
            rowCount.set(rowCount.get() + v.size());
        });

        EvaluationExportExcelDTO dto = new EvaluationExportExcelDTO();
        dto.setGroupScoreList(list);
        dto.setMergeList(mergeList);
        return dto;
    }
}