package com.chinaweal.aiccs.aiccs.expelled.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinaweal.aiccs.aiccs.abnormal.entity.TSAttachment;
import com.chinaweal.aiccs.aiccs.abnormal.service.TSAttachmentService;
import com.chinaweal.aiccs.aiccs.auditing.entity.TSOpinion;
import com.chinaweal.aiccs.aiccs.auditing.service.TSOpinionService;
import com.chinaweal.aiccs.aiccs.business.entity.TSTaskList;
import com.chinaweal.aiccs.aiccs.business.entity.TSTwfProcessNode;
import com.chinaweal.aiccs.aiccs.business.rules.model.SequenceFlowModel;
import com.chinaweal.aiccs.aiccs.business.service.TSTaskListService;
import com.chinaweal.aiccs.aiccs.business.service.WorkFlowService;
import com.chinaweal.aiccs.aiccs.expelled.entity.*;
import com.chinaweal.aiccs.aiccs.expelled.mapper.ExpelledAuditInfoMapper;
import com.chinaweal.aiccs.aiccs.expelled.service.*;
import com.chinaweal.aiccs.aiccs.expelled.vo.AuditInfoVo;
import com.chinaweal.aiccs.aiccs.expelled.vo.BizInfoVo;
import com.chinaweal.aiccs.aiccs.expelled.vo.RemoveApproveInfo;
import com.chinaweal.aiccs.common.base.controller.BaseController;
import com.chinaweal.aiccs.common.constant.BaseDataConstant;
import com.chinaweal.aiccs.common.constant.Constant;
import com.chinaweal.aiccs.common.util.FlowUtil;
import com.chinaweal.aiccs.common.util.HandleWorkFlowUtil;
import com.chinaweal.aiccs.common.util.WorkFlowUtil;
import com.chinaweal.aiccs.config.CommonConfig;
import com.chinaweal.aiccs.utils.BeanUtil;
import com.chinaweal.aiccs.utils.DocumentNoGenerator;
import com.chinaweal.aicorg.model.AICUser;
import com.chinaweal.youfool.framework.springboot.base.query.BaseQuery;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import com.chinaweal.youfool.framework.springboot.rest.RestResult;
import com.chinaweal.youfool.framework.springboot.rest.ResultCode;
import com.deepoove.poi.XWPFTemplate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.*;

/**
 * @Description: 市场主体拟除名名单决定业务表实现类
 * @Author: TiAmo-cc
 * @Email: 1049976610@qq.com
 * @Date: 2026/1/7 10:42
 */
@Service
public class ExpelledAuditInfoServiceImpl extends ServiceImpl<ExpelledAuditInfoMapper, ExpelledAuditInfo> implements IExpelledAuditInfoService {

    @Resource
    private IExpelledResultInfoService expelledResultInfoService;
    @Resource
    private IExpelledBizInfoService expelledBizInfoService;
    @Resource
    private IExpelledEntInfoService expelledEntInfoService;
    @Resource
    private IEntBaseExpelledInfoService entBaseExpelledInfoService;
    @Resource
    private TSTaskListService tsTaskListService;
    @Resource
    private WorkFlowService workFlowService;
    @Resource
    private TSOpinionService opinionService;
    @Resource
    private TSAttachmentService attachmentService;

    @Override
    public IPage<AuditInfoVo> listHavedoAuditInfo(BaseQuery<AuditInfoVo> query) {
        AuditInfoVo entity = query.getEntity(AuditInfoVo.class);
        Page<AuditInfoVo> page = query.getPage();
        return baseMapper.listHavedoAuditInfo(page, entity);
    }

    @Override
    public RestResult<?> startObjectionBiz(AuditInfoVo query, HttpServletRequest request) {
        AICUser user = BaseController.getLoginUser(request);
        if (user == null) {
            throw new BusinessException("登录超时，请重新登录");
        }
        if (CollectionUtils.isEmpty(query.getBizInfos())) {
            return RestResult.error(ResultCode.PARAM_IS_BLANK, "请至少勾选一个拟除名市场主体");
        }
        Map<String, Object> resultMap = new HashMap<>();
        String bizId = UUID.randomUUID().toString();
        // 添加待办启动流程
        TSTaskList tsTaskList = new TSTaskList();
        tsTaskList.setBizseqid(bizId);
        tsTaskList.setBustype(BaseDataConstant.BUSINESS_TYPE_REMOVE_OBJECTION); // 除名异议
        tsTaskList.setBusname(query.getBusName());
        // 保存除名异议数据
        ExpelledAuditInfo objectionInfo = new ExpelledAuditInfo();
        objectionInfo.setId(bizId);
        objectionInfo.setBizType("1");
        objectionInfo.setAuditNo(generateAuditNo());
        // 初始化市场主体除名异议信息
        for (BizInfoVo bizInfo : query.getBizInfos()) {
            ExpelledResultInfo resultInfo = new ExpelledResultInfo();
            resultInfo.setAuditId(objectionInfo.getId());
            resultInfo.setEntId(bizInfo.getEntId());
            expelledResultInfoService.saveExpelledResultInfo(resultInfo);
            // 同步更新除名告知业务申请中的市场主体企业信息的异议中状态
            ExpelledEntInfo entInfo = expelledEntInfoService.getById(bizInfo.getEntId());
            if (entInfo == null) {
                continue;
            }
            entInfo.setStatus("1"); // 异议中
            expelledEntInfoService.saveOrUpdate(entInfo);
        }
        // 保存业务待办信息
        tsTaskList = startBizAccept(user, tsTaskList, objectionInfo);
        List<SequenceFlowModel> nextSequenceFlows = workFlowService.findNextSequenceFlowList(tsTaskList.getWorkflowid());
        TSTwfProcessNode currentNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());
        String opinionType = BaseDataConstant.getOpinionTypeByWorkFlowNode(currentNode.getCurrentnode());
        if (opinionType == null) {
            opinionType = "1";
        }
        resultMap.put("objectionInfo", objectionInfo);
        resultMap.put("taskId", tsTaskList.getTasklistid());
        resultMap.put("bizId", bizId);
        resultMap.put("nextSequenceFlows", nextSequenceFlows);
        resultMap.put("currentNode", currentNode.getCurrentnode());
        resultMap.put("currentNodeName", WorkFlowUtil.getNodeName(currentNode.getCurrentnode()));
        resultMap.put("currentLinkTypeID", opinionType);
        return RestResult.ok(resultMap);
    }

    @Override
    public RestResult<?> getObjectionBiz(String bizId) {
        Map<String, Object> resultMap = new HashMap<>();
        // 除名异议业务表
        ExpelledAuditInfo objectionInfo = getById(bizId);
        if (objectionInfo == null) {
            throw new BusinessException("除名异议业务信息不存在，请联系管理员");
        }
        List<ExpelledResultInfo> resultInfos = expelledResultInfoService.searchResultInfoByAudit(bizId);
        if (CollectionUtils.isNotEmpty(resultInfos)) {
            objectionInfo.setOpinion(resultInfos.get(0).getOpinion());
            objectionInfo.setAuditOpinion(resultInfos.get(0).getAuditOpinion());
        }
        resultMap.put("objectionInfo", objectionInfo);
        // 拟除名异议企业信息
        AuditInfoVo query = new AuditInfoVo();
        query.setAuditId(bizId);
        query.setBizType("1");
        List<AuditInfoVo> entInfos = baseMapper.listAuditEntBaseInfo(query);
        resultMap.put("entInfos", entInfos);
        // 除名业务待办
        TSTaskList tsTaskList = tsTaskListService.searchTaskListByBizId(bizId);
        if (tsTaskList == null) {
            throw new BusinessException("除名异议业务待办信息不存在，请联系管理员");
        }
        resultMap.put("tsTaskList", new TSTaskList().setTasklistid(tsTaskList.getTasklistid()).setWorkflowid(tsTaskList.getWorkflowid()));
        // 获取历史审批意见
        LambdaQueryWrapper<TSOpinion> opinionWrapper = new LambdaQueryWrapper<>();
        opinionWrapper.eq(TSOpinion::getBizseq, bizId)
                .ne(TSOpinion::getOpiniontype, "55")
                .orderByAsc(TSOpinion::getHandledate);
        List<TSOpinion> tsOpinions = opinionService.list(opinionWrapper);
        resultMap.put("historyOpinions", tsOpinions);
        return RestResult.ok(resultMap);
    }

    @Override
    public RestResult<?> nextObjectionBiz(RemoveApproveInfo removeApproveInfo, HttpServletRequest request) {
        AICUser user = BaseController.getLoginUser(request);
        if (user == null) {
            throw new BusinessException("登录超时，请重新登录");
        }
        String bizId = removeApproveInfo.getBizId();
        String taskId = removeApproveInfo.getTaskId();
        String nextNodeId = removeApproveInfo.getNextNodeId();
        String nextPerformerIds = removeApproveInfo.getNextPerformerIds();
        String nextPerformerNames = removeApproveInfo.getNextPerformerNames();
        ExpelledAuditInfo objectionInfoQuery = removeApproveInfo.getObjectionInfo();
        if (StringUtils.isBlank(bizId)) {
            throw new BusinessException("bizId参数缺失");
        }
        if (StringUtils.isBlank(taskId)) {
            throw new BusinessException("taskId参数缺失");
        }
        if (StringUtils.isBlank(nextNodeId)) {
            throw new BusinessException("nextNodeId参数缺失");
        }
        if (objectionInfoQuery == null) {
            throw new BusinessException("objectionInfoQuery参数缺失");
        }
        Map<String, Object> resultMap = new HashMap<>();
        ExpelledAuditInfo objectionInfo = getById(bizId);
        if (objectionInfo == null) {
            throw new BusinessException("除名异议业务信息不存在，请联系管理员");
        }
        // 更新除名异议业务表
        if (objectionInfoQuery != null && StringUtils.isNotBlank(objectionInfoQuery.getId())) {
            TSTaskList tsTaskList = tsTaskListService.selectByTasklistID(taskId);
            TSTwfProcessNode processNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());

            // 下一步为审核
            if (StringUtils.equals(FlowUtil.EXPTLISTWORKFLOW_HANDLEEXPTLIST, nextNodeId)) {
                if (StringUtils.equals(FlowUtil.EXPTLISTWORKFLOW_EXPTLISTENTER, processNode.getCurrentnode())) {
                    BeanUtil.copyBean(objectionInfoQuery, objectionInfo);
                }
            }

            if (StringUtils.isBlank(nextPerformerIds)) {
                processNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());
                int order = WorkFlowUtil.checkNextOrder(processNode.getCurrentnode(), nextNodeId);
                // 通过order判断为回退还是前进 >0 前进
                if (order > 0) {
                    LambdaQueryWrapper<TSOpinion> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(TSOpinion::getWorkflowid, tsTaskList.getWorkflowid())
                            .eq(TSOpinion::getOpiniontype, "0") // 经办为0
                            .orderByDesc(TSOpinion::getLauptime);
                    List<TSOpinion> list = opinionService.list(wrapper);
                    if (org.apache.commons.collections.CollectionUtils.isEmpty(list)) {
                        return RestResult.error(ResultCode.DATA_NONE, "除名异议审批意见不存在，请联系管理员");
                    }
                    nextPerformerIds = list.get(0).getHandlerid();
                    nextPerformerNames = list.get(0).getHandler();
                }
                // 回退时获取经办人
                if (order < 0) {
                    // 获取经办人
                    LambdaQueryWrapper<TSOpinion> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(TSOpinion::getWorkflowid, tsTaskList.getWorkflowid())
                            .eq(TSOpinion::getOpiniontype, '0')
                            .orderByDesc(TSOpinion::getLauptime);
                    List<TSOpinion> list = opinionService.list(wrapper);
                    if (org.apache.commons.collections.CollectionUtils.isEmpty(list)) {
                        return RestResult.error(ResultCode.DATA_NONE, "除名异议审批意见不存在，请联系管理员");
                    }
                    nextPerformerIds = list.get(0).getHandlerid();
                    nextPerformerNames = list.get(0).getHandler();
                }
            }

            // 发送
            String[] ids = StringUtils.split(nextPerformerIds, Constant.COMMA);
            String[] names = StringUtils.split(nextPerformerNames, Constant.COMMA);
            try {
                tsTaskList = saveAuditProcess(user, tsTaskList, objectionInfo, removeApproveInfo.getOpinionQuery(), nextNodeId, ids, names);
                if (ids.length == 1 && StringUtils.equals(user.getPrimaryKey(), ids[0])) {
                    resultMap.put("bizId", bizId);
                    resultMap.put("taskId", taskId);
                    resultMap.put("nextNodeId", nextNodeId);
                    resultMap.put("workFlowId", tsTaskList.getWorkflowid());
                }
            } catch (Exception e) {
                log.error("除名异议业务审批出错：", e);
                throw new BusinessException("除名异议业务审批出错");
            }
        }
        return RestResult.ok(resultMap);
    }

    @Override
    public RestResult<?> startAuditBiz(AuditInfoVo query, HttpServletRequest request) {
        AICUser user = BaseController.getLoginUser(request);
        if (user == null) {
            throw new BusinessException("登录超时，请重新登录");
        }
        if (CollectionUtils.isEmpty(query.getBizInfos())) {
            return RestResult.error(ResultCode.PARAM_IS_BLANK, "请至少勾选一个拟除名市场主体");
        }
        Map<String, Object> resultMap = new HashMap<>();
        String bizId = UUID.randomUUID().toString();
        // 添加待办启动流程
        TSTaskList tsTaskList = new TSTaskList();
        tsTaskList.setBizseqid(bizId);
        tsTaskList.setBustype(BaseDataConstant.BUSINESS_TYPE_REMOVE_AUDIT); // 除名决定
        tsTaskList.setBusname(query.getBusName());
        // 保存除名决定数据
        ExpelledAuditInfo auditInfo = new ExpelledAuditInfo();
        auditInfo.setId(bizId);
        auditInfo.setBizType("2");
        auditInfo.setAuditNo(generateAuditNo());
        // 初始化市场主体除名决定信息
        for (BizInfoVo bizInfo : query.getBizInfos()) {
            ExpelledResultInfo resultInfo = new ExpelledResultInfo();
            resultInfo.setAuditId(auditInfo.getId());
            resultInfo.setEntId(bizInfo.getEntId());
            expelledResultInfoService.saveExpelledResultInfo(resultInfo);
            // 同步更新除名告知业务申请中的市场主体企业信息的决定中状态
            ExpelledEntInfo entInfo = expelledEntInfoService.getById(bizInfo.getEntId());
            if (entInfo == null) {
                continue;
            }
            entInfo.setStatus("2"); // 决定中
            expelledEntInfoService.saveOrUpdate(entInfo);
        }
        // 保存业务待办信息
        tsTaskList = startBizAccept(user, tsTaskList, auditInfo);
        List<SequenceFlowModel> nextSequenceFlows = workFlowService.findNextSequenceFlowList(tsTaskList.getWorkflowid());
        TSTwfProcessNode currentNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());
        String opinionType = BaseDataConstant.getOpinionTypeByWorkFlowNode(currentNode.getCurrentnode());
        if (opinionType == null) {
            opinionType = "1";
        }
        resultMap.put("auditInfo", auditInfo);
        resultMap.put("taskId", tsTaskList.getTasklistid());
        resultMap.put("bizId", bizId);
        resultMap.put("nextSequenceFlows", nextSequenceFlows);
        resultMap.put("currentNode", currentNode.getCurrentnode());
        resultMap.put("currentNodeName", WorkFlowUtil.getNodeName(currentNode.getCurrentnode()));
        resultMap.put("currentLinkTypeID", opinionType);
        return RestResult.ok(resultMap);
    }

    @Override
    public RestResult<?> getAuditBiz(String bizId) {
        Map<String, Object> resultMap = new HashMap<>();
        // 除名决定业务表
        ExpelledAuditInfo auditInfo = getById(bizId);
        if (auditInfo == null) {
            throw new BusinessException("除名决定业务信息不存在，请联系管理员");
        }
        List<ExpelledResultInfo> resultInfos = expelledResultInfoService.searchResultInfoByAudit(bizId);
        if (CollectionUtils.isNotEmpty(resultInfos)) {
            auditInfo.setAuditOpinion(resultInfos.get(0).getAuditOpinion());
        }
        resultMap.put("auditInfo", auditInfo);
        // 拟除名决定企业信息
        AuditInfoVo query = new AuditInfoVo();
        query.setAuditId(bizId);
        query.setBizType("2");
        List<AuditInfoVo> entInfos = baseMapper.listAuditEntBaseInfo(query);
        resultMap.put("entInfos", entInfos);
        // 除名业务待办
        TSTaskList tsTaskList = tsTaskListService.searchTaskListByBizId(bizId);
        if (tsTaskList == null) {
            throw new BusinessException("除名决定业务待办信息不存在，请联系管理员");
        }
        resultMap.put("tsTaskList", new TSTaskList().setTasklistid(tsTaskList.getTasklistid()).setWorkflowid(tsTaskList.getWorkflowid()));
        // 获取历史审批意见
        LambdaQueryWrapper<TSOpinion> opinionWrapper = new LambdaQueryWrapper<>();
        opinionWrapper.eq(TSOpinion::getBizseq, bizId)
                .ne(TSOpinion::getOpiniontype, "55")
                .orderByAsc(TSOpinion::getHandledate);
        List<TSOpinion> tsOpinions = opinionService.list(opinionWrapper);
        resultMap.put("historyOpinions", tsOpinions);
        return RestResult.ok(resultMap);
    }

    @Override
    public RestResult<?> nextAuditBiz(RemoveApproveInfo removeApproveInfo, HttpServletRequest request) {
        AICUser user = BaseController.getLoginUser(request);
        if (user == null) {
            throw new BusinessException("登录超时，请重新登录");
        }
        String bizId = removeApproveInfo.getBizId();
        String taskId = removeApproveInfo.getTaskId();
        String nextNodeId = removeApproveInfo.getNextNodeId();
        String nextPerformerIds = removeApproveInfo.getNextPerformerIds();
        String nextPerformerNames = removeApproveInfo.getNextPerformerNames();
        ExpelledAuditInfo auditInfoQuery = removeApproveInfo.getAuditInfo();
        if (StringUtils.isBlank(bizId)) {
            throw new BusinessException("bizId参数缺失");
        }
        if (StringUtils.isBlank(taskId)) {
            throw new BusinessException("taskId参数缺失");
        }
        if (StringUtils.isBlank(nextNodeId)) {
            throw new BusinessException("nextNodeId参数缺失");
        }
        if (auditInfoQuery == null) {
            throw new BusinessException("auditInfoQuery参数缺失");
        }
        Map<String, Object> resultMap = new HashMap<>();
        ExpelledAuditInfo auditInfo = getById(bizId);
        if (auditInfo == null) {
            throw new BusinessException("除名决定业务信息不存在，请联系管理员");
        }
        // 更新除名决定业务表
        if (auditInfoQuery != null && StringUtils.isNotBlank(auditInfoQuery.getId())) {
            TSTaskList tsTaskList = tsTaskListService.selectByTasklistID(taskId);
            TSTwfProcessNode processNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());

            // 下一步为审核
            if (StringUtils.equals(FlowUtil.EXPTLISTWORKFLOW_HANDLEEXPTLIST, nextNodeId)) {
                if (StringUtils.equals(FlowUtil.EXPTLISTWORKFLOW_EXPTLISTENTER, processNode.getCurrentnode())) {
                    BeanUtil.copyBean(auditInfoQuery, auditInfo);
                }
            }

            if (StringUtils.isBlank(nextPerformerIds)) {
                processNode = workFlowService.findCurrentNode(tsTaskList.getWorkflowid());
                int order = WorkFlowUtil.checkNextOrder(processNode.getCurrentnode(), nextNodeId);
                // 通过order判断为回退还是前进 >0 前进
                if (order > 0) {
                    LambdaQueryWrapper<TSOpinion> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(TSOpinion::getWorkflowid, tsTaskList.getWorkflowid())
                            .eq(TSOpinion::getOpiniontype, "0") // 经办为0
                            .orderByDesc(TSOpinion::getLauptime);
                    List<TSOpinion> list = opinionService.list(wrapper);
                    if (org.apache.commons.collections.CollectionUtils.isEmpty(list)) {
                        return RestResult.error(ResultCode.DATA_NONE, "除名决定审批意见不存在，请联系管理员");
                    }
                    nextPerformerIds = list.get(0).getHandlerid();
                    nextPerformerNames = list.get(0).getHandler();
                }
                // 回退时获取经办人
                if (order < 0) {
                    // 获取经办人
                    LambdaQueryWrapper<TSOpinion> wrapper = new LambdaQueryWrapper<>();
                    wrapper.eq(TSOpinion::getWorkflowid, tsTaskList.getWorkflowid())
                            .eq(TSOpinion::getOpiniontype, '0')
                            .orderByDesc(TSOpinion::getLauptime);
                    List<TSOpinion> list = opinionService.list(wrapper);
                    if (org.apache.commons.collections.CollectionUtils.isEmpty(list)) {
                        return RestResult.error(ResultCode.DATA_NONE, "除名决定审批意见不存在，请联系管理员");
                    }
                    nextPerformerIds = list.get(0).getHandlerid();
                    nextPerformerNames = list.get(0).getHandler();
                }
            }

            // 发送
            String[] ids = StringUtils.split(nextPerformerIds, Constant.COMMA);
            String[] names = StringUtils.split(nextPerformerNames, Constant.COMMA);
            try {
                tsTaskList = saveAuditProcess(user, tsTaskList, auditInfo, removeApproveInfo.getOpinionQuery(), nextNodeId, ids, names);
                if (ids.length == 1 && StringUtils.equals(user.getPrimaryKey(), ids[0])) {
                    resultMap.put("bizId", bizId);
                    resultMap.put("taskId", taskId);
                    resultMap.put("nextNodeId", nextNodeId);
                    resultMap.put("workFlowId", tsTaskList.getWorkflowid());
                }
            } catch (Exception e) {
                log.error("除名决定业务审批出错：", e);
                throw new BusinessException("除名决定业务审批出错");
            }
        }
        return RestResult.ok(resultMap);
    }

    @Override
    public TSTaskList startBizAccept(AICUser user, TSTaskList tsTaskList, ExpelledAuditInfo auditInfo) {
        if (StringUtils.isBlank(tsTaskList.getTasklistid())) {
            auditInfo.setIsDelete("0");
            saveOrUpdate(auditInfo);
            String definedname = FlowUtil.EXPTLISTWORKFLOW; // 除名异议/决定，这类参考使用企业经营异常名录流程模板，应该是可以的吧
            // 新待办
            tsTaskList = HandleWorkFlowUtil.createTaskList(tsTaskList, user);
            // 开始工作流
            tsTaskListService.startWorkFlow(tsTaskList, user, definedname);
        }
        return tsTaskList;
    }

    @Override
    public TSTaskList saveAuditProcess(AICUser user, TSTaskList tsTaskList, ExpelledAuditInfo auditInfo, TSOpinion opinion, String nextNodeId, String[] nextPerformerIds, String[] nextPerformerNames) {
        try {
            if (StringUtils.isNotBlank(tsTaskList.getAcceptgroupid())) {
                workFlowService.claimGroup(tsTaskList.getWorkflowid(), user.getPrimaryKey());
            }
            tsTaskListService.updateWorkFlow(user, opinion, tsTaskList, nextNodeId, nextPerformerIds, nextPerformerNames);
            auditInfo.setRemoveDate(LocalDate.now());
            auditInfo.setRemoveOrgNo(user.getRegionID());
            auditInfo.setRemoveOrgName(user.getOrgName());
            saveOrUpdate(auditInfo);
            List<ExpelledResultInfo> resultInfos = expelledResultInfoService.searchResultInfoByAudit(auditInfo.getId());
            if (!CollectionUtils.isEmpty(resultInfos)) {
                for  (ExpelledResultInfo resultInfo : resultInfos) {
                    resultInfo.setOpinion(auditInfo.getOpinion());
                    resultInfo.setAuditOpinion(auditInfo.getAuditOpinion());
                    // 同步更新拟除名名单企业信息表状态
                    ExpelledEntInfo entInfo = expelledEntInfoService.getById(resultInfo.getEntId());
                    if (entInfo == null) {
                        continue;
                    }
                    // 同步更新拟除名名单库状态
                    EntBaseExpelledInfo expelledInfo = entBaseExpelledInfoService.getById(entInfo.getExpelledId());
                    if (expelledInfo == null) {
                        continue;
                    }
                    if (FlowUtil.EXPTLISTWORKFLOW_ENDEXPTLIST.equals(nextNodeId)) { // 完结时
                        resultInfo.setState("10");
                        if (StringUtils.equals(BaseDataConstant.BUSINESS_TYPE_REMOVE_OBJECTION, tsTaskList.getBustype())) {
                            resultInfo.setIsObjection("1"); // 有异议
                            entInfo.setStatus("3"); // 已异议
                            expelledInfo.setState("2"); // 有效
                        } else if (StringUtils.equals(BaseDataConstant.BUSINESS_TYPE_REMOVE_AUDIT, tsTaskList.getBustype())) {
                            resultInfo.setIsRemove("1"); // 同意除名
                            entInfo.setStatus("4"); // 已决定
                            expelledInfo.setState("1"); // 已除名
                        }
                    }
                    if (FlowUtil.EXPTLISTWORKFLOW_OVEREXPTLIST.equals(nextNodeId) || FlowUtil.EXPTLISTWORKFLOW_OVERFINISH.equals(nextNodeId)) {
                        if (StringUtils.equals(BaseDataConstant.BUSINESS_TYPE_REMOVE_OBJECTION, tsTaskList.getBustype())) {
                            resultInfo.setIsObjection("0"); // 无异议
                            resultInfo.setState("-1"); // 除名异议不通过
                            entInfo.setStatus("5"); // 异议不通过
                        } else if (StringUtils.equals(BaseDataConstant.BUSINESS_TYPE_REMOVE_AUDIT, tsTaskList.getBustype())) {
                            resultInfo.setIsRemove("0"); // 不同意除名
                            resultInfo.setState("-2"); // 除名决定不通过
                            entInfo.setStatus("6"); // 决定不通过
                        }
                        expelledInfo.setState("2"); // 有效
                    }
                    expelledEntInfoService.saveOrUpdate(entInfo);
                    entBaseExpelledInfoService.saveOrUpdate(expelledInfo);
                    expelledResultInfoService.saveOrUpdate(resultInfo);
                }
            }
            // 生成文书
            if (StringUtils.equals(BaseDataConstant.BUSINESS_TYPE_REMOVE_AUDIT, tsTaskList.getBustype())) {
                createApproveDoc(auditInfo, tsTaskList);
            }
        } catch (Exception e) {
            log.error("除名申请（异议、决定）流程审核出错", e);
            throw new BusinessException("除名申请（异议、决定）流程审核出错");
        }
        return tsTaskList;
    }

    @Override
    public ExpelledAuditInfo getExpelledAuditInfoByAuditNo(String auditNo) {
        return getOne(new LambdaQueryWrapper<ExpelledAuditInfo>().eq(ExpelledAuditInfo::getAuditNo, auditNo));
    }

    @Override
    public String generateAuditNo() {
        String bizNo = DocumentNoGenerator.generateBizNo();
        ExpelledAuditInfo auditInfo = getExpelledAuditInfoByAuditNo(bizNo);
        if (auditInfo == null) {
            return bizNo;
        }
        return generateAuditNo();
    }

    @Override
    public void createApproveDoc(ExpelledAuditInfo auditInfo, TSTaskList tsTaskList) {
        Map<String, Object> map = new HashMap<>();
        map.put("orgName", auditInfo.getRemoveOrgName());
        // 拟除名企业信息
        AuditInfoVo query = new AuditInfoVo();
        query.setAuditId(auditInfo.getId());
        query.setBizType("2");
        List<AuditInfoVo> entInfos = baseMapper.listAuditEntBaseInfo(query);
        String entNames = "";
        String auditOpinion = "";
        if (!CollectionUtils.isEmpty(entInfos)) {
            auditOpinion = entInfos.get(0).getAuditOpinion();
            for (int i = 0; i < entInfos.size(); i++) {
                if (i >= 3) {
                    continue;
                }
                entNames += entInfos.get(i).getEntName() + '、';
            }
            entNames = entNames.substring(0, entNames.length() - 1) + "等" + entInfos.size() + "户企业/个体户";
        }
        map.put("entNames", entNames);
        map.put("auditOpinion", auditOpinion);
        // 获取历史审批意见
        LambdaQueryWrapper<TSOpinion> opinionWrapper = new LambdaQueryWrapper<>();
        opinionWrapper.eq(TSOpinion::getBizseq, auditInfo.getId())
                .in(TSOpinion::getOpiniontype,"0", "1", "2")
                .orderByAsc(TSOpinion::getHandledate);
        List<TSOpinion> tsOpinions = opinionService.list(opinionWrapper);
        for (TSOpinion item : tsOpinions) {
            int index = Integer.parseInt(item.getOpiniontype()) + 1;
            map.put("opinion" + index, item.getOpinioncontent());
            map.put("handler" + index, item.getHandler());
            map.put("year" + index, item.getHandledate().getYear());
            map.put("month" + index, item.getHandledate().getMonthValue());
            map.put("day" + index, item.getHandledate().getDayOfMonth());
        }
        try {
            // 文书模板路径
            String wordTemplatePath = "static" + File.separator + "template" + File.separator + "expelled" + File.separator + "auditDoc.docx";
            String resource = this.getClass().getClassLoader().getResource(wordTemplatePath).getPath();
            // URL解码
            resource = URLDecoder.decode(resource, "UTF-8");
            String realPath = CommonConfig.getUploadPath(); // 存储路径
            String docName = UUID.randomUUID().toString(); // 文件名
            TSAttachment tsAttachment = attachmentService.getByBizseqAndType(auditInfo.getId(), "1");
            if (tsAttachment == null) {
                tsAttachment = new TSAttachment();
                tsAttachment.setAttachmentid(UUID.randomUUID().toString());
                tsAttachment.setUploaddate(LocalDate.now());
            } else {
                realPath = CommonConfig.getUploadPathByDate(tsAttachment.getUploaddate());
                docName = tsAttachment.getFilename().substring(0, tsAttachment.getFilename().lastIndexOf("."));
            }
            realPath += File.separator + auditInfo.getId();
            File dir = new File(realPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            // 生成
            XWPFTemplate.compile(resource).render(map).writeToFile(realPath + File.separator + docName + ".docx");
            // 保存记录
            String ext = ".docx";
            String fileName = docName + ext;
            String tempPath = auditInfo.getId() + File.separator + fileName;
            tsAttachment.setCreatetype("1"); // 文件为系统生成
            tsAttachment.setBizseq(auditInfo.getId());
            tsAttachment.setFileext(ext);
            tsAttachment.setFilename(fileName);
            tsAttachment.setTemppath(tempPath);
            tsAttachment.setAttachtype("1"); // 审批表
            attachmentService.saveOrUpdate(tsAttachment);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void createAuditDoc(ExpelledResultInfo resultInfo, ExpelledEntInfo entInfo) {
        Map<String, Object> map = new HashMap<>();
        ExpelledAuditInfo auditInfo = getById(resultInfo.getAuditId());
        if (auditInfo == null) {
            throw new BusinessException("除名决定业务信息不存在，请联系管理员");
        }
        map.put("orgName", auditInfo.getRemoveOrgName());
        map.put("noticeNo", entInfo.getNoticeNo());
        EntBaseExpelledInfo expelledInfo = entBaseExpelledInfoService.getById(entInfo.getExpelledId());
        if (expelledInfo == null) {
            throw new BusinessException("拟除名企业信息不存在，请联系管理员");
        }
        map.put("entName", expelledInfo.getEntName());
        map.put("uscc", expelledInfo.getUscc());
        map.put("lerepName", expelledInfo.getLerepName());
        map.put("year", auditInfo.getRemoveDate().getYear());
        map.put("month", auditInfo.getRemoveDate().getMonthValue());
        map.put("day", auditInfo.getRemoveDate().getDayOfMonth());
        try {
            // 文书模板路径
            String wordTemplatePath = "static" + File.separator + "template" + File.separator + "expelled" + File.separator + "auditEntDoc.docx";
            String resource = this.getClass().getClassLoader().getResource(wordTemplatePath).getPath();
            // URL解码
            resource = URLDecoder.decode(resource, "UTF-8");
            String realPath = CommonConfig.getUploadPath(); // 存储路径
            String docName = UUID.randomUUID().toString(); // 文件名
            TSAttachment tsAttachment = attachmentService.getByBizseqAndType(resultInfo.getId(), "1");
            if (tsAttachment == null) {
                tsAttachment = new TSAttachment();
                tsAttachment.setAttachmentid(UUID.randomUUID().toString());
                tsAttachment.setUploaddate(LocalDate.now());
            } else {
                realPath = CommonConfig.getUploadPathByDate(tsAttachment.getUploaddate());
                docName = tsAttachment.getFilename().substring(0, tsAttachment.getFilename().lastIndexOf("."));
            }
            realPath += File.separator + resultInfo.getId();
            File dir = new File(realPath);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            // 生成
            XWPFTemplate.compile(resource).render(map).writeToFile(realPath + File.separator + docName + ".docx");
            // 保存记录
            String ext = ".docx";
            String fileName = docName + ext;
            String tempPath = resultInfo.getId() + File.separator + fileName;
            tsAttachment.setCreatetype("1"); // 文件为系统生成
            tsAttachment.setBizseq(resultInfo.getId());
            tsAttachment.setFileext(ext);
            tsAttachment.setFilename(fileName);
            tsAttachment.setTemppath(tempPath);
            tsAttachment.setAttachtype("3"); // 除名决定书
            attachmentService.saveOrUpdate(tsAttachment);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void downloadAuditDoc(HttpServletResponse response, String resultId, String noticeNo) {
        ExpelledResultInfo resultInfo = expelledResultInfoService.getById(resultId);
        if (resultInfo == null) {
            return;
        }
        ExpelledEntInfo entInfo = expelledEntInfoService.getExpelledEntInfo(noticeNo);
        if (entInfo == null) {
            return;
        }
        TSAttachment tsAttachment = attachmentService.getByBizseqAndType(resultInfo.getId(), "3");
        if (tsAttachment == null) {
            createAuditDoc(resultInfo, entInfo);
            tsAttachment = attachmentService.getByBizseqAndType(resultInfo.getId(), "3");
            if (tsAttachment == null) {
                return;
            }
        }
        // 获取流
        InputStream is = null;
        OutputStream os = null;
        try {
            // 获取文件
            String realPath = CommonConfig.getUploadPathByDate(tsAttachment.getUploaddate()) + File.separator + tsAttachment.getTemppath();
            is = new FileInputStream(realPath);
            os = response.getOutputStream();
            String fileName = new String(tsAttachment.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            // 设置：当浏览器收到这份资源的时候，以下载的方式提醒用户，而不是直接显示
            response.setHeader("Content-Disposition", "attachment;  filename=\"" + fileName + "\"");
            byte[] buffer = new byte[4096];
            int len;
            while ((len = is.read(buffer)) != -1) {
                os.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("下载文书时发生异常:{}=", e);
            return;
        } finally {
            try {
                os.close();
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
