package com.malk.qiwang.Service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.malk.qiwang.Service.QiWangService;
import com.malk.qiwang.Service.TXYInvoice;
import com.malk.qiwang.entity.CompanyTitle;
import com.malk.qiwang.entity.InvoiceLibrary;
import com.malk.qiwang.mapper.CompanyTitleMapper;
import com.malk.qiwang.mapper.InvoiceLibraryMapper;
import com.malk.qiwang.Service.IInvoiceLibraryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.malk.qiwang.model.McInvoiceDto;
import com.malk.server.common.FilePath;
import com.malk.server.common.McException;
import com.malk.server.common.McR;
import com.malk.server.dingtalk.DDR_New;
import com.malk.service.aliwork.YDClient;
import com.malk.service.dingtalk.DDClient;
import com.malk.service.dingtalk.DDClient_Contacts;
import com.malk.service.dingtalk.DDClient_Workflow;
import com.malk.utils.*;
import com.spire.pdf.PdfCompressionLevel;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.exporting.PdfImageInfo;
import com.spire.pdf.graphics.PdfBitmap;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hpsf.Decimal;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 发票库表 服务实现类
 * </p>
 *
 * @author LQY
 * @since 2026-04-27
 */
@Service
@Slf4j
public class InvoiceLibraryServiceImpl extends ServiceImpl<InvoiceLibraryMapper, InvoiceLibrary> implements IInvoiceLibraryService {
    @Autowired
    private QiWangService qiWangService;
    @Autowired
    private DDClient ddClient;
    @Autowired
    private YDClient ydClient;
    @Autowired
    private TXYInvoice txyInvoice;
    @Value("${dingtalk.operator}")
    private String operator;
    @Value("${dingtalk.downloadPath}")
    private String downloadPath;
    @Autowired
    private FilePath filePath;
    @Autowired
    private DDClient_Workflow ddClientWorkflow;
    @Autowired
    private InvoiceLibraryMapper baseMapper;
    @Autowired
    private CompanyTitleMapper companyTitleMapper;
    @Autowired
    private DDClient_Contacts ddClient_contacts;
    private static final String url = "http://47.103.203.2:9092/qiwang/";
//    private static final String url = "http://410a09c5.r39.cpolar.top/qiwang/";

    @Override
    public McR invoiceLibrary(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String bm = null;
            String bxlb = null;
            String fkzhxx = null;
            String fkzh = null;
            String yhqc = null;
//            String sfct = null;
            BigDecimal mainJe = null;

            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("MoneyField_3QZLY8BD3780".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                if ("DDSelectField_1TP75OVCPAAO0".equals(id)) {
                    bxlb = value != null ? String.valueOf(value) : "";
                }
                if ("DepartmentField_1RD2SROH579C0".equals(id)) {
                    bm = value != null ? String.valueOf(value) : "";
                }
                if ("DDSelectField_11D6S45JKFHS0".equals(id)) {
                    fkzhxx = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_1S1VV9PIIQWW0".equals(id)) {
                    fkzh = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_ZUVAAH3FIGW0".equals(id)) {
                    yhqc = value != null ? String.valueOf(value) : "";
                }

            }

            // 遍历子表数据
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));

                if ("TableField_1A1CDMEN8DDS0".equals(id)) {
                    String tableFieldValue = String.valueOf(formComponentValue.get("value"));
                    log.info("子表数据: {}", tableFieldValue);

                    try {
                        List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
                        if (tableRows == null || tableRows.isEmpty()) {
                            log.warn("子表数据为空");
                            return McR.error("400", "发票明细为空");
                        }

                        // 用于存储无发票记录和发票记录
                        List<InvoiceLibrary> noInvoiceList = new ArrayList<>();
                        List<InvoiceLibrary> invoiceList = new ArrayList<>();
                        List<Object> allResults = new ArrayList<>();

                        // 存储有发票（"是"和"被共享"）的解析数据
                        List<Map<String, Object>> parsedInvoiceDataList = new ArrayList<>();
                        // 存储共享发票数据
                        List<Map<String, Object>> sharedInvoiceDataList = new ArrayList<>();
                        // 用于校验的集合
                        List<String> invoiceNumberList = new ArrayList<>();
                        Map<String, String> invoiceNumberToFileName = new HashMap<>();
                        List<String> invalidBuyerTaxIds = new ArrayList<>();

                        // 存储税率信息（从"被共享"发票中获取）
                        BigDecimal sharedTaxRate = BigDecimal.ZERO;
                        String sharedKind = "";
                        boolean hasSharedInvoice = false; // 标记是否存在"被共享"发票

                        // ========== 第一遍遍历：收集数据并查找"被共享"发票 ==========
                        for (Map row : tableRows) {
                            List<Map> rowValues = (List<Map>) row.get("rowValue");

                            String hasInvoice = null;
                            String cdbm = null;
                            String lbmx = null;
                            String bz = null;
                            BigDecimal detailje = null;
                            List<Map> attachmentList = null;

                            for (Map rowItem : rowValues) {
                                String key = String.valueOf(rowItem.get("key"));
                                if ("DDSelectField_1ORUK0KIM5D6O".equals(key)) {
                                    Object value = rowItem.get("value");
                                    hasInvoice = value != null ? String.valueOf(value) : "";
                                }
                                if ("DDSelectField_12SQMP8DSUF40".equals(key)) {
                                    Object value = rowItem.get("value");
                                    lbmx = value != null ? String.valueOf(value) : "";
                                }
                                if ("TextareaField_1GRJNUC4BAE80".equals(key)) {
                                    Object value = rowItem.get("value");
                                    bz = value != null ? String.valueOf(value) : "";
                                }
                                if ("DepartmentField_ATSWRJBJ7K00".equals(key)) {
                                    Object value = rowItem.get("value");
                                    cdbm = value != null ? String.valueOf(value) : "";
                                }

                                if ("NumberField_1622XLFLYEWW0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof BigDecimal) {
                                        detailje = (BigDecimal) value;
                                    } else if (value != null) {
                                        try {
                                            detailje = new BigDecimal(String.valueOf(value));
                                        } catch (NumberFormatException e) {
                                            log.error("金额格式转换失败: {}", value);
                                            detailje = BigDecimal.ZERO;
                                        }
                                    } else {
                                        detailje = BigDecimal.ZERO;
                                    }
                                }
                                if ("DDAttachment_Z02OGR5QL8U8".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof List) {
                                        attachmentList = (List<Map>) value;
                                    }
                                }
                            }

                            // ========== 处理 hasInvoice = "否" 的情况（无发票） ==========
                            if ("否".equals(hasInvoice)) {
                                // 保存基础报销记录（无发票）
                                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                                baseInvoice.setOaId(processInstanceId);
                                baseInvoice.setOaStatus("0");
                                baseInvoice.setInvoiceStatus("0");
                                baseInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                baseInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                baseInvoice.setDetailAmount(detailje != null ? detailje : BigDecimal.ZERO);
                                baseInvoice.setCreatedAt(LocalDateTime.now());
                                baseInvoice.setUpdatedAt(LocalDateTime.now());
                                baseInvoice.setInvoiceCode("");
                                baseInvoice.setInvoiceNumber("");
                                baseInvoice.setInvoiceType("");
                                baseInvoice.setAmount(null);
                                baseInvoice.setTaxAmount(null);
                                baseInvoice.setTotalAmount(null);
                                baseInvoice.setBuyerName("");
                                baseInvoice.setBuyerTaxId("");
                                baseInvoice.setSellerName("");
                                baseInvoice.setSellerTaxId("");
                                baseInvoice.setFormName("员工费用报销");
                                baseInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                baseInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                baseInvoice.setBankName(yhqc != null ? yhqc : "");
                                baseInvoice.setHasInvoice("否");
                                baseInvoice.setSharedTaxAmount(null);
                                baseInvoice.setSharedAmount(null);
                                baseInvoice.setSharedRate(null);
                                baseInvoice.setNote(bz != null ? bz : "");
                                noInvoiceList.add(baseInvoice);
                                log.info("收集无发票记录: 成本部门={}, 费用明细={}", cdbm, lbmx);
                                continue;
                            }

                            // ========== 处理 hasInvoice = "被共享"（被共享发票，提供税率） ==========
                            if ("被共享".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                // 标记存在被共享发票
                                hasSharedInvoice = true;

                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        // 解析发票数据
                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                // ========== 获取税率（供共享发票使用） ==========
                                                Object taxRateObj = invoice.get("taxRate");
                                                Object kind = invoice.getString("kindName");

                                                if (taxRateObj != null) {
                                                    String taxRateStr = String.valueOf(taxRateObj);
                                                    String taxRateNum = taxRateStr.replace("%", "").trim();
                                                    sharedKind = kind != null ? String.valueOf(kind) : "";
                                                    sharedTaxRate = new BigDecimal(taxRateNum);
                                                    sharedTaxRate = sharedTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP);
                                                    log.info("从被共享发票获取税率: 原始={}, 转换后={}", taxRateStr, sharedTaxRate);
                                                }

                                                // 保存解析的数据供后续使用
                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // ========== 校验1：抬头校验 ==========
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // ========== 校验2：发票号重复校验 ==========
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("被共享发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "被共享发票解析失败: " + e.getMessage());
                                        return McR.error("400", "被共享发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "是"（有发票，但不共享） ==========
                            if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // 抬头校验
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // 发票号重复校验
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "发票解析失败: " + e.getMessage());
                                        return McR.error("400", "发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "共享"（共享发票，需要从被共享发票获取税率） ==========

                            if ("共享".equals(hasInvoice)) {
                                if (detailje != null && detailje.compareTo(BigDecimal.ZERO) > 0) {
                                    Map<String, Object> sharedData = new HashMap<>();
                                    sharedData.put("detailje", detailje);
                                    sharedData.put("lbmx", lbmx);
                                    sharedData.put("bz", bz);
                                    sharedData.put("cdbm", cdbm);
                                    sharedData.put("hasInvoice", hasInvoice);
                                    sharedInvoiceDataList.add(sharedData);
                                    log.info("收集共享发票数据: 金额={}, 成本部门={}", detailje, cdbm);
                                }
                            }
                        }

                        // ========== 检查：如果存在共享发票但没有被共享发票 ==========
                        if (!sharedInvoiceDataList.isEmpty() && !hasSharedInvoice) {
                            String errorMsg = "存在'共享'发票，但未找到'被共享'发票，无法获取税率信息，请确保至少有一行选择'被共享'并上传发票附件";
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        // ========== 抬头校验失败处理 ==========
                        if (!invalidBuyerTaxIds.isEmpty()) {
                            String errorMsg = "发票抬头有误，以下发票的购买方税号不在公司抬头库中:\n" + String.join("\n", invalidBuyerTaxIds);
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        BigDecimal totalAmount = BigDecimal.ZERO;

                        // ========== 第二遍遍历：保存发票数据 ==========
                        // 1. 保存有发票数据（"是"和"被共享"）
                        for (Map<String, Object> parsedData : parsedInvoiceDataList) {
                            JSONObject invoice = (JSONObject) parsedData.get("invoice");
                            Object responseData = parsedData.get("responseData");
                            String cdbm = (String) parsedData.get("cdbm");
                            String lbmx = (String) parsedData.get("lbmx");
                            String bz = (String) parsedData.get("bz");
                            String hasInvoice = (String) parsedData.get("hasInvoice");
                            Object detailjeObj = parsedData.get("detailje");
                            String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";

                            allResults.add(responseData);
                            BigDecimal amount = invoice.getBigDecimal("amount");
                            if (amount != null) {
                                totalAmount = totalAmount.add(amount);
                            }

                            InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                            invoiceLibrary.setOaId(processInstanceId);
                            invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                            invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                            invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                            String date = invoice.getString("date");
                            if (StringUtils.isNotBlank(date)) {
                                try {
                                    invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                } catch (Exception e) {
                                    log.warn("日期解析失败: {}", date);
                                }
                            }

                            invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                            invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                            invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                            invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                            invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                            invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                            invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                            invoiceLibrary.setOaStatus("0");
                            invoiceLibrary.setNote(bz != null ? bz : "");
                            invoiceLibrary.setFormName("员工费用报销");
                            invoiceLibrary.setPaySubject(fkzhxx != null ? fkzhxx : "");
                            invoiceLibrary.setPayAccount(fkzh != null ? fkzh : "");
                            invoiceLibrary.setBankName(yhqc != null ? yhqc : "");
                            invoiceLibrary.setInvoiceStatus("0");
                            invoiceLibrary.setHasInvoice(hasInvoice);

                            if (StringUtils.isNotBlank(detailje)) {
                                try {
                                    invoiceLibrary.setDetailAmount(new BigDecimal(detailje));
                                } catch (NumberFormatException e) {
                                    log.error("detailJe格式转换失败: {}", detailje);
                                    invoiceLibrary.setDetailAmount(null);
                                }
                            } else {
                                invoiceLibrary.setDetailAmount(null);
                            }

                            invoiceLibrary.setSharedTaxAmount(null);
                            invoiceLibrary.setSharedAmount(null);
                            invoiceLibrary.setSharedRate(null);
                            invoiceLibrary.setAccountTitle(lbmx != null ? lbmx : "");
                            invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                            invoiceLibrary.setCreatedAt(LocalDateTime.now());
                            invoiceLibrary.setUpdatedAt(LocalDateTime.now());

                            if (cdbm != null && StringUtils.isNotBlank(cdbm)) {
                                invoiceLibrary.setDep(cdbm);
                            } else {
                                invoiceLibrary.setDep(bm != null ? bm : "");
                            }

                            invoiceList.add(invoiceLibrary);
                        }

                        // 2. 保存共享发票数据（使用从"被共享"发票获取的税率）
                        if (!sharedInvoiceDataList.isEmpty()) {
                            // 检查税率是否有效
                            if (sharedTaxRate.compareTo(BigDecimal.ZERO) == 0) {
                                log.warn("共享发票税率未获取到，使用默认税率0");
                            }

                            for (Map<String, Object> sharedData : sharedInvoiceDataList) {
                                Object detailjeObj = sharedData.get("detailje");
                                String cdbm = (String) sharedData.get("cdbm");
                                String lbmx = (String) sharedData.get("lbmx");
                                String bz = (String) sharedData.get("bz");
                                String hasInvoice = (String) sharedData.get("hasInvoice");
                                String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";
                                try {
                                    BigDecimal detailAmount = new BigDecimal(detailje);

                                    // 使用从"被共享"发票解析到的税率
                                    BigDecimal ocrTaxRate = sharedTaxRate;

                                    // 计算金额: 含税金额 / (1 + 税率) = 不含税金额
                                    BigDecimal divisor = BigDecimal.ONE.add(ocrTaxRate);
                                    BigDecimal sharedTaxAmount = detailAmount.divide(divisor, 2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal sharedAmount = detailAmount.subtract(sharedTaxAmount);
                                    BigDecimal sharedRate = ocrTaxRate;

                                    log.info("共享发票计算: 含税金额={}, 税率={}%, 不含税金额={}, 税额={}",
                                            detailAmount, ocrTaxRate.multiply(new BigDecimal("100")),
                                            sharedAmount, sharedTaxAmount);

                                    InvoiceLibrary sharedInvoice = new InvoiceLibrary();
                                    sharedInvoice.setOaId(processInstanceId);
                                    sharedInvoice.setOaStatus("0");
                                    sharedInvoice.setInvoiceStatus("0");
                                    sharedInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                    sharedInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                    sharedInvoice.setNote(bz != null ? bz : "");
                                    sharedInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                    sharedInvoice.setAmount(null);
                                    sharedInvoice.setTaxAmount(null);
                                    sharedInvoice.setTotalAmount(null);
                                    sharedInvoice.setFormName("员工费用报销");
                                    sharedInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                    sharedInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                    sharedInvoice.setBankName(yhqc != null ? yhqc : "");
                                    sharedInvoice.setHasInvoice(hasInvoice);
                                    sharedInvoice.setDetailAmount(detailAmount);
                                    sharedInvoice.setSharedTaxAmount(sharedAmount);
                                    sharedInvoice.setSharedAmount(sharedTaxAmount);
                                    sharedInvoice.setSharedRate(String.valueOf(sharedRate));
                                    sharedInvoice.setCreatedAt(LocalDateTime.now());
                                    sharedInvoice.setUpdatedAt(LocalDateTime.now());
                                    sharedInvoice.setInvoiceCode("");
                                    sharedInvoice.setInvoiceNumber("");
                                    sharedInvoice.setInvoiceType(sharedKind);
                                    sharedInvoice.setBuyerName("");
                                    sharedInvoice.setBuyerTaxId("");
                                    sharedInvoice.setSellerName("");
                                    sharedInvoice.setSellerTaxId("");
                                    invoiceList.add(sharedInvoice);
                                    log.info("成功保存共享发票记录，成本部门: {}", cdbm);

                                } catch (NumberFormatException e) {
                                    log.error("共享发票金额格式转换失败: detailje={}", detailje, e);
                                } catch (Exception e) {
                                    log.error("共享发票处理失败", e);
                                }
                            }
                        }

                        // 保存所有记录（无发票 + 有发票）
                        if (!noInvoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : noInvoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条无发票记录", noInvoiceList.size());
                            addWorkflowComment(processInstanceId, userId, "报销总金额：" + mainJe);
                        }

                        if (!invoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : invoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条发票记录（有发票: {}, 共享发票: {}）",
                                    invoiceList.size(),
                                    parsedInvoiceDataList.stream().filter(d -> "是".equals(d.get("hasInvoice")) || "被共享".equals(d.get("hasInvoice"))).count(),
                                    sharedInvoiceDataList.size());
                            addWorkflowComment1(processInstanceId, userId, totalAmount);
                        }

                        if (!allResults.isEmpty()) {
                            return McR.success(allResults);
                        } else {
                            return McR.success();
                        }

                    } catch (Exception e) {
                        log.error("解析子表数据失败", e);
                        return McR.error("300", "解析数据失败: " + e.getMessage());
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }
    /**
     * 终止钉钉审批流程
     *
     * @param accessToken 钉钉accessToken
     * @param processInstanceId 审批实例ID
     * @param operatingUserId 操作人用户ID（通常是发起人ID）
     * @param remark 终止原因备注
     */
    private void terminateWorkflow(String accessToken, String processInstanceId, String operatingUserId, String remark) {
        // 异步延迟15秒后执行终止
        CompletableFuture.runAsync(() -> {
            try {
                log.info("延迟15秒后开始终止审批流程: processInstanceId={}, remark={}", processInstanceId, remark);
                Thread.sleep(15000);

                // 实际执行终止操作
                doTerminateWorkflow(accessToken, processInstanceId, operatingUserId, remark);

            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.error("延迟终止流程被中断: processInstanceId={}", processInstanceId, e);
            } catch (Exception e) {
                log.error("异步执行终止流程异常: processInstanceId={}", processInstanceId, e);
            }
        });
    }

    /**
     * 实际执行钉钉审批流程终止
     */
    private void doTerminateWorkflow(String accessToken, String processInstanceId, String operatingUserId, String remark) {
        try {
            log.info("开始调用钉钉API终止审批流程: processInstanceId={}", processInstanceId);

            // 构建请求URL
            String url = "https://api.dingtalk.com/v1.0/workflow/processInstances/terminate";

            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("x-acs-dingtalk-access-token", accessToken);

            // 构建请求体
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("processInstanceId", processInstanceId);
            requestBody.put("isSystem", true);  // 系统调用终止
            requestBody.put("remark", remark);
            requestBody.put("operatingUserId", operatingUserId);

            log.info("钉钉终止请求参数: {}", requestBody);

            // 发送POST请求
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);

            if (response.getStatusCode().is2xxSuccessful()) {
                log.info("审批流程终止成功: processInstanceId={}, response={}", processInstanceId, response.getBody());
            } else {
                log.error("审批流程终止失败: processInstanceId={}, statusCode={}, response={}",
                        processInstanceId, response.getStatusCode(), response.getBody());
            }

        } catch (Exception e) {
            log.error("调用钉钉终止流程接口异常: processInstanceId={}, error={}", processInstanceId, e.getMessage(), e);
        }
    }



    @Override
    public void updateOaStatusByOaId(Map map) {
        try {
            String oaId = UtilMap.getString(map, "oaId");
            // 创建更新条件
            LambdaUpdateWrapper<InvoiceLibrary> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(InvoiceLibrary::getOaId, oaId)
                    .set(InvoiceLibrary::getOaStatus, "1")
                    .set(InvoiceLibrary::getUpdatedAt, LocalDateTime.now());

            int updateCount = baseMapper.update(null, updateWrapper);

            if (updateCount > 0) {
                log.info("更新成功: 共更新{}条记录", updateCount);
            } else {
                log.warn("未找到符合条件的记录: oaId={}", oaId);
            }
        } catch (Exception e) {

            throw new RuntimeException("更新OA状态失败", e);
        }
    }

    @Override
    public McR invoiceLibrarys(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String zt = null;
            BigDecimal mainJe = null;
            String bxlb = null;
            String bm = null;

            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("DDSelectField_4SITXLYUEO80".equals(id)) {
                    zt = value != null ? String.valueOf(value) : "";
                }
                if ("MoneyField_3QZLY8BD3780".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                if ("DDSelectField_1TP75OVCPAAO0".equals(id)) {
                    bxlb = value != null ? String.valueOf(value) : "";
                }
                if ("DepartmentField_OKBSJN0MD6O0".equals(id)) {
                    bm = value != null ? String.valueOf(value) : "";
                }
            }



            // 判断主表状态 - 无发票
            if ("否".equals(zt)) {
                Map<String, Object> result = new HashMap<>();
                result.put("je", mainJe);
                result.put("status", "否");
                result.put("message", "无发票报销");
// 保存基础报销记录
                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                baseInvoice.setOaId(processInstanceId);
                baseInvoice.setOaStatus("0");
                baseInvoice.setInvoiceStatus("0");
                baseInvoice.setDep(bm != null ? bm : "");
                baseInvoice.setAccountTitle(bxlb != null ? bxlb : "");
                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                baseInvoice.setCreatedAt(LocalDateTime.now());
                baseInvoice.setUpdatedAt(LocalDateTime.now());
                baseInvoice.setInvoiceCode("");
                baseInvoice.setInvoiceNumber("");
                baseInvoice.setInvoiceType("");
                baseInvoice.setAmount(BigDecimal.ZERO);
                baseInvoice.setTaxAmount(BigDecimal.ZERO);
                baseInvoice.setTotalAmount(BigDecimal.ZERO);
                baseInvoice.setBuyerName("");
                baseInvoice.setBuyerTaxId("");
                baseInvoice.setSellerName("");
                baseInvoice.setSellerTaxId("");
                baseMapper.insert(baseInvoice);
                addWorkflowComment(processInstanceId, userId, result);
                return McR.success(result);
            }

            // 判断主表状态 - 有发票
            if ("是".equals(zt)) {
                for (Map formComponentValue : formComponentValues) {
                    String id = String.valueOf(formComponentValue.get("id"));

                    if ("TableField_1A1CDMEN8DDS0".equals(id)) {
                        String tableFieldValue = String.valueOf(formComponentValue.get("value"));
                        log.info("子表数据: {}", tableFieldValue);

                        try {
                            List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
                            if (tableRows == null || tableRows.isEmpty()) {
                                log.warn("子表数据为空");
                                return McR.error("400", "发票明细为空");
                            }

                            List<Object> allResults = new ArrayList<>();
                            List<InvoiceLibrary> invoiceList = new ArrayList<>();

                            for (Map row : tableRows) {
                                List<Map> rowValues = (List<Map>) row.get("rowValue");

                                String hasInvoice = null;
                                List<Map> attachmentList = null;

                                for (Map rowItem : rowValues) {
                                    String key = String.valueOf(rowItem.get("key"));

                                    if ("DDSelectField_1ORUK0KIM5D6O".equals(key)) {
                                        Object value = rowItem.get("value");
                                        hasInvoice = value != null ? String.valueOf(value) : "";
                                    }

                                    if ("DDAttachment_Z02OGR5QL8U8".equals(key)) {
                                        Object value = rowItem.get("value");
                                        if (value instanceof List) {
                                            attachmentList = (List<Map>) value;
                                        }
                                    }
                                }

                                if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                    for (Map attachment : attachmentList) {
                                        String fileId = UtilMap.getString(attachment, "fileId");
                                        String fileType = UtilMap.getString(attachment, "fileType");
                                        String fileName = UtilMap.getString(attachment, "fileName");

                                        log.info("处理发票: fileName={}, fileId={}", fileName, fileId);

                                        try {
                                            String filePath = downloadPath + fileId + "." + fileType;
                                            downloadDdFile(processInstanceId, fileId, filePath);

                                            String hz = "qw/files/" + fileId + "." + fileType;
                                            Map fileMap = new HashMap();
                                            fileMap.put("url", url + hz);
                                            fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                            fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                            McR<Object> result = processMixedInvoice(fileMap);
                                            Object responseData = result.getData();
                                            allResults.add(responseData);

                                            // 解析发票数据 - responseData 是对象，不是数组
                                            if (responseData != null) {
                                                try {
                                                    String jsonStr = JSONObject.toJSONString(responseData);
                                                    JSONObject jsonObject = JSONObject.parseObject(jsonStr);

                                                    // 获取 result 数组
                                                    JSONArray resultArray = jsonObject.getJSONArray("result");

                                                    if (resultArray != null && !resultArray.isEmpty()) {
                                                        JSONObject invoice = resultArray.getJSONObject(0);

                                                        InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                                                        invoiceLibrary.setOaId(processInstanceId);
                                                        invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                                                        invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                                                        invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                                                        String date = invoice.getString("date");
                                                        if (StringUtils.isNotBlank(date)) {
                                                            try {
                                                                invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                                            } catch (Exception e) {
                                                                log.warn("日期解析失败: {}", date);
                                                            }
                                                        }

                                                        invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                                                        invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                                                        invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                                                        invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                                                        invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                                                        invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                                                        invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                                                        invoiceLibrary.setOaStatus("0");
                                                        invoiceLibrary.setInvoiceStatus("0");
                                                        invoiceLibrary.setDep(bm != null ? bm : "");
                                                        invoiceLibrary.setAccountTitle(bxlb != null ? bxlb : "");
                                                        invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                                        invoiceLibrary.setCreatedAt(LocalDateTime.now());
                                                        invoiceLibrary.setUpdatedAt(LocalDateTime.now());

                                                        invoiceList.add(invoiceLibrary);
                                                    }
                                                } catch (Exception e) {
                                                    log.error("解析发票数据失败", e);
                                                }
                                            }

                                        } catch (Exception e) {
                                            log.error("处理发票失败: fileId={}, fileName={}", fileId, fileName, e);
                                        }
                                    }
                                }
                            }

                            if (!invoiceList.isEmpty()) {
                                for (InvoiceLibrary invoice : invoiceList) {
                                    baseMapper.insert(invoice);
                                }
                                log.info("成功保存 {} 条发票记录", invoiceList.size());
                            }

                            addWorkflowComment(processInstanceId, userId, allResults);
                            return McR.success(allResults);

                        } catch (Exception e) {
                            log.error("解析子表数据失败", e);
                            return McR.error("300", "解析数据失败: " + e.getMessage());
                        }
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }

    @Override
    public McR deleteAllByOaId(String oaId) {
        try {

            // 创建删除条件
            LambdaQueryWrapper<InvoiceLibrary> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(InvoiceLibrary::getOaId, oaId);

            // 执行删除
            int deleteCount = baseMapper.delete(queryWrapper);

            if (deleteCount > 0) {
                return McR.success("删除成功，共删除 " + deleteCount + " 条记录");
            } else {
                return McR.error("404", "未找到 oa_id 为 " + oaId + " 的记录");
            }
        } catch (Exception e) {
            log.error("删除失败", e);
            return McR.error("500", "删除失败: " + e.getMessage());
        }
    }

    @Override
    public McR invoiceLibrary1(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String bm = null;
            String bxlb = null;
            String fkzhxx = null;
            String fkzh = null;
            String yhqc = null;
//            String sfct = null;
            BigDecimal mainJe = null;

            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("MoneyField_1FVEBDQBSQ680".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                if ("DDSelectField_YLLB7AD1ATS0".equals(id)) {
                    bxlb = value != null ? String.valueOf(value) : "";
                }
                if ("DepartmentField_RF93A6VHA9C0".equals(id)) {
                    bm = value != null ? String.valueOf(value) : "";
                }
                if ("DDSelectField_23RVAEKUM5UO0".equals(id)) {
                    fkzhxx = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_1TE3AOHRMD4W0".equals(id)) {
                    fkzh = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_EN2MDZIMUTK0".equals(id)) {
                    yhqc = value != null ? String.valueOf(value) : "";
                }

            }

            // 遍历子表数据
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));

                if ("TableField_1VKP90DW7WKG0".equals(id)) {
                    String tableFieldValue = String.valueOf(formComponentValue.get("value"));
                    log.info("子表数据: {}", tableFieldValue);

                    try {
                        List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
                        if (tableRows == null || tableRows.isEmpty()) {
                            log.warn("子表数据为空");
                            return McR.error("400", "发票明细为空");
                        }

                        // 用于存储无发票记录和发票记录
                        List<InvoiceLibrary> noInvoiceList = new ArrayList<>();
                        List<InvoiceLibrary> invoiceList = new ArrayList<>();
                        List<Object> allResults = new ArrayList<>();

                        // 存储有发票（"是"和"被共享"）的解析数据
                        List<Map<String, Object>> parsedInvoiceDataList = new ArrayList<>();
                        // 存储共享发票数据
                        List<Map<String, Object>> sharedInvoiceDataList = new ArrayList<>();
                        // 用于校验的集合
                        List<String> invoiceNumberList = new ArrayList<>();
                        Map<String, String> invoiceNumberToFileName = new HashMap<>();
                        List<String> invalidBuyerTaxIds = new ArrayList<>();

                        // 存储税率信息（从"被共享"发票中获取）
                        BigDecimal sharedTaxRate = BigDecimal.ZERO;
                        String sharedKind = "";
                        boolean hasSharedInvoice = false; // 标记是否存在"被共享"发票

                        // ========== 第一遍遍历：收集数据并查找"被共享"发票 ==========
                        for (Map row : tableRows) {
                            List<Map> rowValues = (List<Map>) row.get("rowValue");

                            String hasInvoice = null;
                            String cdbm = null;
                            String lbmx = null;
                            String bz = null;
                            BigDecimal detailje = null;
                            List<Map> attachmentList = null;

                            for (Map rowItem : rowValues) {
                                String key = String.valueOf(rowItem.get("key"));
                                if ("DDSelectField_20ZGDOIRHB400".equals(key)) {
                                    Object value = rowItem.get("value");
                                    hasInvoice = value != null ? String.valueOf(value) : "";
                                }
                                if ("DDSelectField_BVQPDAKTMO74".equals(key)) {
                                    Object value = rowItem.get("value");
                                    lbmx = value != null ? String.valueOf(value) : "";
                                }
                                if ("TextareaField_MO34ZZVGJHC".equals(key)) {
                                    Object value = rowItem.get("value");
                                    bz = value != null ? String.valueOf(value) : "";
                                }
                                if ("DepartmentField_1VQ3M98PC7SW0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    cdbm = value != null ? String.valueOf(value) : "";
                                }

                                if ("NumberField_BLX4BRW8GEW0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof BigDecimal) {
                                        detailje = (BigDecimal) value;
                                    } else if (value != null) {
                                        try {
                                            detailje = new BigDecimal(String.valueOf(value));
                                        } catch (NumberFormatException e) {
                                            log.error("金额格式转换失败: {}", value);
                                            detailje = BigDecimal.ZERO;
                                        }
                                    } else {
                                        detailje = BigDecimal.ZERO;
                                    }
                                }
                                if ("DDAttachment_1YQ3DD7BH4BK0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof List) {
                                        attachmentList = (List<Map>) value;
                                    }
                                }
                            }

                            // ========== 处理 hasInvoice = "否" 的情况（无发票） ==========
                            if ("否".equals(hasInvoice)) {
                                // 保存基础报销记录（无发票）
                                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                                baseInvoice.setOaId(processInstanceId);
                                baseInvoice.setOaStatus("0");
                                baseInvoice.setInvoiceStatus("0");
                                baseInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                baseInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                baseInvoice.setDetailAmount(detailje != null ? detailje : BigDecimal.ZERO);
                                baseInvoice.setCreatedAt(LocalDateTime.now());
                                baseInvoice.setUpdatedAt(LocalDateTime.now());
                                baseInvoice.setInvoiceCode("");
                                baseInvoice.setInvoiceNumber("");
                                baseInvoice.setInvoiceType("");
                                baseInvoice.setAmount(null);
                                baseInvoice.setTaxAmount(null);
                                baseInvoice.setTotalAmount(null);
                                baseInvoice.setBuyerName("");
                                baseInvoice.setBuyerTaxId("");
                                baseInvoice.setSellerName("");
                                baseInvoice.setSellerTaxId("");
                                baseInvoice.setFormName("付款申请");
                                baseInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                baseInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                baseInvoice.setBankName(yhqc != null ? yhqc : "");
                                baseInvoice.setHasInvoice("否");
                                baseInvoice.setSharedTaxAmount(null);
                                baseInvoice.setSharedAmount(null);
                                baseInvoice.setSharedRate(null);
                                baseInvoice.setNote(bz != null ? bz : "");
                                noInvoiceList.add(baseInvoice);
                                log.info("收集无发票记录: 成本部门={}, 费用明细={}", cdbm, lbmx);
                                continue;
                            }

                            // ========== 处理 hasInvoice = "被共享"（被共享发票，提供税率） ==========
                            if ("被共享".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                // 标记存在被共享发票
                                hasSharedInvoice = true;

                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        // 解析发票数据
                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                // ========== 获取税率（供共享发票使用） ==========
                                                Object taxRateObj = invoice.get("taxRate");
                                                Object kind = invoice.getString("kindName");

                                                if (taxRateObj != null) {
                                                    String taxRateStr = String.valueOf(taxRateObj);
                                                    String taxRateNum = taxRateStr.replace("%", "").trim();
                                                    sharedKind = kind != null ? String.valueOf(kind) : "";
                                                    sharedTaxRate = new BigDecimal(taxRateNum);
                                                    sharedTaxRate = sharedTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP);
                                                    log.info("从被共享发票获取税率: 原始={}, 转换后={}", taxRateStr, sharedTaxRate);
                                                }

                                                // 保存解析的数据供后续使用
                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // ========== 校验1：抬头校验 ==========
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // ========== 校验2：发票号重复校验 ==========
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("被共享发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "被共享发票解析失败: " + e.getMessage());
                                        return McR.error("400", "被共享发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "是"（有发票，但不共享） ==========
                            if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // 抬头校验
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // 发票号重复校验
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "发票解析失败: " + e.getMessage());
                                        return McR.error("400", "发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "共享"（共享发票，需要从被共享发票获取税率） ==========

                            if ("共享".equals(hasInvoice)) {
                                if (detailje != null && detailje.compareTo(BigDecimal.ZERO) > 0) {
                                    Map<String, Object> sharedData = new HashMap<>();
                                    sharedData.put("detailje", detailje);
                                    sharedData.put("lbmx", lbmx);
                                    sharedData.put("bz", bz);
                                    sharedData.put("cdbm", cdbm);
                                    sharedData.put("hasInvoice", hasInvoice);
                                    sharedInvoiceDataList.add(sharedData);
                                    log.info("收集共享发票数据: 金额={}, 成本部门={}", detailje, cdbm);
                                }
                            }
                        }

                        // ========== 检查：如果存在共享发票但没有被共享发票 ==========
                        if (!sharedInvoiceDataList.isEmpty() && !hasSharedInvoice) {
                            String errorMsg = "存在'共享'发票，但未找到'被共享'发票，无法获取税率信息，请确保至少有一行选择'被共享'并上传发票附件";
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        // ========== 抬头校验失败处理 ==========
                        if (!invalidBuyerTaxIds.isEmpty()) {
                            String errorMsg = "发票抬头有误，以下发票的购买方税号不在公司抬头库中:\n" + String.join("\n", invalidBuyerTaxIds);
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        BigDecimal totalAmount = BigDecimal.ZERO;

                        // ========== 第二遍遍历：保存发票数据 ==========
                        // 1. 保存有发票数据（"是"和"被共享"）
                        for (Map<String, Object> parsedData : parsedInvoiceDataList) {
                            JSONObject invoice = (JSONObject) parsedData.get("invoice");
                            Object responseData = parsedData.get("responseData");
                            String cdbm = (String) parsedData.get("cdbm");
                            String lbmx = (String) parsedData.get("lbmx");
                            String bz = (String) parsedData.get("bz");
                            String hasInvoice = (String) parsedData.get("hasInvoice");
                            Object detailjeObj = parsedData.get("detailje");
                            String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";

                            allResults.add(responseData);
                            BigDecimal amount = invoice.getBigDecimal("amount");
                            if (amount != null) {
                                totalAmount = totalAmount.add(amount);
                            }

                            InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                            invoiceLibrary.setOaId(processInstanceId);
                            invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                            invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                            invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                            String date = invoice.getString("date");
                            if (StringUtils.isNotBlank(date)) {
                                try {
                                    invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                } catch (Exception e) {
                                    log.warn("日期解析失败: {}", date);
                                }
                            }

                            invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                            invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                            invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                            invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                            invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                            invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                            invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                            invoiceLibrary.setOaStatus("0");
                            invoiceLibrary.setNote(bz != null ? bz : "");
                            invoiceLibrary.setFormName("付款申请");
                            invoiceLibrary.setPaySubject(fkzhxx != null ? fkzhxx : "");
                            invoiceLibrary.setPayAccount(fkzh != null ? fkzh : "");
                            invoiceLibrary.setBankName(yhqc != null ? yhqc : "");
                            invoiceLibrary.setInvoiceStatus("0");
                            invoiceLibrary.setHasInvoice(hasInvoice);

                            if (StringUtils.isNotBlank(detailje)) {
                                try {
                                    invoiceLibrary.setDetailAmount(new BigDecimal(detailje));
                                } catch (NumberFormatException e) {
                                    log.error("detailJe格式转换失败: {}", detailje);
                                    invoiceLibrary.setDetailAmount(null);
                                }
                            } else {
                                invoiceLibrary.setDetailAmount(null);
                            }

                            invoiceLibrary.setSharedTaxAmount(null);
                            invoiceLibrary.setSharedAmount(null);
                            invoiceLibrary.setSharedRate(null);
                            invoiceLibrary.setAccountTitle(lbmx != null ? lbmx : "");
                            invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                            invoiceLibrary.setCreatedAt(LocalDateTime.now());
                            invoiceLibrary.setUpdatedAt(LocalDateTime.now());

                            if (cdbm != null && StringUtils.isNotBlank(cdbm)) {
                                invoiceLibrary.setDep(cdbm);
                            } else {
                                invoiceLibrary.setDep(bm != null ? bm : "");
                            }

                            invoiceList.add(invoiceLibrary);
                        }

                        // 2. 保存共享发票数据（使用从"被共享"发票获取的税率）
                        if (!sharedInvoiceDataList.isEmpty()) {
                            // 检查税率是否有效
                            if (sharedTaxRate.compareTo(BigDecimal.ZERO) == 0) {
                                log.warn("共享发票税率未获取到，使用默认税率0");
                            }

                            for (Map<String, Object> sharedData : sharedInvoiceDataList) {
                                Object detailjeObj = sharedData.get("detailje");
                                String cdbm = (String) sharedData.get("cdbm");
                                String lbmx = (String) sharedData.get("lbmx");
                                String bz = (String) sharedData.get("bz");
                                String hasInvoice = (String) sharedData.get("hasInvoice");
                                String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";
                                try {
                                    BigDecimal detailAmount = new BigDecimal(detailje);

                                    // 使用从"被共享"发票解析到的税率
                                    BigDecimal ocrTaxRate = sharedTaxRate;

                                    // 计算金额: 含税金额 / (1 + 税率) = 不含税金额
                                    BigDecimal divisor = BigDecimal.ONE.add(ocrTaxRate);
                                    BigDecimal sharedTaxAmount = detailAmount.divide(divisor, 2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal sharedAmount = detailAmount.subtract(sharedTaxAmount);
                                    BigDecimal sharedRate = ocrTaxRate;

                                    log.info("共享发票计算: 含税金额={}, 税率={}%, 不含税金额={}, 税额={}",
                                            detailAmount, ocrTaxRate.multiply(new BigDecimal("100")),
                                            sharedAmount, sharedTaxAmount);

                                    InvoiceLibrary sharedInvoice = new InvoiceLibrary();
                                    sharedInvoice.setOaId(processInstanceId);
                                    sharedInvoice.setOaStatus("0");
                                    sharedInvoice.setInvoiceStatus("0");
                                    sharedInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                    sharedInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                    sharedInvoice.setNote(bz != null ? bz : "");
                                    sharedInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                    sharedInvoice.setAmount(null);
                                    sharedInvoice.setTaxAmount(null);
                                    sharedInvoice.setTotalAmount(null);
                                    sharedInvoice.setFormName("付款申请");
                                    sharedInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                    sharedInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                    sharedInvoice.setBankName(yhqc != null ? yhqc : "");
                                    sharedInvoice.setHasInvoice(hasInvoice);
                                    sharedInvoice.setDetailAmount(detailAmount);
                                    sharedInvoice.setSharedTaxAmount(sharedAmount);
                                    sharedInvoice.setSharedAmount(sharedTaxAmount);
                                    sharedInvoice.setSharedRate(String.valueOf(sharedRate));
                                    sharedInvoice.setCreatedAt(LocalDateTime.now());
                                    sharedInvoice.setUpdatedAt(LocalDateTime.now());
                                    sharedInvoice.setInvoiceCode("");
                                    sharedInvoice.setInvoiceNumber("");
                                    sharedInvoice.setInvoiceType(sharedKind);
                                    sharedInvoice.setBuyerName("");
                                    sharedInvoice.setBuyerTaxId("");
                                    sharedInvoice.setSellerName("");
                                    sharedInvoice.setSellerTaxId("");
                                    invoiceList.add(sharedInvoice);
                                    log.info("成功保存共享发票记录，成本部门: {}", cdbm);

                                } catch (NumberFormatException e) {
                                    log.error("共享发票金额格式转换失败: detailje={}", detailje, e);
                                } catch (Exception e) {
                                    log.error("共享发票处理失败", e);
                                }
                            }
                        }

                        // 保存所有记录（无发票 + 有发票）
                        if (!noInvoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : noInvoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条无发票记录", noInvoiceList.size());
                            addWorkflowComment(processInstanceId, userId, "报销总金额：" + mainJe);
                        }

                        if (!invoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : invoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条发票记录（有发票: {}, 共享发票: {}）",
                                    invoiceList.size(),
                                    parsedInvoiceDataList.stream().filter(d -> "是".equals(d.get("hasInvoice")) || "被共享".equals(d.get("hasInvoice"))).count(),
                                    sharedInvoiceDataList.size());
                            addWorkflowComment1(processInstanceId, userId, totalAmount);
                        }

                        if (!allResults.isEmpty()) {
                            return McR.success(allResults);
                        } else {
                            return McR.success();
                        }

                    } catch (Exception e) {
                        log.error("解析子表数据失败", e);
                        return McR.error("300", "解析数据失败: " + e.getMessage());
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }
    @Override
    public McR invoiceLibrary2(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String bm = null;
            String bxlb = null;
            String fkzhxx = null;
            String fkzh = null;
            String yhqc = null;
            BigDecimal mainJe = null;

            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("MoneyField_1V4A9P72K6TC0".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                if ("DDSelectField_YLLB7AD1ATS0".equals(id)) {
                    bxlb = value != null ? String.valueOf(value) : "";
                }
                if ("DepartmentField_ZI9KALEYOTC0".equals(id)) {
                    bm = value != null ? String.valueOf(value) : "";
                }
                if ("DDSelectField_1WEX2WWCJ3PC0".equals(id)) {
                    fkzhxx = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_2W39FPCZH1A0".equals(id)) {
                    fkzh = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_QW7HJIR7T800".equals(id)) {
                    yhqc = value != null ? String.valueOf(value) : "";
                }

            }

            // 遍历子表数据
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));

                if ("TableField_182UNZEX02U80".equals(id)) {
                    String tableFieldValue = String.valueOf(formComponentValue.get("value"));
                    log.info("子表数据: {}", tableFieldValue);

                    try {
                        List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
                        if (tableRows == null || tableRows.isEmpty()) {
                            log.warn("子表数据为空");
                            return McR.error("400", "发票明细为空");
                        }

                        // 用于存储无发票记录和发票记录
                        List<InvoiceLibrary> noInvoiceList = new ArrayList<>();
                        List<InvoiceLibrary> invoiceList = new ArrayList<>();
                        List<Object> allResults = new ArrayList<>();

                        // 存储有发票（"是"和"被共享"）的解析数据
                        List<Map<String, Object>> parsedInvoiceDataList = new ArrayList<>();
                        // 存储共享发票数据
                        List<Map<String, Object>> sharedInvoiceDataList = new ArrayList<>();
                        // 用于校验的集合
                        List<String> invoiceNumberList = new ArrayList<>();
                        Map<String, String> invoiceNumberToFileName = new HashMap<>();
                        List<String> invalidBuyerTaxIds = new ArrayList<>();

                        // 存储税率信息（从"被共享"发票中获取）
                        BigDecimal sharedTaxRate = BigDecimal.ZERO;
                        String sharedKind = "";
                        boolean hasSharedInvoice = false; // 标记是否存在"被共享"发票

                        // ========== 第一遍遍历：收集数据并查找"被共享"发票 ==========
                        for (Map row : tableRows) {
                            List<Map> rowValues = (List<Map>) row.get("rowValue");

                            String hasInvoice = null;
                            String cdbm = null;
                            String lbmx = null;
                            String bz = null;
                            BigDecimal detailje = null;
                            List<Map> attachmentList = null;

                            for (Map rowItem : rowValues) {
                                String key = String.valueOf(rowItem.get("key"));
                                if ("DDSelectField_44I0SP6M1I00".equals(key)) {
                                    Object value = rowItem.get("value");
                                    hasInvoice = value != null ? String.valueOf(value) : "";
                                }
                                if ("DDSelectField_20HL7OBLLB4W0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    lbmx = value != null ? String.valueOf(value) : "";
                                }
                                if ("TextField_1YUNETYYW9XC0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    bz = value != null ? String.valueOf(value) : "";
                                }
                                if ("DepartmentField_RC2YZRJQAQ80".equals(key)) {
                                    Object value = rowItem.get("value");
                                    cdbm = value != null ? String.valueOf(value) : "";
                                }

                                if ("NumberField_1UC3HZ8OEIPS0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof BigDecimal) {
                                        detailje = (BigDecimal) value;
                                    } else if (value != null) {
                                        try {
                                            detailje = new BigDecimal(String.valueOf(value));
                                        } catch (NumberFormatException e) {
                                            log.error("金额格式转换失败: {}", value);
                                            detailje = BigDecimal.ZERO;
                                        }
                                    } else {
                                        detailje = BigDecimal.ZERO;
                                    }
                                }
                                if ("DDAttachment_LEUWYIC68TC0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof List) {
                                        attachmentList = (List<Map>) value;
                                    }
                                }
                            }

                            // ========== 处理 hasInvoice = "否" 的情况（无发票） ==========
                            if ("否".equals(hasInvoice)) {
                                // 保存基础报销记录（无发票）
                                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                                baseInvoice.setOaId(processInstanceId);
                                baseInvoice.setOaStatus("0");
                                baseInvoice.setInvoiceStatus("0");
                                baseInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                baseInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                baseInvoice.setDetailAmount(detailje != null ? detailje : BigDecimal.ZERO);
                                baseInvoice.setCreatedAt(LocalDateTime.now());
                                baseInvoice.setUpdatedAt(LocalDateTime.now());
                                baseInvoice.setInvoiceCode("");
                                baseInvoice.setInvoiceNumber("");
                                baseInvoice.setInvoiceType("");
                                baseInvoice.setAmount(null);
                                baseInvoice.setTaxAmount(null);
                                baseInvoice.setTotalAmount(null);
                                baseInvoice.setBuyerName("");
                                baseInvoice.setBuyerTaxId("");
                                baseInvoice.setSellerName("");
                                baseInvoice.setSellerTaxId("");
                                baseInvoice.setFormName("合作商付款申请");
                                baseInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                baseInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                baseInvoice.setBankName(yhqc != null ? yhqc : "");
                                baseInvoice.setHasInvoice("否");
                                baseInvoice.setSharedTaxAmount(null);
                                baseInvoice.setSharedAmount(null);
                                baseInvoice.setSharedRate(null);
                                baseInvoice.setNote(bz != null ? bz : "");
                                noInvoiceList.add(baseInvoice);
                                log.info("收集无发票记录: 成本部门={}, 费用明细={}", cdbm, lbmx);
                                continue;
                            }

                            // ========== 处理 hasInvoice = "被共享"（被共享发票，提供税率） ==========
                            if ("被共享".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                // 标记存在被共享发票
                                hasSharedInvoice = true;

                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        // 解析发票数据
                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                // ========== 获取税率（供共享发票使用） ==========
                                                Object taxRateObj = invoice.get("taxRate");
                                                Object kind = invoice.getString("kindName");

                                                if (taxRateObj != null) {
                                                    String taxRateStr = String.valueOf(taxRateObj);
                                                    String taxRateNum = taxRateStr.replace("%", "").trim();
                                                    sharedKind = kind != null ? String.valueOf(kind) : "";
                                                    sharedTaxRate = new BigDecimal(taxRateNum);
                                                    sharedTaxRate = sharedTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP);
                                                    log.info("从被共享发票获取税率: 原始={}, 转换后={}", taxRateStr, sharedTaxRate);
                                                }

                                                // 保存解析的数据供后续使用
                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // ========== 校验1：抬头校验 ==========
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // ========== 校验2：发票号重复校验 ==========
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("被共享发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "被共享发票解析失败: " + e.getMessage());
                                        return McR.error("400", "被共享发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "是"（有发票，但不共享） ==========
                            if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // 抬头校验
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // 发票号重复校验
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "发票解析失败: " + e.getMessage());
                                        return McR.error("400", "发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "共享"（共享发票，需要从被共享发票获取税率） ==========

                            if ("共享".equals(hasInvoice)) {
                                if (detailje != null && detailje.compareTo(BigDecimal.ZERO) > 0) {
                                    Map<String, Object> sharedData = new HashMap<>();
                                    sharedData.put("detailje", detailje);
                                    sharedData.put("lbmx", lbmx);
                                    sharedData.put("bz", bz);
                                    sharedData.put("cdbm", cdbm);
                                    sharedData.put("hasInvoice", hasInvoice);
                                    sharedInvoiceDataList.add(sharedData);
                                    log.info("收集共享发票数据: 金额={}, 成本部门={}", detailje, cdbm);
                                }
                            }
                        }

                        // ========== 检查：如果存在共享发票但没有被共享发票 ==========
                        if (!sharedInvoiceDataList.isEmpty() && !hasSharedInvoice) {
                            String errorMsg = "存在'共享'发票，但未找到'被共享'发票，无法获取税率信息，请确保至少有一行选择'被共享'并上传发票附件";
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        // ========== 抬头校验失败处理 ==========
                        if (!invalidBuyerTaxIds.isEmpty()) {
                            String errorMsg = "发票抬头有误，以下发票的购买方税号不在公司抬头库中:\n" + String.join("\n", invalidBuyerTaxIds);
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        BigDecimal totalAmount = BigDecimal.ZERO;

                        // ========== 第二遍遍历：保存发票数据 ==========
                        // 1. 保存有发票数据（"是"和"被共享"）
                        for (Map<String, Object> parsedData : parsedInvoiceDataList) {
                            JSONObject invoice = (JSONObject) parsedData.get("invoice");
                            Object responseData = parsedData.get("responseData");
                            String cdbm = (String) parsedData.get("cdbm");
                            String lbmx = (String) parsedData.get("lbmx");
                            String bz = (String) parsedData.get("bz");
                            String hasInvoice = (String) parsedData.get("hasInvoice");
                            Object detailjeObj = parsedData.get("detailje");
                            String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";

                            allResults.add(responseData);
                            BigDecimal amount = invoice.getBigDecimal("amount");
                            if (amount != null) {
                                totalAmount = totalAmount.add(amount);
                            }

                            InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                            invoiceLibrary.setOaId(processInstanceId);
                            invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                            invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                            invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                            String date = invoice.getString("date");
                            if (StringUtils.isNotBlank(date)) {
                                try {
                                    invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                } catch (Exception e) {
                                    log.warn("日期解析失败: {}", date);
                                }
                            }

                            invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                            invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                            invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                            invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                            invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                            invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                            invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                            invoiceLibrary.setOaStatus("0");
                            invoiceLibrary.setNote(bz != null ? bz : "");
                            invoiceLibrary.setFormName("合作商付款申请");
                            invoiceLibrary.setPaySubject(fkzhxx != null ? fkzhxx : "");
                            invoiceLibrary.setPayAccount(fkzh != null ? fkzh : "");
                            invoiceLibrary.setBankName(yhqc != null ? yhqc : "");
                            invoiceLibrary.setInvoiceStatus("0");
                            invoiceLibrary.setHasInvoice(hasInvoice);

                            if (StringUtils.isNotBlank(detailje)) {
                                try {
                                    invoiceLibrary.setDetailAmount(new BigDecimal(detailje));
                                } catch (NumberFormatException e) {
                                    log.error("detailJe格式转换失败: {}", detailje);
                                    invoiceLibrary.setDetailAmount(null);
                                }
                            } else {
                                invoiceLibrary.setDetailAmount(null);
                            }

                            invoiceLibrary.setSharedTaxAmount(null);
                            invoiceLibrary.setSharedAmount(null);
                            invoiceLibrary.setSharedRate(null);
                            invoiceLibrary.setAccountTitle(lbmx != null ? lbmx : "");
                            invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                            invoiceLibrary.setCreatedAt(LocalDateTime.now());
                            invoiceLibrary.setUpdatedAt(LocalDateTime.now());

                            if (cdbm != null && StringUtils.isNotBlank(cdbm)) {
                                invoiceLibrary.setDep(cdbm);
                            } else {
                                invoiceLibrary.setDep(bm != null ? bm : "");
                            }

                            invoiceList.add(invoiceLibrary);
                        }

                        // 2. 保存共享发票数据（使用从"被共享"发票获取的税率）
                        if (!sharedInvoiceDataList.isEmpty()) {
                            // 检查税率是否有效
                            if (sharedTaxRate.compareTo(BigDecimal.ZERO) == 0) {
                                log.warn("共享发票税率未获取到，使用默认税率0");
                            }

                            for (Map<String, Object> sharedData : sharedInvoiceDataList) {
                                Object detailjeObj = sharedData.get("detailje");
                                String cdbm = (String) sharedData.get("cdbm");
                                String lbmx = (String) sharedData.get("lbmx");
                                String bz = (String) sharedData.get("bz");
                                String hasInvoice = (String) sharedData.get("hasInvoice");
                                String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";
                                try {
                                    BigDecimal detailAmount = new BigDecimal(detailje);

                                    // 使用从"被共享"发票解析到的税率
                                    BigDecimal ocrTaxRate = sharedTaxRate;

                                    // 计算金额: 含税金额 / (1 + 税率) = 不含税金额
                                    BigDecimal divisor = BigDecimal.ONE.add(ocrTaxRate);
                                    BigDecimal sharedTaxAmount = detailAmount.divide(divisor, 2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal sharedAmount = detailAmount.subtract(sharedTaxAmount);
                                    BigDecimal sharedRate = ocrTaxRate;

                                    log.info("共享发票计算: 含税金额={}, 税率={}%, 不含税金额={}, 税额={}",
                                            detailAmount, ocrTaxRate.multiply(new BigDecimal("100")),
                                            sharedAmount, sharedTaxAmount);

                                    InvoiceLibrary sharedInvoice = new InvoiceLibrary();
                                    sharedInvoice.setOaId(processInstanceId);
                                    sharedInvoice.setOaStatus("0");
                                    sharedInvoice.setInvoiceStatus("0");
                                    sharedInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                    sharedInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                    sharedInvoice.setNote(bz != null ? bz : "");
                                    sharedInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                    sharedInvoice.setAmount(null);
                                    sharedInvoice.setTaxAmount(null);
                                    sharedInvoice.setTotalAmount(null);
                                    sharedInvoice.setFormName("合作商付款申请");
                                    sharedInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                    sharedInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                    sharedInvoice.setBankName(yhqc != null ? yhqc : "");
                                    sharedInvoice.setHasInvoice(hasInvoice);
                                    sharedInvoice.setDetailAmount(detailAmount);
                                    sharedInvoice.setSharedTaxAmount(sharedAmount);
                                    sharedInvoice.setSharedAmount(sharedTaxAmount);
                                    sharedInvoice.setSharedRate(String.valueOf(sharedRate));
                                    sharedInvoice.setCreatedAt(LocalDateTime.now());
                                    sharedInvoice.setUpdatedAt(LocalDateTime.now());
                                    sharedInvoice.setInvoiceCode("");
                                    sharedInvoice.setInvoiceNumber("");
                                    sharedInvoice.setInvoiceType(sharedKind);
                                    sharedInvoice.setBuyerName("");
                                    sharedInvoice.setBuyerTaxId("");
                                    sharedInvoice.setSellerName("");
                                    sharedInvoice.setSellerTaxId("");
                                    invoiceList.add(sharedInvoice);
                                    log.info("成功保存共享发票记录，成本部门: {}", cdbm);

                                } catch (NumberFormatException e) {
                                    log.error("共享发票金额格式转换失败: detailje={}", detailje, e);
                                } catch (Exception e) {
                                    log.error("共享发票处理失败", e);
                                }
                            }
                        }

                        // 保存所有记录（无发票 + 有发票）
                        if (!noInvoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : noInvoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条无发票记录", noInvoiceList.size());
                            addWorkflowComment(processInstanceId, userId, "报销总金额：" + mainJe);
                        }

                        if (!invoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : invoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条发票记录（有发票: {}, 共享发票: {}）",
                                    invoiceList.size(),
                                    parsedInvoiceDataList.stream().filter(d -> "是".equals(d.get("hasInvoice")) || "被共享".equals(d.get("hasInvoice"))).count(),
                                    sharedInvoiceDataList.size());
                            addWorkflowComment1(processInstanceId, userId, totalAmount);
                        }

                        if (!allResults.isEmpty()) {
                            return McR.success(allResults);
                        } else {
                            return McR.success();
                        }

                    } catch (Exception e) {
                        log.error("解析子表数据失败", e);
                        return McR.error("300", "解析数据失败: " + e.getMessage());
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }
    @Override
    public McR invoiceLibrary3(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String bm = null;
            String bxlb = null;
            String fkzhxx = null;
            String fkzh = null;
            String yhqc = null;
            BigDecimal mainJe = null;

            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("MoneyField_5U5SLLA3CS40".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                if ("DDSelectField_BS1HCMO7YTK0".equals(id)) {
                    bxlb = value != null ? String.valueOf(value) : "";
                }
                if ("DepartmentField_S9DH58V8SNK0".equals(id)) {
                    bm = value != null ? String.valueOf(value) : "";
                }
                if ("DDSelectField_GLW8YHBHSLS0".equals(id)) {
                    fkzhxx = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_1PR1HQ4H28SG0".equals(id)) {
                    fkzh = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_1UPR1XZTI3VK".equals(id)) {
                    yhqc = value != null ? String.valueOf(value) : "";
                }

            }

            // 遍历子表数据
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));

                if ("TableField_9LJ65U3CQ980".equals(id)) {
                    String tableFieldValue = String.valueOf(formComponentValue.get("value"));
                    log.info("子表数据: {}", tableFieldValue);

                    try {
                        List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
                        if (tableRows == null || tableRows.isEmpty()) {
                            log.warn("子表数据为空");
                            return McR.error("400", "发票明细为空");
                        }

                        // 用于存储无发票记录和发票记录
                        List<InvoiceLibrary> noInvoiceList = new ArrayList<>();
                        List<InvoiceLibrary> invoiceList = new ArrayList<>();
                        List<Object> allResults = new ArrayList<>();

                        // 存储有发票（"是"和"被共享"）的解析数据
                        List<Map<String, Object>> parsedInvoiceDataList = new ArrayList<>();
                        // 存储共享发票数据
                        List<Map<String, Object>> sharedInvoiceDataList = new ArrayList<>();
                        // 用于校验的集合
                        List<String> invoiceNumberList = new ArrayList<>();
                        Map<String, String> invoiceNumberToFileName = new HashMap<>();
                        List<String> invalidBuyerTaxIds = new ArrayList<>();

                        // 存储税率信息（从"被共享"发票中获取）
                        BigDecimal sharedTaxRate = BigDecimal.ZERO;
                        String sharedKind = "";
                        boolean hasSharedInvoice = false; // 标记是否存在"被共享"发票

                        // ========== 第一遍遍历：收集数据并查找"被共享"发票 ==========
                        for (Map row : tableRows) {
                            List<Map> rowValues = (List<Map>) row.get("rowValue");

                            String hasInvoice = null;
                            String cdbm = null;
                            String lbmx = null;
                            String bz = null;
                            BigDecimal detailje = null;
                            List<Map> attachmentList = null;

                            for (Map rowItem : rowValues) {
                                String key = String.valueOf(rowItem.get("key"));
                                if ("DDSelectField_TTTOAI0FDXJ4".equals(key)) {
                                    Object value = rowItem.get("value");
                                    hasInvoice = value != null ? String.valueOf(value) : "";
                                }
                                if ("DDSelectField_17FH3ES8HWHS0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    lbmx = value != null ? String.valueOf(value) : "";
                                }
                                if ("TextareaField_1XIFOSSQO5A80".equals(key)) {
                                    Object value = rowItem.get("value");
                                    bz = value != null ? String.valueOf(value) : "";
                                }
                                if ("DepartmentField_15QGD1PV69XC0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    cdbm = value != null ? String.valueOf(value) : "";
                                }

                                if ("NumberField_FYHZK218TTDS".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof BigDecimal) {
                                        detailje = (BigDecimal) value;
                                    } else if (value != null) {
                                        try {
                                            detailje = new BigDecimal(String.valueOf(value));
                                        } catch (NumberFormatException e) {
                                            log.error("金额格式转换失败: {}", value);
                                            detailje = BigDecimal.ZERO;
                                        }
                                    } else {
                                        detailje = BigDecimal.ZERO;
                                    }
                                }
                                if ("DDAttachment_XVU9V89QOEM8".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof List) {
                                        attachmentList = (List<Map>) value;
                                    }
                                }
                            }

                            // ========== 处理 hasInvoice = "否" 的情况（无发票） ==========
                            if ("否".equals(hasInvoice)) {
                                // 保存基础报销记录（无发票）
                                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                                baseInvoice.setOaId(processInstanceId);
                                baseInvoice.setOaStatus("0");
                                baseInvoice.setInvoiceStatus("0");
                                baseInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                baseInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                baseInvoice.setDetailAmount(detailje != null ? detailje : BigDecimal.ZERO);
                                baseInvoice.setCreatedAt(LocalDateTime.now());
                                baseInvoice.setUpdatedAt(LocalDateTime.now());
                                baseInvoice.setInvoiceCode("");
                                baseInvoice.setInvoiceNumber("");
                                baseInvoice.setInvoiceType("");
                                baseInvoice.setAmount(null);
                                baseInvoice.setTaxAmount(null);
                                baseInvoice.setTotalAmount(null);
                                baseInvoice.setBuyerName("");
                                baseInvoice.setBuyerTaxId("");
                                baseInvoice.setSellerName("");
                                baseInvoice.setSellerTaxId("");
                                baseInvoice.setFormName("合作商报销申请");
                                baseInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                baseInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                baseInvoice.setBankName(yhqc != null ? yhqc : "");
                                baseInvoice.setHasInvoice("否");
                                baseInvoice.setSharedTaxAmount(null);
                                baseInvoice.setSharedAmount(null);
                                baseInvoice.setSharedRate(null);
                                baseInvoice.setNote(bz != null ? bz : "");
                                noInvoiceList.add(baseInvoice);
                                log.info("收集无发票记录: 成本部门={}, 费用明细={}", cdbm, lbmx);
                                continue;
                            }

                            // ========== 处理 hasInvoice = "被共享"（被共享发票，提供税率） ==========
                            if ("被共享".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                // 标记存在被共享发票
                                hasSharedInvoice = true;

                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        // 解析发票数据
                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                // ========== 获取税率（供共享发票使用） ==========
                                                Object taxRateObj = invoice.get("taxRate");
                                                Object kind = invoice.getString("kindName");

                                                if (taxRateObj != null) {
                                                    String taxRateStr = String.valueOf(taxRateObj);
                                                    String taxRateNum = taxRateStr.replace("%", "").trim();
                                                    sharedKind = kind != null ? String.valueOf(kind) : "";
                                                    sharedTaxRate = new BigDecimal(taxRateNum);
                                                    sharedTaxRate = sharedTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP);
                                                    log.info("从被共享发票获取税率: 原始={}, 转换后={}", taxRateStr, sharedTaxRate);
                                                }

                                                // 保存解析的数据供后续使用
                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // ========== 校验1：抬头校验 ==========
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // ========== 校验2：发票号重复校验 ==========
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("被共享发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "被共享发票解析失败: " + e.getMessage());
                                        return McR.error("400", "被共享发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "是"（有发票，但不共享） ==========
                            if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // 抬头校验
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // 发票号重复校验
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "发票解析失败: " + e.getMessage());
                                        return McR.error("400", "发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "共享"（共享发票，需要从被共享发票获取税率） ==========

                            if ("共享".equals(hasInvoice)) {
                                if (detailje != null && detailje.compareTo(BigDecimal.ZERO) > 0) {
                                    Map<String, Object> sharedData = new HashMap<>();
                                    sharedData.put("detailje", detailje);
                                    sharedData.put("lbmx", lbmx);
                                    sharedData.put("bz", bz);
                                    sharedData.put("cdbm", cdbm);
                                    sharedData.put("hasInvoice", hasInvoice);
                                    sharedInvoiceDataList.add(sharedData);
                                    log.info("收集共享发票数据: 金额={}, 成本部门={}", detailje, cdbm);
                                }
                            }
                        }

                        // ========== 检查：如果存在共享发票但没有被共享发票 ==========
                        if (!sharedInvoiceDataList.isEmpty() && !hasSharedInvoice) {
                            String errorMsg = "存在'共享'发票，但未找到'被共享'发票，无法获取税率信息，请确保至少有一行选择'被共享'并上传发票附件";
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        // ========== 抬头校验失败处理 ==========
                        if (!invalidBuyerTaxIds.isEmpty()) {
                            String errorMsg = "发票抬头有误，以下发票的购买方税号不在公司抬头库中:\n" + String.join("\n", invalidBuyerTaxIds);
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        BigDecimal totalAmount = BigDecimal.ZERO;

                        // ========== 第二遍遍历：保存发票数据 ==========
                        // 1. 保存有发票数据（"是"和"被共享"）
                        for (Map<String, Object> parsedData : parsedInvoiceDataList) {
                            JSONObject invoice = (JSONObject) parsedData.get("invoice");
                            Object responseData = parsedData.get("responseData");
                            String cdbm = (String) parsedData.get("cdbm");
                            String lbmx = (String) parsedData.get("lbmx");
                            String bz = (String) parsedData.get("bz");
                            String hasInvoice = (String) parsedData.get("hasInvoice");
                            Object detailjeObj = parsedData.get("detailje");
                            String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";

                            allResults.add(responseData);
                            BigDecimal amount = invoice.getBigDecimal("amount");
                            if (amount != null) {
                                totalAmount = totalAmount.add(amount);
                            }

                            InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                            invoiceLibrary.setOaId(processInstanceId);
                            invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                            invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                            invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                            String date = invoice.getString("date");
                            if (StringUtils.isNotBlank(date)) {
                                try {
                                    invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                } catch (Exception e) {
                                    log.warn("日期解析失败: {}", date);
                                }
                            }

                            invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                            invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                            invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                            invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                            invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                            invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                            invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                            invoiceLibrary.setOaStatus("0");
                            invoiceLibrary.setNote(bz != null ? bz : "");
                            invoiceLibrary.setFormName("合作商报销申请");
                            invoiceLibrary.setPaySubject(fkzhxx != null ? fkzhxx : "");
                            invoiceLibrary.setPayAccount(fkzh != null ? fkzh : "");
                            invoiceLibrary.setBankName(yhqc != null ? yhqc : "");
                            invoiceLibrary.setInvoiceStatus("0");
                            invoiceLibrary.setHasInvoice(hasInvoice);

                            if (StringUtils.isNotBlank(detailje)) {
                                try {
                                    invoiceLibrary.setDetailAmount(new BigDecimal(detailje));
                                } catch (NumberFormatException e) {
                                    log.error("detailJe格式转换失败: {}", detailje);
                                    invoiceLibrary.setDetailAmount(null);
                                }
                            } else {
                                invoiceLibrary.setDetailAmount(null);
                            }

                            invoiceLibrary.setSharedTaxAmount(null);
                            invoiceLibrary.setSharedAmount(null);
                            invoiceLibrary.setSharedRate(null);
                            invoiceLibrary.setAccountTitle(lbmx != null ? lbmx : "");
                            invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                            invoiceLibrary.setCreatedAt(LocalDateTime.now());
                            invoiceLibrary.setUpdatedAt(LocalDateTime.now());

                            if (cdbm != null && StringUtils.isNotBlank(cdbm)) {
                                invoiceLibrary.setDep(cdbm);
                            } else {
                                invoiceLibrary.setDep(bm != null ? bm : "");
                            }

                            invoiceList.add(invoiceLibrary);
                        }

                        // 2. 保存共享发票数据（使用从"被共享"发票获取的税率）
                        if (!sharedInvoiceDataList.isEmpty()) {
                            // 检查税率是否有效
                            if (sharedTaxRate.compareTo(BigDecimal.ZERO) == 0) {
                                log.warn("共享发票税率未获取到，使用默认税率0");
                            }

                            for (Map<String, Object> sharedData : sharedInvoiceDataList) {
                                Object detailjeObj = sharedData.get("detailje");
                                String cdbm = (String) sharedData.get("cdbm");
                                String lbmx = (String) sharedData.get("lbmx");
                                String bz = (String) sharedData.get("bz");
                                String hasInvoice = (String) sharedData.get("hasInvoice");
                                String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";
                                try {
                                    BigDecimal detailAmount = new BigDecimal(detailje);

                                    // 使用从"被共享"发票解析到的税率
                                    BigDecimal ocrTaxRate = sharedTaxRate;

                                    // 计算金额: 含税金额 / (1 + 税率) = 不含税金额
                                    BigDecimal divisor = BigDecimal.ONE.add(ocrTaxRate);
                                    BigDecimal sharedTaxAmount = detailAmount.divide(divisor, 2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal sharedAmount = detailAmount.subtract(sharedTaxAmount);
                                    BigDecimal sharedRate = ocrTaxRate;

                                    log.info("共享发票计算: 含税金额={}, 税率={}%, 不含税金额={}, 税额={}",
                                            detailAmount, ocrTaxRate.multiply(new BigDecimal("100")),
                                            sharedAmount, sharedTaxAmount);

                                    InvoiceLibrary sharedInvoice = new InvoiceLibrary();
                                    sharedInvoice.setOaId(processInstanceId);
                                    sharedInvoice.setOaStatus("0");
                                    sharedInvoice.setInvoiceStatus("0");
                                    sharedInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                    sharedInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                    sharedInvoice.setNote(bz != null ? bz : "");
                                    sharedInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                    sharedInvoice.setAmount(null);
                                    sharedInvoice.setTaxAmount(null);
                                    sharedInvoice.setTotalAmount(null);
                                    sharedInvoice.setFormName("合作商报销申请");
                                    sharedInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                    sharedInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                    sharedInvoice.setBankName(yhqc != null ? yhqc : "");
                                    sharedInvoice.setHasInvoice(hasInvoice);
                                    sharedInvoice.setDetailAmount(detailAmount);
                                    sharedInvoice.setSharedTaxAmount(sharedAmount);
                                    sharedInvoice.setSharedAmount(sharedTaxAmount);
                                    sharedInvoice.setSharedRate(String.valueOf(sharedRate));
                                    sharedInvoice.setCreatedAt(LocalDateTime.now());
                                    sharedInvoice.setUpdatedAt(LocalDateTime.now());
                                    sharedInvoice.setInvoiceCode("");
                                    sharedInvoice.setInvoiceNumber("");
                                    sharedInvoice.setInvoiceType(sharedKind);
                                    sharedInvoice.setBuyerName("");
                                    sharedInvoice.setBuyerTaxId("");
                                    sharedInvoice.setSellerName("");
                                    sharedInvoice.setSellerTaxId("");
                                    invoiceList.add(sharedInvoice);
                                    log.info("成功保存共享发票记录，成本部门: {}", cdbm);

                                } catch (NumberFormatException e) {
                                    log.error("共享发票金额格式转换失败: detailje={}", detailje, e);
                                } catch (Exception e) {
                                    log.error("共享发票处理失败", e);
                                }
                            }
                        }

                        // 保存所有记录（无发票 + 有发票）
                        if (!noInvoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : noInvoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条无发票记录", noInvoiceList.size());
                            addWorkflowComment(processInstanceId, userId, "报销总金额：" + mainJe);
                        }

                        if (!invoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : invoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条发票记录（有发票: {}, 共享发票: {}）",
                                    invoiceList.size(),
                                    parsedInvoiceDataList.stream().filter(d -> "是".equals(d.get("hasInvoice")) || "被共享".equals(d.get("hasInvoice"))).count(),
                                    sharedInvoiceDataList.size());
                            addWorkflowComment1(processInstanceId, userId, totalAmount);
                        }

                        if (!allResults.isEmpty()) {
                            return McR.success(allResults);
                        } else {
                            return McR.success();
                        }

                    } catch (Exception e) {
                        log.error("解析子表数据失败", e);
                        return McR.error("300", "解析数据失败: " + e.getMessage());
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }

    @Override
    public McR invoiceLibrary5(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String bm = null;
            String bxlb = null;
            String fkzhxx = null;
            String fkzh = null;
            String yhqc = null;
            BigDecimal mainJe = null;

            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("MoneyField_1435GRXGYPA80".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                if ("DDSelectField_1UX0JVU89Q000".equals(id)) {
                    bxlb = value != null ? String.valueOf(value) : "";
                }
                if ("DepartmentField_1BJT6UY9Y5B40".equals(id)) {
                    bm = value != null ? String.valueOf(value) : "";
                }
                if ("DDSelectField_1D77TV92WXEO0".equals(id)) {
                    fkzhxx = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_3CQPLF9BVBO0".equals(id)) {
                    fkzh = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_YSFYQQ305SG0".equals(id)) {
                    yhqc = value != null ? String.valueOf(value) : "";
                }

            }

            // 遍历子表数据
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));

                if ("TableField_169TONKJ3KW00".equals(id)) {
                    String tableFieldValue = String.valueOf(formComponentValue.get("value"));
                    log.info("子表数据: {}", tableFieldValue);

                    try {
                        List<Map> tableRows = (List<Map>) JSONObject.parse(tableFieldValue);
                        if (tableRows == null || tableRows.isEmpty()) {
                            log.warn("子表数据为空");
                            return McR.error("400", "发票明细为空");
                        }

                        // 用于存储无发票记录和发票记录
                        List<InvoiceLibrary> noInvoiceList = new ArrayList<>();
                        List<InvoiceLibrary> invoiceList = new ArrayList<>();
                        List<Object> allResults = new ArrayList<>();

                        // 存储有发票（"是"和"被共享"）的解析数据
                        List<Map<String, Object>> parsedInvoiceDataList = new ArrayList<>();
                        // 存储共享发票数据
                        List<Map<String, Object>> sharedInvoiceDataList = new ArrayList<>();
                        // 用于校验的集合
                        List<String> invoiceNumberList = new ArrayList<>();
                        Map<String, String> invoiceNumberToFileName = new HashMap<>();
                        List<String> invalidBuyerTaxIds = new ArrayList<>();

                        // 存储税率信息（从"被共享"发票中获取）
                        BigDecimal sharedTaxRate = BigDecimal.ZERO;
                        String sharedKind = "";
                        boolean hasSharedInvoice = false; // 标记是否存在"被共享"发票

                        // ========== 第一遍遍历：收集数据并查找"被共享"发票 ==========
                        for (Map row : tableRows) {
                            List<Map> rowValues = (List<Map>) row.get("rowValue");

                            String hasInvoice = null;
                            String cdbm = null;
                            String lbmx = null;
                            String bz = null;
                            BigDecimal detailje = null;
                            List<Map> attachmentList = null;

                            for (Map rowItem : rowValues) {
                                String key = String.valueOf(rowItem.get("key"));
                                if ("DDSelectField_1G6XMYA3FMCG0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    hasInvoice = value != null ? String.valueOf(value) : "";
                                }
                                if ("DDSelectField_17K1Q5M73YKG0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    lbmx = value != null ? String.valueOf(value) : "";
                                }
                                if ("TextareaField_207VNZ39WOCG0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    bz = value != null ? String.valueOf(value) : "";
                                }
                                if ("DepartmentField_KJIWTTZLE800".equals(key)) {
                                    Object value = rowItem.get("value");
                                    cdbm = value != null ? String.valueOf(value) : "";
                                }

                                if ("NumberField_L0ALER5S6180".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof BigDecimal) {
                                        detailje = (BigDecimal) value;
                                    } else if (value != null) {
                                        try {
                                            detailje = new BigDecimal(String.valueOf(value));
                                        } catch (NumberFormatException e) {
                                            log.error("金额格式转换失败: {}", value);
                                            detailje = BigDecimal.ZERO;
                                        }
                                    } else {
                                        detailje = BigDecimal.ZERO;
                                    }
                                }
                                if ("DDAttachment_EPL7ILUTD0G0".equals(key)) {
                                    Object value = rowItem.get("value");
                                    if (value instanceof List) {
                                        attachmentList = (List<Map>) value;
                                    }
                                }
                            }

                            // ========== 处理 hasInvoice = "否" 的情况（无发票） ==========
                            if ("否".equals(hasInvoice)) {
                                // 保存基础报销记录（无发票）
                                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                                baseInvoice.setOaId(processInstanceId);
                                baseInvoice.setOaStatus("0");
                                baseInvoice.setInvoiceStatus("0");
                                baseInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                baseInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                baseInvoice.setDetailAmount(detailje != null ? detailje : BigDecimal.ZERO);
                                baseInvoice.setCreatedAt(LocalDateTime.now());
                                baseInvoice.setUpdatedAt(LocalDateTime.now());
                                baseInvoice.setInvoiceCode("");
                                baseInvoice.setInvoiceNumber("");
                                baseInvoice.setInvoiceType("");
                                baseInvoice.setAmount(null);
                                baseInvoice.setTaxAmount(null);
                                baseInvoice.setTotalAmount(null);
                                baseInvoice.setBuyerName("");
                                baseInvoice.setBuyerTaxId("");
                                baseInvoice.setSellerName("");
                                baseInvoice.setSellerTaxId("");
                                baseInvoice.setFormName("出差费用报销");
                                baseInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                baseInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                baseInvoice.setBankName(yhqc != null ? yhqc : "");
                                baseInvoice.setHasInvoice("否");
                                baseInvoice.setSharedTaxAmount(null);
                                baseInvoice.setSharedAmount(null);
                                baseInvoice.setSharedRate(null);
                                baseInvoice.setNote(bz != null ? bz : "");
                                noInvoiceList.add(baseInvoice);
                                log.info("收集无发票记录: 成本部门={}, 费用明细={}", cdbm, lbmx);
                                continue;
                            }

                            // ========== 处理 hasInvoice = "被共享"（被共享发票，提供税率） ==========
                            if ("被共享".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                // 标记存在被共享发票
                                hasSharedInvoice = true;

                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        // 解析发票数据
                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                // ========== 获取税率（供共享发票使用） ==========
                                                Object taxRateObj = invoice.get("taxRate");
                                                Object kind = invoice.getString("kindName");

                                                if (taxRateObj != null) {
                                                    String taxRateStr = String.valueOf(taxRateObj);
                                                    String taxRateNum = taxRateStr.replace("%", "").trim();
                                                    sharedKind = kind != null ? String.valueOf(kind) : "";
                                                    sharedTaxRate = new BigDecimal(taxRateNum);
                                                    sharedTaxRate = sharedTaxRate.divide(new BigDecimal("100"), 10, BigDecimal.ROUND_HALF_UP);
                                                    log.info("从被共享发票获取税率: 原始={}, 转换后={}", taxRateStr, sharedTaxRate);
                                                }

                                                // 保存解析的数据供后续使用
                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // ========== 校验1：抬头校验 ==========
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // ========== 校验2：发票号重复校验 ==========
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("被共享发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "被共享发票解析失败: " + e.getMessage());
                                        return McR.error("400", "被共享发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "是"（有发票，但不共享） ==========
                            if ("是".equals(hasInvoice) && attachmentList != null && !attachmentList.isEmpty()) {
                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("bz", bz);
                                                parsedData.put("lbmx", lbmx);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("cdbm", cdbm);
                                                parsedData.put("hasInvoice", hasInvoice);
                                                parsedData.put("detailje", detailje);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // 抬头校验
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // 发票号重复校验
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    InvoiceLibrary existingInvoice = baseMapper.selectByInvoiceNumber(invoiceNumber);
                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            }
                                        }
                                    } catch (Exception e) {
                                        log.error("发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        terminateWorkflow(accessToken, processInstanceId, userId, "发票解析失败: " + e.getMessage());
                                        return McR.error("400", "发票解析失败: " + e.getMessage());
                                    }
                                }
                                continue;
                            }

                            // ========== 处理 hasInvoice = "共享"（共享发票，需要从被共享发票获取税率） ==========

                            if ("共享".equals(hasInvoice)) {
                                if (detailje != null && detailje.compareTo(BigDecimal.ZERO) > 0) {
                                    Map<String, Object> sharedData = new HashMap<>();
                                    sharedData.put("detailje", detailje);
                                    sharedData.put("lbmx", lbmx);
                                    sharedData.put("bz", bz);
                                    sharedData.put("cdbm", cdbm);
                                    sharedData.put("hasInvoice", hasInvoice);
                                    sharedInvoiceDataList.add(sharedData);
                                    log.info("收集共享发票数据: 金额={}, 成本部门={}", detailje, cdbm);
                                }
                            }
                        }

                        // ========== 检查：如果存在共享发票但没有被共享发票 ==========
                        if (!sharedInvoiceDataList.isEmpty() && !hasSharedInvoice) {
                            String errorMsg = "存在'共享'发票，但未找到'被共享'发票，无法获取税率信息，请确保至少有一行选择'被共享'并上传发票附件";
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        // ========== 抬头校验失败处理 ==========
                        if (!invalidBuyerTaxIds.isEmpty()) {
                            String errorMsg = "发票抬头有误，以下发票的购买方税号不在公司抬头库中:\n" + String.join("\n", invalidBuyerTaxIds);
                            log.error(errorMsg);
                            terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                            return McR.error("400", errorMsg);
                        }

                        BigDecimal totalAmount = BigDecimal.ZERO;

                        // ========== 第二遍遍历：保存发票数据 ==========
                        // 1. 保存有发票数据（"是"和"被共享"）
                        for (Map<String, Object> parsedData : parsedInvoiceDataList) {
                            JSONObject invoice = (JSONObject) parsedData.get("invoice");
                            Object responseData = parsedData.get("responseData");
                            String cdbm = (String) parsedData.get("cdbm");
                            String lbmx = (String) parsedData.get("lbmx");
                            String bz = (String) parsedData.get("bz");
                            String hasInvoice = (String) parsedData.get("hasInvoice");
                            Object detailjeObj = parsedData.get("detailje");
                            String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";

                            allResults.add(responseData);
                            BigDecimal amount = invoice.getBigDecimal("amount");
                            if (amount != null) {
                                totalAmount = totalAmount.add(amount);
                            }

                            InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                            invoiceLibrary.setOaId(processInstanceId);
                            invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                            invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                            invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                            String date = invoice.getString("date");
                            if (StringUtils.isNotBlank(date)) {
                                try {
                                    invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                } catch (Exception e) {
                                    log.warn("日期解析失败: {}", date);
                                }
                            }

                            invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                            invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                            invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                            invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                            invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                            invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                            invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                            invoiceLibrary.setOaStatus("0");
                            invoiceLibrary.setNote(bz != null ? bz : "");
                            invoiceLibrary.setFormName("出差费用报销");
                            invoiceLibrary.setPaySubject(fkzhxx != null ? fkzhxx : "");
                            invoiceLibrary.setPayAccount(fkzh != null ? fkzh : "");
                            invoiceLibrary.setBankName(yhqc != null ? yhqc : "");
                            invoiceLibrary.setInvoiceStatus("0");
                            invoiceLibrary.setHasInvoice(hasInvoice);

                            if (StringUtils.isNotBlank(detailje)) {
                                try {
                                    invoiceLibrary.setDetailAmount(new BigDecimal(detailje));
                                } catch (NumberFormatException e) {
                                    log.error("detailJe格式转换失败: {}", detailje);
                                    invoiceLibrary.setDetailAmount(null);
                                }
                            } else {
                                invoiceLibrary.setDetailAmount(null);
                            }

                            invoiceLibrary.setSharedTaxAmount(null);
                            invoiceLibrary.setSharedAmount(null);
                            invoiceLibrary.setSharedRate(null);
                            invoiceLibrary.setAccountTitle(lbmx != null ? lbmx : "");
                            invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                            invoiceLibrary.setCreatedAt(LocalDateTime.now());
                            invoiceLibrary.setUpdatedAt(LocalDateTime.now());

                            if (cdbm != null && StringUtils.isNotBlank(cdbm)) {
                                invoiceLibrary.setDep(cdbm);
                            } else {
                                invoiceLibrary.setDep(bm != null ? bm : "");
                            }

                            invoiceList.add(invoiceLibrary);
                        }

                        // 2. 保存共享发票数据（使用从"被共享"发票获取的税率）
                        if (!sharedInvoiceDataList.isEmpty()) {
                            // 检查税率是否有效
                            if (sharedTaxRate.compareTo(BigDecimal.ZERO) == 0) {
                                log.warn("共享发票税率未获取到，使用默认税率0");
                            }

                            for (Map<String, Object> sharedData : sharedInvoiceDataList) {
                                Object detailjeObj = sharedData.get("detailje");
                                String cdbm = (String) sharedData.get("cdbm");
                                String lbmx = (String) sharedData.get("lbmx");
                                String bz = (String) sharedData.get("bz");
                                String hasInvoice = (String) sharedData.get("hasInvoice");
                                String detailje = detailjeObj != null ? String.valueOf(detailjeObj) : "";
                                try {
                                    BigDecimal detailAmount = new BigDecimal(detailje);

                                    // 使用从"被共享"发票解析到的税率
                                    BigDecimal ocrTaxRate = sharedTaxRate;

                                    // 计算金额: 含税金额 / (1 + 税率) = 不含税金额
                                    BigDecimal divisor = BigDecimal.ONE.add(ocrTaxRate);
                                    BigDecimal sharedTaxAmount = detailAmount.divide(divisor, 2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal sharedAmount = detailAmount.subtract(sharedTaxAmount);
                                    BigDecimal sharedRate = ocrTaxRate;

                                    log.info("共享发票计算: 含税金额={}, 税率={}%, 不含税金额={}, 税额={}",
                                            detailAmount, ocrTaxRate.multiply(new BigDecimal("100")),
                                            sharedAmount, sharedTaxAmount);

                                    InvoiceLibrary sharedInvoice = new InvoiceLibrary();
                                    sharedInvoice.setOaId(processInstanceId);
                                    sharedInvoice.setOaStatus("0");
                                    sharedInvoice.setInvoiceStatus("0");
                                    sharedInvoice.setDep(cdbm != null && StringUtils.isNotBlank(cdbm) ? cdbm : (bm != null ? bm : ""));
                                    sharedInvoice.setAccountTitle(lbmx != null ? lbmx : "");
                                    sharedInvoice.setNote(bz != null ? bz : "");
                                    sharedInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                    sharedInvoice.setAmount(null);
                                    sharedInvoice.setTaxAmount(null);
                                    sharedInvoice.setTotalAmount(null);
                                    sharedInvoice.setFormName("出差费用报销");
                                    sharedInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                    sharedInvoice.setPayAccount(fkzh != null ? fkzh : "");
                                    sharedInvoice.setBankName(yhqc != null ? yhqc : "");
                                    sharedInvoice.setHasInvoice(hasInvoice);
                                    sharedInvoice.setDetailAmount(detailAmount);
                                    sharedInvoice.setSharedTaxAmount(sharedAmount);
                                    sharedInvoice.setSharedAmount(sharedTaxAmount);
                                    sharedInvoice.setSharedRate(String.valueOf(sharedRate));
                                    sharedInvoice.setCreatedAt(LocalDateTime.now());
                                    sharedInvoice.setUpdatedAt(LocalDateTime.now());
                                    sharedInvoice.setInvoiceCode("");
                                    sharedInvoice.setInvoiceNumber("");
                                    sharedInvoice.setInvoiceType(sharedKind);
                                    sharedInvoice.setBuyerName("");
                                    sharedInvoice.setBuyerTaxId("");
                                    sharedInvoice.setSellerName("");
                                    sharedInvoice.setSellerTaxId("");
                                    invoiceList.add(sharedInvoice);
                                    log.info("成功保存共享发票记录，成本部门: {}", cdbm);

                                } catch (NumberFormatException e) {
                                    log.error("共享发票金额格式转换失败: detailje={}", detailje, e);
                                } catch (Exception e) {
                                    log.error("共享发票处理失败", e);
                                }
                            }
                        }

                        // 保存所有记录（无发票 + 有发票）
                        if (!noInvoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : noInvoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条无发票记录", noInvoiceList.size());
                            addWorkflowComment(processInstanceId, userId, "报销总金额：" + mainJe);
                        }

                        if (!invoiceList.isEmpty()) {
                            for (InvoiceLibrary invoice : invoiceList) {
                                baseMapper.insert(invoice);
                            }
                            log.info("成功保存 {} 条发票记录（有发票: {}, 共享发票: {}）",
                                    invoiceList.size(),
                                    parsedInvoiceDataList.stream().filter(d -> "是".equals(d.get("hasInvoice")) || "被共享".equals(d.get("hasInvoice"))).count(),
                                    sharedInvoiceDataList.size());
                            addWorkflowComment1(processInstanceId, userId, totalAmount);
                        }

                        if (!allResults.isEmpty()) {
                            return McR.success(allResults);
                        } else {
                            return McR.success();
                        }

                    } catch (Exception e) {
                        log.error("解析子表数据失败", e);
                        return McR.error("300", "解析数据失败: " + e.getMessage());
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }


    @Override
    public McR invoiceLibrary6(Map map) {
        log.info("接收到的参数: {}", map);

        try {
            String processInstanceId = UtilMap.getString(map, "processInstanceId");
            if (StringUtils.isBlank(processInstanceId)) {
                log.error("processInstanceId为空");
                return McR.error("400", "审批实例ID不能为空");
            }

            // 获取审批实例信息
            String accessToken = ddClient.getAccessToken();
            Map processInstance = ddClientWorkflow.getProcessInstanceId(accessToken, processInstanceId);

            if (processInstance == null) {
                log.error("获取审批实例失败: {}", processInstanceId);
                return McR.error("500", "获取审批实例信息失败");
            }

            String userId = (String) processInstance.get("originatorUserId");
            log.info("审批人ID: {}", userId);

            List<Map> formComponentValues = (List<Map>) processInstance.get("formComponentValues");
            if (formComponentValues == null || formComponentValues.isEmpty()) {
                log.warn("表单数据为空");
                return McR.error("400", "表单数据为空");
            }

            // 存储主表的字段值
            String zt = null;
            BigDecimal mainJe = null;
            String bxlb = null;
            String bm = null;
            String fkzhxx = null;
            String fkzh = null;
            String yhqc = null;
            String sfct = null;
            // 遍历收集主表字段值
            for (Map formComponentValue : formComponentValues) {
                String id = String.valueOf(formComponentValue.get("id"));
                Object value = formComponentValue.get("value");

                if ("DDSelectField_VWIFJ1JZK0W0".equals(id)) {
                    zt = value != null ? String.valueOf(value) : "";
                }
                if ("MoneyField_3QS10ALLABU0".equals(id)) {
                    if (value instanceof BigDecimal) {
                        mainJe = (BigDecimal) value;
                    } else if (value != null) {
                        try {
                            mainJe = new BigDecimal(String.valueOf(value));
                        } catch (NumberFormatException e) {
                            log.error("金额格式转换失败: {}", value, e);
                            mainJe = BigDecimal.ZERO;
                        }
                    }
                }
                // 如果需要这两个字段，请取消注释并填写正确的字段ID
                 if ("DDSelectField_YLLB7AD1ATS0".equals(id)) {
                     bxlb = value != null ? String.valueOf(value) : "";
                 }
                 if ("DepartmentField_RF93A6VHA9C0".equals(id)) {
                     bm = value != null ? String.valueOf(value) : "";
                 }
                if ("DDSelectField_IQXAGL7Z8XC0".equals(id)) {
                    fkzhxx = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_3W9CLQOZZ540".equals(id)) {
                    fkzh = value != null ? String.valueOf(value) : "";
                }
                if ("TextField_9PJ4JW8KTCS0".equals(id)) {
                    yhqc = value != null ? String.valueOf(value) : "";
                }
                if ("DDSelectField_21L6KT7DT70G0".equals(id)) {
                    sfct = value != null ? String.valueOf(value) : "否";
                }
            }

            // 判断主表状态 - 无发票
            if ("否".equals(zt)) {
//                Map<String, Object> result = new HashMap<>();
//                result.put("je", mainJe);
//                result.put("status", "否");
//                result.put("message", "无发票报销");
                // 保存基础报销记录
                InvoiceLibrary baseInvoice = new InvoiceLibrary();
                baseInvoice.setOaId(processInstanceId);
                baseInvoice.setOaStatus("0");
                baseInvoice.setInvoiceStatus("0");
                baseInvoice.setDep(bm != null ? bm : "");
                baseInvoice.setAccountTitle(bxlb != null ? bxlb : "");
                baseInvoice.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                baseInvoice.setCreatedAt(LocalDateTime.now());
                baseInvoice.setUpdatedAt(LocalDateTime.now());
                baseInvoice.setInvoiceCode("");
                baseInvoice.setInvoiceNumber("");
                baseInvoice.setInvoiceType("");
                baseInvoice.setAmount(BigDecimal.ZERO);
                baseInvoice.setTaxAmount(BigDecimal.ZERO);
                baseInvoice.setTotalAmount(BigDecimal.ZERO);
                baseInvoice.setBuyerName("");
                baseInvoice.setFormName("批量付款申请（一对多）");
                baseInvoice.setPaySubject(fkzhxx != null ? fkzhxx : "");
                baseInvoice.setPayAccount(fkzh != null ? fkzh : "");
                baseInvoice.setBankName(yhqc != null ? yhqc : "");
                baseInvoice.setIsLongTerm(sfct != null ? sfct : "");
                baseInvoice.setBuyerTaxId("");
                baseInvoice.setSellerName("");
                baseInvoice.setSellerTaxId("");
                baseMapper.insert(baseInvoice);
                addWorkflowComment(processInstanceId, userId, "报销总金额："+mainJe);
                return McR.success();
            }

            // 判断主表状态 - 有发票
            if ("是".equals(zt)) {
                for (Map formComponentValue : formComponentValues) {
                    String id = String.valueOf(formComponentValue.get("id"));

                    if ("DDAttachment_1C1GRYIRFJOG0".equals(id)) {
                        // 获取附件value（它是一个JSON字符串）
                        Object attachmentValue = formComponentValue.get("value");
                        List<Map> attachmentList = null;

                        // 解析附件JSON字符串
                        if (attachmentValue != null) {
                            String attachmentJsonStr = String.valueOf(attachmentValue);
                            if (StringUtils.isNotBlank(attachmentJsonStr)) {
                                try {
                                    attachmentList = JSONObject.parseArray(attachmentJsonStr, Map.class);
                                    log.info("解析附件列表成功，共{}个附件", attachmentList != null ? attachmentList.size() : 0);
                                } catch (Exception e) {
                                    log.error("解析附件JSON失败: {}", attachmentJsonStr, e);
                                    return McR.error("400", "附件格式解析失败");
                                }
                            }
                        }

                        try {
                            List<Object> allResults = new ArrayList<>();
                            List<InvoiceLibrary> invoiceList = new ArrayList<>();

                            // 用于校验的集合
                            List<String> invoiceNumberList = new ArrayList<>();
                            Map<String, String> invoiceNumberToFileName = new HashMap<>();
                            List<String> invalidBuyerTaxIds = new ArrayList<>();

                            // 存储第一遍解析的发票数据，避免重复解析
                            List<Map<String, Object>> parsedInvoiceDataList = new ArrayList<>();

                            if (attachmentList != null && !attachmentList.isEmpty()) {
                                for (Map attachment : attachmentList) {
                                    String fileId = UtilMap.getString(attachment, "fileId");
                                    String fileType = UtilMap.getString(attachment, "fileType");
                                    String fileName = UtilMap.getString(attachment, "fileName");

                                    // 参数校验
                                    if (StringUtils.isBlank(fileId) || StringUtils.isBlank(fileType)) {
                                        log.warn("文件信息不完整: fileId={}, fileType={}, fileName={}", fileId, fileType, fileName);
                                        continue;
                                    }

                                    try {
                                        String filePath = downloadPath + fileId + "." + fileType;
                                        downloadDdFile(processInstanceId, fileId, filePath);

                                        String hz = "qw/files/" + fileId + "." + fileType;
                                        Map fileMap = new HashMap();
                                        fileMap.put("url", url + hz);
                                        fileMap.put("size", new File(filePath).length() / 1024f / 1024f);
                                        fileMap.put("isPdf", "pdf".equalsIgnoreCase(fileType));

                                        McR<Object> result = processMixedInvoice(fileMap);
                                        Object responseData = result.getData();

                                        // 解析发票数据
                                        if (responseData != null) {
                                            String jsonStr = JSONObject.toJSONString(responseData);
                                            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
                                            JSONArray resultArray = jsonObject.getJSONArray("result");

                                            if (resultArray != null && !resultArray.isEmpty()) {
                                                JSONObject invoice = resultArray.getJSONObject(0);
                                                String invoiceNumber = invoice.getString("serial") != null ? invoice.getString("serial") : "";
                                                String buyerTaxId = invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "";
                                                String buyerName = invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "";

                                                // 保存解析的数据供后续使用
                                                Map<String, Object> parsedData = new HashMap<>();
                                                parsedData.put("invoice", invoice);
                                                parsedData.put("fileId", fileId);
                                                parsedData.put("fileName", fileName);
                                                parsedData.put("fileType", fileType);
                                                parsedData.put("responseData", responseData);
                                                parsedInvoiceDataList.add(parsedData);

                                                // ========== 校验1：抬头校验 ==========
                                                if (StringUtils.isNotBlank(buyerName)) {
                                                    CompanyTitle existingTitle = companyTitleMapper.selectByTaxId(buyerName);
                                                    if (existingTitle == null) {
                                                        String errorInfo = String.format("发票: %s, 购买方名称: %s, 税号: %s",
                                                                fileName, buyerName, buyerTaxId);
                                                        invalidBuyerTaxIds.add(errorInfo);
                                                        log.warn("抬头校验失败: 税号={} 不存在于抬头库, 文件名={}", buyerTaxId, fileName);
                                                    }
                                                } else {
                                                    String errorInfo = String.format("发票: %s, 购买方税号为空", fileName);
                                                    invalidBuyerTaxIds.add(errorInfo);
                                                    log.warn("抬头校验失败: 购买方税号为空, 文件名={}", fileName);
                                                }

                                                // ========== 校验2：发票号重复校验（与数据库中的发票号比较） ==========
                                                if (StringUtils.isNotBlank(invoiceNumber)) {
                                                    // 检查数据库中是否已存在相同的发票号
                                                    LambdaQueryWrapper<InvoiceLibrary> queryWrapper = new LambdaQueryWrapper<>();
                                                    queryWrapper.eq(InvoiceLibrary::getInvoiceNumber, invoiceNumber);
                                                    InvoiceLibrary existingInvoice = baseMapper.selectOne(queryWrapper);

                                                    if (existingInvoice != null) {
                                                        String errorMsg = String.format("发票号重复: %s (当前文件: %s, 已存在于OA审批单: %s)",
                                                                invoiceNumber, fileName, existingInvoice.getOaId());
                                                        log.error(errorMsg);

                                                        // 终止流程并回写原因
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }

                                                    // 同时检查同一审批单内是否有重复（防止同一单据内上传重复发票）
                                                    if (invoiceNumberList.contains(invoiceNumber)) {
                                                        String errorMsg = String.format("当前审批单内发票号重复: %s (当前文件: %s, 已存在文件: %s)",
                                                                invoiceNumber, fileName, invoiceNumberToFileName.get(invoiceNumber));
                                                        log.error(errorMsg);

                                                        // 终止流程并回写原因
                                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                                        return McR.error("400", errorMsg);
                                                    }
                                                    invoiceNumberList.add(invoiceNumber);
                                                    invoiceNumberToFileName.put(invoiceNumber, fileName);
                                                }
                                            } else {
                                                log.warn("发票解析结果为空: fileName={}", fileName);
                                            }
                                        } else {
                                            log.warn("发票OCR识别结果为空: fileName={}", fileName);
                                        }
                                    } catch (Exception e) {
                                        log.error("发票解析异常: fileId={}, fileName={}", fileId, fileName, e);
                                        String errorMsg = "发票解析失败: " + e.getMessage();
                                        terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                        return McR.error("400", errorMsg);
                                    }
                                }
                            } else {
                                log.warn("附件列表为空");
                                return McR.error("400", "请上传发票附件");
                            }

                            // ========== 抬头校验失败处理 ==========
                            if (!invalidBuyerTaxIds.isEmpty()) {
                                String errorMsg = "发票抬头有误，以下发票的购买方税号不在公司抬头库中:\n" + String.join("\n", invalidBuyerTaxIds);
                                log.error(errorMsg);

                                // 终止流程
                                terminateWorkflow(accessToken, processInstanceId, userId, errorMsg);
                                return McR.error("400", errorMsg);
                            }
                            BigDecimal totalAmount = BigDecimal.ZERO;
                            // ========== 第二遍遍历：保存发票数据（校验通过后） ==========
                            for (Map<String, Object> parsedData : parsedInvoiceDataList) {
                                JSONObject invoice = (JSONObject) parsedData.get("invoice");
                                Object responseData = parsedData.get("responseData");

                                allResults.add(responseData);
                                BigDecimal amount = invoice.getBigDecimal("amount");
                                if (amount != null) {
                                    totalAmount = totalAmount.add(amount);
                                }
                                // 构建InvoiceLibrary对象
                                InvoiceLibrary invoiceLibrary = new InvoiceLibrary();
                                invoiceLibrary.setOaId(processInstanceId);
                                invoiceLibrary.setInvoiceCode(invoice.getString("code") != null ? invoice.getString("code") : "");
                                invoiceLibrary.setInvoiceNumber(invoice.getString("serial") != null ? invoice.getString("serial") : "");
                                invoiceLibrary.setInvoiceType(invoice.getString("kindName") != null ? invoice.getString("kindName") : "");

                                String date = invoice.getString("date");
                                if (StringUtils.isNotBlank(date)) {
                                    try {
                                        invoiceLibrary.setInvoiceDate(LocalDate.parse(date.trim()));
                                    } catch (Exception e) {
                                        log.warn("日期解析失败: {}", date, e);
                                    }
                                }

                                invoiceLibrary.setAmount(invoice.getBigDecimal("excludingTax") != null ? invoice.getBigDecimal("excludingTax") : BigDecimal.ZERO);
                                invoiceLibrary.setTaxAmount(invoice.getBigDecimal("tax") != null ? invoice.getBigDecimal("tax") : BigDecimal.ZERO);
                                invoiceLibrary.setTotalAmount(invoice.getBigDecimal("amount") != null ? invoice.getBigDecimal("amount") : BigDecimal.ZERO);
                                invoiceLibrary.setBuyerName(invoice.getString("buyerName") != null ? invoice.getString("buyerName") : "");
                                invoiceLibrary.setBuyerTaxId(invoice.getString("buyerTaxId") != null ? invoice.getString("buyerTaxId") : "");
                                invoiceLibrary.setSellerName(invoice.getString("sellerName") != null ? invoice.getString("sellerName") : "");
                                invoiceLibrary.setSellerTaxId(invoice.getString("sellerTaxId") != null ? invoice.getString("sellerTaxId") : "");
                                invoiceLibrary.setOaStatus("0");
                                invoiceLibrary.setInvoiceStatus("0");
                                invoiceLibrary.setDep(bm != null ? bm : "");
                                invoiceLibrary.setAccountTitle(bxlb != null ? bxlb : "");
                                invoiceLibrary.setPayAmount(mainJe != null ? mainJe : BigDecimal.ZERO);
                                invoiceLibrary.setCreatedAt(LocalDateTime.now());
                                invoiceLibrary.setUpdatedAt(LocalDateTime.now());
                                invoiceLibrary.setFormName("批量付款申请（一对多）");
                                invoiceLibrary.setPaySubject(fkzhxx != null ? fkzhxx : "");
                                invoiceLibrary.setPayAccount(fkzh != null ? fkzh : "");
                                invoiceLibrary.setBankName(yhqc != null ? yhqc : "");
                                invoiceLibrary.setIsLongTerm(sfct != null ? sfct : "");
                                invoiceList.add(invoiceLibrary);
                            }

                            // 保存发票记录
                            if (!invoiceList.isEmpty()) {
                                for (InvoiceLibrary invoice : invoiceList) {
                                    baseMapper.insert(invoice);
                                }
                                log.info("成功保存 {} 条发票记录", invoiceList.size());
                            } else {
                                log.warn("没有有效的发票数据可保存");
                            }

                            addWorkflowComment1(processInstanceId, userId, totalAmount);
                            return McR.success(allResults);

                        } catch (Exception e) {
                            log.error("解析子表数据失败", e);
                            return McR.error("300", "解析数据失败: " + e.getMessage());
                        }
                    }
                }
            }

            return McR.success();

        } catch (Exception e) {
            log.error("处理审批实例失败", e);
            return McR.error("500", "系统处理失败: " + e.getMessage());
        }
    }

    @Override
    public void updateSfctByOaId(Map map) {
        try {
            String oaId = UtilMap.getString(map, "oaId");
//            String sfct = UtilMap.getString(map, "sfct");
            String fkzhxx = UtilMap.getString(map, "fkzhxx");
            String fkzh = UtilMap.getString(map, "fkzh");
            String yhqc = UtilMap.getString(map, "yhqc");
//            sfct = (sfct == null || sfct.trim().isEmpty()) ? "否" : sfct;
            // 创建更新条件
            LambdaUpdateWrapper<InvoiceLibrary> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(InvoiceLibrary::getOaId, oaId)
//                    .set(InvoiceLibrary::getIsLongTerm, sfct)
                    .set(InvoiceLibrary::getPayAccount, fkzh)
                    .set(InvoiceLibrary::getBankName, yhqc)
                    .set(InvoiceLibrary::getPaySubject, fkzhxx)
                    .set(InvoiceLibrary::getUpdatedAt, LocalDateTime.now());

            int updateCount = baseMapper.update(null, updateWrapper);

            if (updateCount > 0) {
                log.info("更新成功: 共更新{}条记录", updateCount);
            } else {
                log.warn("未找到符合条件的记录: oaId={}", oaId);
            }
        } catch (Exception e) {

            throw new RuntimeException("更新OA状态失败", e);
        }
    }


    /**
     * 添加钉钉审批评论
     */
    private void addWorkflowComment(String processInstanceId, String userId, Object totalAmount) {
        try {
            Map<String, Object> body = new HashMap<>();
            body.put("processInstanceId", processInstanceId);
            body.put("text", totalAmount);
            body.put("commentUserId", userId);

            String result = UtilHttp.doPost(
                    "https://api.dingtalk.com/v1.0/workflow/processInstances/comments",
                    ddClient.initTokenHeader(),
                    null,
                    body
            );

            log.info("添加审批评论成功: {}", result);
        } catch (Exception e) {
            log.error("添加审批评论失败", e);
        }
    }
    private void addWorkflowComment1(String processInstanceId, String userId, BigDecimal totalAmount) {
        try {
            Map<String, Object> body = new HashMap<>();
            body.put("processInstanceId", processInstanceId);
            body.put("text", "发票总金额："+totalAmount);
            body.put("commentUserId", userId);

            String result = UtilHttp.doPost(
                    "https://api.dingtalk.com/v1.0/workflow/processInstances/comments",
                    ddClient.initTokenHeader(),
                    null,
                    body
            );

            log.info("添加审批评论成功: {}", result);
        } catch (Exception e) {
            log.error("添加审批评论失败", e);
        }
    }
    /**
     * 从 Map 中获取字符串值
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? String.valueOf(value) : "";
    }

    /**
     * 从 Map 中获取 BigDecimal 值
     */
    private BigDecimal getBigDecimalValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return BigDecimal.ZERO;
        }
        if (value instanceof BigDecimal) {
            return (BigDecimal) value;
        }
        try {
            return new BigDecimal(String.valueOf(value));
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }



    /**
     * 空字符串转换
     */
    private String nullToEmpty(String str) {
        return str != null ? str : "";
    }


    private void downloadDdFile(String processInstanceId, String fileId, String downloadPath) {
        try {
            Map body = new HashMap();
            body.put("processInstanceId", processInstanceId);
            body.put("fileId", fileId);

            DDR_New ddrNew = (DDR_New) UtilHttp.doPost("https://api.dingtalk.com/v1.0/workflow/processInstances/spaces/files/urls/download", ddClient.initTokenHeader(), null, body, DDR_New.class);

            //2、执行下载
            Map result = (Map) ddrNew.getResult();

            String downloadUri = UtilMap.getString(result, "downloadUri");

            downloadFile(downloadUri, downloadPath);

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

    //文件下载到本地
    private void downloadFile(String downloadUri, String downloadPath) {
        try {
            URL url = new URL(downloadUri);

            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            int responseCode = httpConn.getResponseCode();

            // 检查HTTP响应代码是否为200
            if (responseCode == HttpURLConnection.HTTP_OK) {
                InputStream inputStream = httpConn.getInputStream();
                FileOutputStream outputStream = new FileOutputStream(downloadPath);

                byte[] buffer = new byte[4096];
                int bytesRead = -1;

                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }

                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("无法下载文件。HTTP响应代码: " + responseCode);
            }
            httpConn.disconnect();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 私有化方法：混票识别处理
     *
     * @param data 包含url、size、isPdf的Map参数
     * @return 识别结果
     */
    private McR<Object> processMixedInvoice(Map<String, Object> data) throws TencentCloudSDKException {
        McException.assertParamException_Null(data, "url");
        String image = String.valueOf(data.get("url"));
        log.info("混票识别, 免登地址, {}", image);

        // 非PDF, 且内存大于3M, 压缩后上传
        if (UtilMap.getFloat(data, "size") > 3.0f && !UtilMap.getBoolean(data, "isPdf")) {
            image = imageUrlConvertBase64(image);
        }
        if (UtilMap.getFloat(data, "size") > 6.0f && UtilMap.getBoolean(data, "isPdf")) {
            image = pdfUrlConvertBase64(image);
        }

        List<Map> invoices = (List<Map>) txyInvoice.doRecognizeGeneralInvoice(image).get("MixedInvoiceItems");
        System.out.println("invoices=====" + invoices);
        List<String> nos = new ArrayList<>();

        List<McInvoiceDto> result = invoices.stream().map(item -> {
            Map prop = UtilMap.getMap(UtilMap.getMap(item, "SingleInvoiceInfos"), UtilMap.getString(item, "SubType"));
            String taxRate = null;
//            List<Map<String, Object>> vatInvoiceItemInfos = UtilMap.getList(prop, "VatInvoiceItemInfos");
            // 优先使用 VatInvoiceItemInfos，如果为空则使用 VatElectronicItems
            List<Map<String, Object>> vatInvoiceItemInfos =
                    UtilMap.getList(prop, "VatInvoiceItemInfos") != null && !UtilMap.getList(prop, "VatInvoiceItemInfos").isEmpty()
                            ? UtilMap.getList(prop, "VatInvoiceItemInfos")
                            : UtilMap.getList(prop, "VatElectronicItems");
//            if (!vatInvoiceItemInfos.isEmpty()) {
//                 taxRate = UtilMap.getString(vatInvoiceItemInfos.get(0), "TaxRate");
//            }
            if (!vatInvoiceItemInfos.isEmpty()) {
                String originalTaxRate = UtilMap.getString(vatInvoiceItemInfos.get(0), "TaxRate");

                // 判断是否为有效数字（包括带%号的格式，如"9%"）
                if (StringUtils.isNotBlank(originalTaxRate)) {
                    // 移除百分号并尝试解析为数字
                    String cleanedTaxRate = originalTaxRate.replace("%", "").trim();
                    try {
                        // 尝试转换为数字
                        new BigDecimal(cleanedTaxRate);
                        taxRate = originalTaxRate; // 保持原值（可能带%）
                    } catch (NumberFormatException e) {
                        // 如果不是数字（如"不征税"、"免税"等），赋值为"0"
                        taxRate = "0";
                        log.debug("税率格式异常，原始值: {}, 已设置为0", originalTaxRate);
                    }
                } else {
                    taxRate = "0";
                }
            } else {
                taxRate = "0";
            }
            String no = UtilMap.getString(prop, "Number");
            if (nos.contains(no)) {
                return null;
            }
            nos.add(no);
            String kind = UtilMap.getString(item, "TypeDescription");
            String invoiceName = UtilMap.getString(item, "SubTypeDescription");

            if (kind.equals("全电发票")) {
                if (invoiceName.contains("铁路电子客票")) {
                    kind = "火车票";
                } else if (invoiceName.contains("机票行程单")) {
                    kind = "机票行程单";
                } else if (invoiceName.contains("专用发票")) {
                    kind = "全电专用发票";
                } else {
                    kind = "全电普通发票";
                }
            }

            if (kind.equals("增值税发票")) {
                if (invoiceName.contains("区块链电子发票")) {
                    kind = "区块链电子发票";
                } else if (invoiceName.contains("增值税专用发票")) {
                    kind = "增值税专用发票";
                } else if (invoiceName.contains("增值税普通发票")) {
                    kind = "增值税普通发票";
                } else if (invoiceName.contains("增值税电子专用发票")) {
                    kind = "增值税电子专用发票";
                } else if (invoiceName.contains("增值税电子普通发票")) {
                    kind = "增值税电子普通发票";
                } else {
                    kind = "增值税普通发票";
                }
            }

            McInvoiceDto invoiceDto = McInvoiceDto.builder()
                    .name(UtilMap.getString(item, "SubTypeDescription"))
                    .kindName(kind)
                    .kind(UtilMap.getInt(item, "Type"))
                    .taxRate(taxRate)
                    .code(UtilMap.getString(prop, "Code"))
                    .serial(UtilMap.getString(prop, "Number"))
                    .date(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "Date")))
                    .checkCode(UtilMap.getString(prop, "CheckCode"))
                    .amount(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Total", "Fare")))
                    .tax(UtilNumber.setBigDecimal(UtilMap.getString_first(prop, "Tax")))
                    .excludingTax(UtilNumber.setBigDecimal(UtilMap.getString(prop, "PretaxAmount")))
                    .buyerName(StringUtils.defaultString(guyuanNameRepalce(UtilMap.getString(prop, "Buyer"))))
                    .buyerTaxId(StringUtils.isBlank(UtilMap.getString(prop, "BuyerTaxID"))
                            ? "" : UtilMap.getString(prop, "BuyerTaxID"))
                    .sellerName(guyuanNameRepalce(UtilMap.getString_first(prop, "Seller", "Issuer")))
                    .sellerTaxId(UtilMap.getString_first(prop, "SellerTaxID", "AgentCode"))
                    .passengerName(UtilMap.getString_first(prop, "Name", "UserName"))
                    .seatType(UtilMap.getString(prop, "Seat"))
                    .departureTime(UtilString.replaceDateZH_cn(UtilMap.getString(prop, "DateGetOn"))
                            + " " + UtilMap.getString(prop, "TimeGetOn"))
                    .departurePort(UtilMap.getString_first(prop, "StationGetOn", "Entrance", "Place"))
                    .arrivePort(UtilMap.getString_first(prop, "StationGetOff", "Exit"))
                    .trainNo(UtilMap.getString_first(prop, "TrainNumber", "LicensePlate"))
                    .insuranceCosts(UtilNumber.setBigDecimal(UtilMap.getString(prop, "Insurance")))
                    .fuelCosts(UtilNumber.setBigDecimal(UtilMap.getString(prop, "FuelSurcharge")))
                    .constructionCosts(UtilNumber.setBigDecimal(UtilMap.getString(prop, "AirDevelopmentFund")))
                    .build();

            if ("机票行程单".equals(kind)) {
                invoiceDto.setSellerName(UtilMap.getString_first(prop, "Issuer"));
                invoiceDto.setSellerTaxId(UtilMap.getString_first(prop, "Seller"));
                Map flight = (Map) UtilMap.getList(prop, "FlightItems").get(0);
                invoiceDto.setDepartureTime(UtilString.replaceDateZH_cn(UtilMap.getString(item, "DateGetOn"))
                        + " " + UtilMap.getString(prop, "TimeGetOn"));
                invoiceDto.setDeparturePort(UtilMap.getString(flight, "StationGetOn"));
                invoiceDto.setArrivePort(UtilMap.getString(flight, "StationGetOff"));
                invoiceDto.setSeatType(UtilMap.getString(flight, "Seat"));
            }

            if ("出租车发票".equals(item.get("TypeDescription"))) {
                invoiceDto.setDepartureTime(UtilMap.getString(prop, "TimeGetOn")
                        + " ~ " + UtilMap.getString(prop, "TimeGetOff"));
            }

            return invoiceDto;
        }).filter(Objects::nonNull).collect(Collectors.toList());

        return McR.success(McInvoiceDto.formatResponse(result));
    }

    private static String guyuanNameRepalce(String name) {
        name = name.replaceAll(" ", "");
        if (name.contains("谷元")) {
            return UtilString.replaceBracketIsWhole(name);
        } else {
            return UtilString.replaceBracketIsSemiangle(name);
        }
    }

    /// url压缩转base64
    @SneakyThrows
    private String imageUrlConvertBase64(String imageUrl) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        // scale(比例), outputQuality(质量)
        Thumbnails.fromURLs(Arrays.asList(new URL(imageUrl))).scale(0.5f).outputQuality(0.25f).toOutputStream(out);
        InputStream inputStream = new ByteArrayInputStream(out.toByteArray());
        //转换为base64
        byte[] bytes = IOUtils.toByteArray(inputStream);
        return Base64.getEncoder().encodeToString(bytes);
    }

    @SneakyThrows
    private String pdfUrlConvertBase64(String pdfUrl) {
        String fileName = "tmp_" + new Date().getTime() + ".pdf";
        // 下载文件
        File file = UtilFile.mkdirIfNot(fileName, filePath.getPath().getTmp());
        UtilHttp.doDownload(pdfUrl, file);

        // PDF压缩
        PdfDocument doc = new PdfDocument(); // 创建PdfDocument类的对象
        doc.loadFromFile(file.getAbsolutePath()); // 加载PDF文档
        doc.getFileInfo().setIncrementalUpdate(false); // 禁用增量更新
        doc.setCompressionLevel(PdfCompressionLevel.Normal); // 将压缩级别设置为最佳

        // 遍历文档页面
        for (int i = 0; i < doc.getPages().getCount(); i++) {
            PdfPageBase page = doc.getPages().get(i);  // 获取指定页面
            PdfImageInfo[] images = page.getImagesInfo(); // 获取每个页面的图像信息集合
            // 遍历集合中的所有项目
            if (images != null && images.length > 0)
                for (int j = 0; j < images.length; j++) {
                    PdfImageInfo image = images[j];  // 获取指定图片
                    PdfBitmap bp = new PdfBitmap(image.getImage());
                    bp.setQuality(30); // 设置压缩质量
                    page.replaceImage(j, bp); // 将原始图像替换为压缩图像
                }
        }
        // 将结果文档保存至另一个PDF文档中: 覆盖
        doc.saveToFile(file.getAbsolutePath());
        doc.close();
        // PDF转base64, 无需透出本地文件地址
        String base64 = UtilFile.fileToBase64(file.getAbsolutePath());
        // 删除临时PDF文件
        UtilFile.deleteFile(file.getAbsolutePath());
        return base64;
    }

    @GetMapping("/files/{fileId}")
    public ResponseEntity<Resource> getFileResource(
            @PathVariable String fileId,
            @RequestParam(defaultValue = "download") String option) throws IOException {

        // 根据fileId获取实际文件路径，这里简化处理，实际可能需要从数据库查询
        Path filePath = Paths.get(downloadPath).resolve(fileId).normalize();
//        Path filePath = Paths.get("D://qiwang//files//").resolve(fileId).normalize();

        // 检查文件是否存在
        if (!Files.exists(filePath)) {
            return ResponseEntity.notFound().build();
        }

        // 创建Resource对象
        Resource resource = new UrlResource(filePath.toUri());

        // 根据选项设置响应头
        HttpHeaders headers = new HttpHeaders();
        if ("preview".equalsIgnoreCase(option)) {
            // 预览模式 - 尝试确定内容类型
            String contentType = Files.probeContentType(filePath);
            // 强制修正 PDF 的 Content-Type
            if (filePath.toString().toLowerCase().endsWith(".pdf")) {
                contentType = "application/pdf";
            } else if (contentType == null) {
                contentType = "application/octet-stream";
            }
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.add("Content-Disposition", "inline; filename=\"" + resource.getFilename() + "\"");
            headers.add("X-Content-Type-Options", "nosniff"); // 防止浏览器忽略 Content-Type
        } else {
            // 下载模式 - 默认处理
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.add("Content-Disposition", "attachment; filename=\"" + resource.getFilename() + "\"");
        }

        return ResponseEntity.ok()
                .headers(headers)
                .contentLength(resource.contentLength())
                .body(resource);
    }
}
