package com.rongwei.sfcommon.sys.service.impl;
import com.aspose.words.Document;
import com.aspose.words.DocumentBuilder;
import com.aspose.words.MailMergeCleanupOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rongwe.scentity.domian.*;
import com.rongwei.commonservice.service.dao.FileItemDao;
import com.rongwei.rwadmincommon.system.dao.SysDictDao;
import com.rongwei.rwadmincommon.system.domain.SysDictDo;
import com.rongwei.rwcommon.base.exception.CustomException;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.rwcommonentity.commonservers.domain.SysFileItemDo;
import com.rongwei.safecommon.fegin.WFFeginClient;
import com.rongwei.sfcommon.sys.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import com.rongwei.rwcommon.base.BaseDo;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RiskJobServiceImpl implements RiskJobService {
    private static final Logger logger = LoggerFactory.getLogger(RiskJobServiceImpl.class.getName());
    public static final String DEFAULT_FONT_NAME = "仿宋";
//    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    public static final Map<String, String> CHECK_BOX= new HashMap<String, String>() {{
        put("DHFS", "dhfs");
        put("FHYP", "fhyp");
    }};
    public static final Map<String, String> TEMPLATE_MAP = new HashMap<String, String>() {{
        put("动火作业", "导出PDF（动火作业待修改).docx");
        put("高处作业", "高处作业.docx");
        put("吊装作业", "吊装作业.docx");
        put("受限空间作业", "受限空间作业.docx");
        put("临时用电作业", "临时用电作业.docx");
        put("动土作业", "动土作业.docx");
        put("断路作业", "断路作业.docx");
        put("盲板抽堵", "盲板抽堵作业.docx");
    }};


    public static final List<String> IMG_SUFFIX = new ArrayList<String>() {{
        add("png");
        add("jpg");
        add("jpeg");
        add("bmp");
        add("gif");
        add("svg");
        add("webp");
    }};

    @Autowired
    AspJobConfigFxbsService aspJobConfigFxbsService;

    @Autowired
    AspDhzyService dhzyService;

    @Autowired
    AspSxkjzyService sxkjzyService;

    @Autowired
    AspGczyService aspGczyService;

    @Autowired
    AspDzzyService aspDzzyService;

    @Autowired
    AspLsydzyService aspLsydzyService;

    @Autowired
    AspDtzyService aspDtzyService;

    @Autowired
    AspDlzzService aspDlzzService;

    @Autowired
    AspMbcdzyService aspMbcdzyService;

    @Autowired
    private WFFeginClient wfFeginClient;

    @Autowired
    AspCombustibleGasDetectionService aspCombustibleGasDetectionService;

    @Autowired
    AspJobSjzyService aspJobSjzyService;

    @Autowired
    private SysDictDao sysDictDao;
    @Autowired
    private FileItemDao fileItemDao;

    @Autowired
     AspInspectionInformationTableService aspInspectionInformationTableService;

    @Autowired
    AspSpecialPersonalInformationService aspSpecialPersonalInformationService;

    @Autowired
    AspPersonnelItemRegistrationService aspPersonnelItemRegistrationService;
    // 获取系统字典数据
    private List<SysDictDo> getSysDictDoList() {
        List<SysDictDo> sysDictDoList = sysDictDao.selectList(new LambdaQueryWrapper<SysDictDo>()
                .eq(BaseDo::getDeleted, "0")
                .in(SysDictDo::getDicttype, "dhfs", "dhzyjb", "DHFXBW","dzzyjb","Hight_work_level","SXKJ-ZYLB","fhyp","YDZY-GZDY","mbcdzylb"));
        return sysDictDoList == null ? Collections.emptyList() : sysDictDoList;
    }

    // 获取燃气检测数据
    private List<Map<String, String>> getCombustibleGasDetectionList(String id,  List<SysDictDo> sysDictDoList) {
        List<AspCombustibleGasDetectionDo> qtjcList = aspCombustibleGasDetectionService.list(new QueryWrapper<AspCombustibleGasDetectionDo>()
                .eq("jobid", id)
                .eq("deleted", '0'));
        Map<String, String> dhfxbwDictMap = sysDictDoList.stream()
                .filter(dict -> "DHFXBW".equals(dict.getDicttype()))
                .collect(Collectors.toMap(SysDictDo::getValue, SysDictDo::getName, (a, b) -> b));
        List<Map<String, String>> subList1 = new ArrayList<>();
        if (qtjcList != null) {
            qtjcList.forEach(item -> {
                Map<String, String> subItem = new HashMap<>();
                subItem.put("COMBUSTIBLEGASLETCONTENT", defaultEmptyStr(item.getCombustiblegasletcontent()));
                subItem.put("OXYGENCONTENT", defaultEmptyStr(item.getOxygencontent()));
                subItem.put("TOXICGAS", defaultEmptyStr(item.getToxicgas()));
                subItem.put("SAMPLINGTIME", defaultEmptyStr(item.getSamplingtime()));
                //动火分析部位
                subItem.put("LELSAMPLINGSITE", defaultEmptyStr(dhfxbwDictMap.getOrDefault(item.getLelsamplingsite(), "")));
                subItem.put("ANALYST", defaultEmptyStr(item.getAnalyst()));
                subList1.add(subItem);
            });
        }
        return subList1;
    }


    // 获取关联作业数据
    private Map<String, String> getJobData(String id ,Map<String, String> wordMap) {
        List<AspJobSjzyDo> resultList = aspJobSjzyService.list(new QueryWrapper<AspJobSjzyDo>()
                .eq("JOBID", id)
                .eq("DELETED", "0"));
        if (resultList != null && !resultList.isEmpty()) {
            String jobTypeString = resultList.stream().map(AspJobSjzyDo::getJobtype).distinct().collect(Collectors.joining(","));
            String sjzyzbhString = resultList.stream().map(AspJobSjzyDo::getSjzyzbh).distinct().collect(Collectors.joining(","));
            wordMap.put("SJQTZYLX", defaultEmptyStr(jobTypeString));
            wordMap.put("SJQTTSZYZBH", defaultEmptyStr(sjzyzbhString));
        }
        return wordMap;
    }


    // 获取安全措施数据
//    private List<Map<String, String>> getRywpList(String id) {
//        List<AspPersonnelItemRegistrationDo> rywpList = aspPersonnelItemRegistrationService.list(new QueryWrapper<AspPersonnelItemRegistrationDo>()
//                .eq("jobid",id)
//                .eq("deleted", '0'));
//        List<Map<String, String>> subList3 = new ArrayList<>();
//        if (rywpList != null) {
//            for (AspPersonnelItemRegistrationDo item : rywpList) {
//                Map<String, String> subItem3 = new HashMap<>();
//                subItem3.put("MAINSAFETYMEASURES", defaultEmptyStr(item.getMainsafetymeasures()));
//                subItem3.put("WHETHERITINVOLVES", defaultEmptyStr(item.getWhetheritinvolves()));
//                subItem3.put("CHECKUSER", defaultEmptyStr(item.getCheckuser()));
//                subList3.add(subItem3);
//            }
//        }
//        return subList3;
//    }

    private List<Map<String, String>> getAqcsList(String id,Map<String, String> wordMap) {
        List<AspInspectionInformationTableDo> aqcsList = aspInspectionInformationTableService.list(new QueryWrapper<AspInspectionInformationTableDo>()
                .eq("jobid",id)
                .eq("deleted", '0'));
        List<Map<String, String>> subList2 = new ArrayList<>();
        if (aqcsList != null) {
            for (AspInspectionInformationTableDo item : aqcsList) {
                Map<String, String> subItem2 = new HashMap<>();
                subItem2.put("MAINSAFETYMEASURES", defaultEmptyStr(item.getMainsafetymeasures()));
                subItem2.put("WHETHERITINVOLVES", defaultEmptyStr(item.getWhetheritinvolves()));
                // 检查人
                subItem2.put("CHECKUSER", defaultEmptyStr(item.getCheckuser()));

                // 插入图片签名
//                insertImageToBookmark(doc, "CHECKUSER", wordMap.get("SDBMFZRQZ"));

                subList2.add(subItem2);
            }
        }
        return subList2;
    }


    // 获取动火人信息
//    private String getDhrxx(String id,Map<String, String> wordMap) {
//        List<AspSpecialPersonalInformationDo> dhrList = aspSpecialPersonalInformationService.list(new QueryWrapper<AspSpecialPersonalInformationDo>()
//                .eq("jobid", id)
//                .eq("deleted", "0"));
//        if (dhrList != null && !dhrList.isEmpty()) {
//            String dhrxx = dhrList.stream()
//                    .map(item -> defaultEmptyStr(item.getName()) + "," + defaultEmptyStr(item.getCertificateno()))
//                    .collect(Collectors.joining(" "));
//            wordMap.put("DHRJZSBH", defaultEmptyStr(dhrxx));
//        }
//        return "";  // 如果没有动火人信息，返回空字符串
//    }
    private String getryxx(String id,Map<String, String> wordMap) {
        List<AspSpecialPersonalInformationDo> dhrList = aspSpecialPersonalInformationService.list(new QueryWrapper<AspSpecialPersonalInformationDo>()
                .eq("jobid", id)
                .eq("deleted", "0"));
        if (dhrList != null && !dhrList.isEmpty()) {
            String ryxx = dhrList.stream()
                    .map(item -> defaultEmptyStr(item.getName()) )
                    .collect(Collectors.joining(" "));
            wordMap.put("ZYRYXX", defaultEmptyStr(ryxx));

            String zsbh = dhrList.stream()
                    .map(item -> defaultEmptyStr( item.getCertificateno()))
                    .collect(Collectors.joining(" "));
            wordMap.put("ZYRYZSBH", defaultEmptyStr(zsbh));
            //作业人员证书类型
            String zslxxx = dhrList.stream()
                    .map(item -> defaultEmptyStr( item.getJobtype()))
                    .collect(Collectors.joining(" "));
            wordMap.put("ZYRYZSLX", defaultEmptyStr(zslxxx));
        }
        return "";  // 如果没有信息，返回空字符串
    }

    @Override
    public void riskJobExport2(String id, String jobtype, String tenantid, HttpServletResponse response) {
        riskJobExportCommon(id, jobtype, tenantid, null, response);
    }

    @Override
    public void riskJobExport2(String id, String jobtype, String tenantid, String processinstid, HttpServletResponse response) {
        riskJobExportCommon(id, jobtype, tenantid, processinstid, response);
    }


    private void riskJobExportCommon(String id, String jobtype, String tenantid, String processinstid, HttpServletResponse response) {
        Map<String, String> wordMap = new HashMap<>();
        // 获取通用数据字典数据
        List<SysDictDo> sysDictDoList = getSysDictDoList();

        // 根据作业类型获取并处理数据
        processJobDataByType(id, jobtype, wordMap, sysDictDoList);

        // 气体检查数据
        List<Map<String, String>> subList1 = getCombustibleGasDetectionList(id, sysDictDoList);

        // 关联作业
        getJobData(id, wordMap);

        // 安全措施数据
        List<Map<String, String>> subList2 = getAqcsList(id, wordMap);

        // 作业人信息
        getryxx(id, wordMap);

        // 如果有流程实例ID，处理流程评论信息
        if (processinstid != null) {
            processWorkflowComments(processinstid, wordMap);
        }

        // 风险辨识
        List<AspJobConfigFxbsDo> fxbsList = aspJobConfigFxbsService.list(new QueryWrapper<AspJobConfigFxbsDo>()
                .eq("tenantid", tenantid)
                .eq("jobtype", jobtype)
                .eq("deleted", '0'));
        String[] fxbs = fxbsList != null
                ? fxbsList.stream()
                .sorted(Comparator.comparing(AspJobConfigFxbsDo::getSon))
                .map(AspJobConfigFxbsDo::getFxbsx)
                .toArray(String[]::new)
                : new String[0];

        response(wordMap, response, subList1, subList2, fxbs, sysDictDoList, jobtype);
    }


    private void processJobDataByType(String id, String jobtype, Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        if ("动火作业".equals(jobtype)) {
            AspDhzyDo dhzyDo = dhzyService.getById(id);
            if (dhzyDo == null) {
                throw new RuntimeException("未找到该动火作业信息！");
            }
            processAspDhzyDo(dhzyDo, wordMap, sysDictDoList);
        } else if ("受限空间作业".equals(jobtype)) {
            AspSxkjzyDo sxkjzyDo = sxkjzyService.getById(id);
            if (sxkjzyDo == null) {
                throw new RuntimeException("未找到该受限空间作业信息！");
            }
            processAspSxkjzyDo(sxkjzyDo, wordMap, sysDictDoList);
        } else if ("高处作业".equals(jobtype)) {
            AspGczyDo aspGczyDo = aspGczyService.getById(id);
            if (aspGczyDo == null) {
                throw new RuntimeException("未找到该高处作业信息！");
            }
            processAspGczyDo(aspGczyDo, wordMap, sysDictDoList);
        } else if ("吊装作业".equals(jobtype)) {
            AspDzzyDo aspDzzyDo = aspDzzyService.getById(id);
            if (aspDzzyDo == null) {
                throw new RuntimeException("未找到该吊装作业信息！");
            }
            processAspDzzyDo(aspDzzyDo, wordMap, sysDictDoList);
        } else if ("临时用电作业".equals(jobtype)) {
            AspLsydzyDo aspLsydzyDo = aspLsydzyService.getById(id);
            if (aspLsydzyDo == null) {
                throw new RuntimeException("未找到该临时用电作业信息！");
            }
            processAspLsydzyDo(aspLsydzyDo, wordMap, sysDictDoList);
        } else if ("动土作业".equals(jobtype)) {
            AspDtzyDo aspdtzyDo = aspDtzyService.getById(id);
            if (aspdtzyDo == null) {
                throw new RuntimeException("未找到该动土作业信息！");
            }
            processAspDtzyDo(aspdtzyDo, wordMap, sysDictDoList);
        } else if ("断路作业".equals(jobtype)) {
            AspDlzzDo aspdlzzDo = aspDlzzService.getById(id);
            if (aspdlzzDo == null) {
                throw new RuntimeException("未找到该断路作业信息！");
            }
            processAspDlzzDo(aspdlzzDo, wordMap, sysDictDoList);
        } else if ("盲板抽堵".equals(jobtype)) {
            AspMbcdzyDo aspmbcdzyDo = aspMbcdzyService.getById(id);
            if (aspmbcdzyDo == null) {
                throw new RuntimeException("未找到该盲板抽堵作业信息！");
            }
            processAspMbcdDo(aspmbcdzyDo, wordMap, sysDictDoList);
        } else {
            throw new RuntimeException("未找到作业信息！");
        }
    }



    private void processWorkflowComments(String processinstid, Map<String, String> wordMap) {
        //获取流程评论信息 取每个节点最新的  留下审批人名字 和审批人评论 签名使用流程控制
        List<Map<String, Object>> wfinfolist = wfFeginClient.getCommentsByProcInstId(processinstid);
        List<Map<String, Object>> resultList = processComments(wfinfolist);

        //去resultList里找
        for (Map<String, Object> map : resultList) {
            String taskName = defaultEmptyStr(map.get("taskname"));
            if ("安环部".equals(taskName)) {
                wordMap.put("AQGLBYJ", defaultEmptyStr(map.get("taskcomment")));
                wordMap.put("AHBWXZYZG", defaultEmptyStr(map.get("assigneename")));
                wordMap.put("AQGLBMSPRQ", defaultEmptyStr(map.get("provedate")));
            } else if ("部门副总".equals(taskName)) {
                wordMap.put("FGLDYJ", defaultEmptyStr(map.get("taskcomment")));
                wordMap.put("BMFZQZ", defaultEmptyStr(map.get("assigneename")));
                wordMap.put("FGLDSPRQ", defaultEmptyStr(map.get("provedate")));
            } else if ("总经理".equals(taskName)) {
                // 补充逻辑
            } else if ("总工程师".equals(taskName)) {
                // 补充逻辑
            } else if ("属地部门经理".equals(taskName)) {
                wordMap.put("SDBMYJ", defaultEmptyStr(map.get("taskcomment")));
                wordMap.put("BMJLQM", defaultEmptyStr(map.get("assigneename")));
                wordMap.put("SDBMSPRQ", defaultEmptyStr(map.get("provedate")));
            } else if ("开始".equals(taskName)) {
                wordMap.put("ZYFZRYJ", "同意开始");
                wordMap.put("ZYFZRSPRQ", defaultEmptyStr(map.get("provedate")));
            }
        }
    }


    // 处理评论列表，按TASKNAME分组并保留CREATEDATE最新的记录
    public static List<Map<String, Object>> processComments(List<Map<String, Object>> wfinfolist) {
        return wfinfolist.stream()
                .filter(comment ->
                        comment.get("taskname") instanceof String &&
                                comment.get("createdate") instanceof String
//                                &&
//                                comment.get("assigneename") instanceof String &&
//                                !((String) comment.get("assigneename")).trim().isEmpty()
                )
                .collect(Collectors.groupingBy(
                        comment -> (String) comment.get("taskname"),
                        Collectors.collectingAndThen(
                                Collectors.maxBy(Comparator.comparing(
                                        comment -> (String) comment.get("createdate")
                                )),
                                Optional::get
                        )
                ))
                .values()
                .stream()
                .map(comment -> {
                    Map<String, Object> result = new HashMap<>();
                    result.put("taskname", comment.get("taskname"));
                    result.put("assigneename", comment.get("assigneename"));
                    result.put("taskcomment", comment.get("taskcomment"));

                    // 处理provedate字段，将字符串转换为LocalDateTime
                    Object provedateObj = comment.get("provedate");
                    if (provedateObj instanceof String) {
                        try {
                            // 解析为OffsetDateTime以处理时区，然后转换为LocalDateTime
                            OffsetDateTime offsetDateTime = OffsetDateTime.parse((String) provedateObj, DATE_TIME_FORMATTER);
                            result.put("provedate", offsetDateTime.toLocalDateTime());
                        } catch (DateTimeParseException e) {
                            // 解析失败时保留原始值或设置为null
                            System.err.println("Failed to parse date: " + provedateObj);
                            result.put("provedate", null);
                        }
                    } else {
                        result.put("provedate", null);
                    }

                    return result;
                })
                .collect(Collectors.toList());
    }






    public void processAspDhzyDo(AspDhzyDo dhzyDo, Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        // 动火方式处理
//        String dhfs = dhzyDo.getDhfs();
//        String DHFS = "";
//        if (dhfs != null) {
//            String[] dhfsValues = dhfs.split(",");
//            Map<String, String> dictValueNameMap = sysDictDoList.stream()
//                    .filter(dict -> "dhfs".equals(dict.getDicttype()))
//                    .collect(Collectors.toMap(SysDictDo::getValue, SysDictDo::getName, (v1, v2) -> v1));
//            List<String> dhfsNames = Arrays.stream(dhfsValues)
//                    .map(String::trim)
//                    .map(dictValueNameMap::get)
//                    .filter(Objects::nonNull)
//                    .collect(Collectors.toList());
//            DHFS = String.join(",", dhfsNames);
//        }
//        wordMap.put("DHFS", DHFS);

        // 动火作业级别处理
        String DHZYJB = "";
        String dhzyjb = dhzyDo.getDhzyjb();
        if (dhzyjb != null) {
            SysDictDo sysDictDo = sysDictDoList.stream()
                    .filter(dict -> "dhzyjb".equals(dict.getDicttype()) &&
                            dhzyjb.equals(dict.getValue()))
                    .findFirst()
                    .orElse(null);
            DHZYJB = sysDictDo == null ? "" : defaultEmptyStr(sysDictDo.getName());
        }
        wordMap.put("DHZYJB", DHZYJB);

        wordMap.put("SQR", defaultEmptyStr(dhzyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(dhzyDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(dhzyDo.getZywz()));
        wordMap.put("ZYKSSJ", defaultEmptyStr(dhzyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(dhzyDo.getZyjssj()));
        wordMap.put("ZYNR", defaultEmptyStr(dhzyDo.getZynr()));
        wordMap.put("DHDD", defaultEmptyStr(dhzyDo.getDhdd()));
        String zydwlx = dhzyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(dhzyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(dhzyDo.getCbsname()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("SQDW", defaultEmptyStr(dhzyDo.getSqdw()));
        wordMap.put("ZYFZR", defaultEmptyStr(dhzyDo.getZyfzr()));
        wordMap.put("ZYKSSJ", defaultEmptyStr(dhzyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(dhzyDo.getZyjssj()));
        wordMap.put("JHRQM", defaultEmptyStr(dhzyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(dhzyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(dhzyDo.getJsjdrqm()));
        wordMap.put("SDBMFZRQZ", defaultEmptyStr(dhzyDo.getSdbmfzrqz()));
        wordMap.put("FXBSX", defaultEmptyStr(dhzyDo.getFxbs()));
        wordMap.put("DHFS", defaultEmptyStr(dhzyDo.getDhfs()));

    }


//受限空间
    public void processAspSxkjzyDo(AspSxkjzyDo SxkjzyDo, Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {

   //受限空间作业类别
        String SXKJZYLB = "";
        String sxkjzylb = SxkjzyDo.getZylb();
        if (sxkjzylb != null) {
            SysDictDo sysDictDo = sysDictDoList.stream()
                    .filter(dict -> "SXKJ-ZYLB".equals(dict.getDicttype()) &&
                            sxkjzylb.equals(dict.getValue()))
                    .findFirst()
                    .orElse(null);
            SXKJZYLB = sysDictDo == null ? "" : defaultEmptyStr(sysDictDo.getName());
        }
        wordMap.put("SXKJZYLB", SXKJZYLB);

        wordMap.put("SQR", defaultEmptyStr(SxkjzyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(SxkjzyDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(SxkjzyDo.getZywz()));
        wordMap.put("ZYKSSJ", defaultEmptyStr(SxkjzyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(SxkjzyDo.getZyjssj()));
        wordMap.put("SXKJMC", defaultEmptyStr(SxkjzyDo.getSxkjmc()));
        wordMap.put("YYJZMC", defaultEmptyStr(SxkjzyDo.getYyjzmc()));
        wordMap.put("ZYNR", defaultEmptyStr(SxkjzyDo.getZynr()));

        String zydwlx = SxkjzyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(SxkjzyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(SxkjzyDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("SQDW", defaultEmptyStr(SxkjzyDo.getSqdw()));
        wordMap.put("ZYFZR", defaultEmptyStr(SxkjzyDo.getZyfzr()));
        wordMap.put("JHRQM", defaultEmptyStr(SxkjzyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(SxkjzyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(SxkjzyDo.getJsjdrqm()));
        wordMap.put("SDBMFZRQZ", defaultEmptyStr(SxkjzyDo.getSdbmfzrqz()));
        wordMap.put("FXBSX", defaultEmptyStr(SxkjzyDo.getFxbs()));
        wordMap.put("FHYP", defaultEmptyStr(SxkjzyDo.getFhyp()));
        wordMap.put("FXBSX", defaultEmptyStr(SxkjzyDo.getFxbs()));
    }

    //高处作业
    public void processAspGczyDo(AspGczyDo GczyDo, Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {

        // 作业级别处理
        String GCZYJB = "";
        String gczyjb = GczyDo.getZyjb();
        if (gczyjb != null) {
            SysDictDo sysDictDo = sysDictDoList.stream()
                    .filter(dict -> "Hight_work_level".equals(dict.getDicttype()) &&
                            gczyjb.equals(dict.getValue()))
                    .findFirst()
                    .orElse(null);
            GCZYJB = sysDictDo == null ? "" : defaultEmptyStr(sysDictDo.getName());
        }
        wordMap.put("GCZYJB", GCZYJB);

        wordMap.put("SQR", defaultEmptyStr(GczyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(GczyDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(GczyDo.getZywz()));
        wordMap.put("ZYNR", defaultEmptyStr(GczyDo.getZynr()));
        String zydwlx = GczyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(GczyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(GczyDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("SQDW", defaultEmptyStr(GczyDo.getSqdw()));
        wordMap.put("ZYGD", defaultEmptyStr(GczyDo.getZygd()));
        wordMap.put("ZYFZR", defaultEmptyStr(GczyDo.getZyfzr()));
        wordMap.put("JHR", defaultEmptyStr(GczyDo.getJhr()));
        wordMap.put("ZYKSSJ", defaultEmptyStr(GczyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(GczyDo.getZyjssj()));
        wordMap.put("JHRQM", defaultEmptyStr(GczyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(GczyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(GczyDo.getJsjdrqm()));
        wordMap.put("FXBSX", defaultEmptyStr(GczyDo.getFxbs()));

    }


    public void processAspDzzyDo(AspDzzyDo DzzyDo, Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        // 吊装作业级别处理
        String DZZYJB = "";
        String dzzyjb = DzzyDo.getZyjb();
        if (dzzyjb != null) {
            SysDictDo sysDictDo = sysDictDoList.stream()
                    .filter(dict -> "dzzyjb".equals(dict.getDicttype()) &&
                            dzzyjb.equals(dict.getValue()))
                    .findFirst()
                    .orElse(null);
            DZZYJB = sysDictDo == null ? "" : defaultEmptyStr(sysDictDo.getName());
        }
        wordMap.put("DZZYJB", DZZYJB);



        wordMap.put("SQR", defaultEmptyStr(DzzyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(DzzyDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(DzzyDo.getZywz()));
        wordMap.put("DZNR", defaultEmptyStr(DzzyDo.getDznr()));
        String zydwlx = DzzyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(DzzyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(DzzyDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("SQDW", defaultEmptyStr(DzzyDo.getSqdw()));

//        wordMap.put("ZYFZR", defaultEmptyStr(DzzyDo.getZyfzr()));
        wordMap.put("JHR", defaultEmptyStr(DzzyDo.getJhr()));
        wordMap.put("ZYKSSJ", defaultEmptyStr(DzzyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(DzzyDo.getZyjssj()));
        wordMap.put("JHRQM", defaultEmptyStr(DzzyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(DzzyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(DzzyDo.getJsjdrqm()));
        wordMap.put("FXBSX", defaultEmptyStr(DzzyDo.getFxbs()));
        wordMap.put("SSR", defaultEmptyStr(DzzyDo.getSsr()));
        wordMap.put("DJMC", defaultEmptyStr(DzzyDo.getDjmc()));
        wordMap.put("DZZHRY", defaultEmptyStr(DzzyDo.getDzzhry()));
        wordMap.put("DZSJ", defaultEmptyStr(DzzyDo.getDzsj()));

    }


    public void processAspLsydzyDo(AspLsydzyDo LsydzyDo, Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        // 吊装作业级别处理
        String GZDY = "";
        String gzdy = LsydzyDo.getGzdy();
        if (gzdy != null) {
            SysDictDo sysDictDo = sysDictDoList.stream()
                    .filter(dict -> "YDZY-GZDY".equals(dict.getDicttype()) &&
                            gzdy.equals(dict.getValue()))
                    .findFirst()
                    .orElse(null);
            GZDY = sysDictDo == null ? "" : defaultEmptyStr(sysDictDo.getName());
        }
        wordMap.put("GZDY", GZDY);



        wordMap.put("SQR", defaultEmptyStr(LsydzyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(LsydzyDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(LsydzyDo.getZywz()));
        wordMap.put("ZYNR", defaultEmptyStr(LsydzyDo.getZynr()));
        String zydwlx = LsydzyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(LsydzyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(LsydzyDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("SQDW", defaultEmptyStr(LsydzyDo.getSqdw()));

        wordMap.put("ZYFZR", defaultEmptyStr(LsydzyDo.getZyfzr()));
        wordMap.put("JHR", defaultEmptyStr(LsydzyDo.getJhr()));
        wordMap.put("ZYKSSJ", defaultEmptyStr(LsydzyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(LsydzyDo.getZyjssj()));

        wordMap.put("JHRQM", defaultEmptyStr(LsydzyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(LsydzyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(LsydzyDo.getJsjdrqm()));

        wordMap.put("FXBSX", defaultEmptyStr(LsydzyDo.getFxbs()));

        wordMap.put("DYJRDJXKYDGL", defaultEmptyStr(LsydzyDo.getDyjrdjxkydgl()));
        wordMap.put("YDSBMCJEDGL", defaultEmptyStr(LsydzyDo.getYdsbmcjedgl()));
        wordMap.put("YDR", defaultEmptyStr(LsydzyDo.getYdr()));
    }

    public void processAspDtzyDo(AspDtzyDo aspdtzyDo , Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        wordMap.put("SQR", defaultEmptyStr(aspdtzyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(aspdtzyDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(aspdtzyDo.getZywz()));
        wordMap.put("ZYNR", defaultEmptyStr(aspdtzyDo.getZynr()));
        String zydwlx = aspdtzyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(aspdtzyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(aspdtzyDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("ZYKSSJ", defaultEmptyStr(aspdtzyDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(aspdtzyDo.getZyjssj()));
        wordMap.put("SQDW", defaultEmptyStr(aspdtzyDo.getSqdw()));
        wordMap.put("JHR", defaultEmptyStr(aspdtzyDo.getJhr()));
        wordMap.put("ZYFZR", defaultEmptyStr(aspdtzyDo.getZyfzr()));
        wordMap.put("FXBSX", defaultEmptyStr(aspdtzyDo.getFxbs()));
        wordMap.put("ZYFWFS", defaultEmptyStr(aspdtzyDo.getZyfwfs()));

        wordMap.put("JHRQM", defaultEmptyStr(aspdtzyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(aspdtzyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(aspdtzyDo.getJsjdrqm()));
    }

    public void processAspDlzzDo(AspDlzzDo aspdlzzDo , Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        wordMap.put("SQR", defaultEmptyStr(aspdlzzDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(aspdlzzDo.getZyzbh()));
        wordMap.put("ZYWZ", defaultEmptyStr(aspdlzzDo.getZywz()));
        wordMap.put("ZYNR", defaultEmptyStr(aspdlzzDo.getZynr()));
        String zydwlx = aspdlzzDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(aspdlzzDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(aspdlzzDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("ZYKSSJ", defaultEmptyStr(aspdlzzDo.getZykssj()));
        wordMap.put("ZYJSSJ", defaultEmptyStr(aspdlzzDo.getZyjssj()));
        wordMap.put("SQDW", defaultEmptyStr(aspdlzzDo.getSqdw()));
        wordMap.put("JHR", defaultEmptyStr(aspdlzzDo.getJhr()));
        wordMap.put("ZYFZR", defaultEmptyStr(aspdlzzDo.getZyfzr()));
        wordMap.put("FXBSX", defaultEmptyStr(aspdlzzDo.getFxbs()));
        wordMap.put("JHRQM", defaultEmptyStr(aspdlzzDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(aspdlzzDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(aspdlzzDo.getJsjdrqm()));

        wordMap.put("SJXGDWBM", defaultEmptyStr(aspdlzzDo.getSjxgdwbm()));
        wordMap.put("DLYY", defaultEmptyStr(aspdlzzDo.getDlyy()));
        wordMap.put("XGSM", defaultEmptyStr(aspdlzzDo.getXgsm()));

        wordMap.put("DLDDSYT", defaultEmptyStr(aspdlzzDo.getDlddsyt()));
    }

    public void processAspMbcdDo(AspMbcdzyDo aspmbcdzyDo , Map<String, String> wordMap, List<SysDictDo> sysDictDoList) {
        // 盲板作业类别
        String MBCDZYLB = "";
        String mbcdzylb = aspmbcdzyDo.getZylb();
        if (mbcdzylb != null) {
            SysDictDo sysDictDo = sysDictDoList.stream()
                    .filter(dict -> "mbcdzylb".equals(dict.getDicttype()) &&
                            mbcdzylb.equals(dict.getValue()))
                    .findFirst()
                    .orElse(null);
            MBCDZYLB = sysDictDo == null ? "" : defaultEmptyStr(sysDictDo.getName());
        }
        wordMap.put("MBCDZYLB", MBCDZYLB);




        wordMap.put("SQR", defaultEmptyStr(aspmbcdzyDo.getSqr()));
        wordMap.put("ZYZBH", defaultEmptyStr(aspmbcdzyDo.getZyzbh()));


        String zydwlx = aspmbcdzyDo.getZydwlx();
        String zydwmc = "1".equals(zydwlx) ? defaultEmptyStr(aspmbcdzyDo.getSqdw()) :
                "2".equals(zydwlx) ? defaultEmptyStr(aspmbcdzyDo.getCbsmc()) : "";
        wordMap.put("ZYDWMC", zydwmc);
        wordMap.put("SQDW", defaultEmptyStr(aspmbcdzyDo.getSqdw()));


        wordMap.put("ZYKSSJ", defaultEmptyStr(aspmbcdzyDo.getZykssj()));
//        wordMap.put("ZYJSSJ", defaultEmptyStr(aspmbcdzyDo.getZyjssj()));

        wordMap.put("JHR", defaultEmptyStr(aspmbcdzyDo.getJhr()));
        wordMap.put("ZYFZR", defaultEmptyStr(aspmbcdzyDo.getZyfzr()));
        wordMap.put("FXBSX", defaultEmptyStr(aspmbcdzyDo.getFxbs()));
        wordMap.put("JHRQM", defaultEmptyStr(aspmbcdzyDo.getJhrqm()));
        wordMap.put("AQJDRQM", defaultEmptyStr(aspmbcdzyDo.getAqjdrqm()));
        wordMap.put("JSJDRQM", defaultEmptyStr(aspmbcdzyDo.getJsjdrqm()));


        wordMap.put("SBGDMC", defaultEmptyStr(aspmbcdzyDo.getSbgdmc()));
        wordMap.put("GDJZ", defaultEmptyStr(aspmbcdzyDo.getGdjz()));
        wordMap.put("GDWDU", defaultEmptyStr(aspmbcdzyDo.getGdwdu()));
        wordMap.put("GDYL", defaultEmptyStr(aspmbcdzyDo.getSbgdmc()));
        wordMap.put("MBCZ", defaultEmptyStr(aspmbcdzyDo.getMbcz()));

        wordMap.put("MBGG", defaultEmptyStr(aspmbcdzyDo.getMbgg()));

        wordMap.put("MBBM", defaultEmptyStr(aspmbcdzyDo.getMbbm()));

        wordMap.put("MBWZT", defaultEmptyStr(aspmbcdzyDo.getMbwzt()));
        wordMap.put("MBWZTBH", defaultEmptyStr(aspmbcdzyDo.getMbwztbh()));
    }



    public String defaultEmptyStr(Object str) {
        if (str == null) {
            return "";
        }
        if (str instanceof Date) {
            // 处理旧版 Date 类型
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) str);
        } else if (str instanceof java.time.temporal.TemporalAccessor) {
            // 统一处理 Java 8 时间类型（LocalDateTime、LocalDate、ZonedDateTime 等）
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            if (str instanceof LocalDateTime) {
                return ((LocalDateTime) str).format(formatter);
            } else if (str instanceof LocalDate) {
                return ((LocalDate) str).atStartOfDay().format(formatter);
            } else if (str instanceof ZonedDateTime) {
                return ((ZonedDateTime) str).format(formatter);
            }
            return formatter.format((TemporalAccessor) str);
        }
        return str.toString();
    }

//    public String defaultEmptyStr(Object str) {
//        if (str == null) {
//            return "";
//        }
//        if (str instanceof Date) {
////            return new SimpleDateFormat("yyyy-MM-dd").format(str);
//            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) str);
//        }
//        return str.toString();
//    }

    public void checkBoxDispose(Map<String, String> wordMap, Document document, String[] fxbs, List<SysDictDo> sysDictDoList) {
        try {
            DocumentBuilder builder = new DocumentBuilder(document);
            if (fxbs.length > 0) {
                String bsx = "FXBS";
                builder.moveToMergeField(bsx);
                for (String info : fxbs) {
                    builder.getFont().setName(DEFAULT_FONT_NAME);
                    builder.write(info);
                    builder.getFont().setName("Wingdings");
                  String fxbsx = wordMap.get("FXBSX");
                    if (StringUtils.isBlank(fxbsx)) {
                        // 如果 wordMap 中 FXBS 键的值为空，复选框不勾选
                        builder.write("\u00A8");
                    } else {
                        String[] values = fxbsx.split(",");
                        boolean isChecked = false;
                        for (String value : values) {
                            if (value.trim().equals(info)) {
                                // 如果 FXBS 键的值中包含当前选项，复选框勾选
                                isChecked = true;
                                break;
                            }
                        }
                        builder.write(isChecked ? "\u00FE" : "\u00A8");
                    }
                    builder.write(" ");
                }
            }
            for (Map.Entry<String, String> entry : CHECK_BOX.entrySet()) {
                String k = entry.getKey();
                String v = entry.getValue();
                // 先判断文档中是否存在该合并字段，存在再处理
                boolean found = builder.moveToMergeField(k);
                if (!found) {
                    continue; // 不存在该合并字段，跳过本轮处理
                }

//                builder.moveToMergeField(k);
                List<SysDictDo> dicts = sysDictDoList.stream().filter(dict -> v.equals(dict.getDicttype()) && !dict.getPid().equals("-1"))
                        .sorted(Comparator.comparing(SysDictDo::getSort).reversed())
                        .collect(Collectors.toList());
                for (SysDictDo info : dicts) {
                    builder.getFont().setName(DEFAULT_FONT_NAME);
                    builder.write(info.getName());
                    builder.getFont().setName("Wingdings");
                    builder.write(StringUtils.isBlank(wordMap.get(k)) ? "\u00A8" : wordMap.get(k).contains(info.getValue()) ? "\u00FE" : "\u00A8");
                    builder.write(" ");
                }
            }


        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }



    public void response(Map<String, String> wordMap, HttpServletResponse response , List<Map<String, String>> subList1,List<Map<String, String>> subList2, String[] fxbs, List<SysDictDo> sysDictDoList,String jobtype) {
        try ( InputStream inputStream = new ClassPathResource(TEMPLATE_MAP.get(jobtype)).getInputStream();
             OutputStream outputStream = response.getOutputStream()) {
            if (inputStream == null) {
                log.error("无法找到指定的 Word 模板文件");
                throw new FileNotFoundException("无法找到 Word 模板文件");
            }
            Document doc = new Document(inputStream);
            log.info("文档加载成功");
            if (wordMap != null) {
                log.info("执行邮件合并");
                checkBoxDispose(wordMap, doc, fxbs ,sysDictDoList );
                // 删除图片字段，防止插入为 ID
                List<String> imageBookmarks = Arrays.asList("JHRQM", "AQJDRQM", "JSJDRQM","SDBMFZRQZ","DLDDSYT","MBWZT");
                Map<String, String> textMap = new HashMap<>(wordMap);
                imageBookmarks.forEach(textMap::remove);
//                doc.getMailMerge().execute(wordMap.keySet().toArray(new String[0]), wordMap.values().toArray(new String[0]));
                doc.getMailMerge().execute(textMap.keySet().toArray(new String[0]), textMap.values().toArray(new String[0]));
                // 插入图片签名
                insertImageToBookmark(doc, "SDBMFZRQZ", wordMap.get("SDBMFZRQZ"));
                insertImageToBookmark(doc, "JHRQM", wordMap.get("JHRQM"));
                insertImageToBookmark(doc, "AQJDRQM", wordMap.get("AQJDRQM"));
                insertImageToBookmark(doc, "JSJDRQM", wordMap.get("JSJDRQM"));

//                insertImageToBookmark(doc, "DLDDSYT", wordMap.get("DLDDSYT"),200,150);
//                insertImageToBookmark(doc, "MBWZT", wordMap.get("MBWZT"),200,150);

                insertImagesIntoMergeField(doc,"DLDDSYT",processImageid(wordMap.get("DLDDSYT")),300,200);
                insertImagesIntoMergeField(doc,"MBWZT",processImageid(wordMap.get("MBWZT")),300,200);
                if (!subList1.isEmpty()) {
                    log.info("执行 List1 区域合并");
                    CustomMailMergeDataSource dataSource = new CustomMailMergeDataSource(subList1,"list1");
                    // 执行嵌套邮件合并
                    doc.getMailMerge().executeWithRegions(dataSource);
                }
                if (!subList2.isEmpty()) {
                    log.info("执行 List2 区域合并");
                    CustomMailMergeDataSource dataSource2 = new CustomMailMergeDataSource(subList2,"list2");
                    // 执行嵌套邮件合并
                    doc.getMailMerge().executeWithRegions(dataSource2);
                }

            }

            doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS | MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS);
            doc.getMailMerge().deleteFields();

            // 设置返回 PDF 的响应头
            response.setContentType("application/pdf");
            String zyzbh = wordMap.get("ZYZBH"); // 假设 wordMap 是 Map<String, String>
            String rawFileName = jobtype + (zyzbh != null ? zyzbh : "");
            String fileName = URLEncoder.encode(rawFileName + ".pdf", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);
//            response.setHeader("Content-Disposition", "inline; filename*=UTF-8''" + fileName);
            log.info("开始输出 PDF 至前端");

            // 输出为 PDF 流
            doc.save(response.getOutputStream(), com.aspose.words.SaveFormat.PDF);

        } catch (IOException e) {
            log.error("文件导出过程中出现 IO 异常", e);
            throw new CustomException("文件导出异常");
        } catch (Exception e) {
            log.error("文件导出过程中出现未知异常", e);
            throw new RuntimeException("文件导出过程中出现未知异常", e);
        }

    }



    @SneakyThrows
    public void insertImageToBookmark(Document doc, String bookmark, String fileId) {
        insertImageToBookmark(doc, bookmark, fileId, 100, 50); // 默认尺寸
    }

    @SneakyThrows
    public void insertImageToBookmark(Document doc, String bookmark, String fileId, int width, int height) {
        if (StringUtils.isBlank(fileId)) return;

        SysFileItemDo file = fileItemDao.selectById(fileId);
        if (file == null || !IMG_SUFFIX.contains(file.getFiletype().toLowerCase())) return;
//        String filePath = "D:\\js-safe-production1\\upload_files\\SXQM\\a0989b35eb88469b8d798fcca98d2dd6.png";
        try (InputStream inputStream = Files.newInputStream(Paths.get(file.getFullpath()))) {
            DocumentBuilder builder = new DocumentBuilder(doc);
            builder.moveToMergeField(bookmark);
            builder.insertImage(inputStream, width, height); // 使用指定尺寸
        }
    }

    @SneakyThrows
    public void insertImagesIntoMergeField(Document doc, String fieldName, List<String> imageIds, int width, int height) {
        DocumentBuilder builder = new DocumentBuilder(doc);

        // 移动到合并字段位置
        if (!builder.moveToMergeField(fieldName, false, false)) {
            log.error("找不到合并字段: {}", fieldName);
            return;
        }

        // 清除合并字段内容
        builder.getCurrentParagraph().removeAllChildren();

        // 插入所有图片
        for (String imageId : imageIds) {
            try {
                SysFileItemDo file = fileItemDao.selectById(imageId);
                if (file == null || !IMG_SUFFIX.contains(file.getFiletype().toLowerCase())) {
                    log.warn("无效图片文件，imageId: {}", imageId);
                    continue;
                }

                // 插入图片file.getFullpath()
                try (InputStream stream = Files.newInputStream(Paths.get(file.getFullpath()))) {
                    builder.insertImage(stream, width, height);
                    log.info("插入图片成功");
                }

                // 添加空行分隔图片
                builder.insertParagraph();
            } catch (Exception e) {
                log.error("插入图片失败，imageId: {}", imageId, e);
            }
        }
    }


    public  List<String> processImageid(String input) {
        List<String> imageInfos = new ArrayList<>();
        if (input == null || input.isEmpty()) {
            return imageInfos;
        }

        String[] parts = input.split("\\^_\\^");
        for (String part : parts) {
            int index = part.indexOf("-;-");
            if (index != -1) {

                String imageId = part.substring(index + 3);
                imageInfos.add(imageId);
            }
        }

        return imageInfos;
    }

}
