package com.ruoyi.project.training.bccnew.controller;

import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.*;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.page.TableDataInfo;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.service.ISysDictDataService;
import com.ruoyi.project.system.service.ISysUserService;
import com.ruoyi.project.training.bccnew.domain.*;
import com.ruoyi.project.training.bccnew.service.*;
import io.jsonwebtoken.lang.Assert;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 导师带徒Controller
 *
 * @author ssy
 * @date 2024-05-20
 */
@RestController
@RequestMapping("/bccnew/tsnew")
public class TTsNewController extends BaseController {
    @Autowired
    private ITTsNewService tTsNewService;

    @Autowired
    private ITTsFirstplanService tTsFirstplanService;

    @Autowired
    private ITTsFirstplanTmplService tTsFirstplanTmplService;

    @Autowired
    private ITTsLjplanTmplService tTsLjplanTmplService;

    @Autowired
    private ITTsLjplanService tTsLjplanService;


    @Autowired
    private ITTsYsplanTmplService tTsYsplanTmplService;

    @Autowired
    private ITTsYsplanService tTsYsplanService;


    @Autowired
    private ITTsFlplanTmplService tTsFlplanTmplService;

    @Autowired
    private ITTsFlplanService tTsFlplanService;


    @Autowired
    private ITTsFtplanTmplService tTsFtplanTmplService;

    @Autowired
    private ITTsFtplanService tTsFtplanService;

    @Autowired
    private ITTsFtplanContentService tTsFtplanContentService;

    @Autowired
    private ITTsFlplanContentService tTsFlplanContentService;

    @Autowired
    private ITTsLjplanContentService tTsLjplanContentService;

    @Autowired
    private ITTsYsplanContentService tTsYsplanContentService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ITTsYsplanService tsYsplanService;

    @Autowired
    private ITTsFlplanService tsFlplanService;

    @Autowired
    private ITTsFtplanService tsFtplanService;

    @Autowired
    private ITTsApproveService tsApproveService;

    @Autowired
    private ISysDictDataService sysDictDataService;

    /**
     * 查询导师带徒列表
     */
//    @PreAuthorize("@ss.hasPermi('bccnew:tsnew:list')")
    @GetMapping("/list")
    public TableDataInfo list(TTsNew tTsNew) {
        if ("1".equals(tTsNew.getIsStudent())) {
            tTsNew.setStaffId(getBaseStaffId());
        }
        if ("1".equals(tTsNew.getIsTeacher())) {
            tTsNew.setMentorStaffId(getBaseStaffId());
        }
        startPage();
        List<TTsNew> list = tTsNewService.selectTTsNewList(tTsNew);
        //线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        final CountDownLatch latch = new CountDownLatch(list.size()); //相同线程数量的计数
        for (TTsNew t : list) {
            executorService.execute(() -> {
                try {
                    //岗前培训
                    TTsFirstplan tTsFirstplan = new TTsFirstplan();
                    tTsFirstplan.setNewId(t.getNewId());
                    List<TTsFirstplan> firstplanAll = tTsFirstplanService.selectTTsFirstplanListByNewId(tTsFirstplan);
                    tTsFirstplan.setPlanStatus(5L);
                    List<TTsFirstplan> firstplanNow = tTsFirstplanService.selectTTsFirstplanListByNewId(tTsFirstplan);
                    if (firstplanNow.isEmpty()) {
                        tTsFirstplan.setPlanStatus(3L);
                        firstplanNow = tTsFirstplanService.selectTTsFirstplanListByNewId(tTsFirstplan);
                    }
                    Integer firstAll = firstplanAll.size();
                    Integer firstNow = firstplanNow.size();
                    Integer secAll = 0;
                    Integer secNow = 0;
                    if (t.getPlanType() == 1) {
                        TTsLjplan tTsLjplan = new TTsLjplan();
                        tTsLjplan.setNewId(t.getNewId());
                        List<TTsLjplan> ljPlansAll = tTsLjplanService.selectTTsLjplanListByNewId(tTsLjplan);
                        tTsLjplan.setPlanStatus(5L);
                        List<TTsLjplan> ljPlansNow = tTsLjplanService.selectTTsLjplanListByNewId(tTsLjplan);
                        if (ljPlansNow.isEmpty()) {
                            tTsLjplan.setPlanStatus(3L);
                            ljPlansNow = tTsLjplanService.selectTTsLjplanListByNewId(tTsLjplan);
                        }
                        secAll = ljPlansAll.size();
                        secNow = ljPlansNow.size();
                    } else if (t.getPlanType() == 2) {
                        TTsYsplan tTsYsplan = new TTsYsplan();
                        tTsYsplan.setNewId(t.getNewId());
                        List<TTsYsplan> ysPlansAll = tTsYsplanService.selectTTsYsplanListByNewId(tTsYsplan);
                        tTsYsplan.setPlanStatus(5L);
                        List<TTsYsplan> ysPlansNow = tTsYsplanService.selectTTsYsplanListByNewId(tTsYsplan);
                        if (ysPlansNow.isEmpty()) {
                            tTsYsplan.setPlanStatus(3L);
                            ysPlansNow = tTsYsplanService.selectTTsYsplanListByNewId(tTsYsplan);
                        }
                        secAll = ysPlansAll.size();
                        secNow = ysPlansNow.size();
                    } else if (t.getPlanType() == 3) {
                        TTsFlplan tTsFlplan = new TTsFlplan();
                        tTsFlplan.setNewId(t.getNewId());
                        List<TTsFlplan> flPlansAll = tTsFlplanService.selectTTsFlplanListByNewId(tTsFlplan);
                        tTsFlplan.setPlanStatus(5L);
                        List<TTsFlplan> flPlansNow = tTsFlplanService.selectTTsFlplanListByNewId(tTsFlplan);
                        if (flPlansNow.isEmpty()) {
                            tTsFlplan.setPlanStatus(3L);
                            flPlansNow = tTsFlplanService.selectTTsFlplanListByNewId(tTsFlplan);
                        }
                        secAll = flPlansAll.size();
                        secNow = flPlansNow.size();
                    } else if (t.getPlanType() == 4) {
                        TTsFtplan tTsFtplan = new TTsFtplan();
                        tTsFtplan.setNewId(t.getNewId());
                        List<TTsFtplan> ftPlansAll = tTsFtplanService.selectTTsFtplanListByNewId(tTsFtplan);
                        tTsFtplan.setPlanStatus(5L);
                        List<TTsFtplan> ftPlansNow = tTsFtplanService.selectTTsFtplanListByNewId(tTsFtplan);
                        if (ftPlansNow.isEmpty()) {
                            tTsFtplan.setPlanStatus(3L);
                            ftPlansNow = tTsFtplanService.selectTTsFtplanListByNewId(tTsFtplan);
                        }
                        secAll = ftPlansAll.size();
                        secNow = ftPlansNow.size();
                    }
                    if (secAll + firstAll != 0) {
                        String finsh = String.valueOf((secNow + firstNow) * 100 / (secAll + firstAll));
                        t.setPlanFinish(finsh);
                    } else {
                        t.setPlanFinish("0");
                    }
                } catch (Exception e) {
                    logger.error("e:", e);
                } finally {
                    latch.countDown(); //线程计数
                }
            });
        }

        try {
            latch.await(); //线程计数完毕后继续执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
        return getDataTable(list);
    }

    /**
     * 导出导师带徒列表
     */
//    @PreAuthorize("@ss.hasPermi('bccnew:tsnew:export')")
    @Log(title = "导师带徒", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(TTsNew tTsNew) {
        List<TTsNew> list = tTsNewService.selectTTsNewList(tTsNew);
        ExcelUtil<TTsNew> util = new ExcelUtil<TTsNew>(TTsNew.class);
        return util.exportExcel(list, "tsnew");
    }

    /**
     * 获取导师带徒详细信息
     */
//    @PreAuthorize("@ss.hasPermi('bccnew:tsnew:query')")
    @GetMapping(value = "/{newId}")
    public AjaxResult getInfo(@PathVariable("newId") Long newId) {
        return AjaxResult.success(tTsNewService.selectTTsNewById(newId));
    }

    /**
     * 修改导师带徒
     */
//    @PreAuthorize("@ss.hasPermi('bccnew:tsnew:edit')")
    @Log(title = "导师带徒", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TTsNew tTsNew) {
        return toAjax(tTsNewService.updateTTsNew(tTsNew));
    }

    /**
     * 删除导师带徒
     */
//    @PreAuthorize("@ss.hasPermi('bccnew:tsnew:remove')")
    @Log(title = "导师带徒", businessType = BusinessType.DELETE)
    @DeleteMapping("/{newIds}")
    public AjaxResult remove(@PathVariable Long[] newIds) {
        return toAjax(tTsNewService.deleteTTsNewByIds(newIds));
    }

    /**
     * 新增导师带徒
     */
//    @PreAuthorize("@ss.hasPermi('bccnew:tsnew:add')")
    @Log(title = "导师带徒", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TTsNew tTsNew) throws IOException {
        // 新增操作
        int result = tTsNewService.insertTTsNew(tTsNew);
        // 新增生成word
        if (result != 0) {
            this.genWordAfterInsert(tTsNew);
        }
        // 返回新增操作结果
        return toAjax(result);
    }

    /**
     * 新增生成word
     */
    private void genWordAfterInsert(TTsNew tTsNew) throws IOException {
        // 生成word - Mentor Agreement
        String mentorAgreementWordPath = this.genMentorAgreementWord(tTsNew);
        // 生成word - Target Plan
        String targetPlanWordPath = this.genTargetPlanWord(tTsNew);
        // 更新文件地址
        tTsNew.setMentorAgreementWordPath(mentorAgreementWordPath);
        tTsNew.setTargetPlanWordPath(targetPlanWordPath);
//        tTsNew.setAppraisalFormWordPath(appraisalFormWordPath);
        tTsNewService.updateTTsNew(tTsNew);
    }

    @GetMapping("/genAppraisalFormWord/{newId}")
    public AjaxResult genAppraisalFormWord(@PathVariable Long newId) throws IOException {
        // 生成word - Appraisal Form
        TTsNew tTsNew = tTsNewService.selectTTsNewById(newId);
        String appraisalFormWordPath = this.genAppraisalFormWord(tTsNew);
        tTsNew.setAppraisalFormWordPath(appraisalFormWordPath);
        tTsNewService.updateTTsNew(tTsNew);
        return AjaxResult.success(appraisalFormWordPath);
    }

    /**
     * 生成word - Mentor Agreement
     */
    private String genMentorAgreementWord(TTsNew tTsNew) throws IOException {
        //渲染文本
        Map<String, Object> params = getMentorAgreementWordData(tTsNew);
        // 模板路径
        String templatePath = "static/word/training/mentorAgreement.docx";
        // 生成word的路径
        String fileDir = RuoYiConfig.getProfile() + "/" + "mentorAgreementWord";
        // 生成word的文件名称
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        String fileName = time + tTsNew.getNewId() + ".docx";
        String wordPath = this.createWord(templatePath, fileDir, fileName, params, "mentorAgreementWord");
        return wordPath;
    }

    /**
     * 生成word - Target Plan
     */
    private String genTargetPlanWord(TTsNew tTsNew) throws IOException {
        //渲染文本
        Map<String, Object> params = getTargetPlanWordData(tTsNew);
        // 模板路径
        String templatePath = "static/word/training/targetPlan.docx";
        // 生成word的路径
        String fileDir = RuoYiConfig.getProfile() + "/" + "targetPlanWord";
        // 生成word的文件名称
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        String fileName = time + tTsNew.getNewId() + ".docx";
        String wordPath = this.createWord(templatePath, fileDir, fileName, params, "targetPlanWord");
        return wordPath;
    }

    /**
     * 生成word - Appraisal Form
     */
    private String genAppraisalFormWord(TTsNew tTsNew) throws IOException {
        //渲染文本
        Map<String, Map<String, Object>> appraisalFormWordData = getAppraisalFormWordData(tTsNew);
        Map<String, Object> params = appraisalFormWordData.get("params");
        // 模板路径
        String templatePath = "static/word/training/appraisalForm.docx";
        // 生成word的路径
        String fileDir = RuoYiConfig.getProfile() + "/" + "appraisalFormWord";
        // 生成word的文件名称
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss"));
        String fileName = time + tTsNew.getNewId() + ".docx";
        String wordPath = this.createWord(templatePath, fileDir, fileName, params, "appraisalFormWord");
        wordPath = this.createWord(wordPath, fileDir, fileName, genSign(appraisalFormWordData.get("signs")), "appraisalFormWord",true);
        return wordPath;
    }

    /**
     * 获取word数据 - Mentor Agreement
     */
    private Map<String, Object> getMentorAgreementWordData(TTsNew tTsNew) {
        Map<String, Object> params = new HashMap<>();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tTsNew.getStartdate());
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        Date endDate = tTsNew.getEnddate();
        params.put("startDate", Texts.of(formatter.format(calendar.getTime())).create());
        params.put("endDate", Texts.of(formatter.format(endDate)).create());
        String mentorStaffId = tTsNew.getMentorStaffId();
        String staffId = tTsNew.getStaffId();
        SysUser mentor = sysUserService.selectUserByStaffId(mentorStaffId);
        SysUser apprentice = sysUserService.selectUserByStaffId(staffId);
        if (StringUtils.isNotEmpty(mentor.getSignUrl()))
            params.put("mentorSignature", Pictures.ofLocal(fileName(mentor.getSignUrl())).size(100, 40).create());
        if (StringUtils.isNotEmpty(apprentice.getSignUrl()))
            params.put("apprenticeSignature", Pictures.ofLocal(fileName(apprentice.getSignUrl())).size(100, 40).create());
        String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        params.put("date", Texts.of(date).create());
        // 渲染文本
        return params;
    }

    /**
     * 获取word数据 - Target Plan
     */
    private Map<String, Object> getTargetPlanWordData(TTsNew tTsNew) {
        Map<String, Object> params = new HashMap<>();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = new Date(tTsNew.getStartdate().toString());
        startDate.setMonth(startDate.getMonth() + 1);
        Date endDate = tTsNew.getEnddate();
        params.put("startDate", Texts.of(formatter.format(startDate)).create());
        params.put("endDate", Texts.of(formatter.format(endDate)).create());
        String mentorStaffId = tTsNew.getMentorStaffId();
        String staffId = tTsNew.getStaffId();
        SysUser mentor = sysUserService.selectUserByStaffId(mentorStaffId);
        SysUser apprentice = sysUserService.selectUserByStaffId(staffId);
        if (StringUtils.isNotEmpty(mentor.getSignUrl()))
            params.put("tutorSignature", Pictures.ofLocal(fileName(mentor.getSignUrl())).size(100, 40).create());
        if (StringUtils.isNotEmpty(apprentice.getSignUrl()))
            params.put("traineeSignature", Pictures.ofLocal(fileName(apprentice.getSignUrl())).size(100, 40).create());
        params.put("tutor", Texts.of(mentor.getNickName()).create());
        params.put("trainee", Texts.of(apprentice.getNickName()).create());
        RowRenderData[] planList = null;
        String post = "";
        Long planType = tTsNew.getPlanType();
        Long newId = tTsNew.getNewId();
        if (planType == 1L) {
            post = "裂解";
            TTsLjplan ljplan = new TTsLjplan();
            ljplan.setNewId(newId);
            List<TTsLjplan> tTsLjplans = tTsLjplanService.selectTTsLjplanListByNewId(ljplan);
            planList = new RowRenderData[tTsLjplans.size() + 1];
            planList[0] = Rows.create("Training Plan 详细计划", "Planned Training Date 计划培训日期", "Training Topics 培训主题", "Expected Training Requirement 培训预期达到的要求");
            int i = 0;
            for (TTsLjplan plan : tTsLjplans) {
                i++;
                String dateStr = getPlanDate(1, plan.getId());//获取整个内容的周期
                planList[i] = Rows.create(plan.getDetailPlan(), dateStr, plan.getTopic(), "学习结束考核，且考试成绩达到80分以上");
            }
        } else if (planType == 2L) {
            post = "压缩";
            TTsYsplan ysplan = new TTsYsplan();
            ysplan.setNewId(newId);
            List<TTsYsplan> tTsYsplans = tTsYsplanService.selectTTsYsplanListByNewId(ysplan);
            planList = new RowRenderData[tTsYsplans.size() + 1];
            planList[0] = Rows.create("Training Plan 详细计划", "Planned Training Date 计划培训日期", "Training Topics 培训主题", "Expected Training Requirement 培训预期达到的要求");
            int i = 0;
            for (TTsYsplan plan : tTsYsplans) {
                i++;
                String dateStr = getPlanDate(2, plan.getId());//获取整个内容的周期
                planList[i] = Rows.create(plan.getDetailPlan(), dateStr, plan.getTopic(), "学习结束考核，且考试成绩达到80分以上");
            }
        } else if (planType == 3L) {
            post = "分离";
            TTsFlplan flplan = new TTsFlplan();
            flplan.setNewId(newId);
            List<TTsFlplan> tTsFlplans = tTsFlplanService.selectTTsFlplanListByNewId(flplan);
            planList = new RowRenderData[tTsFlplans.size() + 1];
            planList[0] = Rows.create("Training Plan 详细计划", "Planned Training Date 计划培训日期", "Training Topics 培训主题", "Expected Training Requirement 培训预期达到的要求");
            int i = 0;
            for (TTsFlplan plan : tTsFlplans) {
                i++;
                String dateStr = getPlanDate(3, plan.getId());//获取整个内容的周期
                planList[i] = Rows.create(plan.getDetailPlan(), dateStr, plan.getTopic(), "学习结束考核，且考试成绩达到80分以上");
            }
        } else if (planType == 4L) {
            post = "芳烃";
            TTsFtplan ftplan = new TTsFtplan();
            ftplan.setNewId(newId);
            List<TTsFtplan> tTsFtplans = tTsFtplanService.selectTTsFtplanListByNewId(ftplan);
            planList = new RowRenderData[tTsFtplans.size() + 1];
            planList[0] = Rows.create("Training Plan 详细计划", "Planned Training Date 计划培训日期", "Training Topics 培训主题", "Expected Training Requirement 培训预期达到的要求");
            int i = 0;
            for (TTsFtplan plan : tTsFtplans) {
                i++;
                String dateStr = getPlanDate(4, plan.getId());//获取整个内容的周期
                planList[i] = Rows.create(plan.getDetailPlan(), dateStr, plan.getTopic(), "学习结束考核，且考试成绩达到80分以上");
            }
        }
        params.put("tutorPost", Texts.of(post).create());
        params.put("traineePost", Texts.of(post).create());
        params.put("planType", Texts.of(post).create());
        params.put("planList", Tables.of(planList).create());
        // 渲染文本
        return params;
    }

    private Map<String, Object> genSign(Map<String, Object> map) {
        Map<String, Object> params = new HashMap<>();
        for (String s : map.keySet()) {
            if (s.equals("traineeSignature")){
                params.put(s, map.get(s));
            }
            if (Objects.nonNull(map.get(s))) {
                SysUser sysUser = new SysUser();
                sysUser.setNickName(map.get(s).toString().replaceAll(" ",""));
                sysUser.setDeptId(103L);
                List<SysUser> sysUsers = sysUserService.selectUserList(sysUser);
                if (CollectionUtils.isNotEmpty(sysUsers)) {
                    if (sysUsers.get(0).getSignUrl() != null) {
                        s = s.replace("{{@","");
                        s = s.replace("}}","");
                        params.put(s, Pictures.ofLocal(fileName(sysUsers.get(0).getSignUrl())).size(100, 40).create());
                    }
                }
            }
        }
        return params;
    }

    /**
     * 获取word数据 - Appraisal Form
     */
    private Map<String, Map<String, Object>> getAppraisalFormWordData(TTsNew tTsNew) {
        Map<String, Object> params = new HashMap<>();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        //装置级培训
        TTsFirstplan tTsFirstplan = new TTsFirstplan();
        tTsFirstplan.setNewId(tTsNew.getNewId());
        List<TTsFirstplan> tTsFirstplans = tTsFirstplanService.selectTTsFirstplanListByNewId(tTsFirstplan);
        RowRenderData[] plantList = new RowRenderData[tTsFirstplans.size() + 1];
        plantList[0] = Rows.create("序号", "计划培训日期", "培训主题", "材料版本", "培训时长h", "讲师", "培训日期", "讲师签名", "考试评估方式", "评估结果", "学员签名");
        int i = 0;
        Map<String, Object> signMap = new HashMap<>();
        for (TTsFirstplan firstplan : tTsFirstplans) {
            i++;
            String planDate = "";
            if (firstplan.getTrainingPlanDate() != null) {
                planDate = formatter.format(firstplan.getTrainingPlanDate());
            }
            String trainDate = "";
            if (firstplan.getCourseDate() != null) {
                trainDate = formatter.format(firstplan.getCourseDate());
            }
            String tn = "";
            String trainerSign="";
            String traineeSign="";
            if (StringUtils.isNotEmpty(firstplan.getTrainerConfirm())) {
                if (StringUtils.isNotEmpty(firstplan.getTrainer())){
                    tn = firstplan.getTrainer().replaceAll(" ","");
                    trainerSign = "{{@trainSign" + tn + "}}";
                    signMap.put(trainerSign, tn);
                }
            }
            if(StringUtils.isNotEmpty(firstplan.getStudentConfirm())){
                traineeSign="{{@traineeSignature}}";
            }
            plantList[i] = Rows.create(String.valueOf(i), planDate, firstplan.getTopic(), firstplan.getMaterialVer(), String.valueOf(firstplan.getCourseHour())
                    , firstplan.getTrainer(), trainDate, trainerSign, firstplan.getExamType(), firstplan.getAssess(), traineeSign);
        }
        params.put("staffId", tTsNew.getStaffId());
        //导师带徒培训
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(tTsNew.getStartdate());
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        Date endDate = tTsNew.getEnddate();
        params.put("startDate", Texts.of(formatter.format(calendar.getTime())).create());
        params.put("endDate", Texts.of(formatter.format(endDate)).create());
        String mentorStaffId = tTsNew.getMentorStaffId();
        String staffId = tTsNew.getStaffId();
        SysUser mentor = sysUserService.selectUserByStaffId(mentorStaffId);
        SysUser apprentice = sysUserService.selectUserByStaffId(staffId);
        List<TTsApprove> tTsApproves = tsApproveService.selectTTsApproveByNewId(tTsNew.getNewId());
        if (CollectionUtils.isNotEmpty(tTsApproves)) {
            if (tTsApproves.get(0).getApprover() != null) {
                SysUser manager = sysUserService.selectUserById(Long.valueOf(tTsApproves.get(0).getApprover()));
                if (StringUtils.isNotEmpty(manager.getSignUrl()))
                    params.put("mgrSign", Pictures.ofLocal(fileName(manager.getSignUrl())).size(100, 40).create());
                if (tTsNew.getPlanStatus() == 3) {// 模板路径
                    String imgPath = "/static/word/training/commentImg/end2.png";
                    params.put("mentorComments", Pictures.ofLocal(Objects.requireNonNull(getClass().getResource(imgPath)).getPath()).size(500, 80).create());
                }
                if (tTsNew.getPlanStatus() == 1) {// 模板路径
                    String imgPath = "/static/word/training/commentImg/end1.png";
                    params.put("mentorComments", Pictures.ofLocal(Objects.requireNonNull(getClass().getResource(imgPath)).getPath()).size(500, 80).create());
                }
            }
        }
        if (StringUtils.isNotEmpty(mentor.getSignUrl()))
            params.put("tutorSignature", Pictures.ofLocal(fileName(mentor.getSignUrl())).size(100, 40).create());
        if (StringUtils.isNotEmpty(apprentice.getSignUrl())) {
            params.put("traineeSignature", Pictures.ofLocal(fileName(apprentice.getSignUrl())).size(100, 40).create());
            signMap.put("traineeSignature", Pictures.ofLocal(fileName(apprentice.getSignUrl())).size(100, 40).create());
        }
        params.put("tutor", Texts.of(mentor.getNickName()).create());
        params.put("trainee", Texts.of(apprentice.getNickName()).create());
        String label = sysDictDataService.selectDictLabel("training_bccnew_status", tTsNew.getPlanStatus().toString());
        params.put("appaisalResult", Texts.of(label).create());
        List<RowRenderData> planList = new ArrayList<>();
        String post = "";
        Long planType = tTsNew.getPlanType();
        Long newId = tTsNew.getNewId();
        if (planType == 1L) {
            post = "裂解";
            TTsLjplan ljplan = new TTsLjplan();
            ljplan.setNewId(newId);
            List<TTsLjplan> tTsLjplans = tTsLjplanService.selectTTsLjplanListByNewId(ljplan);
            planList.add(Rows.create("Training Topics 培训主题", "", "Training Date 培训日期", "Training Effectiveness Evaluation* 培训效果评价*", "Training Effectiveness Acknowledgement 培训效果确认", "", "Mentor comment 导师意见"));
            planList.add(Rows.create("", "", "", "", "Trainee 学徒", "Tutor 导师", "Proceed to next topic or not 是否转至下一主题"));
            for (TTsLjplan plan : tTsLjplans) {//如果有多次成绩，则将每次成绩都展示
                String dateStr = getPlanDate(1, plan.getId());//获取整个内容的周期
                if (StringUtils.isNotEmpty(dateStr) && dateStr.contains("~")) {
                    dateStr = dateStr.substring(dateStr.lastIndexOf("~") + 2);
                }
                if (StringUtils.isNotEmpty(plan.getScore1())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore1(), apprentice.getNickName(), mentor.getNickName(), plan.getScore1().equals("好") ? "是" : "否"));
                } else if (plan.getPlanStatus() == 4 || plan.getPlanStatus() == 1) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "终止", apprentice.getNickName(), mentor.getNickName(), "否"));
                } else {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "", apprentice.getNickName(), mentor.getNickName(), ""));
                }
                if (StringUtils.isNotEmpty(plan.getScore2())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore2(), apprentice.getNickName(), mentor.getNickName(), plan.getScore2().equals("好") ? "是" : "否"));
                }
                if (StringUtils.isNotEmpty(plan.getScore3())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore3(), apprentice.getNickName(), mentor.getNickName(), plan.getScore3().equals("好") ? "是" : "否"));
                }
            }
        } else if (planType == 2L) {
            post = "压缩";
            TTsYsplan ysplan = new TTsYsplan();
            ysplan.setNewId(newId);
            List<TTsYsplan> tTsYsplans = tTsYsplanService.selectTTsYsplanListByNewId(ysplan);
            planList.add(Rows.create("Training Topics 培训主题", "", "Training Date 培训日期", "Training Effectiveness Evaluation* 培训效果评价*", "Training Effectiveness Acknowledgement 培训效果确认", "", "Mentor comment 导师意见"));
            planList.add(Rows.create("", "", "", "", "Trainee 学徒", "Tutor 导师", "Proceed to next topic or not 是否转至下一主题"));

            for (TTsYsplan plan : tTsYsplans) {
                String dateStr = getPlanDate(2, plan.getId());
                if (StringUtils.isNotEmpty(dateStr) && dateStr.contains("~")) {
                    dateStr = dateStr.substring(dateStr.lastIndexOf("~") + 2);
                }
                if (StringUtils.isNotEmpty(plan.getScore1())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore1(), apprentice.getNickName(), mentor.getNickName(), plan.getScore1().equals("好") ? "是" : "否"));
                } else if (plan.getPlanStatus() == 4 || plan.getPlanStatus() == 1) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "终止", apprentice.getNickName(), mentor.getNickName(), "否"));
                } else {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "", apprentice.getNickName(), mentor.getNickName(), ""));
                }
                if (StringUtils.isNotEmpty(plan.getScore2())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore2(), apprentice.getNickName(), mentor.getNickName(), plan.getScore2().equals("好") ? "是" : "否"));
                }
                if (StringUtils.isNotEmpty(plan.getScore3())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore3(), apprentice.getNickName(), mentor.getNickName(), plan.getScore3().equals("好") ? "是" : "否"));
                }
            }
        } else if (planType == 3L) {
            post = "分离";
            TTsFlplan flplan = new TTsFlplan();
            flplan.setNewId(newId);
            List<TTsFlplan> tTsFlplans = tTsFlplanService.selectTTsFlplanListByNewId(flplan);
            planList.add(Rows.create("Training Topics 培训主题", "", "Training Date 培训日期", "Training Effectiveness Evaluation* 培训效果评价*", "Training Effectiveness Acknowledgement 培训效果确认", "", "Mentor comment 导师意见"));
            planList.add(Rows.create("", "", "", "", "Trainee 学徒", "Tutor 导师", "Proceed to next topic or not 是否转至下一主题"));
            for (TTsFlplan plan : tTsFlplans) {
                String dateStr = getPlanDate(3, plan.getId());
                if (StringUtils.isNotEmpty(dateStr) && dateStr.contains("~")) {
                    dateStr = dateStr.substring(dateStr.lastIndexOf("~") + 2);
                }
                if (StringUtils.isNotEmpty(plan.getScore1())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore1(), apprentice.getNickName(), mentor.getNickName(), plan.getScore1().equals("好") ? "是" : "否"));
                } else if (plan.getPlanStatus() == 4 || plan.getPlanStatus() == 1) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "终止", apprentice.getNickName(), mentor.getNickName(), "否"));
                } else {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "", apprentice.getNickName(), mentor.getNickName(), ""));
                }
                if (StringUtils.isNotEmpty(plan.getScore2())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore2(), apprentice.getNickName(), mentor.getNickName(), plan.getScore2().equals("好") ? "是" : "否"));
                }
                if (StringUtils.isNotEmpty(plan.getScore3())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore3(), apprentice.getNickName(), mentor.getNickName(), plan.getScore3().equals("好") ? "是" : "否"));
                }
            }
        } else if (planType == 4L) {
            post = "芳烃";
            TTsFtplan ftplan = new TTsFtplan();
            ftplan.setNewId(newId);
            List<TTsFtplan> tTsFtplans = tTsFtplanService.selectTTsFtplanListByNewId(ftplan);
            planList.add(Rows.create("Training Topics 培训主题", "", "Training Date 培训日期", "Training Effectiveness Evaluation* 培训效果评价*", "Training Effectiveness Acknowledgement 培训效果确认", "", "Mentor comment 导师意见"));
            planList.add(Rows.create("", "", "", "", "Trainee 学徒", "Tutor 导师", "Proceed to next topic or not 是否转至下一主题"));
            for (TTsFtplan plan : tTsFtplans) {
                String dateStr = getPlanDate(4, plan.getId());
                if (StringUtils.isNotEmpty(dateStr) && dateStr.contains("~")) {
                    dateStr = dateStr.substring(dateStr.lastIndexOf("~") + 2);
                }
                if (StringUtils.isNotEmpty(plan.getScore1())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore1(), apprentice.getNickName(), mentor.getNickName(), plan.getScore1().equals("好") ? "是" : "否"));
                } else if (plan.getPlanStatus() == 4 || plan.getPlanStatus() == 1) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "终止", apprentice.getNickName(), mentor.getNickName(), "否"));
                } else {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, "", apprentice.getNickName(), mentor.getNickName(), ""));
                }
                if (StringUtils.isNotEmpty(plan.getScore2())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore2(), apprentice.getNickName(), mentor.getNickName(), plan.getScore2().equals("好") ? "是" : "否"));
                }
                if (StringUtils.isNotEmpty(plan.getScore3())) {
                    planList.add(Rows.create(plan.getDetailPlan(), plan.getTopic(), dateStr, plan.getScore3(), apprentice.getNickName(), mentor.getNickName(), plan.getScore3().equals("好") ? "是" : "否"));
                }
            }
        }
        params.put("tutorPost", Texts.of(post).create());
        params.put("traineePost", Texts.of(post).create());
        MergeCellRule rule = MergeCellRule.builder()
                .map(MergeCellRule.Grid.of(0, 0), MergeCellRule.Grid.of(1, 1))
                .map(MergeCellRule.Grid.of(0, 2), MergeCellRule.Grid.of(1, 2))
                .map(MergeCellRule.Grid.of(0, 4), MergeCellRule.Grid.of(0, 5))
                .map(MergeCellRule.Grid.of(0, 3), MergeCellRule.Grid.of(1, 3)).build();
        params.put("planList", Tables.of(planList.toArray(new RowRenderData[0])).mergeRule(rule).create());
        params.put("plantList", Tables.of(plantList).create());
        // 渲染文本
        Map<String, Map<String, Object>> result = new HashMap<>();
        result.put("params", params);
        result.put("signs", signMap);
        return result;
    }

    private String getPlanDate(int planType, Long id) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        StringBuilder sb = new StringBuilder();
        if (planType == 1) {
            TTsLjplanContent item = new TTsLjplanContent();
            item.setPid(id);
            List<TTsLjplanContent> list = tTsLjplanContentService.selectTTsLjplanContentList(item);
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.get(0).getPlanDate() != null) {
                    sb.append(format.format(list.get(0).getPlanDate())).append(" ~ ");
                }
                if (list.get(list.size() - 1).getPlanDate() != null) {
                    sb.append(format.format(list.get(list.size() - 1).getPlanDate()));
                }
            }
        } else if (planType == 2) {
            TTsYsplanContent item = new TTsYsplanContent();
            item.setPid(id);
            List<TTsYsplanContent> list = tTsYsplanContentService.selectTTsYsplanContentList(item);
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.get(0).getPlanDate() != null) {
                    sb.append(format.format(list.get(0).getPlanDate())).append(" ~ ");
                }
                if (list.get(list.size() - 1).getPlanDate() != null) {
                    sb.append(format.format(list.get(list.size() - 1).getPlanDate()));
                }
            }
        } else if (planType == 3) {
            TTsFlplanContent item = new TTsFlplanContent();
            item.setPid(id);
            List<TTsFlplanContent> list = tTsFlplanContentService.selectTTsFlplanContentList(item);
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.get(0).getPlanDate() != null) {
                    sb.append(format.format(list.get(0).getPlanDate())).append(" ~ ");
                }
                if (list.get(list.size() - 1).getPlanDate() != null) {
                    sb.append(format.format(list.get(list.size() - 1).getPlanDate()));
                }
            }
        } else if (planType == 4) {
            TTsFtplanContent item = new TTsFtplanContent();
            item.setPid(id);
            List<TTsFtplanContent> list = tTsFtplanContentService.selectTTsFtplanContentList(item);
            if (CollectionUtils.isNotEmpty(list)) {
                if (list.get(0).getPlanDate() != null) {
                    sb.append(format.format(list.get(0).getPlanDate())).append(" ~ ");
                }
                if (list.get(list.size() - 1).getPlanDate() != null) {
                    sb.append(format.format(list.get(list.size() - 1).getPlanDate()));
                }
            }
        }
        return sb.toString();
    }

    /**
     * 生成word
     *
     * @param templatePath word模板文件路径
     * @param fileDir      生成的文件存放地址
     * @param fileName     生成的文件名
     * @param paramMap     参数集合
     * @return 返回word生成的路径
     */
    private String createWord(String templatePath, String fileDir, String fileName, Map<String, Object> paramMap, String directory, boolean... flag) throws IOException {
        Assert.notNull(templatePath, "word模板文件路径不能为空");
        Assert.notNull(fileDir, "生成的文件存放地址不能为空");
        Assert.notNull(fileName, "生成的文件名不能为空");
        File dir = new File(fileDir);
        if (!dir.exists()) {
            logger.info("目录不存在，创建文件夹{}!", fileDir);
            dir.mkdirs();
        }
        fileName = fileName.replaceAll("/", "_"); //替换文件中敏感字段
        logger.info("目录文件{}!", fileName);
        String filePath = fileDir + "/" + fileName;
        logger.info("目录{}!", filePath);
        logger.info("模板{}!", templatePath);
        // 读取模板渲染参数
        InputStream is =  getClass().getClassLoader().getResourceAsStream(templatePath);;
        if (flag.length>0&&flag[0]) {
            logger.info("待签名文件地址：{}!", filePath);
            is = new FileInputStream(filePath);
            fileName = fileName.replace(".docx","_sign.docx");
            filePath = fileDir + "/" + fileName;
        }

        XWPFTemplate template = XWPFTemplate.compile(is).render(paramMap);
        try {
            // 将模板参数写入路径
            template.writeToFile(filePath);
            template.close();
            is.close();
        } catch (Exception e) {
            logger.error("生成word异常{}", e.getMessage());
            e.printStackTrace();
        }
        String pathFileName = FileUploadUtils.getPathFileName(RuoYiConfig.getFilePath("/" + directory), fileName);
        return pathFileName;
    }

    /**
     * @param
     * @return 映射签名的文件名
     * @throws IOException
     */
    private String fileName(String filepath) {
        String newFilePath = filepath.replace("/profile", "");
        String pathName = RuoYiConfig.getProfile() + newFilePath;
        if (!new File(pathName).exists()) {
            genSignImage(pathName);
        }
        return pathName;
    }

    private void genSignImage(String pathName) {
        String nickName = pathName.substring(pathName.lastIndexOf("/") + 1, pathName.lastIndexOf("."));
        String fileType = pathName.substring(pathName.lastIndexOf(".") + 1);
        int width = 350; // 图片宽度
        int height = 100; // 图片高度

        // 创建一个类型为预定义图像类型之一的 BufferedImage
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        // 获取 Graphics2D
        Graphics2D g2d = image.createGraphics();

        // 设置背景颜色
        g2d.setColor(Color.WHITE);
        g2d.fillRect(0, 0, width, height);

        // 设置字体和颜色
        g2d.setFont(new Font("楷体", Font.BOLD, 80)); // 设置字体样式、大小和类型
        g2d.setColor(Color.BLACK); // 设置文字颜色

        // 计算文本的宽度和高度，用于定位
        FontMetrics fm = g2d.getFontMetrics();
        int textWidth = fm.stringWidth(nickName);
        int textHeight = fm.getHeight();

        // 在图片上绘制文本
        // 注意：x和y坐标定义了文本左下角的位置
        int x = (width - textWidth) / 2; // 居中显示
        int y = height - textHeight + 70; // 距离底部10像素
        g2d.drawString(nickName, x, y);

        // 释放图形上下文使用的系统资源
        g2d.dispose();

        // 保存图片到文件
        try {
            String path = pathName.substring(0, pathName.lastIndexOf("/"));
            if (!new File(path).isDirectory()) {
                new File(path).mkdirs();
            }
            OutputStream out = Files.newOutputStream(Paths.get(pathName));
            ImageIO.write(image, fileType, out);
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
