package com.hzs.report.member.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.hzs.common.core.constant.msg.ConfigMsgConstants;
import com.hzs.common.core.domain.R;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.CommonUtil;
import com.hzs.common.domain.report.stat.StatisticalLog;
import com.hzs.report.member.mapper.CuMemberAwardsStatMapper;
import com.hzs.report.member.service.ICuMemberAwardsStatService;
import com.hzs.report.member.service.IStatisticalLogService;
import com.hzs.report.member.vo.*;
import com.hzs.system.sys.IApprovalServiceApi;
import com.hzs.system.sys.dto.ApprovalSubmitDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 会员信息-奖衔升级记录 服务实现类
 */
@Service
public class CuMemberAwardsStatServiceImpl implements ICuMemberAwardsStatService {

    @Autowired
    private CuMemberAwardsStatMapper cuMemberAwardsStatMapper;
    @Autowired
    private IStatisticalLogService iStatisticalLogService;

    @DubboReference
    IApprovalServiceApi iApprovalServiceApi;

    @Override
    public List<CuMemberAwardsStatVO> selectCuMemberAwardsList(CuMemberAwardsStatVO cuMemberAwardsStatVO) {
        return cuMemberAwardsStatMapper.selectCuMemberAwardsList(cuMemberAwardsStatVO);
    }

    @Override
    public List<AwardPromotionVO> awardPromotionList(AwardPromotionVO awardPromotionVO) {
        return cuMemberAwardsStatMapper.awardPromotionList(awardPromotionVO);
    }

    @Override
    public List<MemberAchieveVO> memberAchieveList(MemberAchieveVO memberAchieveVO) {
        return cuMemberAwardsStatMapper.memberAchieveList(memberAchieveVO);
    }

    @Override
    public List<PersonStatVO> selectPersonStatList(PersonStatVO personStatVO) {
        return cuMemberAwardsStatMapper.selectPersonStatList(personStatVO);
    }

    @Override
    public List<CuMemberAwardsAnalysisVO> selectCuMemberAwardsAnalysisList(CuMemberAwardsAnalysisVO cuMemberAwardsAnalysisVO) {
        return cuMemberAwardsStatMapper.selectCuMemberAwardsAnalysisList(cuMemberAwardsAnalysisVO);
    }

    @Override
    public List<CuMemberAwardsAnalysisVO> selectAwardsAnalysisList(List<CuMemberAwardsAnalysisVO> list) {
        return cuMemberAwardsStatMapper.selectAwardsAnalysisList(list);
    }

    @Override
    public List<BloodRemoveSameVO> bloodRemoveSameAllList(BloodRemoveSameVO bloodList,
                                                          String startDate, String endDate,
                                                          List<Integer> orderTypeList,
                                                          List<Integer> pkAwardsList
    ) {
        return cuMemberAwardsStatMapper.bloodRemoveSameAllList(bloodList, startDate, endDate, orderTypeList, pkAwardsList);
    }

    @Override
    public List<BloodRemoveSameVO> bloodSameAllListHistory(List<BloodRemoveSameVO> bloodList,
                                                           Integer periodEnd,
                                                           Integer periodSta,
                                                           String achieveTableNameEnd,
                                                           String achieveTableNameSta,
                                                           String settleTableNameSta,
                                                           String settleTableNameEnd,
                                                           Integer orderType

    ) {
        return cuMemberAwardsStatMapper.bloodSameAllListHistory(bloodList, periodEnd, periodSta, achieveTableNameEnd,
                achieveTableNameSta, settleTableNameSta, settleTableNameEnd, orderType);
    }

    @Override
    public List<BloodRemoveSameVO> bloodRemoveSameMemberAchieveNew(List<BloodRemoveSameVO> bloodList,
                                                                   Integer periodEnd,
                                                                   Integer periodSta,
                                                                   String achieveTableNameEnd,
                                                                   String achieveTableNameSta,
                                                                   String settleTableNameSta,
                                                                   String settleTableNameEnd,
                                                                   Integer orderType,
                                                                   Integer pkCountry, List<Integer> pkAwardsList

    ) {
        return cuMemberAwardsStatMapper.bloodRemoveSameMemberAchieveNew(bloodList, periodEnd, periodSta, achieveTableNameEnd,
                achieveTableNameSta, settleTableNameSta, settleTableNameEnd, orderType, pkCountry, pkAwardsList);
    }

    @Override
    public List<BloodRemoveSameVO> queryAwardAchieList(BloodRemoveSameVO bloodRemoveSameVO) {
        return cuMemberAwardsStatMapper.queryAwardAchieList(bloodRemoveSameVO);
    }

    @Override
    public List<BloodRemoveSameVO> queryAwardAchieListHistory(BloodRemoveSameVO bloodRemoveSameVO) {
        return cuMemberAwardsStatMapper.queryAwardAchieListHistory(bloodRemoveSameVO);
    }

    @Override
    public List<CuMemberAwardsAnalysisVO> selectCuMemberAwardsAnalysisDetailsList(CuMemberAwardsAnalysisVO cuMemberAwardsAnalysisVO) {
        return cuMemberAwardsStatMapper.selectCuMemberAwardsAnalysisDetailsList(cuMemberAwardsAnalysisVO);
    }

    @Override
    public List<RevenueDetailsVO> selectRevenueDetailsList(RevenueDetailsVO revenueDetailsVO) {
        return cuMemberAwardsStatMapper.selectRevenueDetailsList(revenueDetailsVO);
    }

    @Override
    public List<PersonStatVO> selectPersonPvList(List<PersonStatVO> perList) {
        return cuMemberAwardsStatMapper.selectPersonPvList(perList);
    }

    @Override
    public List<DirectPushVO> selectDirectPushStatList(DirectPushVO directPushVO) {
        return cuMemberAwardsStatMapper.selectDirectPushStatList(directPushVO);
    }

    @Override
    public List<DirectPushDataVO> selectDirectPushDataList(DirectPushDataVO dpdVO) {
        return cuMemberAwardsStatMapper.selectDirectPushDataList(dpdVO);
    }

    @Override
    public List<DirectPushDataVO> selectDirectPushDataDetails(DirectPushDataVO dpdVO) {
        return cuMemberAwardsStatMapper.selectDirectPushDataDetails(dpdVO);
    }

    @Override
    public List<OrderScatterVO> memberOrderScatter(OrderScatterVO orderScatterVO) {
        return cuMemberAwardsStatMapper.memberOrderScatter(orderScatterVO);
    }

    @Override
    public List<Integer> awardsLevellist(List<Integer> pkAwardsList, Integer pkCountry) {
        return cuMemberAwardsStatMapper.awardsLevellist(pkAwardsList, pkCountry);
    }

    @Override
    public List<BloodRemoveSameVO> bloodRemoveSameList(BloodRemoveSameVO bloodRemoveSameVO) {
        List<Integer> orderTypeList = bloodRemoveSameVO.getOrderTypeList();
        List<Integer> pkAwardsList = bloodRemoveSameVO.getPkAwardsList();
        bloodRemoveSameVO.setOrderTypeList(orderTypeList);
        if (null != bloodRemoveSameVO.getPkAwards() && CollectionUtil.isEmpty(pkAwardsList)) {
            pkAwardsList.add(bloodRemoveSameVO.getPkAwards());
            bloodRemoveSameVO.setPkAwardsList(pkAwardsList);
        }
        //根据奖衔查询所有会员
        List<BloodRemoveSameVO> achieList = queryAwardAchieList(bloodRemoveSameVO);

        List<BloodRemoveSameVO> allList = new ArrayList<>();
        //查询直推血缘去重的业绩金额
        if (CollectionUtil.isNotEmpty(achieList)) {
            //查询全部伞下血缘业绩
            for (BloodRemoveSameVO brs : achieList) {
                List<BloodRemoveSameVO> allList1 = bloodRemoveSameAllList(brs, bloodRemoveSameVO.getStartDate(),
                        bloodRemoveSameVO.getEndDate(), orderTypeList, pkAwardsList);
                allList.addAll(allList1);
            }
        }
        return allList;
    }

    @Override
    public List<BloodRemoveSameVO> bloodRemoveSameListHistoryNew(BloodRemoveSameVO bloodRemoveSameVO) {
        List<Integer> orderTypeList = bloodRemoveSameVO.getOrderTypeList();
        List<Integer> pkAwardsList = bloodRemoveSameVO.getPkAwardsList();
        bloodRemoveSameVO.setOrderTypeList(orderTypeList);
        if (null != bloodRemoveSameVO.getPkAwards() && CollectionUtil.isEmpty(pkAwardsList)) {
            pkAwardsList.add(bloodRemoveSameVO.getPkAwards());
            bloodRemoveSameVO.setPkAwardsList(pkAwardsList);
        }
        List<BloodRemoveSameVO> allList = new ArrayList<>();
        //根据奖衔查询所有会员
        List<BloodRemoveSameVO> achieList = queryAwardAchieListHistory(bloodRemoveSameVO);
        if (CollectionUtil.isNotEmpty(achieList)) {
            //查询会员的所有血缘业绩
            allList = bloodSameAllListHistory(achieList, bloodRemoveSameVO.getPeriodEnd(), bloodRemoveSameVO.getPeriodSta(),
                    bloodRemoveSameVO.getAchieveTableNameEnd(), bloodRemoveSameVO.getAchieveTableNameSta(),
                    bloodRemoveSameVO.getSettleTableNameSta(),
                    bloodRemoveSameVO.getSettleTableNameEnd(), bloodRemoveSameVO.getOrderType());
            Map<Long, BloodRemoveSameVO> allMap = allList.stream()
                    .collect(Collectors.toMap(BloodRemoveSameVO::getPkMember, Function.identity()));
            //查询伞下要去重的会员业绩
            List<BloodRemoveSameVO> brsmAchieveListAll = new ArrayList<>();
            for (BloodRemoveSameVO brs : achieList) {
                List<BloodRemoveSameVO> brsmAchieveList = bloodRemoveSameMemberAchieveNew(Collections.singletonList(brs), bloodRemoveSameVO.getPeriodEnd(), bloodRemoveSameVO.getPeriodSta(),
                        bloodRemoveSameVO.getAchieveTableNameEnd(), bloodRemoveSameVO.getAchieveTableNameSta(),
                        bloodRemoveSameVO.getSettleTableNameSta(),
                        bloodRemoveSameVO.getSettleTableNameEnd(), bloodRemoveSameVO.getOrderType(),
                        bloodRemoveSameVO.getPkCountry(), pkAwardsList);
                brsmAchieveListAll.addAll(brsmAchieveList);
            }
            if (CollectionUtil.isNotEmpty(brsmAchieveListAll)) {
                Map<Long, BloodRemoveSameVO> brsmAchieveMap = brsmAchieveListAll.stream()
                        .collect(Collectors.toMap(BloodRemoveSameVO::getPkMember, Function.identity()));
                allMap.forEach((key, value) -> {
                    brsmAchieveMap.forEach((key1, value1) -> {
                        if (key.equals(key1)) {
                            value.setOrderAmount(value.getOrderAmount().subtract(brsmAchieveMap.get(key1).getOrderAmount()));
                            value.setOrderAchieve(value.getOrderAchieve().subtract(brsmAchieveMap.get(key1).getOrderAchieve()));
                        }
                    });
                });
            }
        }
        return allList;
    }

    @Override
    public List<ResettleBloodVO> resettleBloodList(ResettleBloodVO resettleBloodVO) {
        List<ResettleBloodVO> resettleBloodList = new ArrayList<>();
        List<ResettleBloodVO> lrMemberCountList = cuMemberAwardsStatMapper.lrMemberCountList(resettleBloodVO);
        if (CollectionUtil.isNotEmpty(lrMemberCountList)) {
            lrMemberCountList.forEach(itm -> {
                if (itm.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                    resettleBloodVO.setLMemberCount(itm.getMemberCount());
                }
                if (itm.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                    resettleBloodVO.setRMemberCount(itm.getMemberCount());
                }
            });
        }
        List<ResettleBloodVO> lrbMemberCountList = cuMemberAwardsStatMapper.lrbMemberCountList(resettleBloodVO);
        if (CollectionUtil.isNotEmpty(lrbMemberCountList)) {
            lrbMemberCountList.forEach(itm -> {
                if (itm.getPlaceDept() == EPlaceDept.LEFT_DEPT.getValue()) {
                    resettleBloodVO.setLbMemberCount(itm.getMemberCount());
                }
                if (itm.getPlaceDept() == EPlaceDept.RIGHT_DEPT.getValue()) {
                    resettleBloodVO.setRbMemberCount(itm.getMemberCount());
                }
            });
        }
        resettleBloodList.add(resettleBloodVO);
        return resettleBloodList;
    }

    @Override
    public List<ResettleBloodVO> lrMemberDetailsList(ResettleBloodVO resettleBloodVO) {
        return cuMemberAwardsStatMapper.lrMemberDetailsList(resettleBloodVO);
    }

    @Override
    public List<ResettleBloodVO> lrbMemberDetailsList(ResettleBloodVO resettleBloodVO) {
        return cuMemberAwardsStatMapper.lrbMemberDetailsList(resettleBloodVO);
    }

    @Override
    public boolean petition(NoticeMemberVO nmvo) {
        //业务单号
        String code = CommonUtil.createSerialNumber(EOrderPrefix.MESSAGE_PLATFORM.getValue());
        // 修改审核状态
        StatisticalLog stLog = new StatisticalLog();
        stLog.setPkCreator(nmvo.getPkCreate());
        stLog.setCreationTime(nmvo.getCreationTime());
        stLog.setPkCountry(nmvo.getPkCountry());
        stLog.setApproveStatus(EApproveStatus.ALREADY_SUBMIT.getValue());
        stLog.setBusinessNo(code);
        stLog.setEditType(EApprovalBusiness.DIRECT_PUSH_DATA_MAIL.getValue());
        stLog.setOperationContent(JSONObject.toJSONString(nmvo));
        iStatisticalLogService.save(stLog);
        Set<Long> pkMemberSet = new HashSet<>(nmvo.getPkMemberList());
        //生成签呈
        ApprovalSubmitDTO approvalSubmitDTO = ApprovalSubmitDTO.builder().eApprovalBusiness(EApprovalBusiness.DIRECT_PUSH_DATA_MAIL)
                .businessCode(code)
                .signType(ESignType.getEnumByValue(nmvo.getSignType()))
                .remark(nmvo.getRemark())
                .pkMemberList(pkMemberSet)
                .userIdList(nmvo.getUserIdList())
                .sendIdList(nmvo.getSendIdList())
                .fileList(nmvo.getFileList())
                .build();
        R<String> submit = iApprovalServiceApi.submit(approvalSubmitDTO, nmvo.getLoginUser());
        if (!submit.isSuccess()) {
            throw new RuntimeException(ConfigMsgConstants.DIRECT_PUSH_DATA_MAIL);
        }
        return true;
    }

    @Override
    public List<PersonRepurchaseVO> personRepurchaseList(PersonRepurchaseVO prVO) {
        return cuMemberAwardsStatMapper.personRepurchaseList(prVO);
    }

    @Override
    public List<PositStatVO> positStatList(PositStatVO psVO) {
        return cuMemberAwardsStatMapper.positStatList(psVO);
    }

    @Override
    public List<PositStatVO> positStatAchieve(PositStatVO psVO) {
        return cuMemberAwardsStatMapper.positStatAchieve(psVO);
    }

    @Override
    public List<UmbrellaBelowProductVO> umbrellaBelowProductList(UmbrellaBelowProductVO ubpVO) {
        return cuMemberAwardsStatMapper.umbrellaBelowProductList(ubpVO);
    }

    @Override
    public List<UmbrellaBelowRepeatVO> umbrellaBelowRepeatList(UmbrellaBelowRepeatVO ubrVO) {
        return cuMemberAwardsStatMapper.umbrellaBelowRepeatList(ubrVO);
    }

    @Override
    public List<StatProductVO> statProductList(StatProductVO sptVO) {
        return cuMemberAwardsStatMapper.statProductList(sptVO);
    }

    @Override
    public List<DomicileDataVO> domicileDataList(DomicileDataVO ddVO) {
        return cuMemberAwardsStatMapper.domicileDataList(ddVO);
    }

    @Override
    public List<AreaAchieveStatVO> areaAchieveStat(AreaAchieveStatVO areaAchieveStatVO) {
        return cuMemberAwardsStatMapper.areaAchieveStat(areaAchieveStatVO);
    }

    @Override
    public List<VertexAchieveStatVO> vertexAchieveStat(VertexAchieveStatVO vertexAchieveStatVO) {
        return cuMemberAwardsStatMapper.vertexAchieveStat(vertexAchieveStatVO);
    }

    @Override
    public void exportExcelWithMergedCells(HttpServletResponse response, String fileName,
                                           List<AreaAchieveStatVO> dataList) throws IOException {

        Workbook workbook = new XSSFWorkbook(); // 创建一个新的Excel工作簿
        Sheet sheet = workbook.createSheet("Sheet1"); // 创建一个新的sheet
        // 样式定义：加粗、居中、灰色背景
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true); // 加粗
        headerStyle.setFont(headerFont);
        headerStyle.setAlignment(HorizontalAlignment.CENTER); // 居中
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 灰色背景
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
        // 写入表头
        Row headerRow = sheet.createRow(0);
        // 创建第一个单元格并合并一行
        Cell headerCell1 = headerRow.createCell(0);
        headerCell1.setCellValue("区域");
        headerCell1.setCellStyle(headerStyle); // 应用样式
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
        //写入第二行每一列的固定值
        Row row1 = sheet.createRow(1);
        for (int i = 1; i < 32; i++) {
            // 创建第二个单元格并合并两列
            Cell headerCell2 = headerRow.createCell(2 * i - 1);
            headerCell2.setCellValue(i);
            headerCell2.setCellStyle(headerStyle); // 应用样式
            sheet.addMergedRegion(new CellRangeAddress(0, 0, (2 * i - 1), 2 * i));
            Cell amountCell = row1.createCell(2 * i - 1);
            amountCell.setCellValue("金额");
            amountCell.setCellStyle(headerStyle);
            Cell achieveCell = row1.createCell(2 * i);
            achieveCell.setCellValue("业绩");
            achieveCell.setCellStyle(headerStyle);
        }
        // 金额总计和业绩总计表头
        Cell totalAmountCell = row1.createCell(63);
        totalAmountCell.setCellValue("金额总计");
        totalAmountCell.setCellStyle(headerStyle); // 应用样式
        Cell totalAchieveCell = row1.createCell(64);
        totalAchieveCell.setCellValue("业绩总计");
        totalAchieveCell.setCellStyle(headerStyle); // 应用样式
        // 写入数据行
        int rowNum = 2; // 从第三行开始写入数据（第一行是表头）
        // 写入数据，并设置居中样式
        CellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setAlignment(HorizontalAlignment.CENTER); // 居中
        for (AreaAchieveStatVO data : dataList) {
            Row row = sheet.createRow(rowNum++);
            Cell prNameCell = row.createCell(0); // 假设T有一个getId()方法
            prNameCell.setCellValue(data.getPrName());
            //应用样式
            prNameCell.setCellStyle(dataStyle);
            for (int i = 1; i <= 31; i++) {
                long orderAmount = getPropertyValue(data, "getOrderAmount" + i);
                long orderAchieve = getPropertyValue(data, "getOrderAchieve" + i);

                Cell amount = row.createCell(2 * i - 1);
                amount.setCellValue(orderAmount);
                amount.setCellStyle(dataStyle);

                Cell achieve = row.createCell(2 * i);
                achieve.setCellValue(orderAchieve);
                achieve.setCellStyle(dataStyle);

                Cell amountSum = row.createCell(63);
                amountSum.setCellValue(data.getOrderAmountSum());
                amountSum.setCellStyle(dataStyle);

                Cell achieveSum = row.createCell(64);
                achieveSum.setCellValue(data.getOrderAchieveSum());
                achieveSum.setCellStyle(dataStyle);

            }
        }
        String safeFileName = fileName.replace(" ", "_"); // 将空格替换为下划线
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 同时设置 filename 和 filename*;filename*=UTF-8'' 编码格式是为了兼容不支持 filename* 的浏览器
        response.setHeader("Content-Disposition", "attachment; filename=\"" + safeFileName + "\"; filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
        workbook.write(response.getOutputStream());
        workbook.close();
    }

    @Override
    public void exportExcelVertexWithMergedCells(HttpServletResponse response, String fileName,
                                                 List<VertexAchieveStatVO> dataList) throws IOException {

        Workbook workbook = new XSSFWorkbook(); // 创建一个新的Excel工作簿
        Sheet sheet = workbook.createSheet("Sheet1"); // 创建一个新的sheet
        // 样式定义：加粗、居中、灰色背景
        CellStyle headerStyle = workbook.createCellStyle();
        Font headerFont = workbook.createFont();
        headerFont.setBold(true); // 加粗
        headerStyle.setFont(headerFont);
        headerStyle.setAlignment(HorizontalAlignment.CENTER); // 居中
        headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 灰色背景
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
        // 写入表头
        Row headerRow = sheet.createRow(0);
        // 创建第一个单元格并合并一行
        Cell headerCell1 = headerRow.createCell(0);
        headerCell1.setCellValue("区域");
        headerCell1.setCellStyle(headerStyle); // 应用样式
        sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, 0));
        //写入第二行每一列的固定值
        Row row1 = sheet.createRow(1);
        for (int i = 1; i < 32; i++) {
            // 创建第二个单元格并合并两列
            Cell headerCell2 = headerRow.createCell(2 * i - 1);
            headerCell2.setCellValue(i);
            headerCell2.setCellStyle(headerStyle); // 应用样式
            sheet.addMergedRegion(new CellRangeAddress(0, 0, (2 * i - 1), 2 * i));
            Cell amountCell = row1.createCell(2 * i - 1);
            amountCell.setCellValue("金额");
            amountCell.setCellStyle(headerStyle);
            Cell achieveCell = row1.createCell(2 * i);
            achieveCell.setCellValue("业绩");
            achieveCell.setCellStyle(headerStyle);
        }
        // 金额总计和业绩总计表头
        Cell totalAmountCell = row1.createCell(63);
        totalAmountCell.setCellValue("金额总计");
        totalAmountCell.setCellStyle(headerStyle); // 应用样式
        Cell totalAchieveCell = row1.createCell(64);
        totalAchieveCell.setCellValue("业绩总计");
        totalAchieveCell.setCellStyle(headerStyle); // 应用样式
        // 写入数据行
        int rowNum = 2; // 从第三行开始写入数据（第一行是表头）
        // 写入数据，并设置居中样式
        CellStyle dataStyle = workbook.createCellStyle();
        dataStyle.setAlignment(HorizontalAlignment.CENTER); // 居中
        for (VertexAchieveStatVO data : dataList) {
            Row row = sheet.createRow(rowNum++);
            Cell prNameCell = row.createCell(0); // 假设T有一个getId()方法
            prNameCell.setCellValue(data.getVertexName());
            //应用样式
            prNameCell.setCellStyle(dataStyle);
            for (int i = 1; i <= 31; i++) {
                long orderAmount = getPropertyValue(data, "getOrderAmount" + i);
                long orderAchieve = getPropertyValue(data, "getOrderAchieve" + i);

                Cell amount = row.createCell(2 * i - 1);
                amount.setCellValue(orderAmount);
                amount.setCellStyle(dataStyle);

                Cell achieve = row.createCell(2 * i);
                achieve.setCellValue(orderAchieve);
                achieve.setCellStyle(dataStyle);

                Cell amountSum = row.createCell(63);
                amountSum.setCellValue(data.getOrderAmountSum());
                amountSum.setCellStyle(dataStyle);

                Cell achieveSum = row.createCell(64);
                achieveSum.setCellValue(data.getOrderAchieveSum());
                achieveSum.setCellStyle(dataStyle);

            }
        }
        String safeFileName = fileName.replace(" ", "_"); // 将空格替换为下划线
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 同时设置 filename 和 filename*;filename*=UTF-8'' 编码格式是为了兼容不支持 filename* 的浏览器
        response.setHeader("Content-Disposition", "attachment; filename=\"" + safeFileName + "\"; filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
        workbook.write(response.getOutputStream());
        workbook.close();
    }

    // 获取对象属性值的通用方法
    private long getPropertyValue(AreaAchieveStatVO data, String methodName) {
        long value = 0;
        try {
            Method method = AreaAchieveStatVO.class.getMethod(methodName);
            value = (long) method.invoke(data);
        } catch (Exception e) {
            // 异常处理
        }
        return value;
    }

    // 获取对象属性值的通用方法
    private long getPropertyValue(VertexAchieveStatVO data, String methodName) {
        long value = 0;
        try {
            Method method = VertexAchieveStatVO.class.getMethod(methodName);
            value = (long) method.invoke(data);
        } catch (Exception e) {
            // 异常处理
        }
        return value;
    }

}
