package com.ruoyi.system.service.loan.impl;


import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SendSmsUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelFillUtils;
import com.ruoyi.common.utils.poi.WordUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.Seq;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.domain.conference.SysUserConference;
import com.ruoyi.system.domain.enterprise.SysUserEnterprise;
import com.ruoyi.system.domain.loan.LoanApplication;
import com.ruoyi.system.domain.loan.LoanApplicationFj;
import com.ruoyi.system.domain.loan.LoanSchedule;
import com.ruoyi.system.domain.loan.ShareholderFj;
import com.ruoyi.system.domain.remind.WaitRemind;
import com.ruoyi.system.domain.review.ReviewComments;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.loan.ILoanApplicationService;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.io.File;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static com.ruoyi.common.constant.CommonConstants.*;

import javax.annotation.Resource;

/**
 * 贷款申请主Service业务层处理
 *
 * @author boman
 * @date 2024-04-24
 */
@Service
public class LoanApplicationServiceImpl implements ILoanApplicationService {
    @Autowired
    private LoanApplicationMapper loanApplicationMapper;
    @Autowired
    private LoanApplicationFjMapper loanApplicationFjMapper;
    @Autowired
    private ShareholderFjMapper shareholderFjMapper;
    @Autowired
    private LoanScheduleMapper loanScheduleMapper;
    @Autowired
    private SysUserEnterpriseMapper sysUserEnterpriseMapper;
    @Autowired
    private SysUserConferenceMapper sysUserConferenceMapper;
    @Autowired
    private ReviewCommentsMapper reviewCommentsMapper;
    @Resource
    private WaitRemindMapper waitRemindMapper;

    @Autowired
    private RedisCache redisCache;


    /**
     * 查询贷款申请主
     *
     * @param loanApplicationId 贷款申请主主键
     * @return 贷款申请主
     */
    @Override
    public LoanApplication selectLoanApplicationByLoanApplicationId(Long loanApplicationId) {

        LoanApplication loanApplication = loanApplicationMapper.selectLoanApplicationByLoanApplicationId(loanApplicationId);
        //查询企业信息
        SysUserEnterprise sysUserEnterprise = sysUserEnterpriseMapper.selectSysUserEnterpriseByEnterpriseId(loanApplication.getEnterpriseId());
        loanApplication.setSysUserEnterprise(sysUserEnterprise);
        //查询相关附件
        List<LoanApplicationFj> loanApplicationFjs = loanApplicationFjMapper.selectLoanApplicationFjByLoanApplicationId(loanApplicationId);
        if (loanApplicationFjs != null && loanApplicationFjs.size() > 0) {
            //所有附件不分类
            loanApplication.setLoanApplicationFjList(loanApplicationFjs);
            //进行大类区分
            Map<String, List<LoanApplicationFj>> bigTypeFj = loanApplicationFjs.stream().collect(Collectors.groupingBy(LoanApplicationFj::getBigType));
            List<LoanApplicationFj> loanApplicationFjsA = bigTypeFj.get(A);
            if (loanApplicationFjsA != null && loanApplicationFjsA.size() > 0) {
                loanApplication.setBasicFj(loanApplicationFjsA.stream().collect(Collectors.groupingBy(LoanApplicationFj::getType)));
            }
            List<LoanApplicationFj> loanApplicationFjsB = bigTypeFj.get(B);
            if (loanApplicationFjsB != null && loanApplicationFjsB.size() > 0) {
                loanApplication.setDeclareFj(loanApplicationFjsB.stream().collect(Collectors.groupingBy(LoanApplicationFj::getType)));
            }
            List<LoanApplicationFj> loanApplicationFjsC = bigTypeFj.get(C);
            if (loanApplicationFjsC != null && loanApplicationFjsC.size() > 0) {
                loanApplication.setFileFj(loanApplicationFjsC.stream().collect(Collectors.groupingBy(LoanApplicationFj::getType)));
            }
            List<LoanApplicationFj> loanApplicationFjsD = bigTypeFj.get(D);
            if (loanApplicationFjsD != null && loanApplicationFjsD.size() > 0) {
                loanApplication.setOtherFj(loanApplicationFjsD.stream().collect(Collectors.groupingBy(LoanApplicationFj::getType)));
            }
        }
        List<ShareholderFj> shareholderFjs = shareholderFjMapper.selectShareholderFjLoanApplicationId(loanApplicationId);
        if (shareholderFjs != null && shareholderFjs.size() > 0) {
            loanApplication.setShareholderFjList(shareholderFjs);
        }
        return loanApplication;
    }

    /**
     * 查询贷款申请主列表
     *
     * @param loanApplication 贷款申请主
     * @return 贷款申请主
     */
    @Override
    public List<LoanApplication> selectLoanApplicationList(LoanApplication loanApplication) {
        //判断是否是admin或者管理员manager
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        String roleKey = "admin,manager,auditing_risk";
        List<LoanApplication> loanApplications = new ArrayList<>();
        for (SysRole role : roles) {
            if (roleKey.contains(role.getRoleKey())) {
                loanApplications = loanApplicationMapper.selectLoanApplicationList(loanApplication);
                return loanApplications;
            }
        }
        loanApplication.setUserId(SecurityUtils.getUserId());
        loanApplications = loanApplicationMapper.selectLoanApplicationList(loanApplication);
        return loanApplications;
    }

    /**
     * 文件管理
     *
     * @param loanApplication
     * @return
     */
    @Override
    public List<LoanApplication> listOss(LoanApplication loanApplication) {
        loanApplication.setLoanSchedule(TEN);
        loanApplication.setLoanApplicationType(FOR);
        List<LoanApplication> loanApplications = loanApplicationMapper.selectLoanApplicationList(loanApplication);
        if (loanApplications != null && loanApplications.size() > 0) {
            for (LoanApplication application : loanApplications) {
                //去查询压缩包
                LoanApplicationFj loanApplicationFj = new LoanApplicationFj();
                loanApplicationFj.setLoanApplicationId(application.getLoanApplicationId());
                loanApplicationFj.setBigType("e");
                List<LoanApplicationFj> loanApplicationFjList = loanApplicationFjMapper.selectLoanApplicationFjList(loanApplicationFj);
                application.setLoanApplicationFjList(loanApplicationFjList);
            }
        }
        return loanApplications;
    }

    /**
     * 新增贷款申请主
     *
     * @param loanApplication 贷款申请主
     * @return 结果
     */
    @Override
    public int insertLoanApplication(LoanApplication loanApplication) {
        //设置为audit_schedule=1 audit_type=1
        loanApplication.setAuditSchedule(ONE);
        loanApplication.setAuditType(ONE);
        //设置申请人用户ID
        loanApplication.setUserId(SecurityUtils.getUserId());
        loanApplication.setApplicationTime(DateUtils.getNowDate());
        //贷款申请进度进入业务审核/分配
        loanApplication.setLoanSchedule(TWO);
        loanApplication.setLoanApplicationType(TWO);
        loanApplication.setUserId(SecurityUtils.getUserId());
        int i = loanApplicationMapper.insertLoanApplication(loanApplication);
        List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
        if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
            for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
                loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            }
            loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
        }
        List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
        if (shareholderFjList != null && shareholderFjList.size() > 0) {
            for (ShareholderFj shareholderFj : shareholderFjList) {
                shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            }
            shareholderFjMapper.batchShareholderFj(shareholderFjList);
        }

        //往业务进度表 loan_schedule 插入数据
        LoanSchedule loanSchedule = new LoanSchedule();
        loanSchedule.setLoanApplicationId(loanApplication.getLoanApplicationId());
        loanSchedule.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
        loanSchedule.setLoanScheduleName(loanApplication.getLoanScheduleName());
        loanSchedule.setLoanScheduleValue(loanApplication.getLoanSchedule());
        loanSchedule.setLoanScheduleScore(0L);
        loanSchedule.setLoanScheduleTime(DateUtils.getNowDate());
        loanScheduleMapper.insertLoanSchedule(loanSchedule);
        return i;
    }

    /**
     * 修改贷款申请主
     *
     * @param loanApplication 贷款申请主
     * @return 结果
     */
    @Override
    public int updateLoanApplication(LoanApplication loanApplication) {
        loanApplication.setUpdateTime(DateUtils.getNowDate());
        loanApplication.setLoanApplicationType(TWO);
        loanApplication.setApplicationTime(DateUtils.getNowDate());
        Long loanApplicationId = loanApplication.getLoanApplicationId();
        //相关附件先删除
        loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationId(loanApplicationId);
        List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
        if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
            for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
                loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            }
            loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
        }
        shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
        List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
        if (shareholderFjList != null && shareholderFjList.size() > 0) {
            for (ShareholderFj shareholderFj : shareholderFjList) {
                shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            }
            shareholderFjMapper.batchShareholderFj(shareholderFjList);
        }
        return loanApplicationMapper.updateLoanApplication(loanApplication);
    }

    /**
     * 暂存
     *
     * @param loanApplication 贷款申请主
     * @return
     */
    @Override
    public int temporary(LoanApplication loanApplication) {
        loanApplication.setLoanApplicationType(ONE);
        Long loanApplicationId = loanApplication.getLoanApplicationId();
        //走修改
        if (loanApplicationId != null) {
            //相关附件先删除
            loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationId(loanApplicationId);
            List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
            if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
                for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
                    loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                    loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                }
                loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
            }
            shareholderFjMapper.deleteShareholderFjByLoanApplicationId(loanApplicationId);
            List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
            if (shareholderFjList != null && shareholderFjList.size() > 0) {
                for (ShareholderFj shareholderFj : shareholderFjList) {
                    shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                    shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
                }
                shareholderFjMapper.batchShareholderFj(shareholderFjList);
            }
            return loanApplicationMapper.updateLoanApplication(loanApplication);
        }
        //设置为audit_schedule=1 audit_type=1
        loanApplication.setAuditSchedule(ONE);
        loanApplication.setAuditType(ONE);
        //设置申请人用户ID
        loanApplication.setUserId(SecurityUtils.getUserId());
        //贷款申请进度进入申报提交
        loanApplication.setLoanSchedule(ONE);
        int i = loanApplicationMapper.insertLoanApplication(loanApplication);
        List<LoanApplicationFj> loanApplicationFjList = loanApplication.getLoanApplicationFjList();
        if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
            for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
                loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                loanApplicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            }
            loanApplicationFjMapper.batchLoanApplicationFj(loanApplicationFjList);
        }
        List<ShareholderFj> shareholderFjList = loanApplication.getShareholderFjList();
        if (shareholderFjList != null && shareholderFjList.size() > 0) {
            for (ShareholderFj shareholderFj : shareholderFjList) {
                shareholderFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
                shareholderFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            }
            shareholderFjMapper.batchShareholderFj(shareholderFjList);
        }

        return i;
    }

    /**
     * 批量删除贷款申请主
     *
     * @param loanApplicationIds 需要删除的贷款申请主主键
     * @return 结果
     */
    @Override
    public int deleteLoanApplicationByLoanApplicationIds(Long[] loanApplicationIds) {
        return loanApplicationMapper.deleteLoanApplicationByLoanApplicationIds(loanApplicationIds);
    }

    /**
     * 删除贷款申请主信息
     *
     * @param loanApplicationId 贷款申请主主键
     * @return 结果
     */
    @Override
    public int deleteLoanApplicationByLoanApplicationId(Long loanApplicationId) {
        return loanApplicationMapper.deleteLoanApplicationByLoanApplicationId(loanApplicationId);
    }

    /**
     * 审核
     *
     * @param reviewComments
     * @return
     */
    @Override
    public AjaxResult sh(ReviewComments reviewComments) {
        reviewComments.setAuditTime(DateUtils.getNowDate());
        List<SysUserConference> sysUserConferenceList = reviewComments.getSysUserConferenceList();
        //审核进度1：业务审核/分配 2：A角色审核 3：B角色审核 4：风险审核 5：尽职调查 6：初审风险合规 7：上会评审
        String auditSchedule = reviewComments.getAuditSchedule();
        //审核状态 1：待审核 2：已通过 3：未通过 4:申诉
        String auditType = reviewComments.getAuditType();
        //校验当前项目进度
        Long loanApplicationId = reviewComments.getLoanApplicationId();
        //获取数据库中项目详情
        LoanApplication loanApplication = loanApplicationMapper.selectLoanApplicationByLoanApplicationId(loanApplicationId);
        String loanScheduleOld = loanApplication.getLoanSchedule();
        String auditScheduleOld = loanApplication.getAuditSchedule();
        String auditTypeOld = loanApplication.getAuditType();
        String loanApplicationType = loanApplication.getLoanApplicationType();
        //判断是否已归档
        if (loanApplication.getLoanApplicationType().equals(FOR)) {
            return AjaxResult.error("当前项目已归档");
        }
        //判断是否无需审核
        if (Integer.parseInt(loanScheduleOld) > 6) {
            return AjaxResult.error("当前项目无需审核");
        }
        if (!Objects.equals(loanApplicationType, TWO)) {
            return AjaxResult.error("当前贷款申请状态非正常，请检查后重新操作");
        }
        if (ObjectUtils.isEmpty(loanApplication)) {
            return AjaxResult.error("当前贷款申请不存在，请重新刷新");
        }

        //判断数据库中进度是否小于当前申请进度
        if (Integer.parseInt(auditSchedule) <= Integer.parseInt(auditScheduleOld) && !Objects.equals(auditTypeOld, ONE)) {
            return AjaxResult.error("当前进度已审核，请勿重复审核");
        }
        List<LoanApplicationFj> fjUrl = reviewComments.getFjUrl();
        if (fjUrl != null && fjUrl.size() > 0) {
            StringBuilder type = new StringBuilder();
            for (LoanApplicationFj loanApplicationFj : fjUrl) {
                type.append(loanApplicationFj.getType()).append(",");
            }
            type.deleteCharAt(type.lastIndexOf(","));
            loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationIdAndType(loanApplicationId, type.toString().split(","));
            //需要删除当前状态下已存在的附件
            loanApplicationFjMapper.batchLoanApplicationFj(fjUrl);
        }
        //业务审核意见
        reviewCommentsMapper.insertReviewComments(reviewComments);
        //A角色进度之前审核不通过，直接放入回收站,之后的进入到申诉状态
        if (THR.equals(auditType) && ONE.equals(auditSchedule)) {
            loanApplication.setAuditType(auditType);
            loanApplication.setAuditSchedule(auditSchedule);
            loanApplication.setLoanApplicationType(THR);
            loanApplicationMapper.updateLoanApplication(loanApplication);
            return AjaxResult.success();
            //A角色审核不通过 audit_schedule = 2的时候贷款申请进度处于担保初审状态
        } else if (THR.equals(auditType) && auditSchedule.equals(TWO)) {
            loanApplication.setLoanSchedule(THR);
            loanApplication.setAuditType(auditType);
            loanApplication.setAuditSchedule(auditSchedule);
            loanApplication.setLoanApplicationType(TWO);
            loanApplicationMapper.updateLoanApplication(loanApplication);
            return AjaxResult.success();
            //审核流程结束
        } else if (THR.equals(auditType) && Integer.parseInt(auditSchedule) > 2) {
            //进入到A角色申诉状态
            loanApplication.setLoanSchedule(TWO);
            loanApplication.setAuditType(FOR);
            loanApplication.setAuditSchedule(TWO);
            loanApplicationMapper.updateLoanApplication(loanApplication);
            return AjaxResult.success();
        }
        //通过,进入到下一个步骤
        if (TWO.equals(auditType)) {
            WaitRemind waitRemind = new WaitRemind();
            waitRemind.setLoanApplicationId(loanApplicationId);
            waitRemind.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            waitRemind.setRemindTitle("您有一条审核信息待办");
            waitRemind.setRemindTime(DateUtils.getNowDate());
            waitRemind.setRemindType(TWO);
            if (auditSchedule.equals(ONE)) {
                //设置AB角色id
                loanApplication.setaUserId(reviewComments.getaUserId());
                loanApplication.setaUserName(reviewComments.getaUserName());
                loanApplication.setbUserId(reviewComments.getbUserId());
                loanApplication.setbUserName(reviewComments.getbUserName());
                //给A角色发送待办提醒
                waitRemind.setReadUserId(reviewComments.getaUserId().toString());
                String enterpriseName = loanApplication.getEnterpriseName();
                waitRemind.setRemindContent(enterpriseName + "有一条贷款申请需及时处理");
                waitRemindMapper.insertWaitRemind(waitRemind);
            }
            //保存参会人员数据
            if (sysUserConferenceList != null && sysUserConferenceList.size() > 0 && auditSchedule.equals(SEV)) {
                sysUserConferenceMapper.batchSysUserConference(sysUserConferenceList);
            }
            //audit_schedule = 2,3的时候贷款申请进度处于担保初审状态
            if (auditSchedule.equals(TWO) || auditSchedule.equals(THR)) {
                loanApplication.setLoanSchedule(THR);
                loanApplication.setAuditSchedule(String.valueOf(Integer.parseInt(auditSchedule) + 1));
                loanApplication.setAuditType(ONE);
                if (auditSchedule.equals(TWO)) {
                    //给B角色发送待办提醒
                    waitRemind.setReadUserId(loanApplication.getbUserId().toString());
                    String enterpriseName = loanApplication.getEnterpriseName();
                    waitRemind.setRemindContent(enterpriseName + "有一条贷款申请需及时处理");
                    waitRemindMapper.insertWaitRemind(waitRemind);
                }
                //审核流程结束
            } else if (auditSchedule.equals(SEV)) {
                loanApplication.setLoanSchedule(String.valueOf(Integer.parseInt(loanScheduleOld) + 1));
                loanApplication.setAuditSchedule(auditSchedule);
                loanApplication.setAuditType(auditType);
            } else {
                loanApplication.setLoanSchedule(String.valueOf(Integer.parseInt(loanScheduleOld) + 1));
                loanApplication.setAuditSchedule(String.valueOf(Integer.parseInt(auditSchedule) + 1));
                loanApplication.setAuditType(ONE);
            }
            loanApplicationMapper.updateLoanApplication(loanApplication);
            //插入流程记录表
            LoanSchedule loanSchedule = new LoanSchedule();
            loanSchedule.setLoanApplicationId(loanApplicationId);
            loanSchedule.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
            loanSchedule.setLoanScheduleValue(loanApplication.getLoanSchedule());
            loanSchedule.setLoanScheduleScore(Long.parseLong(loanApplication.getLoanSchedule()));
            loanSchedule.setLoanScheduleTime(DateUtils.getNowDate());
            loanScheduleMapper.insertLoanSchedule(loanSchedule);
        }
        return AjaxResult.success();
    }

    /**
     * 申诉
     *
     * @param loanApplication
     * @return
     */
    @Override
    public AjaxResult ss(LoanApplication loanApplication) {
        //先判断当前人是否是A角色
        Long userId = SecurityUtils.getUserId();
        Long aLong = loanApplication.getaUserId();
        if (!Objects.equals(userId, aLong)) {
            return AjaxResult.error("当前您无权限申诉，请联系管理员");
        }
        loanApplication.setLoanSchedule(TWO);
        //进入待审核
        loanApplication.setAuditType(ONE);
        loanApplication.setAuditSchedule(TWO);
        loanApplicationMapper.updateLoanApplication(loanApplication);
        //删除之后的所有附件
        String type = "jzdcbg," + "dbxmhfhgb," + "psyjqpb," + "clhgb," + "gdhyjy";
        loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationIdAndType(loanApplication.getLoanApplicationId(), type.split(","));
        return AjaxResult.success();
    }

    /**
     * 7：合同签约 8：放款合规风险审核 9：放款通知
     *
     * @param loanApplication
     * @return
     */
    @Override
    public AjaxResult schedule(LoanApplication loanApplication) {
        String loanSchedule = loanApplication.getLoanSchedule();
        if (!SEV.equals(loanSchedule) && !EIG.equals(loanSchedule) && !NIN.equals(loanSchedule)) {
            return AjaxResult.error("当前项目进度错误。");
        }
        LoanApplication application = new LoanApplication();
        application.setLoanApplicationId(loanApplication.getLoanApplicationId());
        if (NIN.equals(loanSchedule)) {
            application.setLoanSchedule(NIN);
            application.setAuditType(TWO);
        } else {
            application.setLoanSchedule(String.valueOf(Integer.parseInt(loanSchedule) + 1));
            application.setAuditType(ONE);
        }
        loanApplicationMapper.updateLoanApplication(application);
        return AjaxResult.success();
    }

    /**
     * 撤销返回到上一步
     *
     * @param loanApplication
     * @return
     */
    @Override
    public AjaxResult cx(LoanApplication loanApplication) {
        Long loanApplicationId = loanApplication.getLoanApplicationId();
        //获取当前状态
        String loanSchedule = loanApplication.getLoanSchedule();
        String auditSchedule = loanApplication.getAuditSchedule();
        String loanApplicationType = loanApplication.getLoanApplicationType();
        String auditType = loanApplication.getAuditType();

        reviewCommentsMapper.deleteReviewCommentsByLoanApplicationIdAndAuditSchedule(loanApplicationId, auditSchedule);
        if (Integer.parseInt(loanSchedule) < 2 || Integer.parseInt(auditSchedule) < 1 || Integer.parseInt(loanApplicationType) != 2) {
            return AjaxResult.error("当前项目不可撤销");
        }
        if (Integer.parseInt(loanSchedule) > 7) {
            //撤销只返回贷款申请进度到上一步
            loanApplication.setLoanSchedule(String.valueOf(Integer.parseInt(auditSchedule) - 1));
        } else {
            //如果是待审核的撤销就退一步否则就是改为待审核
            if (ONE.equals(auditType)) {
                loanApplication.setAuditSchedule(String.valueOf(Integer.parseInt(auditSchedule) - 1));
                loanApplication.setLoanSchedule(String.valueOf(Integer.parseInt(loanSchedule) - 1));
            }
            if (SEV.equals(loanSchedule)) {
                loanApplication.setLoanSchedule(SIX);
            }
            //进入待审核
            loanApplication.setAuditType(ONE);
            String type = "-1";
            if (auditSchedule.equals(FIV)) {
                type = "jzdcbg";
            } else if (auditSchedule.equals(SIX)) {
                type = "dbxmhfhgb,clhgb";
            } else if (auditSchedule.equals(SEV)) {
                type = "psyjqpb,gdhyjy";
            }
            //还需要删除附件
            loanApplicationFjMapper.deleteLoanApplicationFjByLoanApplicationIdAndType(loanApplication.getLoanApplicationId(), type.split(","));
        }
        loanApplicationMapper.updateLoanApplication(loanApplication);
        return AjaxResult.success();
    }

    /**
     * 一键归档
     *
     * @param loanApplication
     * @return
     */
    @Override
    public AjaxResult gd(LoanApplication loanApplication) {
        //判断项目是否能归档
        String loanSchedule = loanApplication.getLoanSchedule();
        String loanApplicationType = loanApplication.getLoanApplicationType();
        String auditType = loanApplication.getAuditType();
        if (!NIN.equals(loanSchedule) && !TWO.equals(loanApplicationType) && !TWO.equals(auditType)) {
            return AjaxResult.error("当前项目进度不能归档");
        }
        loanApplication.setLoanSchedule(TEN);
        loanApplication.setLoanApplicationType(FOR);
        loanApplication.setFileTime(DateUtils.getNowDate());

        //插入流程记录表
        LoanSchedule loanScheduleNew = new LoanSchedule();
        loanScheduleNew.setLoanApplicationId(loanApplication.getLoanApplicationId());
        loanScheduleNew.setLoanScheduleValue(loanApplication.getLoanSchedule());
        loanScheduleNew.setLoanScheduleScore(Long.parseLong(loanApplication.getLoanSchedule()));
        loanScheduleNew.setLoanScheduleTime(DateUtils.getNowDate());
        loanScheduleNew.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
        loanScheduleMapper.insertLoanSchedule(loanScheduleNew);
        // 上传文件路径
        String filePath = RuoYiConfig.getUploadPath() + "/";
        Long loanApplicationId = loanApplication.getLoanApplicationId();
        List<LoanApplicationFj> loanApplicationFjList = loanApplicationFjMapper.selectLoanApplicationFjByLoanApplicationId(loanApplicationId);
        //基础附件
        LoanApplication loanApplicationOld = loanApplicationMapper.selectLoanApplicationByLoanApplicationId(loanApplicationId);
        //股东附件
        List<ShareholderFj> shareholderFjs = shareholderFjMapper.selectShareholderFjLoanApplicationId(loanApplicationId);
        List<File> fileList = new ArrayList<>();
        if (loanApplicationFjList != null && loanApplicationFjList.size() > 0) {
            for (LoanApplicationFj loanApplicationFj : loanApplicationFjList) {
                fileList.add(new File(loanApplicationFj.getUrl().replace("/profile", filePath)));
            }
        }
        String corporationFront = loanApplicationOld.getCorporationFront();
        String corporationBack = loanApplicationOld.getCorporationBack();
        String spouseFront = loanApplicationOld.getSpouseFront();
        String spouseBack = loanApplicationOld.getSpouseBack();
        String guaranteeFront = loanApplicationOld.getGuaranteeFront();
        String guaranteeBack = loanApplicationOld.getGuaranteeBack();
        if (StringUtils.isNotEmpty(corporationFront)) {
            fileList.add(new File(corporationFront.replace("/profile/upload/", filePath)));
        }
        if (StringUtils.isNotEmpty(corporationBack)) {
            fileList.add(new File(corporationBack.replace("/profile/upload/", filePath)));
        }
        if (StringUtils.isNotEmpty(spouseFront)) {
            fileList.add(new File(spouseFront.replace("/profile/upload/", filePath)));
        }
        if (StringUtils.isNotEmpty(spouseBack)) {
            fileList.add(new File(spouseBack.replace("/profile/upload/", filePath)));
        }
        if (StringUtils.isNotEmpty(guaranteeFront)) {
            fileList.add(new File(guaranteeFront.replace("/profile/upload/", filePath)));
        }
        if (StringUtils.isNotEmpty(guaranteeBack)) {
            fileList.add(new File(guaranteeBack.replace("/profile/upload/", filePath)));
        }
        if (shareholderFjs != null && shareholderFjs.size() > 0) {
            for (ShareholderFj shareholderFj : shareholderFjs) {
                fileList.add(new File(shareholderFj.getShareholderZxUrl().replace("/profile/upload/", filePath)));
                fileList.add(new File(shareholderFj.getShareholderFrontUrl().replace("/profile/upload/", filePath)));
                fileList.add(new File(shareholderFj.getShareholderBackUrl().replace("/profile/upload/", filePath)));
            }
        }


        String name = StringUtils.format("{}_{}.{}",
                loanApplicationOld.getEnterpriseName(), Seq.getId(Seq.uploadSeqType) + "文档", "zip");
        //进行压缩
        zipEncryptExample(fileList, filePath + loanApplicationOld.getLoanApplicationNumber(), name, "123");
        //把压缩包的url插入附件表
        LoanApplicationFj loanApplicationFj = new LoanApplicationFj();
        loanApplicationFj.setLoanApplicationId(loanApplicationId);
        loanApplicationFj.setLoanApplicationNumber(loanApplicationOld.getLoanApplicationNumber());
        loanApplicationFj.setOldName(name);
        loanApplicationFj.setName(name);
        loanApplicationFj.setUrl("/profile/upload/" + name);
        loanApplicationFj.setBigType("e");
        loanApplicationFj.setCreateTime(DateUtils.getNowDate());
        loanApplicationFjMapper.insertLoanApplicationFj(loanApplicationFj);
        loanApplicationMapper.updateLoanApplication(loanApplication);
        return AjaxResult.success();
    }

    /**
     * 压缩文件，返回地址
     *
     * @param fileList    源文件或目录路径
     * @param zipPathDir  ZIP文件输出路径
     * @param zipFileName ZIP文件名称
     * @param password    加密密码
     * @return
     */
    public String zipEncryptExample(List<File> fileList, String zipPathDir, String zipFileName, String password) {
        String zipFilePath = zipPathDir + "/" + zipFileName;
        try {

/*            ZipParameters zipParameters = new ZipParameters();
            zipParameters.setEncryptFiles(true);
            zipParameters.setEncryptionMethod(EncryptionMethod.ZIP_STANDARD); // 标准AES加密
            ZipFile zipFile = new ZipFile(zipPathDir, password.toCharArray());
            zipFile.addFiles(fileList, zipParameters);*/

            ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(zipFilePath)));
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(zos));
            File zipFile = new File(zipPathDir);
            if (!zipFile.exists()) {
                zipFile.mkdirs();
            }
            for (File file : fileList) {
                if (file.exists()) {
                    ZipEntry zipEntry = new ZipEntry(file.getName());
                    zos.putNextEntry(zipEntry);
                    Path path = Paths.get(file.getAbsolutePath());
                    BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(path)));
                    while (reader.ready()) {
                        writer.write(reader.readLine());
                    }
                    writer.flush();
                    reader.close();
                    zos.closeEntry();
                } else {
                    //文件路径异常filePath：filePath
                }
            }
            zos.flush();
            writer.close();
            System.out.println("文件加密成功，保存位置：" + zipFilePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return zipFilePath;
    }

    /**
     * 导出模板附件
     */
    @Override
    public AjaxResult exportMb(LoanApplication loanApplication) {
        Map<String, Object> map = new HashMap<>();
        String type = loanApplication.getType();
        String loanApplicationNumber = loanApplication.getLoanApplicationNumber();
        if (loanApplication.getLoanApplicationId() != null || loanApplication.getLoanApplicationId() != 0L) {
            loanApplication = loanApplicationMapper.selectLoanApplicationByLoanApplicationId(loanApplication.getLoanApplicationId());
            loanApplication.setType(type);
            //判断附件存不存在
            LoanApplicationFj loanApplicationFj = new LoanApplicationFj();
            loanApplicationFj.setLoanApplicationId(loanApplication.getLoanApplicationId());
            //返回附件表对应type
            String fileType = contrastType(type);
            loanApplicationFj.setType(fileType);
            List<LoanApplicationFj> loanApplicationFjs = loanApplicationFjMapper.selectLoanApplicationFjList(loanApplicationFj);
            if (loanApplicationFjs != null && loanApplicationFjs.size() > 0) {
                for (LoanApplicationFj applicationFj : loanApplicationFjs) {
                    redisCache.setCacheObject(applicationFj.getFjId() + "info", applicationFj, 2, TimeUnit.HOURS);
                    map.put("fileId", applicationFj.getFjId());
                    map.put("path", applicationFj.getUrl());
                    map.put("fileName", applicationFj.getName());
                    return AjaxResult.success(map);
                }
            }
        }

        Map<String, Object> params = new HashMap<>();
        String path = "/profile/mb/temporarily";
        //查询公司信息
        SysUserEnterprise sysUserEnterprise = sysUserEnterpriseMapper.selectSysUserEnterpriseByEnterpriseId(loanApplication.getEnterpriseId());
        params.put("loanApplication", loanApplication);
        params.put("sysUserEnterprise", sysUserEnterprise);
        String templatePath = RuoYiConfig.getProfile();
        String fileDir = RuoYiConfig.getProfile();
        String fileName = "";
        String fileNameHz = "";
        String wordPath = "";
        switch (type) {
            case "1":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/委托担保申请书.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("委托担保申请书");
                fileName = loanApplication.getEnterpriseName() + "-委托担保申请书";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "2":
                params.put("enterpriseAddres", sysUserEnterprise.getEnterpriseAddress());
                params.put("corporationPhone", loanApplication.getCorporationPhone());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/委托保证合同.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("委托担保申请书");
                fileName = loanApplication.getEnterpriseName() + "-委托担保申请书";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "3":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = templatePath + "/mb/担保意向函.docx";
                fileDir = fileDir + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("担保意向函");
                fileName = loanApplication.getEnterpriseName() + "-担保意向函";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "4":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/放款（出票）通知书.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily/" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("放款（出票）通知书");
                fileName = loanApplication.getEnterpriseName() + "-放款（出票）通知书";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "5":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/保证反担保合同（适用于法人).docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("保证反担保合同（适用于法人)");
                fileName = loanApplication.getEnterpriseName() + "-保证反担保合同（适用于法人)";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "6":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/保证反担保合同（适用于自然人）.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("保证反担保合同（适用于自然人）");
                fileName = loanApplication.getEnterpriseName() + "-保证反担保合同（适用于自然人）";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "7":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/抵押反担保合同（适用于法人）.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("抵押反担保合同（适用于法人）");
                fileName = loanApplication.getEnterpriseName() + "-抵押反担保合同（适用于法人）";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "8":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/抵押反担保合同（适用于自然人）.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("抵押反担保合同（适用于自然人）");
                fileName = loanApplication.getEnterpriseName() + "-抵押反担保合同（适用于自然人）";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "9":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/权利质权反担保合同（适用于法人）.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("权利质权反担保合同（适用于法人）");
                fileName = loanApplication.getEnterpriseName() + "-权利质权反担保合同（适用于法人）";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "10":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/权利质权反担保合同（适用于自然人）.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("权利质权反担保合同（适用于自然人）");
                fileName = loanApplication.getEnterpriseName() + "-权利质权反担保合同（适用于自然人）";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "11":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/股东会决议.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily" + loanApplicationNumber;
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("股东会决议");
                fileName = loanApplication.getEnterpriseName() + "-股东会决议";
                fileNameHz = fileName + ".docx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            case "12":

                // 创建一个列表，用来存储要填充到Excel中的数据
                List<Map<String, Object>> list = new ArrayList<>();
                // 向列表中添加数据
/*                list.add( Map.of("name","zou" ,"age" ,18) );
                list.add( Map.of("name","li" ,"age" ,28) );
                list.add( Map.of("name","wang" ,"age" ,15) );
                list.add( Map.of("name","quan" ,"age" ,19) );
                list.add( Map.of("name","zhao" ,"age" ,98) );*/

                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("项目评审意见签批表");
                fileName = loanApplication.getEnterpriseName() + "-项目评审意见签批表";
                fileNameHz = fileName + ".xlsx";
                templatePath = RuoYiConfig.getProfile() + "/mb/项目评审意见签批表.xlsx";
                ExcelFillUtils.fillOneSheet(templatePath, fileName, list);

                //templatePath = RuoYiConfig.getProfile() + "/mb/项目评审意见签批表.docx";
                //fileDir = RuoYiConfig.getProfile() + "/mb/temporarily";
                //fileName = loanApplication.getEnterpriseName() + "-项目评审意见签批表";
                //wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".xlsx";
                break;
            case "13":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/担保项目合法合规表企业.docx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily";
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("担保项目合法合规表企业");
                fileName = loanApplication.getEnterpriseName() + "-担保项目合法合规表企业";
                if ("2".equals(loanApplication.getApplicationType())) {
                    templatePath = RuoYiConfig.getProfile() + "/mb/担保项目合法合规表个人个体户.docx";
                    fileDir = RuoYiConfig.getProfile() + "/mb/temporarily";
                    //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("担保项目合法合规表个人个体户");
                    fileName = loanApplication.getEnterpriseName() + "-担保项目合法合规表个人个体户";
                }
                fileNameHz = fileName + ".xlsx";
                path = path + "/" + fileName + ".docx";
                break;
            case "14":
                //params.put("enterpriseName", loanApplication.getEnterpriseName());
                //path = path + "/委托担保申请书.doc";
                templatePath = RuoYiConfig.getProfile() + "/mb/放款审批合规表企业.xlsx";
                fileDir = RuoYiConfig.getProfile() + "/mb/temporarily";
                //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("放款审批合规表企业");
                fileName = loanApplication.getEnterpriseName() + "-放款审批合规表企业";
                if ("2".equals(loanApplication.getApplicationType())) {
                    templatePath = RuoYiConfig.getProfile() + "/mb/放款审批合规表个人个体户.docx";
                    fileDir = RuoYiConfig.getProfile() + "/mb/temporarily";
                    //fileName = FileUploadUtils.extractFilenameLoanApplicationNumberNoHzm("放款审批合规表个人个体户");
                    fileName = loanApplication.getEnterpriseName() + "-放款审批合规表个人个体户";
                }
                fileNameHz = fileName + ".xlsx";
                wordPath = WordUtil.createWord(templatePath, fileDir, fileName, params);
                path = path + "/" + fileName + ".docx";
                break;
            default:
                break;
        }

        LoanApplicationFj applicationFj = new LoanApplicationFj();
        applicationFj.setType(type);
        applicationFj.setLoanApplicationNumber(loanApplication.getLoanApplicationNumber());
        applicationFj.setName(fileName);
        String fileId = IdUtils.fastSimpleUUID();
        redisCache.setCacheObject(fileId + "info", applicationFj, 2, TimeUnit.HOURS);

        map.put("fileId", fileId);
        map.put("path", path);
        map.put("fileName", fileNameHz);
        return AjaxResult.success(map);
    }

    private String contrastType(String type) {
        String fileType = "";
        switch (type) {
            case "1":
                fileType = "wtdbsqs";
                break;
            case "2":
                fileType = "wtdbht";
                break;
            case "3":
                fileType = "dbyxh";
                break;
            case "4":
                fileType = "fktzhsh";
                break;
            case "5":
                fileType = "bzfdbhtfr";
                break;
            case "6":
                fileType = "bzfdbhtzrr";
                break;
            case "7":
                fileType = "dyfdbhtfr";
                break;
            case "8":
                fileType = "dyfdbhtzrr";
                break;
            case "9":
                fileType = "27";
                break;
            case "10":
                fileType = "27";
                break;
            case "11":
                fileType = "gdhyjy";
                break;
            case "12":
                fileType = "psyjqpb";
                break;
            case "13":
                fileType = "clhgb";
                break;
            default:
                fileType = "fkhgb";
                break;
        }
        return fileType;
    }
}
