package com.ruoyi.project.sems.controller;

import java.awt.*;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deepoove.poi.XWPFTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.document.DocumentHandler;
import com.ruoyi.common.utils.document.PDFTemplateUtil;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.interceptor.annotation.RepeatSubmit;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.security.service.TokenService;
import com.ruoyi.project.approve.damain.DevTask;
import com.ruoyi.project.listener.monthSemsApprove.*;
import com.ruoyi.project.listener.semsApprove.*;
import com.ruoyi.project.listener.yearSemsApprove.*;
import com.ruoyi.project.sems.domain.*;
import com.ruoyi.project.sems.his.controller.*;
import com.ruoyi.project.sems.mapper.TApproveMapper;
import com.ruoyi.project.sems.service.*;
import com.ruoyi.project.system.domain.SysConfig;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysConfigMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysUserService;
import freemarker.template.Template;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.page.TableDataInfo;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 特种设备申请Controller
 *
 * @author ruoyi
 * @date 2021-08-05
 */
@RestController("tApproveController")
@RequestMapping("/sems/approve")
public class TApproveController extends BaseController {
    @Autowired
    private ITApproveService tApproveService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private ITSpecdevDtService tSpecdevDtService;
    @Autowired
    private ITSpecdevDzsbService tSpecdevDzsbService;
    @Autowired
    private ITSpecdevGlService tSpecdevGlService;
    @Autowired
    private ITSpecdevYlgdService tSpecdevYlgdService;
    @Autowired
    private ITSpecdevYlrqService tSpecdevYlrqService;
    @Autowired
    private ITSpecdevCcService tSpecdevCcService;
    @Autowired
    private ITApproverFileService tApproverFileService;
    @Autowired
    private ISysUserService sysUserService;
    @Resource
    private TApproveMapper tApproveMapper;
    @Autowired
    private ITReportYlrqService tReportYlrqService;
    @Autowired
    private ITReportYlgdService tReportYlgdService;
    @Autowired
    private ITReportMonthService tReportMonthService;
    @Resource
    private SysConfigMapper configMapper;
    @Resource
    private SysUserMapper userMapper;
    @Autowired
    private TSpechiCcController tSpechiCcController;
    @Autowired
    private TSpechiDtController tSpechiDtController;
    @Autowired
    private TSpechiGlController tSpechiGlController;
    @Autowired
    private TSpechiDzsbController tSpechiDzsbController;
    @Autowired
    private TSpechiYlrqController tSpechiYlrqController;
    @Autowired
    private TSpechiYlgdController tSpechiYlgdController;

    /**
     * 查询特种设备申请列表
     */
    @PreAuthorize("@ss.hasPermi('sems:approve:list')")
    @GetMapping("/list")
    public TableDataInfo list(TApprove tApprove) {
        startPage();
        List<TApprove> list = tApproveService.selectTApproveList(tApprove);
        return getDataTable(list);
    }

    /**
     * 根据参数键名查询政府回执
     */
    @GetMapping(value = "/getGovUserId")
    public AjaxResult govUserId() {
        SysConfig config = new SysConfig();
        config.setConfigKey("sems.approve.gov");
        SysConfig retConfig = configMapper.selectConfig(config);
        SysUser sysUser = userMapper.selectUserByStaffId(retConfig.getConfigValue());
        return AjaxResult.success(sysUser.getUserId());
    }


    /**
     * 历史申请列表
     */
    @RequestMapping("/hisApprovelist")
    public AjaxResult hisApprovelist(@RequestParam Map<String, Object> params) {
        String sql = params.get("devId") + " in (SELECT REGEXP_SUBSTR (DEV_ID, '[^,]+', 1,rownum) from dual connect by rownum<=LENGTH (DEV_ID) - LENGTH (regexp_replace(DEV_ID, ',', ''))+1 )";
        List<TApprove> list = tApproveMapper.selectList(new QueryWrapper<TApprove>().apply(sql).orderByDesc("CREATTIME")
        );
        for (TApprove t : list
        ) {
            SysUser userEntity = sysUserService.selectUserById(t.getUserId());
            t.setUserName(userEntity.getNickName());
        }
        return AjaxResult.success(list);
    }

    /**
     * 导出特种设备申请列表
     */
    @PreAuthorize("@ss.hasPermi('sems:approve:export')")
    @Log(title = "特种设备申请", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TApprove tApprove) {
        List<TApprove> list = tApproveService.selectTApproveList(tApprove);
        ExcelUtil<TApprove> util = new ExcelUtil<TApprove>(TApprove.class);
        return util.exportExcel(list, "approve");
    }

    /**
     * 获取特种设备申请详细信息
     */
    @PreAuthorize("@ss.hasPermi('sems:approve:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(tApproveService.selectTApproveById(id));
    }

    /**
     * 新增特种设备申请
     */
    @Log(title = "特种设备申请", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TApprove tApprove) {
        logger.info(JSON.toJSONString(tApprove));
        Long userid = getUserId();
        tApprove.setUserId(userid);
        //审批编号
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
        String data = sdf.format(dt) + userid;
        tApprove.setApNo(data);
        tApproveService.insertTApprove(tApprove);
        if (tApprove.getFiles().size() > 0) {
            for (TApproverFile t : tApprove.getFiles()
            ) {
                t.setApproveId(tApprove.getId());
                t.setFileType(1l);
                tApproverFileService.save(t);
            }
        }
        //获取操作日志参数
        String operType = getOperType(Integer.parseInt(tApprove.getApproveType().toString()));
        LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
        String userName = loginUser != null ? loginUser.getUsername() : "";

        String[] ids = tApprove.getDevId().split(",");
        switch (Integer.parseInt(tApprove.getDevType().toString())) {
            case 1:
                for (String i : ids
                ) {
                    TSpecdevYlrq ylrqEntity = tSpecdevYlrqService.getById(i);
                    ylrqEntity.setApproveStatus(tApprove.getApproveType());
                    ylrqEntity.setApproveTime(new Date());
                    tSpecdevYlrqService.updateById(ylrqEntity);
                }
                logger.info("特种设备操作日志");
                new Thread(() -> {
                    tSpechiYlrqController.addOperLog(ids, userName, new Date(), operType + "-申请");
                }, "特种设备操作日志").start();
                break;
            case 2:
                for (String i : ids
                ) {
                    TSpecdevYlgd ylgdEntity = tSpecdevYlgdService.getById(i);
                    ylgdEntity.setApproveStatus(tApprove.getApproveType());
                    ylgdEntity.setApproveTime(new Date());
                    tSpecdevYlgdService.updateById(ylgdEntity);
                }
                logger.info("特种设备操作日志");
                new Thread(() -> {
                    tSpechiYlgdController.addOperLog(ids, userName, new Date(), operType + "-申请");
                }, "特种设备操作日志").start();
                break;
            case 3:
                for (String i : ids
                ) {
                    TSpecdevDzsb dzsbEntity = tSpecdevDzsbService.getById(i);
                    dzsbEntity.setApproveStatus(tApprove.getApproveType());
                    dzsbEntity.setApproveTime(new Date());
                    tSpecdevDzsbService.updateById(dzsbEntity);
                }
                logger.info("特种设备操作日志");
                new Thread(() -> {
                    tSpechiDzsbController.addOperLog(ids, userName, new Date(), operType + "-申请");
                }, "特种设备操作日志").start();
                break;
            case 4:
                for (String i : ids
                ) {
                    TSpecdevGl glEntity = tSpecdevGlService.getById(i);
                    glEntity.setApproveStatus(tApprove.getApproveType());
                    glEntity.setApproveTime(new Date());
                    tSpecdevGlService.updateById(glEntity);
                }
                logger.info("特种设备操作日志");
                new Thread(() -> {
                    tSpechiGlController.addOperLog(ids, userName, new Date(), operType + "-申请");
                }, "特种设备操作日志").start();
                break;
            case 5:
                for (String i : ids
                ) {
                    TSpecdevDt dtEntity = tSpecdevDtService.getById(i);
                    dtEntity.setApproveStatus(tApprove.getApproveType());
                    dtEntity.setApproveTime(new Date());
                    tSpecdevDtService.updateById(dtEntity);
                }
                logger.info("特种设备操作日志");
                new Thread(() -> {
                    tSpechiDtController.addOperLog(ids, userName, new Date(), operType + "-申请");
                }, "特种设备操作日志").start();
                break;
            case 6:
                for (String i : ids
                ) {
                    TSpecdevCc ccEntity = tSpecdevCcService.getById(i);
                    ccEntity.setApproveStatus(tApprove.getApproveType());
                    ccEntity.setApproveTime(new Date());
                    tSpecdevCcService.updateById(ccEntity);
                }
                logger.info("特种设备操作日志");
                new Thread(() -> {
                    tSpechiCcController.addOperLog(ids, userName, new Date(), operType + "-申请");
                }, "特种设备操作日志").start();
                break;
        }
        //
        long bussniseeKey = tApprove.getId();
        Authentication.setAuthenticatedUserId(userid.toString());
        //开始工作流、监听
        Map<String, Object> variables = new HashMap<>();
        variables.put("applyUser", userid.toString());

        variables.put("wxjlusers", tApprove.getWxjl().toString());
        variables.put("gyjlusers", tApprove.getGyjl().toString());
        variables.put("gyzjusers", tApprove.getGyzj().toString());
        variables.put("ctmusers", tApprove.getWxzj().toString());
        variables.put("zfusers", tApprove.getZf().toString());
        if (tApprove.getDevType() == 2l) {
            variables.put("isYlgd", 1); //压力管道不需要政府回执
        }else {
            variables.put("isYlgd", 0);
        }

        variables.put("specEndSucessListener", new SpecEndSucessListener());
        variables.put("specEndFaileListener", new SpecEndFaileListener());
        variables.put("wxjlTaskCreateListener", new WxjlTaskCreateListener());
        variables.put("gyjlTaskCreateListener", new GyjlTaskCreateListener());
        variables.put("gyzjTaskCreateListener", new GyzjTaskCreateListener());
        variables.put("ctmTaskCreateListener", new CtmTaskCreateListener());
        variables.put("zfhzTaskCreateListener", new ZfhzTaskCreateListener());
        //采用key来启动流程定义并设置流程变量，返回流程实例
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("myProcess", String.valueOf(bussniseeKey), variables);
        logger.info("流程部署id：" + pi.getDeploymentId());
        logger.info("流程定义id：" + pi.getProcessDefinitionId());
        logger.info("流程实例id：" + pi.getProcessInstanceId());
        tApprove.setProcessId(pi.getProcessInstanceId());
        tApproveService.updateTApprove(tApprove);

        return AjaxResult.success();
    }

    /**
     * 任务详情
     */
    @RequestMapping("/info/{id}")
//    @RequiresPermissions("approve:tapprove:info")
    public AjaxResult info(@PathVariable("id") Long id) {
        TApprove tApprove = tApproveService.selectTApproveById(id);
        List<TApproverFile> files = tApproverFileService.list(new QueryWrapper<TApproverFile>().eq("APPROVE_ID", id).eq("FILE_TYPE", 1));
        tApprove.setFiles(files);
        List<TApproverFile> govfiles = tApproverFileService.list(new QueryWrapper<TApproverFile>().eq("APPROVE_ID", id).eq("FILE_TYPE", 2));
        tApprove.setGovFiles(govfiles);
        String[] ids = null;
        if (tApprove.getApproveType() == 7) {
            ids = tApprove.getReportId().split(",");
        } else if (tApprove.getApproveType() == 8) {
            ids = tApprove.getMonthId().split(",");
        } else {
            ids = tApprove.getDevId().split(",");
        }
        CopyOnWriteArrayList<Object> devList = new CopyOnWriteArrayList<>();
        //线程池
        ExecutorService executorService = Executors.newFixedThreadPool(30);
        final CountDownLatch latch = new CountDownLatch(ids.length); //相同线程数量的计数

        if (tApprove.getDevType() != null && tApprove.getApproveType() != 7) {
            switch (Integer.parseInt(tApprove.getDevType().toString())) {
                case 1:
                    for (String i : ids
                    ) {
                        TSpecdevYlrq ylrqEntity = tSpecdevYlrqService.getById(i);
                        devList.add(ylrqEntity);
                    }
                    break;
                case 2:
                    for (String i : ids
                    ) {
                        TSpecdevYlgd ylgdEntity = tSpecdevYlgdService.getById(i);
                        devList.add(ylgdEntity);
                    }
                    break;
                case 3:
                    for (String i : ids
                    ) {
                        TSpecdevDzsb dzsbEntity = tSpecdevDzsbService.getById(i);
                        devList.add(dzsbEntity);
                    }
                    break;
                case 4:
                    for (String i : ids
                    ) {
                        TSpecdevGl glEntity = tSpecdevGlService.getById(i);
                        devList.add(glEntity);
                    }
                    break;
                case 5:
                    for (String i : ids
                    ) {
                        TSpecdevDt dtEntity = tSpecdevDtService.getById(i);
                        devList.add(dtEntity);
                    }
                    break;
                case 6:
                    for (String i : ids
                    ) {
                        TSpecdevCc ccEntity = tSpecdevCcService.getById(i);
                        devList.add(ccEntity);
                    }
                    break;
                case 7:
                    for (String i : ids
                    ) {
//                        TOtherTankEntity tankEntity = tOtherTankService.getById(i);
//                        devList.add(tankEntity);
                    }
            }
        }
        switch (Integer.parseInt(tApprove.getApproveType().toString())) {
            case 7:
                switch (tApprove.getDevType().toString()) {
                    case "1":
                        for (String i : ids
                        ) {
                            executorService.execute(() -> {
                                //-- 业务模块
                                try {
                                    TReportYlrq reportYlrqEntity = tReportYlrqService.selectTReportYlrqById(Long.parseLong(i));
                                    reportYlrqEntity.setDevEntity(tSpecdevYlrqService.getById(reportYlrqEntity.getDevId()));
                                    devList.add(reportYlrqEntity);
                                } catch (Exception e) {
                                    logger.error("e:", e);
                                } finally {
                                    latch.countDown(); //线程计数
                                }
                            });
                        }
                        try {
                            latch.await(); //线程计数完毕后继续执行
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        executorService.shutdown();
                        break;
                    case "2":
                        for (String i : ids
                        ) {
                            executorService.execute(() -> {
                                //-- 业务模块
                                try {
                                    TReportYlgd reportYlgdEntity = tReportYlgdService.selectTReportYlgdById(Long.parseLong(i));
                                    reportYlgdEntity.setDevEntity(tSpecdevYlgdService.getById(reportYlgdEntity.getDevId()));
                                    devList.add(reportYlgdEntity);
                                } catch (Exception e) {
                                } finally {
                                    latch.countDown(); //线程计数
                                }
                            });

                        }
                        try {
                            latch.await(); //线程计数完毕后继续执行
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        executorService.shutdown();
                }
                break;
            case 8:
                for (String i : ids
                ) {
                    TReportMonth reportMonthEntity = tReportMonthService.selectTReportMonthById(Long.parseLong(i));
                    devList.add(reportMonthEntity);
                    tApprove.setDevType(0l);
                }
                executorService.shutdown();
                break;
        }
        tApprove.setDevList(devList);
        return AjaxResult.success(tApprove);
    }

    /**
     * 审核处理
     */
    @Log(title = "特种设备审核处理", businessType = BusinessType.UPDATE)
    @PutMapping("/handle")
    public AjaxResult handle(@RequestBody DevTask devTask) {
        Map<String, Object> param = new HashMap<>();
        //流程审批意见
        String symbol = "";
        if (devTask.getComment() != "") {
            symbol = "，";
        }
        if (devTask.getCondition().equals("1")) {
            /* devTask.setComment("通过" + symbol + devTask.getComment());*/
            devTask.setComment("批准" + symbol + devTask.getComment());
        } else if (devTask.getCondition().equals("0")) {
            devTask.setComment("未通过" + symbol + devTask.getComment());
        }
        //使用任务服务完成任务(提交任务)
        String taskId = devTask.getTaskId();
        // 使用任务id,获取任务对象，获取流程实例id
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        //利用任务对象，获取流程实例id
        String processInstancesId = task.getProcessInstanceId();
        System.out.println(processInstancesId);
        //年度报告申请检查人员会签判断
        if (task.getName().equals("检查人员")) {
            //获取当前任务流转列表
            HistoricTaskInstanceQuery htiq = historyService.createHistoricTaskInstanceQuery();
            List<HistoricTaskInstance> htiLists = htiq.processInstanceId(processInstancesId).finished().orderByHistoricTaskInstanceEndTime().asc().list();
            List<DevTask> devTaskList = new ArrayList<>();
            if (htiLists.size() > 0) {
                for (HistoricTaskInstance hi : htiLists
                ) {
                    List<Comment> commentList = taskService.getTaskComments(hi.getId());
                    DevTask dev = new DevTask();
                    if (commentList.size() > 0) {
                        dev.setComment(commentList.get(0).getFullMessage());
                    }
                    devTaskList.add(dev);
                }
            }
            if (devTaskList.size() == 2) {
                for (DevTask d : devTaskList) {
                    if (d.getComment().substring(0, 1).equals("未")) {
                        devTask.setCondition("0");
                    }
                }
            }
        }
        param.put("condition", devTask.getCondition());
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        //认领任务
        processEngine.getTaskService()//
                .claim(taskId, getUserId().toString());
//        Authentication.setAuthenticatedUserId("cmc"); // 添加批注时候的审核人
        taskService.addComment(taskId, processInstancesId, devTask.getComment());
        //业务监听处理
//        tApproveService.handleApprove(task ,devTask);
        taskService.complete(taskId, param);

        //添加回执信息
        if (devTask.getGovFiles().size() > 0) {
            HistoricProcessInstance pi = processEngine.getHistoryService()
                    .createHistoricProcessInstanceQuery().processInstanceId(processInstancesId).singleResult();
            String approveId = pi.getBusinessKey();
            TApprove approveEntity = tApproveService.selectTApproveById(Long.parseLong(approveId));
            approveEntity.setGovDate(devTask.getGovDate());
            tApproveService.updateTApprove(approveEntity);
            for (TApproverFile t : devTask.getGovFiles()
            ) {
                t.setApproveId(Long.parseLong(approveId));
                t.setFileType(2l);
                tApproverFileService.save(t);
            }
        }
        return AjaxResult.success();
    }

    @RequestMapping("/exportPDF")
    public AjaxResult exportWorld(@RequestParam String approveId, String processId, HttpServletRequest request, HttpServletResponse response) {
        String pid = processId;
        logger.info("processId：" + JSON.toJSONString(pid));
        HistoricTaskInstanceQuery htiq = historyService.createHistoricTaskInstanceQuery();
        List<HistoricTaskInstance> htiLists = htiq.processInstanceId(pid).finished().orderByHistoricTaskInstanceEndTime().asc().list();
        logger.info("历史任务：" + JSON.toJSONString(htiLists));
        List<DevTask> devTaskList = new ArrayList<>();
        if (htiLists.size() > 0) {
            for (HistoricTaskInstance hi : htiLists
            ) {
                List<Comment> commentList = taskService.getTaskComments(hi.getId());
                logger.info("评论列表：" + JSON.toJSONString(commentList));
                DevTask devTask = new DevTask();
                devTask.setTaskName(hi.getName());
                devTask.setTaskCreateTime(hi.getCreateTime());
                devTask.setTaskEndTime(hi.getEndTime());
                if (commentList.size() > 0) {
                    devTask.setComment(commentList.get(0).getFullMessage());
                }
                SysUser user = sysUserService.selectUserById(Long.parseLong(hi.getAssignee()));
                devTask.setUserName(user.getNickName());
                devTaskList.add(devTask);
            }
        }
        TApprove tApprove = tApproveService.selectTApproveById(Long.parseLong(approveId));
        String[] ids = tApprove.getDevId().split(",");
        List<Object> devList = new ArrayList<>();
        switch (Integer.parseInt(tApprove.getDevType().toString())) {
            case 1:
                for (String i : ids
                ) {
                    TSpecdevYlrq ylrqEntity = tSpecdevYlrqService.getById(i);
                    devList.add(ylrqEntity);
                }
                break;
            case 2:
                for (String i : ids
                ) {
                    TSpecdevYlgd ylgdEntity = tSpecdevYlgdService.getById(i);
                    devList.add(ylgdEntity);
                }
                break;
            case 3:
                for (String i : ids
                ) {
                    TSpecdevDzsb dzsbEntity = tSpecdevDzsbService.getById(i);
                    devList.add(dzsbEntity);
                }
                break;
            case 4:
                for (String i : ids
                ) {
                    TSpecdevGl glEntity = tSpecdevGlService.getById(i);
                    devList.add(glEntity);
                }
                break;
            case 5:
                for (String i : ids
                ) {
                    TSpecdevDt dtEntity = tSpecdevDtService.getById(i);
                    devList.add(dtEntity);
                }
                break;
            case 6:
                for (String i : ids
                ) {
                    TSpecdevCc ccEntity = tSpecdevCcService.getById(i);
                    devList.add(ccEntity);
                }
                break;
//            case 7:
//                for (String i : ids
//                ) {
//                    TOtherTank tankEntity = tOtherTankService.getById(i);
//                    devList.add(tankEntity);
//                }
        }
        tApprove.setDevList(devList);

        OutputStream out = null;

        try {
            out = response.getOutputStream();
            //获取信息，就是上面的结构
            HashMap<String, Object> map = new HashMap<>();
            DocumentHandler dh = new DocumentHandler();
            Template t = dh.getTemplate();
            //申请设备信息
            List list = tApprove.getDevList();
            int devCount = list.size();
            Object plantCode = tApprove.getDevList().get(0);
            logger.info("DevList:" + list);
            map.put("plantCode", plantCode);
            map.put("list", list);
            map.put("devCount", devCount);
            //申请类型
            String devType = "";
            if (tApprove.getDevType() == 1) {
                devType = "压力容器";
            }
            if (tApprove.getDevType() == 2) {
                devType = "压力管道";
            }
            if (tApprove.getDevType() == 3) {
                devType = "吊装设备";
            }
            if (tApprove.getDevType() == 4) {
                devType = "锅炉";
            }
            if (tApprove.getDevType() == 5) {
                devType = "电梯";
            }
            if (tApprove.getDevType() == 6) {
                devType = "叉车";
            }
            if (tApprove.getDevType() == 7) {
                devType = "空气罐";
            }
            //延期时间
            Date dd = tApprove.getDelayDate();
            SimpleDateFormat sd = new SimpleDateFormat("yyyy年MM月dd日");
            String delayDate = sd.format(dd);
            //申请人及时间
            logger.info(JSON.toJSONString(tApprove));
            Long userId = tApprove.getUserId();
            SysUser user = sysUserService.selectUserById(userId);
            String createTime = sd.format(tApprove.getCreattime());
            //申请单位会签

            logger.info(JSON.toJSONString(devTaskList));
            for (int i = 0; i < devTaskList.size(); i++) {
                ObjectMapper objectMapper = new ObjectMapper();
                DevTask devTask = objectMapper.convertValue(devTaskList.get(i), DevTask.class);
                String taskEndTime = sd.format(devTask.getTaskEndTime());
                if (i == 0) {
                    map.put("equipmentMaintenance", devTask);
                    map.put("emEndTime", taskEndTime);
                }//装置维修经理
                if (i == 1) {
                    map.put("equipmentProcess", devTask);
                    map.put("epEndTime", taskEndTime);
                }//装置工艺经理
                if (i == 2) {
                    map.put("processDirector", devTask);
                    map.put("pdEndTime", taskEndTime);
                }//工艺总监
                if (i == 3) {
                    map.put("mechanicalMaintenance", devTask);
                    map.put("mmEndTime", taskEndTime);
                }//机械维修总监
            }
            //注意 变量名要与xml中占位符保持一致
            map.put("delayReason", tApprove.getDelayReason().replaceAll("\n", "<p></p>"));
            map.put("delayMeasure", tApprove.getDelayMeasure().replaceAll("\n", "<p></p>"));
            map.put("delayNotice", tApprove.getDelayNotice());
            map.put("devType", devType);
            map.put("delayDate", delayDate);
            map.put("userName", user.getNickName());
            map.put("createTime", createTime);
            logger.info("delayNotice:" + tApprove.getDelayNotice());
            if (map == null)
                return AjaxResult.error("导出失败！");
            /*ExportWordUtils word =new ExportWordUtils("/freeMaker", "fmaker.ftl");  // 项目使用的spring boot 。/excel/questionnaire.ftl文件存放在src/main/resources目录下
            word.setHeader(request, response, encodeFilename("1.doc" ,request ));
            word.doExport(out, map);*/
            if (tApprove.getDevType() == 1) {
                PDFTemplateUtil.exportPdf("ylrqFMaker.ftl", "压力容器延期检验报请备案函.pdf", "", map, response);
            }
            if (tApprove.getDevType() == 2) {
                PDFTemplateUtil.exportPdf("ylgdFMaker.ftl", "压力管道延期检验报请备案函.pdf", "", map, response);
            }
            if (tApprove.getDevType() == 3) {
                PDFTemplateUtil.exportPdf("dzsbFMaker.ftl", "吊装设备延期检验报请备案函.pdf", "", map, response);
            }
            if (tApprove.getDevType() == 4) {
                PDFTemplateUtil.exportPdf("glFMaker.ftl", "锅炉延期检验报请备案函.pdf", "", map, response);
            }
            if (tApprove.getDevType() == 5) {
                PDFTemplateUtil.exportPdf("dtFMaker.ftl", "电梯延期检验报请备案函.pdf", "", map, response);
            }
            if (tApprove.getDevType() == 6) {
                PDFTemplateUtil.exportPdf("ccFMaker.ftl", "叉车延期检验报请备案函.pdf", "", map, response);
            }
            if (tApprove.getDevType() == 7) {
                PDFTemplateUtil.exportPdf("tankFMaker.ftl", "空气罐延期检验报请备案函.pdf", "", map, response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null)
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

    /**
     * 修改特种设备申请
     */
    @PreAuthorize("@ss.hasPermi('sems:approve:edit')")
    @Log(title = "特种设备申请", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TApprove tApprove) {
        return toAjax(tApproveService.updateTApprove(tApprove));
    }

    /**
     * 删除特种设备申请
     */
    @PreAuthorize("@ss.hasPermi('sems:approve:remove')")
    @Log(title = "特种设备申请", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(tApproveService.deleteTApproveByIds(ids));
    }

    /**
     * 年度检查报告任务申请
     */
    @RequestMapping("/year")
    @RepeatSubmit
    public AjaxResult year(@RequestBody TApprove tApprove) {
        //任务开始时间
        long startTime = System.currentTimeMillis();
        logger.info("任务申请" + JSON.toJSONString(tApprove));
        Long userid = getUserId();
        //审批编号
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
        String data = sdf.format(dt) + userid;
        tApprove.setApNo(data);
        tApprove.setUserId(userid);
        tApprove.setDevId(null);
        tApproveService.insertTApprove(tApprove);

        //修改设备申请状态
        String[] ids = tApprove.getReportId().split(",");
        ExecutorService executorService = Executors.newFixedThreadPool(30);
        final CountDownLatch latch = new CountDownLatch(ids.length); //相同线程数量的计数
        switch (tApprove.getDevType().toString()) {
            case "1":
                for (String i : ids
                ) {
                    executorService.execute(() -> {
                        try {
                            TReportYlrq rq = tReportYlrqService.selectTReportYlrqById(Long.parseLong(i));
                            rq.setApproveStatus(7l);
                            rq.setApproveTime(new Date());
                            tReportYlrqService.updateTReportYlrq(rq);
                        } catch (Exception e) {
                            logger.error("e:", e);
                        } finally {
                            latch.countDown(); //线程计数
                        }
                    });
                }
                break;
            case "2":
                for (String i : ids
                ) {
                    executorService.execute(() -> {
                        try {
                            TReportYlgd gd = tReportYlgdService.selectTReportYlgdById(Long.parseLong(i));
                            gd.setApproveStatus(7l);
                            gd.setApproveTime(new Date());
                            tReportYlgdService.updateTReportYlgd(gd);
                        } catch (Exception e) {
                            logger.error("e:", e);
                        } finally {
                            latch.countDown(); //线程计数
                        }
                    });
                }
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
        Map<String, Object> variables = new HashMap<>();
        //开始工作流、监听
        variables.put("endSucessListener", new YearEndSucessListener());
        variables.put("endFaileListener", new YearEndFaileListener());
        variables.put("inspectorsTaskCreateListener", new InspectorTaskCreateListener());
        variables.put("auditorTaskCreateListener", new AuditorTaskCreateListener());
        variables.put("approverTaskCreateListener", new ApproverTaskCreateListener());
        //初始化会签人员
        List<Long> inspectorlist = new ArrayList<>();
        inspectorlist.add(tApprove.getInspectorOne());
        inspectorlist.add(tApprove.getInspectorTwo());
        inspectorlist.add(tApprove.getInspectorThree());
        //条件表达式方法 一定要序列号
        variables.put("inspectorlist", inspectorlist);
        //审批人员设置
        variables.put("auditor", tApprove.getAuditor());
        variables.put("approver", tApprove.getApprover());

        long bussniseeKey = tApprove.getId();
        logger.info("bussniseeKey:" + bussniseeKey);
        Authentication.setAuthenticatedUserId(userid.toString());
        //任务执行总时长
        long times = System.currentTimeMillis() - startTime;
        logger.debug("  总共耗时：" + times + "毫秒");
        //采用key来启动流程定义并设置流程变量，返回流程实例
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("yearProcess", String.valueOf(bussniseeKey), variables);
        logger.info("流程部署id：" + pi.getDeploymentId());
        logger.info("流程定义id：" + pi.getProcessDefinitionId());
        logger.info("流程实例id：" + pi.getProcessInstanceId());
        logger.info("流程定义对象：" + pi.getProcessVariables());
        tApprove.setProcessId(pi.getProcessInstanceId());
        tApproveService.updateById(tApprove);
        //任务执行总时长
        long times2 = System.currentTimeMillis() - startTime;
        logger.debug("  总共耗时：" + times2 + "毫秒");
        return AjaxResult.success();
    }

    /**
     * 月度检查报告任务申请
     */
    @RequestMapping("/month")
    public AjaxResult month(@RequestBody TApprove tApprove) {
        if (tApprove.getMechanical() == null || tApprove.getElectric()==null || tApprove.getCraft()== null) {
           return AjaxResult.error("缺少审批人");
        }
        //任务开始时间
        long startTime = System.currentTimeMillis();
        logger.info("任务申请" + JSON.toJSONString(tApprove));
        Long userid = getUserId();
        //审批编号
        Date dt = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
        String data = sdf.format(dt) + userid;
        tApprove.setApNo(data);
        tApprove.setUserId(userid);
        tApproveService.insertTApprove(tApprove);

        //修改设备申请状态
        String[] ids = tApprove.getMonthId().split(",");
        for (String i : ids
        ) {
            TReportMonth tReportMonthEntity = tReportMonthService.selectTReportMonthById(Long.parseLong(i));
            tReportMonthEntity.setApproveStatus(7l);
            tReportMonthEntity.setApproveId(tApprove.getId().toString());
            tReportMonthEntity.setApproveTime(new Date());
            tReportMonthService.updateTReportMonth(tReportMonthEntity);
        }
        Map<String, Object> variables = new HashMap<>();
        //开始工作流、监听
        variables.put("endSucessListener", new MonthEndSucessListener());
        variables.put("endFaileListener", new MonthEndFaileListener());
        variables.put("mechanicalTaskCreateListener", new MechanicalTaskCreateListener());
        variables.put("electricTaskCreateListener", new ElectricTaskCreateListener());
        variables.put("craftTaskCreateListener", new CraftTaskCreateListener());
        //审批人员设置
        variables.put("mechanical", tApprove.getMechanical());
        variables.put("electric", tApprove.getElectric());
        variables.put("craft", tApprove.getCraft());

        long bussniseeKey = tApprove.getId();
        logger.info("bussniseeKey:" + bussniseeKey);
        Authentication.setAuthenticatedUserId(userid.toString());
        //任务执行总时长
        long times = System.currentTimeMillis() - startTime;
        logger.debug("  总共耗时：" + times + "毫秒");
        //采用key来启动流程定义并设置流程变量，返回流程实例
        ProcessInstance pi = runtimeService.startProcessInstanceByKey("monthProcess", String.valueOf(bussniseeKey), variables);
        logger.info("流程部署id：" + pi.getDeploymentId());
        logger.info("流程定义id：" + pi.getProcessDefinitionId());
        logger.info("流程实例id：" + pi.getProcessInstanceId());
        logger.info("流程定义对象：" + pi.getProcessVariables());
        tApprove.setProcessId(pi.getProcessInstanceId());
        tApproveService.updateById(tApprove);
        //任务执行总时长
        long times2 = System.currentTimeMillis() - startTime;
        logger.debug("  总共耗时：" + times2 + "毫秒");
        return AjaxResult.success();
    }

    public String getOperType(int type) {
        switch (type) {
            case 1:
                return "启用";
            case 2:
                return "停用";
            case 3:
                return "报废";
            case 4:
                return "改造";
            case -1:
                return "注销";
        }
        return "申请";
    }


}
