package com.zksy.system.basicData.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zksy.common.config.ThreadPoolConfig;
import com.zksy.common.core.domain.AjaxResult;
import com.zksy.common.utils.DeleteTableUtils;
import com.zksy.common.utils.StringUtil;
import com.zksy.common.utils.ThreadPoolRunTaskListUtil;
import com.zksy.common.utils.bean.PageResult;
import com.zksy.common.utils.page.Page;
import com.zksy.common.utils.page.PageUtil;
import com.zksy.system.basicData.domain.CrmDomesticMarketEntityIndustryInfo;
import com.zksy.system.basicData.domain.CrmHighTechZoneEnterprises;
import com.zksy.system.basicData.domain.RmEnterprisePerformanceStandard;
import com.zksy.system.basicData.domain.RmIndustryScale;
import com.zksy.system.basicData.mapper.CrmDomesticMarketEntityIndustryInfoMapper;
import com.zksy.system.basicData.mapper.CrmHighTechZoneEnterprisesMapper;
import com.zksy.system.basicData.mapper.RmEnterprisePerformanceStandardMapper;
import com.zksy.system.basicData.mapper.RmIndustryScaleMapper;
import com.zksy.system.basicData.model.respone.*;
import com.zksy.system.basicData.service.CrmHighTechZoneEnterprisesService;
import com.zksy.system.constant.*;
import com.zksy.system.domain.bo.FinancialBo;
import com.zksy.system.domain.bo.FinancialRatioBo;
import com.zksy.system.domain.bo.FinancialResultBo;
import com.zksy.system.domain.bo.SortMarkBo;
import com.zksy.system.domain.vo.CompanyScore;
import com.zksy.system.domain.vo.EvaluationReportDetailVo;
import com.zksy.system.domain.vo.GradeVo;
import com.zksy.system.utils.DataUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 高新区企业（119家）Service业务层处理
 *
 * @author sy
 * @date 2024-05-06
 */
@Service
@Slf4j
public class CrmHighTechZoneEnterprisesServiceImpl extends ServiceImpl<CrmHighTechZoneEnterprisesMapper, CrmHighTechZoneEnterprises> implements CrmHighTechZoneEnterprisesService {
    @Resource
    private CrmHighTechZoneEnterprisesMapper mapper;
    @Autowired
    private ThreadPoolConfig threadPool;
    @Autowired
    private RmEnterprisePerformanceStandardMapper rmEnterprisePerformanceStandardMapper;

    @Autowired
    private RmIndustryScaleMapper rmIndustryScaleMapper;

    @Autowired
    private CrmDomesticMarketEntityIndustryInfoMapper crmDomesticMarketEntityIndustryInfoMapper;
    //排序列表
    private static final List<String> order = Arrays.asList("AAA","AA","A", "B", "C", "D");

    private static int sectionNumber = 1; // 初始化序号计数器

    @Override
    public Page creditScoreList(String unifiedSocialCreditCode,String enterpriseName , int pageNum, int pageSize,String ... condition) {
        List<String> list = Arrays.stream(condition).collect(Collectors.toList());
//        PageManager.setPageInfo(pageNum, pageSize);
//        PageResult pageResult = PageManager.getPage(mapper.creditScoreList(unifiedSocialCreditCode));
//        List<FinancialResultBo> finalFinancialScoreList = finalFinancialScore(unifiedSocialCreditCode);
        ThreadPoolRunTaskListUtil<List<CompanyScore>> listThreadPoolRunTaskListUtil = new ThreadPoolRunTaskListUtil<>(
                threadPool,
                () -> commitTask(this::finalFinancialScore, unifiedSocialCreditCode,enterpriseName),
                () -> commitTask(mapper::referenceCreditRating, unifiedSocialCreditCode,enterpriseName),
                () -> commitTask(mapper::regulatoryPenalty, unifiedSocialCreditCode,enterpriseName),
                () -> commitTask(mapper::creditScoreDeductions, unifiedSocialCreditCode,enterpriseName),
                () -> commitTask(mapper::enterpriseScore, unifiedSocialCreditCode,enterpriseName),
                () -> commitTask(mapper::legalDeduction, unifiedSocialCreditCode,enterpriseName)
        );
        Vector<List<CompanyScore>> resultVector = listThreadPoolRunTaskListUtil.runTaskList(Vector::new).getResultVector();
        List<GradeVo> collect = resultVector.stream()
                .flatMap(List::stream)
                .collect(Collectors.groupingBy(CompanyScore::getUnifiedSocialCreditCode))
                .entrySet().stream()
                .map(entry -> {
                    String code = entry.getKey();
                    double total = entry.getValue().stream().mapToDouble(CompanyScore::getTotal).sum();
                    String name = entry.getValue().iterator().next().getEnterpriseName();
                    return new CompanyScore(code, name, total);
                })
                .map(s -> {
                    GradeVo gradeVo = new GradeVo();
                    gradeVo.setEnterpriseName(s.getEnterpriseName());
                    gradeVo.setTotal(s.getTotal());
                    gradeVo.setUnifiedSocialCreditCode(s.getUnifiedSocialCreditCode());
                    if (s.getTotal() >= ScoreConstant.AAA) {
                        gradeVo.setGrade(GradeConstant.AAA_GRADE);
                    } else if (s.getTotal() >= ScoreConstant.AA) {
                        gradeVo.setGrade(GradeConstant.AA_GRADE);
                    } else if (s.getTotal() >= ScoreConstant.A) {
                        gradeVo.setGrade(GradeConstant.A_GRADE);
                    } else if (s.getTotal() >= ScoreConstant.B) {
                        gradeVo.setGrade(GradeConstant.B_GRADE);
                    } else if (s.getTotal() >= ScoreConstant.C) {
                        gradeVo.setGrade(GradeConstant.C_GRADE);
                    } else {
                        gradeVo.setGrade(GradeConstant.D_GRADE);
                    }
                    return gradeVo;
                })
                .collect(Collectors.toList());
        //判断直接得分C的情况
        List<CrmHighTechZoneEnterprises> judgingAsC = mapper.ratedLevelC(unifiedSocialCreditCode);
        if(!judgingAsC.isEmpty()){
            judgingAsC.stream().forEach(item -> {
                collect.stream()
                        .filter(c->c.getUnifiedSocialCreditCode().equals(item.getUnifiedSocialCreditCode()))
                        .findFirst()
                        .ifPresent(f->f.setGrade(GradeConstant.C_GRADE));
            });
        }
        //判断直接得分D的情况
        List<CrmHighTechZoneEnterprises> judgingAsD = mapper.ratedLevelD(unifiedSocialCreditCode);
        if(!judgingAsD.isEmpty()){
            judgingAsD.stream().forEach(item -> {
                collect.stream()
                        .filter(c->c.getUnifiedSocialCreditCode().equals(item.getUnifiedSocialCreditCode()))
                        .findFirst()
                        .ifPresent(f->f.setGrade(GradeConstant.D_GRADE));
            });
        }
        List<GradeVo> sortedCollect = collect.stream()
                .sorted(Comparator.comparing(CompanyScore::getTotal).reversed())
                .sorted(Comparator.comparingInt(c -> order.indexOf(c.getGrade())))
                .collect(Collectors.toList());
        List<GradeVo> collect1 = sortedCollect;
        if(!list.isEmpty()){
            collect1 = sortedCollect.stream().filter(item -> list.contains(item.getGrade())).collect(Collectors.toList());
        }
        int totalSize = collect1.size(); // 总记录数
        int totalPages = (int)Math.ceil((double)totalSize / pageSize); // 总页数，向上取整
        // 应用自定义内存分页逻辑
        List<GradeVo> paginatedCollect = memoryPage(collect1, pageNum, pageSize);
// 封装分页结果
        PageResult pageResult = new PageResult();
        pageResult.setPageNo(pageNum); // 或者使用pageNo，根据您的命名习惯
        pageResult.setPageSize(pageSize);
        pageResult.setTotalPage(totalPages);
        pageResult.setTotalSize(totalSize);
        pageResult.setResult(paginatedCollect); // 分页后的数据列表

// 返回Page对象，假设PageUtil有相应转换方法
        return PageUtil.convertPageResult2Page(pageResult);
    }

    public static <T> List<T> memoryPage(List<T> list, int pageNum, int pageSize) {
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, list.size()); // 防止数组越界
        return list.subList(startIndex, endIndex);
    }

    public <T extends CompanyScore> List<CompanyScore> commitTask(BiFunction<String,String, List<T>> function, String unifiedSocialCreditCode,String enterpriseName) {
        List<T> list = function.apply(unifiedSocialCreditCode, enterpriseName);
        return list.stream().map(item -> {
            CompanyScore companyScore = new CompanyScore();
            companyScore.setEnterpriseName(item.getEnterpriseName());
            companyScore.setTotal(item.getTotal());
            companyScore.setUnifiedSocialCreditCode(item.getUnifiedSocialCreditCode());
            return companyScore;
        }).collect(Collectors.toList());
    }
    public <T extends CompanyScore> List<CompanyScore> commitTask(BiFunction<String,String, List<T>> function, String unifiedSocialCreditCode,String enterpriseName,Integer sortMark) {
        List<T> list = function.apply(unifiedSocialCreditCode,enterpriseName);
        return list.stream().map(item -> {
            CompanyScore companyScore = new CompanyScore();
            companyScore.setEnterpriseName(item.getEnterpriseName());
            companyScore.setTotal(item.getTotal());
            companyScore.setUnifiedSocialCreditCode(item.getUnifiedSocialCreditCode());
            companyScore.setSortMark(sortMark);
            return companyScore;
        }).collect(Collectors.toList());
    }

    public List<FinancialResultBo> finalFinancialScore(String unifiedSocialCreditCode,String enterpriseName) {
        List<FinancialBo> list = getCrmFinancialReportList(unifiedSocialCreditCode,enterpriseName);
        //获取行业类别及规模
        List<RmIndustryScale> rmIndustryScales = rmIndustryScaleMapper.selectList(null);
        //获取评价标准
        List<RmEnterprisePerformanceStandard> rmEnterprisePerformanceStandards = rmEnterprisePerformanceStandardMapper.selectList(null);
        rmEnterprisePerformanceStandards.stream().forEach(this::trimItemWithParentheses);
        Stream<FinancialResultBo> stream1 = list.stream()
                .map(this::computeRatio)
                .map((item) -> {
                    rmIndustryScales.stream()
                            .map(q -> {
                                switch (q.getIndicatorName()) {
                                    case QuotaConstant.ASSETS_TOTAL:
                                        setScaleCategory(item, item.getTotalAssets(), q.getLargeScale(), q.getMediumScale(), q.getSmallScale());
                                        break;
                                    case QuotaConstant.BUSINESS_INCOME:
                                        setScaleCategory(item, item.getOperatingRevenue(), q.getLargeScale(), q.getMediumScale(), q.getSmallScale());
                                        break;
                                    case QuotaConstant.EMPLOYEES:
                                        if (StringUtil.isBlank(item.getPractitioners())) {
                                            item.setPractitioners(QuotaConstant.NO_EMPLOYEES);
                                        }
                                        setScaleCategory(item, Double.parseDouble(item.getPractitioners()), q.getLargeScale(), q.getMediumScale(), q.getSmallScale());
                                        break;
                                }
                                return q;
                            })
                            .filter(a -> item.getCategoryCode().contains(a.getIndustryCode()))
                            .map(RmIndustryScale::getIndustryName)
                            .findFirst()
                            .ifPresent(item::setIndustryCategory);
                    return item;
                })
                .map(item -> {
                    List<RmEnterprisePerformanceStandard> rmEnterprisePerformanceStandardList = rmEnterprisePerformanceStandards.stream()
                            .filter(r -> r.getIndustryCategory().equals(item.getIndustryCategory()))
                            .filter(r -> r.getCompanySizeType().equals(item.getScaleCategory()))
                            .collect(Collectors.toList());
                    Map<String, RmEnterprisePerformanceStandard> standardMap = rmEnterprisePerformanceStandardList.stream()
                            .collect(Collectors.toMap(RmEnterprisePerformanceStandard::getItem, r -> r));
                    FinancialResultBo resultBo = new FinancialResultBo();
                    //设置社会工信码
                    resultBo.setUnifiedSocialCreditCode(item.getUnifiedSocialCreditCode());
                    //设置企业名称
                    resultBo.setEnterpriseName(item.getEnterpriseName());
                    //计算 净资产收益率（%）
                    computeScore(item.getNetAssetReturnRate(), resultBo::setNetAssetReturnRate, standardMap, TargetValueConstant.RETURN_ON_EQUITY, 1D, 0.8D, 0.6D, 0.4D);
                    //计算 营业收入利润率(%)
                    computeScore(item.getOperatingProfitMargin(), resultBo::setOperatingProfitMargin, standardMap, TargetValueConstant.OPERATING_INCOME_MARGIN, 1D, 0.8D, 0.6D, 0.4D);
                    //计算 盈余现金保障倍数
                    computeScore(item.getSurplusCashSecurityRatio(), resultBo::setSurplusCashSecurityRatio, standardMap, TargetValueConstant.EARNINGS_SURPLUS_RATIO, 1D, 0.8D, 0.6D, 0.4D);
                    //计算 总资产周转率(次)
                    computeScore(item.getTotalAssetsTurnover(), resultBo::setTotalAssetsTurnover, standardMap, TargetValueConstant.ASSET_TURN_OVER, 0.75D, 0.6D, 0.45D, 0.3D);
                    //计算 应收账款周转率(次)
                    computeScore(item.getAccountsReceivableTurnover(), resultBo::setAccountsReceivableTurnover, standardMap, TargetValueConstant.ACCOUNTS_RECEIVABLE_TURN_OVER, 0.75D, 0.6D, 0.45D, 0.3D);
                    //计算 存货周转率(次)
                    computeScore(item.getInventoryTurnover(), resultBo::setInventoryTurnover, standardMap, TargetValueConstant.INVENTORY_TURN_OVER, 0.5D, 0.4D, 0.3D, 0.2D);
                    //计算 资产负债率(%)
                    computeScore(item.getAssetLiabilityRatio(), resultBo::setAssetLiabilityRatio, standardMap, TargetValueConstant.DEBT_TO_ASSET_RATIO, 1D, 0.8D, 0.6D, 0.4D,true);
                    //计算 速动比率
                    computeScore(item.getQuickRatio(), resultBo::setQuickRatio, standardMap, TargetValueConstant.QUICK_RATIO, 1D, 0.8D, 0.6D, 0.4D);
                    //计算 现金流动负债比率(%)
                    computeScore(item.getCashToCurrentLiabilitiesRatio(), resultBo::setCashToCurrentLiabilitiesRatio, standardMap, TargetValueConstant.CASH_TO_CURRENT_LIABILITIES_RATIO, 1D, 0.8D, 0.6D, 0.4D);
                    //计算 研发经费投入强度(%)
                    computeScore(item.getRAndDDeploymentIntensity(), resultBo::setRAndDDeploymentIntensity, standardMap, TargetValueConstant.R_AND_D_INVESTMENT_RATE, 0.75D, 0.6D, 0.45D, 0.30D);
                    //计算 利润总额增长率(%)
                    computeScore(item.getTotalProfitGrowthRate(), resultBo::setTotalProfitGrowthRate, standardMap, TargetValueConstant.PROFIT_GROWTH_RATE, 0.75D, 0.6D, 0.45D, 0.30D);
                    //计算 营业总收入增长率(%)
                    computeScore(item.getOperatingIncomeGrowthRate(), resultBo::setOperatingIncomeGrowthRate, standardMap, TargetValueConstant.REVENUE_GROWTH_RATE, 0.5D, 0.4D, 0.3D, 0.2D);
                    //对resultBo中的所有字段求和
                    double total = resultBo.getNetAssetReturnRate() +
                            resultBo.getOperatingProfitMargin() +
                            resultBo.getSurplusCashSecurityRatio() +
                            resultBo.getTotalAssetsTurnover() +
                            resultBo.getAccountsReceivableTurnover() +
                            resultBo.getInventoryTurnover() +
                            resultBo.getAssetLiabilityRatio() +
                            resultBo.getQuickRatio() +
                            resultBo.getCashToCurrentLiabilitiesRatio() +
                            resultBo.getRAndDDeploymentIntensity() +
                            resultBo.getTotalProfitGrowthRate() +
                            resultBo.getOperatingIncomeGrowthRate();
                    //最低6分
                    if (total <= DefaultValueConstant.DEFAULT_FINANCIAL_SCORE) {
                        total = DefaultValueConstant.DEFAULT_FINANCIAL_SCORE;
                    }
                    resultBo.setTotal(
                            Double.parseDouble(String.format("%.2f",total))
                    );
                    return resultBo;
                });
        LambdaQueryWrapper<CrmHighTechZoneEnterprises> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(unifiedSocialCreditCode!=null, CrmHighTechZoneEnterprises::getUnifiedSocialCreditCode, unifiedSocialCreditCode);
        queryWrapper.like(enterpriseName!=null, CrmHighTechZoneEnterprises::getEnterpriseName, enterpriseName);
        List<CrmHighTechZoneEnterprises> crmHighTechZoneEnterprises = mapper.selectList(queryWrapper);
        Stream<FinancialResultBo> stream2 = crmHighTechZoneEnterprises.stream().map(w -> {
            FinancialResultBo companyScore = new FinancialResultBo();
            companyScore.setTotal(DefaultValueConstant.DEFAULT_FINANCIAL_SCORE);
            companyScore.setEnterpriseName(w.getEnterpriseName());
            companyScore.setUnifiedSocialCreditCode(w.getUnifiedSocialCreditCode());
            return companyScore;
        });
        List<FinancialResultBo> collect = new ArrayList<>(Stream.concat(stream2, stream1)
                .collect(Collectors.toMap(
                        CompanyScore::getUnifiedSocialCreditCode,
                        Function.identity(),
                        (v2, v1) -> v1
                )).values());
//        collect.stream().forEach(System.out::println);

        return collect;
    }

    public void trimItemWithParentheses(RmEnterprisePerformanceStandard z) {
        if (z.getItem() != null && z.getItem().contains("(")) {
            int index = z.getItem().indexOf("(");
            if (index != -1) {
                z.setItem(z.getItem().substring(0, index));
            }
        }
    }

    private void setScaleCategory(FinancialRatioBo item, Double needBeCompare, String large, String medium, String small) {
        if (needBeCompare >= Double.parseDouble(large)) {
            item.setScaleCategory(ScaleConstant.LARGE);
        } else if (needBeCompare >= Double.parseDouble(medium)) {
            item.setScaleCategory(ScaleConstant.MEDIUM);
        } else if (needBeCompare >= Double.parseDouble(small)) {
            item.setScaleCategory(ScaleConstant.SMALL);
        } else {
            item.setScaleCategory(ScaleConstant.ALL);
        }
    }

    private void computeScore(
            Double needBeCalc,
            Consumer<Double> action,
            Map<String, RmEnterprisePerformanceStandard> standardMap,
            String targetFiled,
            Double heightScore,
            Double goodScore,
            Double averageScore,
            Double lowerScore
    ) {
//        standardMap.get(targetFiled);
        RmEnterprisePerformanceStandard targetScore = standardMap.get(targetFiled);
        if (needBeCalc >= targetScore.getExcellentValue() || needBeCalc>=((targetScore.getExcellentValue()+ targetScore.getGoodValue())/2)) {
            action.accept(heightScore);
        } else if (needBeCalc >= targetScore.getGoodValue() || needBeCalc>=((targetScore.getGoodValue() + targetScore.getAverageValue())/2)) {
            action.accept(goodScore);
        } else if (needBeCalc >= targetScore.getAverageValue()) {
            action.accept(averageScore);
        } else if (needBeCalc >= targetScore.getLowerValue()) {
            action.accept(lowerScore);
        } else {
            action.accept(lowerScore);
        }
    }
    private void computeScore(
            Double needBeCalc,
            Consumer<Double> action,
            Map<String, RmEnterprisePerformanceStandard> standardMap,
            String targetFiled,
            Double heightScore,
            Double goodScore,
            Double averageScore,
            Double lowerScore,
            Boolean isSpecialComputed
    ) {
        RmEnterprisePerformanceStandard targetScore = standardMap.get(targetFiled);
        if(isSpecialComputed){
            if (needBeCalc <= targetScore.getExcellentValue() || needBeCalc<=((targetScore.getExcellentValue()+ targetScore.getGoodValue())/2)) {
                action.accept(heightScore);
            } else if (needBeCalc <= targetScore.getGoodValue() || needBeCalc<=((targetScore.getGoodValue()+ targetScore.getAverageValue())/2)) {
                action.accept(goodScore);
            } else if (needBeCalc <= targetScore.getAverageValue()) {
                action.accept(averageScore);
            } else if (needBeCalc <= targetScore.getLowerValue()) {
                action.accept(lowerScore);
            } else {
                action.accept(lowerScore);
            }
        }else {
            if (needBeCalc >= targetScore.getExcellentValue() || needBeCalc>=((targetScore.getExcellentValue()+ targetScore.getGoodValue())/2)) {
                action.accept(heightScore);
            } else if (needBeCalc >= targetScore.getGoodValue() || needBeCalc>=((targetScore.getGoodValue()+ targetScore.getAverageValue())/2)) {
                action.accept(goodScore);
            } else if (needBeCalc >= targetScore.getAverageValue()) {
                action.accept(averageScore);
            } else if (needBeCalc >= targetScore.getLowerValue()) {
                action.accept(lowerScore);
            } else {
                action.accept(lowerScore);
            }
        }
    }

    public FinancialRatioBo computeRatio(FinancialBo b) {
        //计算 净资产收益率（%） 净利润/(（年初净资产+年末净资产）/2)*100%
        Double a = b.getEndingNetProfit() / (b.getBeginningEquity() + b.getEndingEquity()) * 2 * 100.0;
        //计算 营业收入利润率（%） 营业利润/营业总收入*100%
        Double aa = b.getEndingOperatingProfit() / b.getEndingOperatingRevenue() * 100.0;
        //计算 盈余现金保障倍数 经营活动产生的现金流量净额/净利润
        Double aaa = b.getEndingCashFlowFromOperations() / b.getEndingNetProfit();
        //计算 总资产周转率（次） 营业总收入/（年初资产总额+年末资产总额）/2
        Double aaaa = b.getEndingOperatingRevenue() / ((b.getBeginningTotalAssets() + b.getEndingTotalAssets()) / 2);
        //计算 应收账款周转率（次） 营业总收入/（年初应收账款余额+年末应收账款余额）*2
        Double aaaaa = b.getEndingOperatingRevenue() / (b.getBeginningAccountsReceivable() + b.getEndingAccountsReceivable()) * 2;
        //计算 存货周转率（次） 营业成本/（年初存货余额+年末存货余额）*2
        Double aaaaaa = b.getEndingOperatingCost() / (b.getBeginningInventory() + b.getEndingInventory()) * 2;
        //计算 资产负债率（%） 负债总额/资产总额*100%
        Double aaaaaaa = b.getEndingTotalLiabilities() / b.getEndingTotalAssets() * 100.0;
        //计算 速动比率（%） （流动资产－存货）/流动负债
        Double aaaaaaaa = (b.getEndingCurrentAssets() - b.getEndingInventory()) / b.getEndingCurrentLiabilities();
        //计算 现金流动负债比率（%） 经营活动产生的现金流量净额/流动负债*100%
        Double aaaaaaaaa = b.getEndingCashFlowFromOperations() / b.getEndingCurrentLiabilities() * 100.0;
        //计算 研发经费投入强度 本年度研发（R&D）经费/营业总收入*100%
        Double aaaaaaaaaa = b.getEndingRAndDExpense() / b.getEndingOperatingRevenue() * 100.0;
        //计算 利润总额增长率（%） （本年利润总额－上年利润总额）/上年利润总额*100%
        Double aaaaaaaaaaa = (b.getEndingTotalProfit() - b.getBeginningTotalProfit()) / b.getBeginningTotalProfit() * 100.0;
        //计算 营业总收入增长率（%） （本年营业总收入－上年营业总收入）/上年营业总收入*100%
        Double aaaaaaaaaaaa = (b.getEndingOperatingRevenue() - b.getBeginningOperatingRevenue()) / b.getBeginningOperatingRevenue() * 100.0;
        //用社会统一工信码获取分类代码表
        LambdaQueryWrapper<CrmDomesticMarketEntityIndustryInfo> crmDomesticMarketEntityIndustryInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        crmDomesticMarketEntityIndustryInfoLambdaQueryWrapper.eq(CrmDomesticMarketEntityIndustryInfo::getUnifiedSocialCreditCode, b.getUnifiedSocialCreditCode());
        CrmDomesticMarketEntityIndustryInfo info = crmDomesticMarketEntityIndustryInfoMapper.selectOne(crmDomesticMarketEntityIndustryInfoLambdaQueryWrapper);
        String categoryCode = info.getIndustryCode();
        FinancialRatioBo ratioBo = new FinancialRatioBo(
                a,
                aa,
                aaa,
                aaaa,
                aaaaa,
                aaaaaa,
                aaaaaaa,
                aaaaaaaa,
                aaaaaaaaa,
                aaaaaaaaaa,
                aaaaaaaaaaa,
                aaaaaaaaaaaa,
                categoryCode,
                b.getUnifiedSocialCreditCode(),
                b.getEnterpriseName(),
                null,
                null,
                b.getEndingOperatingRevenue(),
                b.getEndingTotalAssets(),
                b.getPractitioners()
        );

        return ratioBo;
    }

    public List<FinancialBo> getCrmFinancialReportList(String unifiedSocialCreditCode,String enterpriseName) {
        return mapper.getCrmFinancialReportList(unifiedSocialCreditCode,enterpriseName);
    }

    @Override
    public Page creditScoreListDetails(String unifiedSocialCreditCode ,String enterpriseName, int pageNum, int pageSize) {
//        PageManager.setPageInfo(pageNum, pageSize);
//        PageResult pageResult = PageManager.getPage(mapper.creditScoreListDetails(unifiedSocialCreditCode));
        ThreadPoolRunTaskListUtil<List<CompanyScore>> listThreadPoolRunTaskListUtil = new ThreadPoolRunTaskListUtil<>(
                threadPool,
                () -> commitTask(this::finalFinancialScore, unifiedSocialCreditCode,enterpriseName,TotalNameSortMarkConstant.FINANCIAL_MARK),
                () -> commitTask(mapper::referenceCreditRating, unifiedSocialCreditCode,enterpriseName,TotalNameSortMarkConstant.REFERENCE_CREDIT_RATING_MARK),
                () -> commitTask(mapper::regulatoryPenalty, unifiedSocialCreditCode,enterpriseName,TotalNameSortMarkConstant.ADMINISTRATIVE_PENALTY_MARK),
                () -> commitTask(mapper::creditScoreDeductions, unifiedSocialCreditCode,enterpriseName,TotalNameSortMarkConstant.ADMINISTRATIVE_SUPERVISION_MARK),
                () -> commitTask(mapper::enterpriseScore, unifiedSocialCreditCode,enterpriseName,TotalNameSortMarkConstant.ENTERPRISE_COMPETITIVENESS_MARK),
                () -> commitTask(mapper::legalDeduction, unifiedSocialCreditCode,enterpriseName,TotalNameSortMarkConstant.JUDICIAL_SCORE_MARK)
        );
        Vector<List<CompanyScore>> resultVector = listThreadPoolRunTaskListUtil.runTaskList(Vector::new).getResultVector();
        LambdaQueryWrapper<CrmHighTechZoneEnterprises> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(unifiedSocialCreditCode!=null, CrmHighTechZoneEnterprises::getUnifiedSocialCreditCode, unifiedSocialCreditCode);
        queryWrapper.like(enterpriseName!=null, CrmHighTechZoneEnterprises::getEnterpriseName, enterpriseName);
        List<CrmHighTechZoneEnterprises> crmHighTechZoneEnterprises = mapper.selectList(queryWrapper);
        if(crmHighTechZoneEnterprises.isEmpty()){
            return null;
        }
        Function<List<CompanyScore>, Map<String, Double>> buildScoreMap = scores ->
                scores.stream()
                        .collect(Collectors.toMap(
                                CompanyScore::getUnifiedSocialCreditCode,
                                CompanyScore::getTotal,
                                (oldVal, newVal) -> newVal));
        List<CompanyScore> q = resultVector.stream().flatMap(List::stream).filter(i -> i.getSortMark().equals(TotalNameSortMarkConstant.FINANCIAL_MARK)).collect(Collectors.toList());
        List<CompanyScore> qq = resultVector.stream().flatMap(List::stream).filter(i -> i.getSortMark().equals(TotalNameSortMarkConstant.REFERENCE_CREDIT_RATING_MARK)).collect(Collectors.toList());
        List<CompanyScore> qqq = resultVector.stream().flatMap(List::stream).filter(i -> i.getSortMark().equals(TotalNameSortMarkConstant.ADMINISTRATIVE_PENALTY_MARK)).collect(Collectors.toList());
        List<CompanyScore> qqqq = resultVector.stream().flatMap(List::stream).filter(i -> i.getSortMark().equals(TotalNameSortMarkConstant.ADMINISTRATIVE_SUPERVISION_MARK)).collect(Collectors.toList());
        List<CompanyScore> qqqqq = resultVector.stream().flatMap(List::stream).filter(i -> i.getSortMark().equals(TotalNameSortMarkConstant.ENTERPRISE_COMPETITIVENESS_MARK)).collect(Collectors.toList());
        List<CompanyScore> qqqqqq = resultVector.stream().flatMap(List::stream).filter(i -> i.getSortMark().equals(TotalNameSortMarkConstant.JUDICIAL_SCORE_MARK)).collect(Collectors.toList());
        Map<String, Double> financialScoreMap = buildScoreMap.apply(q);
        Map<String, Double> referenceCreditRatingScoreMap = buildScoreMap.apply(qq);
        Map<String, Double> administrativePenaltyScoreMap = buildScoreMap.apply(qqq);
        Map<String, Double> administrativeSupervisionScoreMap = buildScoreMap.apply(qqqq);
        Map<String, Double> enterpriseCompetitivenessScoreMap = buildScoreMap.apply(qqqqq);
        Map<String, Double> judicialScoreMap = buildScoreMap.apply(qqqqqq);
        List<EvaluationReportDetailVo> vos = crmHighTechZoneEnterprises.stream().map(i -> {
            EvaluationReportDetailVo vo = new EvaluationReportDetailVo();
            vo.setEnterpriseName(i.getEnterpriseName());
            vo.setUnifiedSocialCreditCode(i.getUnifiedSocialCreditCode());
//            //设置财务评分
//            q.stream()
//                    .filter(j -> j.getUnifiedSocialCreditCode().equals(i.getUnifiedSocialCreditCode()))
//                    .findFirst()
//                    .ifPresent(j -> vo.setFinancialScore(j.getTotal()));
//            //设置参考信用评价得分
//            qq.stream()
//                    .filter(j -> j.getUnifiedSocialCreditCode().equals(i.getUnifiedSocialCreditCode()))
//                    .findFirst()
//                    .ifPresent(j -> vo.setReferenceCreditRatingScore(j.getTotal()));
//            //设置行政处罚得分
//            qqq.stream()
//                    .filter(j -> j.getUnifiedSocialCreditCode().equals(i.getUnifiedSocialCreditCode()))
//                    .findFirst()
//                    .ifPresent(j -> vo.setAdministrativePenaltyScore(j.getTotal()));
//            //设置行政监管、践诺履约得分
//            qqqq.stream()
//                    .filter(j -> j.getUnifiedSocialCreditCode().equals(i.getUnifiedSocialCreditCode()))
//                    .findFirst()
//                    .ifPresent(j -> vo.setAdministrativeSupervisionScore(j.getTotal()));
//            //设置企业竞争力得分
//            qqqqq.stream()
//                    .filter(j -> j.getUnifiedSocialCreditCode().equals(i.getUnifiedSocialCreditCode()))
//                    .findFirst()
//                    .ifPresent(j -> vo.setEnterpriseCompetitivenessScore(j.getTotal()));
//            //设置司法裁判得分
//            qqqqqq.stream()
//                    .filter(j -> j.getUnifiedSocialCreditCode().equals(i.getUnifiedSocialCreditCode()))
//                    .findFirst()
//                    .ifPresent(j -> vo.setJudicialScore(j.getTotal()));
            //设置财务评分
            vo.setFinancialScore(this.getScoreOrDefault(financialScoreMap, i.getUnifiedSocialCreditCode(), 0.0));
            //设置参考信用评价得分
            vo.setReferenceCreditRatingScore(this.getScoreOrDefault(referenceCreditRatingScoreMap, i.getUnifiedSocialCreditCode(), 0.0));
            //设置行政处罚得分
            vo.setAdministrativePenaltyScore(this.getScoreOrDefault(administrativePenaltyScoreMap, i.getUnifiedSocialCreditCode(), 0.0));
            //设置行政监管、践诺履约得分
            vo.setAdministrativeSupervisionScore(this.getScoreOrDefault(administrativeSupervisionScoreMap, i.getUnifiedSocialCreditCode(), 0.0));
            //设置企业竞争力得分
            vo.setEnterpriseCompetitivenessScore(this.getScoreOrDefault(enterpriseCompetitivenessScoreMap, i.getUnifiedSocialCreditCode(), 0.0));
            //设置司法裁判得分
            vo.setJudicialScore(this.getScoreOrDefault(judicialScoreMap, i.getUnifiedSocialCreditCode(), 0.0));
            //设置总分
            vo.setTotal(
                    vo.getFinancialScore()+
                    vo.getReferenceCreditRatingScore()+
                    vo.getAdministrativePenaltyScore()+
                    vo.getAdministrativeSupervisionScore()+
                    vo.getEnterpriseCompetitivenessScore()+
                    vo.getJudicialScore()
            );
            if (vo.getTotal() >= ScoreConstant.AAA) {
                vo.setGrade(GradeConstant.AAA_GRADE);
            } else if (vo.getTotal() >= ScoreConstant.AA) {
                vo.setGrade(GradeConstant.AA_GRADE);
            } else if (vo.getTotal() >= ScoreConstant.A) {
                vo.setGrade(GradeConstant.A_GRADE);
            } else if (vo.getTotal() >= ScoreConstant.B) {
                vo.setGrade(GradeConstant.B_GRADE);
            } else if (vo.getTotal() >= ScoreConstant.C) {
                vo.setGrade(GradeConstant.C_GRADE);
            } else {
                vo.setGrade(GradeConstant.D_GRADE);
            }
            return vo;

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

        //判断直接得分C的情况
        List<CrmHighTechZoneEnterprises> judgingAsC = mapper.ratedLevelC(unifiedSocialCreditCode);
        if(!judgingAsC.isEmpty()){
            judgingAsC.stream().forEach(item -> {
                vos.stream()
                        .filter(c->c.getUnifiedSocialCreditCode().equals(item.getUnifiedSocialCreditCode()))
                        .findFirst()
                        .ifPresent(f->f.setGrade(GradeConstant.C_GRADE));
            });
        }
        //判断直接得分D的情况
        List<CrmHighTechZoneEnterprises> judgingAsD = mapper.ratedLevelD(unifiedSocialCreditCode);
        if(!judgingAsD.isEmpty()){
            judgingAsD.stream().forEach(item -> {
                vos.stream()
                        .filter(c->c.getUnifiedSocialCreditCode().equals(item.getUnifiedSocialCreditCode()))
                        .findFirst()
                        .ifPresent(f->f.setGrade(GradeConstant.D_GRADE));
            });
        }
        //排序列表
        List<String> order = Arrays.asList("AAA","AA","A", "B", "C", "D");
        List<EvaluationReportDetailVo> sortedVos = vos.stream()
                .sorted(Comparator.comparing(CompanyScore::getTotal).reversed())
                .sorted(Comparator.comparingInt(c -> order.indexOf(c.getGrade())))
                .collect(Collectors.toList());
        int totalSize = sortedVos.size(); // 总记录数
        int totalPages = (int)Math.ceil((double)totalSize / pageSize); // 总页数，向上取整
        // 应用自定义内存分页逻辑
        List<EvaluationReportDetailVo> paginatedCollect = memoryPage(sortedVos, pageNum, pageSize);
// 封装分页结果
        PageResult pageResult = new PageResult();
        pageResult.setPageNo(pageNum); // 或者使用pageNo，根据您的命名习惯
        pageResult.setPageSize(pageSize);
        pageResult.setTotalPage(totalPages);
        pageResult.setTotalSize(totalSize);
        pageResult.setResult(paginatedCollect); // 分页后的数据列表

// 返回Page对象，假设PageUtil有相应转换方法
        return PageUtil.convertPageResult2Page(pageResult);
    }
    // 辅助方法，用于从映射中获取分数，如果没有找到则返回默认值
    private double getScoreOrDefault(Map<String, Double> map, String key, double defaultValue) {
        return map.getOrDefault(key, defaultValue);
    }
    @Override
    public AjaxResult creditScoreMostDetailsByUniCode(String unifiedSocialCreditCode) {
        ThreadPoolRunTaskListUtil<Object> listThreadPoolRunTaskListUtil = new ThreadPoolRunTaskListUtil<Object>(
                threadPool,
                () -> commitTaskForAny(mapper::enterpriseScore, unifiedSocialCreditCode,TotalNameSortMarkConstant.SORTED_FIRST),
                () -> commitTaskForAny(this::finalFinancialScore, unifiedSocialCreditCode,TotalNameSortMarkConstant.SORTED_SECOND),
                () -> commitTaskForAny(mapper::legalDeduction, unifiedSocialCreditCode,TotalNameSortMarkConstant.SORTED_THIRD),
                () -> commitTaskForAny(mapper::regulatoryPenalty, unifiedSocialCreditCode,TotalNameSortMarkConstant.SORTED_FOURTH),
                () -> commitTaskForAny(mapper::creditScoreDeductions, unifiedSocialCreditCode,TotalNameSortMarkConstant.SORTED_FIFTH),
                () -> commitTaskForAny(mapper::referenceCreditRating, unifiedSocialCreditCode,TotalNameSortMarkConstant.SORTED_SIXTH)
        );
        Vector<Object> resultVector = listThreadPoolRunTaskListUtil.runTaskList(Vector::new).getResultVector();
        LinkedHashMap<String, Double> resMap = new LinkedHashMap<>();
        if (resultVector == null || resultVector.isEmpty()) {
            return AjaxResult.error("出现了问题，请联系管理员");
        }
        Collections.sort((List<List<SortMarkBo>>) (List<?>) resultVector, Comparator.comparingInt(a -> a.get(0).getSortMark()));
        for (Object obj : resultVector){
            if(obj instanceof List<?>){
                List<?> itemList = (List<?>) obj;
                for (Object o : itemList) {
                    if(o instanceof EnterpriseScoreDto)setResMap(o, resMap);
                    if(o instanceof FinancialResultBo)setResMap(o, resMap);
                    if(o instanceof LegalDeductionDto)setResMap(o, resMap);
                    if(o instanceof RegulatoryPenaltyDto)setResMap(o, resMap);
                    if(o instanceof CreditScoreDeductionsDto)setResMap(o, resMap);
                    if(o instanceof CreditRatingEntityDto)setResMap(o, resMap);
                }
            }
        }
        return AjaxResult.success(resMap);
    }

    private static void setResMap(Object o, LinkedHashMap<String, Double> resMap) {
        Class<?> clazz = o.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            try {
                field.setAccessible(true);
                if (field.getType() == Double.class || field.getType() == double.class) {
                    Double value = (Double) field.get(o);
                    String fieldName = field.getName();
                    resMap.put(fieldName, value);
                }
            } catch (IllegalAccessException e) {
                // 处理解析字段失败的情况
                log.error("获取字段失败:{}",field.getName());
            }
        }
    }

    public <K extends SortMarkBo> List<K> commitTaskForAny(BiFunction<String,String, List<K>> function, String unifiedSocialCreditCode, Integer sortMark) {
        List<K> bos = function.apply(unifiedSocialCreditCode,"");
        bos.stream().forEach(q->{
            q.setSortMark(sortMark);
        });
        return bos;
    }


    @Override
    public AjaxResult enterpriseDetails(String unifiedSocialCreditCode) {
        List<QueryResult<?>> results = Arrays.stream(DataUtil.tableStrings)
                .map(tableName -> {
                    List<Map<String, Object>> data = mapper.getTableDataMap(tableName, unifiedSocialCreditCode);
                    if (!data.isEmpty()) {
                        List<Map<String, Object>> orderedData = data.stream()
                                .map(map -> new LinkedHashMap<>(map))
                                .collect(Collectors.toList());

                        return new QueryResult<>(tableName, orderedData);
                    } else {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return AjaxResult.success(results);
    }

    @Override
    public AjaxResult download(String unifiedSocialCreditCode, HttpServletResponse response) {
        XWPFDocument document = new XWPFDocument();
        LocalDate today = LocalDate.now(); // 获取当前日期
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日", Locale.CHINA); // 定义中文日期格式
        String chineseDate = today.format(formatter); // 将日期格式化为中文格式

        Page creditScoreListDetails = this.creditScoreList(unifiedSocialCreditCode,"",1,100000);
        List<GradeVo> evaluationReportDetailVoList = (List<GradeVo>) creditScoreListDetails.getResult();
        // 创建封面
        XWPFParagraph topName = document.createParagraph();
        topName.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun topName1 = topName.createRun();
        topName1.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        topName1.setBold(true);
        topName1.setText("怀化高新区信用分级分类服务平台");
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();

        XWPFParagraph coverTitlePara = document.createParagraph();
        coverTitlePara.setAlignment(ParagraphAlignment.CENTER); // 居中对齐
        XWPFRun coverTitleRun = coverTitlePara.createRun();
        coverTitleRun.setFontSize(16 * 2); // 字体大小，这里以24pt为例，转换为Half Points
        coverTitleRun.setBold(true);
        coverTitleRun.setText("企业信用报告");
        document.createParagraph();

        // 添加企业名称、得分和等级
        XWPFParagraph enterprise = document.createParagraph();
        enterprise.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun enterprise1 = enterprise.createRun();
        enterprise1.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        enterprise1.setBold(true);
        enterprise1.setText("企业名称：" + evaluationReportDetailVoList.get(0).getEnterpriseName());
        document.createParagraph();

        XWPFParagraph unifiedSocialCreditCodeParagraph = document.createParagraph();
        unifiedSocialCreditCodeParagraph.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun unifiedSocialCreditCode1 = unifiedSocialCreditCodeParagraph.createRun();
        unifiedSocialCreditCode1.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        unifiedSocialCreditCode1.setBold(true);
        unifiedSocialCreditCode1.setText("统一社会信用代码：" + evaluationReportDetailVoList.get(0).getUnifiedSocialCreditCode());
        document.createParagraph();

        XWPFParagraph enterpriseInfo = document.createParagraph();
        enterpriseInfo.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun enterpriseInfo2 = enterpriseInfo.createRun();
        enterpriseInfo2.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        enterpriseInfo2.setBold(true);
        enterpriseInfo2.setText("得         分：" + String.format("%.2f", evaluationReportDetailVoList.get(0).getTotal()));
        document.createParagraph();

        XWPFParagraph enterpriseInfoPara = document.createParagraph();
        enterpriseInfoPara.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun enterpriseInfoRun = enterpriseInfoPara.createRun();
        enterpriseInfoRun.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        enterpriseInfoRun.setBold(true);
        enterpriseInfoRun.setText("等         级：" + evaluationReportDetailVoList.get(0).getGrade());
        // 增加换行
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();
        document.createParagraph();

        XWPFParagraph endInfoPara = document.createParagraph();
        endInfoPara.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun endInfoParaRun = endInfoPara.createRun();
        endInfoParaRun.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        endInfoParaRun.setBold(true);
        endInfoParaRun.setText("报告生成日期：" + chineseDate);

        XWPFParagraph endInfo = document.createParagraph();
        endInfo.setAlignment(ParagraphAlignment.CENTER);
        XWPFRun endInfoRun = endInfo.createRun();
        endInfoRun.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        endInfoRun.setBold(true);
        endInfoRun.setText("报告出具单位：怀化高新技术产业开发区管理委员会");

        XWPFParagraph pageBreak = document.createParagraph();
        pageBreak.setPageBreak(true);

        // 添加企业名称、社会信用代码、得分和等级
        XWPFParagraph enterpriseNameParagraph = document.createParagraph();
        enterpriseNameParagraph.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun enterpriseNameRun = enterpriseNameParagraph.createRun();
        enterpriseNameRun.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        enterpriseNameRun.setText("企业名称：" + evaluationReportDetailVoList.get(0).getEnterpriseName());

        XWPFParagraph unifiedSocialCreditCodeParagraph0 = document.createParagraph();
        unifiedSocialCreditCodeParagraph0.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun unifiedSocialCreditCodeH = unifiedSocialCreditCodeParagraph0.createRun();
        unifiedSocialCreditCodeH.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        unifiedSocialCreditCodeH.setText("统一社会信用代码：" + evaluationReportDetailVoList.get(0).getUnifiedSocialCreditCode());

        XWPFParagraph totalParagraph = document.createParagraph();
        totalParagraph.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun totalRun = totalParagraph.createRun();
        totalRun.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        totalRun.setText("得         分：" + String.format("%.2f", evaluationReportDetailVoList.get(0).getTotal()));

        XWPFParagraph gradeInfoPara = document.createParagraph();
        gradeInfoPara.setAlignment(ParagraphAlignment.LEFT);
        XWPFRun gradeInfoParaRun = gradeInfoPara.createRun();
        gradeInfoParaRun.setFontSize(8 * 2); // 字体大小，这里以18pt为例，转换为Half Points
        gradeInfoParaRun.setText("等         级：" + evaluationReportDetailVoList.get(0).getGrade());
        document.createParagraph();

        Set<String> excludedColumns = new HashSet<>(Arrays.asList("id", "unified_social_credit_code","create_time", "update_time")); // 定义需要排除的列名
        // 假设mapper中新增了两个方法来获取表名和字段的中文描述
        for (String tableName : Arrays.asList(DataUtil.tableStrings)) { // 获取所有表名
                // 这里处理前7列
                int columnsLimit = 7;
                // 获取表的中文描述作为二级标题
                String tableChineseTitle = mapper.getTableComment(tableName);
                List<String> columnNames = mapper.getColumnNames(tableName); // 获取表的字段名
            List<String> filteredColumnNames = columnNames.stream()
                    .filter(name -> !excludedColumns.contains(name))
                    .collect(Collectors.toList());

            Map<String, String> columnDescriptionMap = columnNames.stream()
                    .collect(Collectors.toMap(
                            name -> name,
                            name -> mapper.getColumnComment(tableName, name)
                    ));
            // 过滤掉不需要的描述
            List<String> filteredColumnDescriptions = filteredColumnNames.stream()
                    .map(columnDescriptionMap::get)
                    .collect(Collectors.toList());
                // 确保字段名和其描述一一对应
                if (filteredColumnNames.size() != filteredColumnDescriptions.size()) {
                    throw new IllegalStateException("字段名和字段描述数量不匹配");
                }
                List<Map<String, Object>> data = mapper.getTableDataMap(tableName, unifiedSocialCreditCode); // 获取表的数据

                //设置标题
                // 在调用addSectionTitle时，传入期望的字体大小（这里需要转换为Half Points，1pt=2Half Points），和是否加粗
                addSectionTitle(document, tableChineseTitle, 2, "SimHei", 8 * 2, true); // 小二号字约为12pt，转换为Half Points即为24*2

                // 判断数据是否为空
                if (data == null || data.isEmpty()) {
                    XWPFParagraph paragraph = document.createParagraph();
                    paragraph.setStyle("SimHei");
                    // 如果数据为空，插入自定义文字
                    XWPFRun run = paragraph.createRun();
                    run.setFontSize(12); // 字号转换为Half Points
                    run.setBold(true);
                    run.setText("截止"+chineseDate+"，暂未查询到相关信息，仅供参考。");
                    continue; // 跳过当前循环的剩余部分，避免创建空表格
                }

                //设置表头
                // 新建表格，并设置表格标题（使用字段的中文描述）
                XWPFTable table = document.createTable();
                setTableHeaderCellStyle(table, 0, filteredColumnDescriptions);
                for (Map<String, Object> rowMap : data) {
                    XWPFTableRow dataRow = table.createRow();
                    IntStream.range(0, Math.min(filteredColumnNames.size(), columnsLimit))
                            .forEach(i -> {
                                XWPFTableCell cell = dataRow.getCell(i) != null ? dataRow.getCell(i) : dataRow.createCell();
                                cell.setText(String.valueOf(rowMap.getOrDefault(filteredColumnNames.get(i), "")));
                            });
                }
        }
        try {
            QueryWrapper<CrmHighTechZoneEnterprises> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("unified_social_credit_code", unifiedSocialCreditCode);
            CrmHighTechZoneEnterprises  crmHighTechZoneEnterprises= this.baseMapper.selectOne(queryWrapper);
            sectionNumber = 1;
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            document.write(byteArrayOutputStream);
            document.close();

            byte[] bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();

            response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
            response.setHeader("Content-Disposition", "attachment; filename="+crmHighTechZoneEnterprises.getEnterpriseName()+".docx");

            OutputStream out = response.getOutputStream();
            out.write(bytes);
            out.flush();
            out.close();
            return null;
            /*sectionNumber = 1;
            FileOutputStream out = new FileOutputStream("output.docx");
            document.write(out);
            out.close();
            document.close();
            return null;*/
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    // 辅助方法：添加指定级别的标题，并允许自定义字体、字号和是否加粗
    private void addSectionTitle(XWPFDocument document, String title, int level, String fontFamily, int fontSize, boolean isBold) {
        String styleId = level == 1 ? "Heading1" : "Heading2"; // 假设我们使用 Heading1 和 Heading2 样式

        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setStyle(styleId);

        CTFonts fonts = paragraph.getCTP().getPPr().addNewRPr().addNewRFonts();
        fonts.setAscii(fontFamily);
        fonts.setHAnsi(fontFamily);
        fonts.setEastAsia(fontFamily); // 确保中文支持

        // 构建带有序号的标题文本
        String numberedTitle = sectionNumber + ". " + title;
        sectionNumber++; // 序号递增

        XWPFRun run = paragraph.createRun();
        run.setFontSize(fontSize); // 字号转换为Half Points
        run.setBold(isBold);
        run.setColor("0084FF");
        run.setText(numberedTitle);

        // 模拟标题样式的一些其他特性，如行距等（这一步是可选的，根据需要调整）
        CTPPr ppr = paragraph.getCTP().getPPr();
        if (ppr == null) {
            ppr = paragraph.getCTP().addNewPPr();
        }
        ppr.addNewSpacing().setAfter(240); // 例如，设置段落后间距为240 Twips (12pt)
    }
    private void setTableHeaderCellStyle(XWPFTable table, int rowIndex, List<String> descriptions) {
        XWPFTableRow row = table.getRow(rowIndex);
        if (row != null) {
            for (int i = 0; i < Math.min(descriptions.size(), 7); i++) {
                XWPFTableCell cell = row.getCell(i) != null ? row.getCell(i) : row.createCell();
                cell.setColor("C0C0C0");
                cell.getParagraphs().forEach(p -> {
                    p.setAlignment(ParagraphAlignment.CENTER);
                    // 设置其他样式如字体、大小等
                });
                cell.setText(descriptions.get(i));
            }
        }
    }

    @Override
    public AjaxResult getDeductionPoints() {
        List<String> codeString = mapper.getDeductionPoints();
        return AjaxResult.success("查询成功",codeString);
    }

    @Override
    @Transactional
    public AjaxResult deleteAll() {
        DeleteTableUtils<CrmHighTechZoneEnterprises> utils = new DeleteTableUtils<>();
        utils.del(CrmHighTechZoneEnterprises::getId, mapper);
        return AjaxResult.success("全部删除成功");
    }
}
