jialh
1 天以前 dd6687b118561100e1677e88a9c2f5842a54c531
service-job/src/main/java/com/java110/job/importData/adapt/ImportReportMainV2QueueDataAdapt.java
@@ -56,7 +56,6 @@
    // 注入数据库服务(SqlSessionTemplate版Service)
    @Override
    @Transactional(rollbackFor = Exception.class) // 事务控制,确保3张表数据一致性
    public void importData(List<AssetImportLogDetailDto> assetImportLogDetailDtos) {
        for (AssetImportLogDetailDto logDetailDto : assetImportLogDetailDtos) {
            try {
@@ -68,9 +67,6 @@
                String flowNumber = getCellValue(cellArray, 1); // 第2列:流转编号
                String projectName = getCellValue(cellArray, 4); // 第5列:项目名称
                String ownersCommitteeAmountStr = getCellValue(cellArray, 12); // 第13列:业委会金额
                if (Vtil.defaultValue(getCellValue(cellArray, 1)).equals("")) {
                    continue;
                }
                AnnouncementTimeRangePo announcementTimeRangePo = null;
                OwnersCommitteeConventionPo ocoPo = null;
                OwnerWithdrawalInfoPo owiPo = null;
@@ -100,15 +96,11 @@
                importData(mainPo, announcementTimeRangePo, ocoPo, owiPo, oqgPo, paymentRecordPos, fifthPos, ownerRemarkInfoPo);
                // 5. 更新导入日志状态(成功)- 调用父类方法
                super.updateImportLogDetailState(logDetailDto.getDetailId());
                updateImportLogDetailState(logDetailDto.getDetailId());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } catch (Exception e) {
                throw new IllegalArgumentException(e.getMessage());
                e.printStackTrace();
                updateImportLogDetailState(logDetailDto.getDetailId(), e);
            }
        }
    }
@@ -143,9 +135,9 @@
        OwnerRemarkInfoPo po = new OwnerRemarkInfoPo();
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId);
        po.setMpId(flowNumber);
        po.setMpId(id);
        po.setRemarkPerson("导入内容");
        po.setRemarkContent(getCellValue(cellArray, 137));
//        po.setRemarkContent(getCellValue(cellArray, 137));
        return po;
    }
@@ -154,13 +146,13 @@
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId); // 主键ID
        po.setMpId(aLong);
            po.setQualityGuaranteePeriod2Start(Vtil.defaultValueToDate(getCellValue(cellArray, 37)));
            po.setQualityGuaranteePeriod2End(Vtil.defaultValueToDate(getCellValue(cellArray, 38)));
            po.setAcceptanceDate(Vtil.defaultValueToDate(getCellValue(cellArray, 41)));
            po.setAvailableWithdrawalDate(Vtil.defaultValueToDate(getCellValue(cellArray, 43)));
        po.setQualityGuaranteeRatio(getCellNum(cellArray, 39));
        po.setQualityGuaranteeAmount(getCellNum(cellArray, 12) * po.getQualityGuaranteeRatio());
        po.setAuditStatus(getCellValue(cellArray, 42));
//            po.setQualityGuaranteePeriod2Start(Vtil.defaultValueToDate(getCellValue(cellArray, 37)));
//            po.setQualityGuaranteePeriod2End(Vtil.defaultValueToDate(getCellValue(cellArray, 38)));
//            po.setAcceptanceDate(Vtil.defaultValueToDate(getCellValue(cellArray, 41)));
//            po.setAvailableWithdrawalDate(Vtil.defaultValueToDate(getCellValue(cellArray, 43)));
//        po.setQualityGuaranteeRatio(getCellNum(cellArray, 39));
//        po.setQualityGuaranteeAmount(getCellNum(cellArray, 12) * po.getQualityGuaranteeRatio());
//        po.setAuditStatus(getCellValue(cellArray, 42));
        return po;
    }
@@ -169,14 +161,14 @@
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId); // 主键ID
        po.setMpId(aLong);
        po.setWithdrawalEncounteredProblem(getCellValue(cellArray, 28));
        po.setShortageOrArrears(getCellNum(cellArray, 29));
        po.setRoadName(getCellValue(cellArray, 30));
        po.setLane(getCellValue(cellArray, 31));
        po.setDoor(getCellValue(cellArray, 32));
        po.setRoom(getCellValue(cellArray, 33));
        po.setDoorRoomNumber(getCellValue(cellArray, 34));
        po.setOwnerAddress(getCellValue(cellArray, 35));
//        po.setWithdrawalEncounteredProblem(getCellValue(cellArray, 28));
//        po.setShortageOrArrears(getCellNum(cellArray, 29));
//        po.setRoadName(getCellValue(cellArray, 30));
//        po.setLane(getCellValue(cellArray, 31));
//        po.setDoor(getCellValue(cellArray, 32));
//        po.setRoom(getCellValue(cellArray, 33));
//        po.setDoorRoomNumber(getCellValue(cellArray, 34));
//        po.setOwnerAddress(getCellValue(cellArray, 35));
        return po;
    }
@@ -186,9 +178,9 @@
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId); // 主键ID
        po.setMpId(mpId);
        po.setQuota(getCellNum(cellArray, 25));
        po.setOwnersCommitteeResolution(getCellValue(cellArray, 26));
        po.setOwnersCommitteeConsultation(getCellValue(cellArray, 27));
//        po.setQuota(getCellNum(cellArray, 25));
//        po.setOwnersCommitteeResolution(getCellValue(cellArray, 26));
//        po.setOwnersCommitteeConsultation(getCellValue(cellArray, 27));
        return po;
    }
@@ -198,130 +190,163 @@
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId); // 主键ID
        po.setMpId(mpId);
        po.setPlannedAnnouncementStart(getCellValue(cellArray, 21));
        po.setPlannedAnnouncementEnd(getCellValue(cellArray, 22));
        po.setPublishedAnnouncementStart(getCellValue(cellArray, 23));
        po.setPublishedAnnouncementEnd(getCellValue(cellArray, 24));
//        po.setPlannedAnnouncementStart(getCellValue(cellArray, 21));
//        po.setPlannedAnnouncementEnd(getCellValue(cellArray, 22));
//        po.setPublishedAnnouncementStart(getCellValue(cellArray, 23));
//        po.setPublishedAnnouncementEnd(getCellValue(cellArray, 24));
        return po;
    }
    private MaintenancePayment buildMaintenancePaymentPoV2(JSONArray cellArray) throws ParseException {
        MaintenancePayment po = new MaintenancePayment();
        po.setId(GenerateCodeFactory.getGeneratorId("10")); // 主键ID
        po.setAuxiliaryColumn(getCellValue(cellArray, 0)); // 第1列:辅助列
        po.setFlowNumber(getCellValue(cellArray, 1)); // 第2列:流转编号
        po.setSerialNumber(parseInteger(getCellValue(cellArray, 2))); // 第3列:序号
        po.setProjectCode(getCellValue(cellArray, 3)); // 第4列:项目编码
        po.setProjectName(getCellValue(cellArray, 4)); // 第5列:项目名称
        po.setYear(parseInteger(getCellValue(cellArray, 5))); // 第6列:年份
        po.setMonth(parseInteger(getCellValue(cellArray, 6))); // 第7列:月份
        po.setDay(parseInteger(getCellValue(cellArray, 7))); // 第8列:日
        po.setDate(parseDate(getCellValue(cellArray, 8))); // 第9列:日期
        po.setProjectContent(getCellValue(cellArray, 9)); // 第10列:工程内容
        po.setManagementOfficeAmount(getCellValue(cellArray, 10)); // 第11列:管理处金额
        po.setManagementOfficeSeal(convertSealStatus(getCellValue(cellArray, 11))); // 第12列:管理处是否已盖章(√转"是",否则"否")
        po.setOwnersCommitteeAmount(getCellValue(cellArray, 12)); // 第13列:业委会金额
        po.setAuditAmount(getCellNum(cellArray, 13).toString()); // 第14列:审价金额
        po.setOwnersCommitteeSeal(convertSealStatus(getCellValue(cellArray, 14))); // 第15列:业委会是否已盖章
        po.setReportDepartment(getCellValue(cellArray, 15)); // 第16列:签报部门
        po.setFundTypeLevel1(getCellValue(cellArray, 16)); // 第17列:基金类型-一级分类
        po.setFundTypeLevel2(getCellValue(cellArray, 17)); // 第18列:基金类型-二级分类
        po.setMaintenanceType(getCellValue(cellArray, 19)); // 第19列:幢/全体
        po.setBuildingOrAll(getCellValue(cellArray, 18)); // 第20列:维修类型
        po.setPayeeName(getCellValue(cellArray, 145)); // 支付公司名称/个人名字
        po.setIdCardNumber(getCellValue(cellArray, 146)); // 个人身份证号码
        po.setBankName(getCellValue(cellArray, 147)); // 开户银行
        po.setBankAccount(getCellValue(cellArray, 148)); // 开户账号
        return po;
        try {
            po.setId(GenerateCodeFactory.getGeneratorId("10")); // 主键ID
            po.setAuxiliaryColumn(getCellValue(cellArray, 0)); // 第1列:辅助列
            po.setFlowNumber(getCellValue(cellArray, 1)); // 第2列:流转编号
            po.setSerialNumber(getCellValue(cellArray, 2)); // 第3列:序号
            po.setProjectCode(getCellValue(cellArray, 3)); // 第4列:项目编码
            po.setProjectName(getCellValue(cellArray, 4)); // 第5列:项目名称
            po.setYear(getCellValue(cellArray, 5)); // 第6列:年份
            po.setMonth(getCellValue(cellArray, 6)); // 第7列:月份
            po.setDay(getCellValue(cellArray, 7)); // 第8列:日
            po.setDate(Vtil.defaultValueToDate(getCellValue(cellArray, 8))); // 第9列:日期
            po.setProjectContent(getCellValue(cellArray, 9)); // 第10列:工程内容
            po.setManagementOfficeAmount(getCellValue(cellArray, 10)); // 第11列:管理处金额
            po.setManagementOfficeSeal(getCellValue(cellArray, 11)); // 第12列:管理处是否已盖章(√转"是",否则"否")
            po.setOwnersCommitteeAmount(getCellValue(cellArray, 12)); // 第13列:业委会金额
            po.setAuditAmount(getCellValue(cellArray, 13)); // 第14列:审价金额
            po.setOwnersCommitteeSeal(getCellValue(cellArray, 14)); // 第15列:业委会是否已盖章
            po.setReportDepartment(getCellValue(cellArray, 15)); // 第16列:签报部门
            po.setFundTypeLevel1(getCellValue(cellArray, 16)); // 第17列:基金类型-一级分类
            po.setFundTypeLevel2(getCellValue(cellArray, 17)); // 第18列:基金类型-二级分类
            po.setMaintenanceType(getCellValue(cellArray, 18)); // 第19列:幢/全体
            po.setBuildingOrAll(getCellValue(cellArray, 19)); // 第20列:维修类型
            po.setSpecificAnnouncementStatus(getCellValue(cellArray, 20));//具体公布情况 TODO 添加sql字段
            po.setQuota(getCellValue(cellArray, 21)); // 22:额度
            po.setOwnersCommitteeResolution(getCellValue(cellArray, 22)); // 23:业委会大会决议(是/否)
            po.setOwnersCommitteeConsultation(getCellValue(cellArray, 23)); // 24:业委会征询表(是否)
            po.setWithdrawalEncounteredProblem(getCellValue(cellArray, 24)); // 25:支取遇到的问题
            po.setShortageOrArrears(getCellValue(cellArray, 25)); // 26:缺支/欠款(元)
            po.setRoadName(getCellValue(cellArray, 26)); // 路名
            po.setLane(getCellValue(cellArray, 27)); // 弄
            po.setDoor(getCellValue(cellArray, 28)); // 门
            po.setRoom(getCellValue(cellArray, 29)); // 室
            po.setDoorRoomNumber(getCellValue(cellArray, 30)); // 门室号
            po.setOwnerAddress(getCellValue(cellArray, 31)); // 业主地址
            po.setQualityGuaranteePeriod2(getCellValue(cellArray, 32)); // 33:质保期(第二个)
            po.setQualityGuaranteeRatio(getCellValue(cellArray, 33)); // 34:质保金占比
            po.setQualityGuaranteeAmount(getCellValue(cellArray, 34)); // 35:质保金金额(元)
            po.setAcceptanceDate(getCellValue(cellArray, 35)); // 验收日期
            po.setAuditDate(getCellValue(cellArray, 36)); // 审计情况:年/月
            po.setAvailableWithdrawalDate(getCellValue(cellArray, 37)); // 第40列:可启动支取日期(年月日)
            po.setManagementFeeRatio(getCellValue(cellArray, 164)); // 管理费
            po.setPaymentTarget(getCellValue(cellArray, 168)); // 支付对象
            po.setPayeeName(getCellValue(cellArray, 239)); // 支付公司名称/个人名字
            po.setIdCardNumber(getCellValue(cellArray, 240)); // 个人身份证号码
            po.setBankName(getCellValue(cellArray, 241)); // 开户银行
            po.setBankAccount(getCellValue(cellArray, 242)); // 开户账号
            po.setAuditDate(getCellValue(cellArray, 252)); // 审计情况:年/月
            po.setAdvancedPayment(getCellValue(cellArray, 246));//垫付金额
            po.setPayableAmountD(getCellValue(cellArray, 251));//应付金额D(特殊付款)_John
            return po;
        } catch (ArrayIndexOutOfBoundsException e) {
            return po;
        }
    }
        /**
         * 构建 MaintenancePaymentPo(维修资金支取信息表)
         * 字段映射对应"荣顺苑签报单"表头顺序,包含17个自动计算字段
         */
    private MaintenancePaymentPo buildMaintenancePaymentPo(JSONArray cellArray) throws ParseException {
        MaintenancePaymentPo po = new MaintenancePaymentPo();
        // 基础字段(直接映射Excel单元格)
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId+""); // 主键ID
        po.setAuxiliaryColumn(getCellValue(cellArray, 0)); // 第1列:辅助列
        po.setFlowNumber(getCellValue(cellArray, 1)); // 第2列:流转编号
        po.setSerialNumber(parseInteger(getCellValue(cellArray, 2))); // 第3列:序号
        po.setProjectCode(getCellValue(cellArray, 3)); // 第4列:项目编码
        po.setProjectName(getCellValue(cellArray, 4)); // 第5列:项目名称
        po.setYear(parseInteger(getCellValue(cellArray, 5))); // 第6列:年份
        po.setMonth(parseInteger(getCellValue(cellArray, 6))); // 第7列:月份
        po.setDay(parseInteger(getCellValue(cellArray, 7))); // 第8列:日
        po.setDate(parseDate(getCellValue(cellArray, 8))); // 第9列:日期
        po.setProjectContent(getCellValue(cellArray, 9)); // 第10列:工程内容
        po.setManagementOfficeAmount(parseBigDecimal(getCellValue(cellArray, 10))); // 第11列:管理处金额
        po.setManagementOfficeSeal(convertSealStatus(getCellValue(cellArray, 11))); // 第12列:管理处是否已盖章(√转"是",否则"否")
        po.setOwnersCommitteeAmount(parseBigDecimal(getCellValue(cellArray, 12))); // 第13列:业委会金额
        po.setAuditAmount(parseBigDecimal(getCellValue(cellArray, 13))); // 第14列:审价金额
        po.setOwnersCommitteeSeal(convertSealStatus(getCellValue(cellArray, 14))); // 第15列:业委会是否已盖章
        po.setReportDepartment(getCellValue(cellArray, 15)); // 第16列:签报部门
        po.setFundTypeLevel1(getCellValue(cellArray, 16)); // 第17列:基金类型-一级分类
        po.setFundTypeLevel2(getCellValue(cellArray, 17)); // 第18列:基金类型-二级分类
        po.setBuildingOrAll(getCellValue(cellArray, 18)); // 第19列:幢/全体
        po.setMaintenanceType(getCellValue(cellArray, 19)); // 第20列:维修类型
        po.setQualityGuaranteePeriod1(getCellValue(cellArray, 20)); // 第21列:质保期(第一个)
//        po.setPublicIncomeAnnouncement(getCellValue(cellArray, 21)); // 第22列:公共收益金公布情况
        // 公共收益金公布子字段(第23-26列)
        po.setPlannedAnnouncementStart(getCellValue(cellArray, 21)); // 拟公布-起始(年月)
        po.setPlannedAnnouncementEnd(getCellValue(cellArray, 22)); // 拟公布-止(年月)
        po.setPublishedAnnouncementStart(getCellValue(cellArray, 23)); // 已公布-起始(年月)
        po.setPublishedAnnouncementEnd(getCellValue(cellArray, 24)); // 已公布-止(年月)
        po.setQuota(parseBigDecimal(getCellValue(cellArray, 25))); // 第27列:额度
        po.setOwnersCommitteeResolution(convertYesNo(getCellValue(cellArray, 26))); // 第28列:业委会大会决议(是/否)
        po.setOwnersCommitteeConsultation(convertYesNo(getCellValue(cellArray, 27))); // 第29列:业委会征询表(是否)
        po.setWithdrawalEncounteredProblem(getCellValue(cellArray, 28)); // 第30列:支取遇到的问题
        po.setShortageOrArrears(parseBigDecimal(getCellValue(cellArray, 29))); // 第31列:缺支/欠款(元)
        // 业主地址子字段(第32-37列)
        po.setRoadName(getCellValue(cellArray, 30)); // 路名
        po.setLane(getCellValue(cellArray, 31)); // 弄
        po.setDoor(getCellValue(cellArray, 32)); // 门
        po.setRoom(getCellValue(cellArray, 33)); // 室
        po.setDoorRoomNumber(getCellValue(cellArray, 34)); // 门室号
        po.setOwnerAddress(getCellValue(cellArray, 35)); // 业主地址
//        po.setWithdrawalProblem(getCellValue(cellArray, 36)); // 第38列:支取存在问题
        po.setProblemDifficulty(getCellValue(cellArray, 36)); // 第36列:问题难度
        po.setAvailableWithdrawalDate(parseDate(getCellValue(cellArray, 43))); // 第40列:可启动支取日期(年月日)
        po.setQualityGuaranteePeriod2(getCellValue(cellArray, 37) + "~" + getCellValue(cellArray, 38)); // 第41列:质保期(第二个)
        po.setQualityGuaranteeRatio(parseBigDecimal(getCellValue(cellArray, 39))); // 第42列:质保金占比
        po.setQualityGuaranteeAmount(parseBigDecimal(getCellValue(cellArray, 40))); // 第43列:质保金金额(元)
        po.setReceivedQualityGuarantee(parseBigDecimal(getCellValue(cellArray, 44))); // 第44列:已到账质保金
//        po.setStartDate(parseDate(getCellValue(cellArray, 44))); // 第45列:起始(年月日)
//        po.setEndDate(parseDate(getCellValue(cellArray, 45))); // 第46列:终止(年月日)
        // 支付信息(第111-116列)
        po.setPayeeName(getCellValue(cellArray, 143)); // 支付公司名称/个人名字
        po.setIdCardNumber(getCellValue(cellArray, 144)); // 个人身份证号码
        po.setBankName(getCellValue(cellArray, 145)); // 开户银行
        po.setBankAccount(getCellValue(cellArray, 146)); // 开户账号
        po.setRemarks(getCellValue(cellArray, 155)); // 备注
        po.setAcceptanceDate(parseDate(getCellValue(cellArray, 156))); // 验收日期
        po.setAuditDate(getCellValue(cellArray, 157)); // 审计情况:年/月
        return po;
    }
//    private MaintenancePaymentPo buildMaintenancePaymentPo(JSONArray cellArray) throws ParseException {
//        MaintenancePaymentPo po = new MaintenancePaymentPo();
//        // 基础字段(直接映射Excel单元格)
//        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
//        po.setId(longId+""); // 主键ID
//        po.setAuxiliaryColumn(getCellValue(cellArray, 0)); // 第1列:辅助列
//        po.setFlowNumber(getCellValue(cellArray, 1)); // 第2列:流转编号
//        po.setSerialNumber(parseInteger(getCellValue(cellArray, 2))); // 第3列:序号
//        po.setProjectCode(getCellValue(cellArray, 3)); // 第4列:项目编码
//        po.setProjectName(getCellValue(cellArray, 4)); // 第5列:项目名称
//        po.setYear(parseInteger(getCellValue(cellArray, 5))); // 第6列:年份
//        po.setMonth(parseInteger(getCellValue(cellArray, 6))); // 第7列:月份
//        po.setDay(parseInteger(getCellValue(cellArray, 7))); // 第8列:日
//        po.setDate(parseDate(getCellValue(cellArray, 8))); // 第9列:日期
//        po.setProjectContent(getCellValue(cellArray, 9)); // 第10列:工程内容
//        po.setManagementOfficeAmount(parseBigDecimal(getCellValue(cellArray, 10))); // 第11列:管理处金额
//        po.setManagementOfficeSeal(convertSealStatus(getCellValue(cellArray, 11))); // 第12列:管理处是否已盖章(√转"是",否则"否")
//        po.setOwnersCommitteeAmount(parseBigDecimal(getCellValue(cellArray, 12))); // 第13列:业委会金额
//        po.setAuditAmount(parseBigDecimal(getCellValue(cellArray, 13))); // 第14列:审价金额
//        po.setOwnersCommitteeSeal(convertSealStatus(getCellValue(cellArray, 14))); // 第15列:业委会是否已盖章
//        po.setReportDepartment(getCellValue(cellArray, 15)); // 第16列:签报部门
//        po.setFundTypeLevel1(getCellValue(cellArray, 16)); // 第17列:基金类型-一级分类
//        po.setFundTypeLevel2(getCellValue(cellArray, 17)); // 第18列:基金类型-二级分类
//        po.setBuildingOrAll(getCellValue(cellArray, 18)); // 第19列:幢/全体
//        po.setMaintenanceType(getCellValue(cellArray, 19)); // 第20列:维修类型
//        po.setQualityGuaranteePeriod1(getCellValue(cellArray, 20)); // 第21列:质保期(第一个)
////        po.setPublicIncomeAnnouncement(getCellValue(cellArray, 21)); // 第22列:公共收益金公布情况
//        // 公共收益金公布子字段(第23-26列)
//        po.setPlannedAnnouncementStart(getCellValue(cellArray, 21)); // 拟公布-起始(年月)
//        po.setPlannedAnnouncementEnd(getCellValue(cellArray, 22)); // 拟公布-止(年月)
//        po.setPublishedAnnouncementStart(getCellValue(cellArray, 23)); // 已公布-起始(年月)
//        po.setPublishedAnnouncementEnd(getCellValue(cellArray, 24)); // 已公布-止(年月)
//        po.setQuota(parseBigDecimal(getCellValue(cellArray, 25))); // 第27列:额度
//        po.setOwnersCommitteeResolution(convertYesNo(getCellValue(cellArray, 26))); // 第28列:业委会大会决议(是/否)
//        po.setOwnersCommitteeConsultation(convertYesNo(getCellValue(cellArray, 27))); // 第29列:业委会征询表(是否)
//        po.setWithdrawalEncounteredProblem(getCellValue(cellArray, 28)); // 第30列:支取遇到的问题
//        po.setShortageOrArrears(parseBigDecimal(getCellValue(cellArray, 29))); // 第31列:缺支/欠款(元)
//        // 业主地址子字段(第32-37列)
//        po.setRoadName(getCellValue(cellArray, 30)); // 路名
//        po.setLane(getCellValue(cellArray, 31)); // 弄
//        po.setDoor(getCellValue(cellArray, 32)); // 门
//        po.setRoom(getCellValue(cellArray, 33)); // 室
//        po.setDoorRoomNumber(getCellValue(cellArray, 34)); // 门室号
//        po.setOwnerAddress(getCellValue(cellArray, 35)); // 业主地址
////        po.setWithdrawalProblem(getCellValue(cellArray, 36)); // 第38列:支取存在问题
//        po.setProblemDifficulty(getCellValue(cellArray, 36)); // 第36列:问题难度
//        po.setAvailableWithdrawalDate(parseDate(getCellValue(cellArray, 43))); // 第40列:可启动支取日期(年月日)
//        po.setQualityGuaranteePeriod2(getCellValue(cellArray, 37) + "~" + getCellValue(cellArray, 38)); // 第41列:质保期(第二个)
//        po.setQualityGuaranteeRatio(parseBigDecimal(getCellValue(cellArray, 39))); // 第42列:质保金占比
//        po.setQualityGuaranteeAmount(parseBigDecimal(getCellValue(cellArray, 40))); // 第43列:质保金金额(元)
//        po.setReceivedQualityGuarantee(parseBigDecimal(getCellValue(cellArray, 44))); // 第44列:已到账质保金
////        po.setStartDate(parseDate(getCellValue(cellArray, 44))); // 第45列:起始(年月日)
////        po.setEndDate(parseDate(getCellValue(cellArray, 45))); // 第46列:终止(年月日)
//
//
//        // 支付信息(第111-116列)
//        po.setPayeeName(getCellValue(cellArray, 143)); // 支付公司名称/个人名字
//        po.setIdCardNumber(getCellValue(cellArray, 144)); // 个人身份证号码
//        po.setBankName(getCellValue(cellArray, 145)); // 开户银行
//        po.setBankAccount(getCellValue(cellArray, 146)); // 开户账号
//        po.setRemarks(getCellValue(cellArray, 155)); // 备注
//        po.setAcceptanceDate(parseDate(getCellValue(cellArray, 156))); // 验收日期
//        po.setAuditDate(getCellValue(cellArray, 157)); // 审计情况:年/月
//
//        return po;
//    }
    /**
     * 构建 MpPaymentRecordPo 列表(5次打印数据)
     */
    private List<MpPaymentRecordPo> buildMpPaymentRecordPos(JSONArray cellArray, String flowNumber,String mainPo) throws ParseException {
        List<MpPaymentRecordPo> pos = new ArrayList<>();
        // 第一次打印数据(第47-53列)
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 1, 45, pos);
//         第一次打印数据(第47-53列)
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 1, 38, pos);
        // 第二次打印数据(第54-60列)
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 2, 57, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 2, 50, pos);
        // 第三次打印数据(第61-67列)
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 3, 69, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 3, 62, pos);
        // 第四次打印数据(第68-74列)
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 4, 81, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 4, 74, pos);
        // 第五次打印数据(第75-81列)
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 5, 93, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 5, 86, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 6, 98, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 7, 110, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 8, 122, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 9, 134, pos);
        buildSinglePaymentRecord(mainPo, cellArray, flowNumber, 10, 146, pos);
        return pos;
    }
@@ -337,24 +362,27 @@
        MpPaymentRecordPo po = new MpPaymentRecordPo();
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId+"");
        po.setMpId(mpId); // mp_id = 流转编号_打印次数(确保唯一)
        po.setFirstPrintDate(parseDate(getCellValue(cellArray, index)));
        po.setResolutionNumber(getCellValue(cellArray, index + 1));
        po.setPrintAmount(parseBigDecimal(getCellValue(cellArray, index + 2)));
        po.setArrivalDate(parseDate(getCellValue(cellArray, index + 3)));
        po.setArrivalAmount(parseBigDecimal(getCellValue(cellArray, index + 4)));
        po.setWithdrawer(getCellValue(cellArray, index + 5));
        po.setShortageOrArrears(parseBigDecimal(getCellValue(cellArray, index + 6)));
        // 业主地址信息(复用main表的地址)
        po.setRoadName(getCellValue(cellArray, index + 7));
        po.setLane(getCellValue(cellArray, index + 8));
        po.setDoor(getCellValue(cellArray, index + 9));
        po.setRoom(getCellValue(cellArray, index + 10));
        po.setOwnerAddress(getCellValue(cellArray, index + 11));
        po.setPrintAmount(new BigDecimal(flowNumber));
        po.setSnakeCase(getCellValue(cellArray, 105));
        try {
            po.setId(GenerateCodeFactory.getGeneratorId("33"));
            po.setMpId(mpId); // mp_id = 流转编号_打印次数(确保唯一)
            po.setPrintCount(printTimes);
            po.setFirstPrintDate(getCellValue(cellArray, index));
            po.setResolutionNumber(getCellValue(cellArray, index + 1));
            po.setPrintAmount(getCellValue(cellArray, index + 2));
            po.setArrivalDate(getCellValue(cellArray, index + 3));
            po.setArrivalAmount(getCellValue(cellArray, index + 4));
            po.setWithdrawer(getCellValue(cellArray, index + 5));
            po.setShortageOrArrears(getCellValue(cellArray, index + 6));
            // 业主地址信息(复用main表的地址)
            po.setRoadName(getCellValue(cellArray, index + 7));
            po.setLane(getCellValue(cellArray, index + 8));
            po.setDoor(getCellValue(cellArray, index + 9));
            po.setRoom(getCellValue(cellArray, index + 10));
            po.setOwnerAddress(getCellValue(cellArray, index + 11));
            po.setSnakeCase(getCellValue(cellArray, 158));
        } catch (ArrayIndexOutOfBoundsException e) {
        }
        pos.add(po);
    }
@@ -364,20 +392,25 @@
    private List<MpFifthPaymentRecord> buildMpFifthPaymentRecordPos(JSONArray cellArray, String flowNumber,String mainPo) throws ParseException {
        List<MpFifthPaymentRecord> pos = new ArrayList<>();
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 115);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 169,1);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 121);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 176,2);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 127);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 183,3);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 133);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 190,4);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 139);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 197,5);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 204,6);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 211,7);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 218,8);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 225,9);
        buildMpFifthPaymentRecordPo(pos, cellArray, flowNumber, mainPo, 232,10);
        return pos;
    }
    private void buildMpFifthPaymentRecordPo(List<MpFifthPaymentRecord> pos, JSONArray cellArray, String flowNumber, String mainPo, int index) {
    private void buildMpFifthPaymentRecordPo(List<MpFifthPaymentRecord> pos, JSONArray cellArray, String flowNumber, String mainPo, int index, int printTimes) throws ParseException {
//        if (getCellValue(cellArray, index).isEmpty()) {
//            return;
@@ -385,242 +418,32 @@
        MpFifthPaymentRecord po = new MpFifthPaymentRecord();
        long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
        po.setId(longId+"");
        po.setMpId(flowNumber);
        po.setFifthPlannedPaymentAmount(Vtil.defaultValue(getCellValue(cellArray, index)));
        try {
            po.setPlannedPaymentDate(parseDate(getCellValue(cellArray, index + 1)));
            po.setActualPaymentDate(parseDate(getCellValue(cellArray, index  + 5)));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        po.setCategory(getCellValue(cellArray, index + 2));
        po.setReimburser(getCellValue(cellArray, index + 3));
        po.setActualPaymentAmount(getCellValue(cellArray, index + 4));
    }
            long longId = UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE; // 避免负数
            po.setId(longId+"");
            po.setMpId(mainPo);
            po.setPaymentCount(printTimes);
            po.setFifthPlannedPaymentAmount(getCellValue(cellArray, index));
            po.setPlannedPaymentDate(getCellValue(cellArray, index + 1));
            po.setCategory(getCellValue(cellArray, index + 2));
            po.setReimburser(getCellValue(cellArray, index + 3));
            po.setPaymentTarget(getCellValue(cellArray, index + 4));
            po.setActualPaymentAmount(getCellValue(cellArray, index + 5));
            po.setActualPaymentDate(getCellValue(cellArray, index  + 6));
        } catch (ArrayIndexOutOfBoundsException e) {
    /**
     * 计算垫付金额(文档第十三条逻辑)
     */
    private BigDecimal calculateAdvanceAmount(String fundType, BigDecimal arrivalTotal,
                                              BigDecimal actualPayTotal, String publicIncomeAnnouncement) {
        // 条件1:基金类型是"公共收益金"或"维修基金"
        if ("公共收益金".equals(fundType) || "维修基金".equals(fundType)) {
            if (arrivalTotal.compareTo(BigDecimal.ZERO) != 0) {
                // 到账合计≠0:实付>到账则垫付=实付-到账,否则0
                return (actualPayTotal.compareTo(arrivalTotal) > 0)
                        ? subtract(actualPayTotal, arrivalTotal)
                        : BigDecimal.ZERO;
            } else {
                // 到账合计=0:判断"公共收益金公布情况"是否含"公布"且不含"拟"
                boolean hasPublish = !isBlank(publicIncomeAnnouncement) && publicIncomeAnnouncement.contains("公布");
                boolean hasPlanned = !isBlank(publicIncomeAnnouncement) && publicIncomeAnnouncement.contains("拟");
                return (hasPublish && !hasPlanned) ? BigDecimal.ZERO : actualPayTotal;
            }
        }
        // 其他基金类型:垫付金额=0
        return BigDecimal.ZERO;
        pos.add(po);
    }
    /**
     * 计算未付合计(到账口径)(文档第十四条逻辑)
     */
    private BigDecimal calculateUnpaidByArrival(String publicIncomeAnnouncement, BigDecimal ownersAmount,
                                                BigDecimal managementFee, BigDecimal actualPayTotal, BigDecimal arrivalTotal) {
        // 含"公布":未付=业委会金额-管理费-实付合计
        if (!isBlank(publicIncomeAnnouncement) && publicIncomeAnnouncement.contains("公布")) {
            return subtract(ownersAmount, managementFee, actualPayTotal);
        } else {
            // 不含"公布":到账合计=0则0,否则=到账合计-管理费-实付合计
            return (arrivalTotal.compareTo(BigDecimal.ZERO) == 0)
                    ? BigDecimal.ZERO
                    : subtract(arrivalTotal, managementFee, actualPayTotal);
        }
    }
    // -------------------------- 工具方法 --------------------------
    /**
     * 获取单元格值(处理null/空字符串)
     */
    private String getCellValue(JSONArray cellArray, int index) {
        if (index < 0 || index >= cellArray.size()) {
            return "";
        }
        Object value = cellArray.get(index);
        return value == null ? "" : value.toString().trim();
    }
    private Double getCellNum(JSONArray cellArray, int index) {
        if (index < 0 || index >= cellArray.size()) {
            return 0.0;
        }
        Object value = cellArray.get(index);
        return value == null ? 0 : Double.parseDouble((String) value);
    }
    /**
     * 判断字符串是否为空
     */
    private boolean isBlank(String str) {
        return str == null || str.isEmpty() || "null".equalsIgnoreCase(str) || "#REF!".equals(str);
    }
    /**
     * 解析Integer(空值返回null)
     */
    private Integer parseInteger(String str) {
        if (isBlank(str)) {
            return null;
        }
        try {
            return Integer.parseInt(str);
        } catch (NumberFormatException e) {
            return null;
        }
    }
    /**
     * 解析BigDecimal(空值返回0,处理千分位逗号)
     */
    private BigDecimal parseBigDecimal(String str) {
        if (isBlank(str)) {
            return BigDecimal.ZERO;
        }
        try {
            // 处理Excel中的千分位格式(如133,900.57)
            String cleanStr = str.replace(",", "").trim();
            return new BigDecimal(cleanStr);
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }
    private String parseDateToString(String str) throws ParseException{
        return parseDate(str) == null ? "" : str;
    }
    /**
     * 解析日期(支持多种格式,空值返回null)
     */
    // 扩展支持的日期格式:覆盖横线/斜杠分隔、年月日/月日年等常见格式
    private static final List<SimpleDateFormat> DATE_FORMATS = new ArrayList<SimpleDateFormat>() {{
        add(new SimpleDateFormat("yyyy-MM-dd"));      // 2025-12-12
        add(new SimpleDateFormat("yyyy/MM/dd"));      // 2025/12/12
        add(new SimpleDateFormat("yyyyMMdd"));        // 20251212
        add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); // 带时分秒的格式(兼容)
        add(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
        add(new SimpleDateFormat("MM/dd/yyyy"));      // 兼容国外格式(可选)
    }};
    /**
     * 解析日期:支持Excel日期序列号、2025-12-12、2025/12/12等格式
     * @param str 待解析的日期字符串(或Excel序列号)
     * @return 解析后的Date对象,空字符串返回null
     * @throws ParseException 不支持的格式抛出异常
     */
    private Date parseDate(String str) throws ParseException {
        // 空值处理
        if (StringUtils.isBlank(str)) {
            return null;
        }
        String trimStr = str.trim();
        // 第一步:尝试解析Excel日期序列号(数字格式)
        try {
            double excelDateNum = Double.parseDouble(trimStr);
            return convertExcelSerialToDate(excelDateNum);
        } catch (NumberFormatException e) {
            // 不是数字,继续解析文本日期格式
        }
        // 第二步:尝试解析文本格式日期(覆盖-和/分隔符)
        for (SimpleDateFormat format : DATE_FORMATS) {
            try {
                format.setLenient(false); // 严格校验,避免2025-13-32这类无效日期
                return format.parse(trimStr);
            } catch (ParseException e) {
                // 该格式解析失败,尝试下一个
                continue;
            if (index < 0 || index >= cellArray.size()) {
                return "";
            }
        }
        // 所有格式都不匹配,抛异常
        throw new ParseException("不支持的日期格式:" + str, 0);
    }
    /**
     * 转换Excel日期序列号为Date(修正1900闰年bug)
     * Excel序列号规则:1=1900-01-01(错误认为1900是闰年,多算1天)
     * @param excelSerial Excel日期序列号(如45735)
     * @return 对应的Date对象
     */
    private Date convertExcelSerialToDate(double excelSerial) {
        // 初始化Calendar:时区设为GMT,避免本地时区偏移
        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        // Excel 1900日期系统基准:序列号1对应1900-01-01
        cal.set(1900, Calendar.JANUARY, 1, 0, 0, 0);
        cal.set(Calendar.MILLISECOND, 0);
        // 修正Excel的1900闰年bug:Excel认为1900是闰年,实际不是,需减2天
        // 注:如果序列号<60(对应1900-02-28),减1天即可;通用场景减2天兼容所有情况
        int daysToAdd = (int) excelSerial - 2;
        cal.add(Calendar.DAY_OF_YEAR, daysToAdd);
        return cal.getTime();
    }
    /**
     * 转换盖章状态(√→是,其他→否)
     */
    private String convertSealStatus(String str) {
        return "√".equals(str) || "是".equals(str) ? "是" : "否";
    }
    /**
     * 转换是/否(空值返回null)
     */
    private String convertYesNo(String str) {
        if (isBlank(str)) {
            Object value = cellArray.get(index);
            return value == null ? "" : value.toString().trim();
        } catch (ArrayIndexOutOfBoundsException e) {
            return null;
        }
        return "是".equals(str) || "√".equals(str) ? "是" : "否";
    }
    /**
     * 多个BigDecimal相加(处理null,null视为0)
     */
    private BigDecimal add(BigDecimal... decimals) {
        BigDecimal result = BigDecimal.ZERO;
        for (BigDecimal decimal : decimals) {
            result = result.add(decimal == null ? BigDecimal.ZERO : decimal);
        }
        return result;
    }
    /**
     * 多个BigDecimal相减(处理null,null视为0)
     */
    private BigDecimal subtract(BigDecimal... decimals) {
        if (decimals == null || decimals.length == 0) {
            return BigDecimal.ZERO;
        }
        BigDecimal result = decimals[0] == null ? BigDecimal.ZERO : decimals[0];
        for (int i = 1; i < decimals.length; i++) {
            result = result.subtract(decimals[i] == null ? BigDecimal.ZERO : decimals[i]);
        }
        // 避免出现负数(业务中金额不能为负时启用)
        return result.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : result;
    }
    /**
     * 两个BigDecimal相乘(处理null,null视为0)
     */
    private BigDecimal multiply(BigDecimal a, BigDecimal b) {
        if (a == null || b == null) {
            return BigDecimal.ZERO;
        }
        return a.multiply(b).setScale(2, BigDecimal.ROUND_HALF_UP); // 保留2位小数
    }
}