Bläddra i källkod

fix:结算单查询接口(同步 火车结算单 酒店结算单 机票结算单)

sbtjtserver/gw-zhaojq01 2 dagar sedan
förälder
incheckning
426629147b

+ 94 - 0
base/nckd-base-common/src/main/java/nckd/base/common/enums/CurrencyEnum.java

@@ -0,0 +1,94 @@
+package nckd.base.common.enums;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @Author: 赵嘉琪
+ * @Date: 2026/01/05
+ * @Description:币种枚举
+ */
+public enum CurrencyEnum {
+    CNY("CNY", "人民币", "1"),
+    HKD("HKD", "港币", "2"),
+    JPY("JPY", "日元", "3"),
+    USD("USD", "美元", "4"),
+    EUR("EUR", "欧元", "5"),
+    GBP("GBP", "英镑", "6"),
+    AUD("AUD", "澳元", "7"),
+    TWD("TWD", "新台币", "8"),
+    MOP("MOP", "澳门币", "9");
+
+    private final String code;
+    private final String name;
+    private final String value;
+
+    private static final Map<String, CurrencyEnum> CODE_MAP =
+            Arrays.stream(values())
+                    .collect(Collectors.toMap(
+                            CurrencyEnum::getCode,
+                            e -> e,
+                            (e1, e2) -> e1));
+
+    private static final Map<String, CurrencyEnum> VALUE_MAP =
+            Arrays.stream(values())
+                    .filter(e -> e.value != null)
+                    .collect(Collectors.toMap(
+                            CurrencyEnum::getValue,
+                            e -> e,
+                            (e1, e2) -> e1));
+
+    CurrencyEnum(String code, String name, String value) {
+        this.code = code;
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public static CurrencyEnum getByCode(String code) {
+        return code == null ? null : CODE_MAP.get(code.toUpperCase());
+    }
+
+    public static CurrencyEnum getByValue(String value) {
+        return value == null ? null : VALUE_MAP.get(value);
+    }
+
+    public static boolean isValidCode(String code) {
+        return getByCode(code) != null;
+    }
+
+    public static boolean hasValue(String code) {
+        CurrencyEnum currency = getByCode(code);
+        return currency != null && currency.getValue() != null;
+    }
+
+    /**
+     * 获取所有有效值的货币(排除值为null的)
+     */
+    public static Map<String, String> getValidCurrencies() {
+        return Arrays.stream(values())
+                .filter(e -> e.value != null)
+                .collect(Collectors.toMap(
+                        CurrencyEnum::getCode,
+                        CurrencyEnum::getValue));
+    }
+
+    @Override
+    public String toString() {
+        return code;
+    }
+}

+ 139 - 0
base/nckd-base-common/src/main/java/nckd/base/common/enums/InvoiceTypeEnum.java

@@ -0,0 +1,139 @@
+package nckd.base.common.enums;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 发票类型枚举
+ */
+public enum InvoiceTypeEnum {
+
+    /**
+     * 增值税电子普通发票
+     */
+    VATE_INVOICE("vate_invoice", "1", "增值税电子普通发票"),
+
+    /**
+     * 增值税普通发票
+     */
+    VAT_INVOICE("vat_invoice", "2", "增值税普通发票"),
+
+    /**
+     * 增值税专用发票
+     */
+    VATS_INVOICE("vats_invoice", "3", "增值税专用发票"),
+
+    /**
+     * 行程单(机票/电子机票)
+     */
+    AIR_TICKET("air_ticket", "4", "行程单"),
+    AIR_E_TICKET("air_e_ticket", "4", "电子行程单"),
+
+    /**
+     * 火车票/退票
+     */
+    TRAIN_TICKET("train_ticket", "5", "火车票"),
+    TRAIN_TICKET_REFUND("train_ticket_refund", "5", "火车退票"),
+
+    /**
+     * 定额发票
+     */
+    QUOTA_INVOICE("quota_invoice", "6", "定额发票"),
+
+    /**
+     * 全电发票(专票)
+     */
+    E_VATS_INVOICE("e_vats_invoice", "8", "全电发票(专票)"),
+
+    /**
+     * 全电发票(普票)
+     */
+    E_VAT_INVOICE("e_vat_invoice", "9", "全电发票(普票)"),
+
+    /**
+     * 铁路电子客票
+     */
+    RAILWAY_E_TICKET("railway_e_ticket", "29", "铁路电子客票"),
+    RAILWAY_E_TICKET_RE("railway_e_ticket_re", "29", "铁路电子客票退票"),
+
+    /**
+     * 未知类型
+     */
+    UNKNOWN("unknown", "999", "未知发票类型");
+
+    private final String code;
+    private final String value;
+    private final String description;
+
+    private static final Map<String, InvoiceTypeEnum> CODE_MAP = new HashMap<>();
+    private static final Map<String, InvoiceTypeEnum> VALUE_MAP = new HashMap<>();
+
+    static {
+        for (InvoiceTypeEnum type : InvoiceTypeEnum.values()) {
+            CODE_MAP.put(type.getCode(), type);
+            VALUE_MAP.put(type.getValue(), type);
+        }
+    }
+
+    InvoiceTypeEnum(String code, String value, String description) {
+        this.code = code;
+        this.value = value;
+        this.description = description;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * 根据编码获取枚举
+     */
+    public static InvoiceTypeEnum getByCode(String code) {
+        return CODE_MAP.getOrDefault(code, UNKNOWN);
+    }
+
+    /**
+     * 根据值获取枚举
+     */
+    public static InvoiceTypeEnum getByValue(String value) {
+        return VALUE_MAP.getOrDefault(value, UNKNOWN);
+    }
+
+    /**
+     * 根据编码获取对应的值
+     */
+    public static String getValueByCode(String code) {
+        InvoiceTypeEnum type = getByCode(code);
+        return type.getValue();
+    }
+
+    /**
+     * 根据值获取编码
+     */
+    public static String getCodeByValue(String value) {
+        InvoiceTypeEnum type = getByValue(value);
+        return type.getCode();
+    }
+
+    /**
+     * 判断编码是否存在
+     */
+    public static boolean containsCode(String code) {
+        return CODE_MAP.containsKey(code);
+    }
+
+    /**
+     * 判断值是否存在
+     */
+    public static boolean containsValue(String value) {
+        return VALUE_MAP.containsKey(value);
+    }
+}

+ 70 - 0
base/nckd-base-common/src/main/java/nckd/base/common/enums/TrainseatEnum.java

@@ -0,0 +1,70 @@
+package nckd.base.common.enums;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @Author: 赵嘉琪
+ * @Date: 2026/01/05
+ * @Description:火车席位 转换为系统枚举编码
+ */
+public enum TrainseatEnum {
+    HARD_SLEEPER("硬卧", "1"),
+    SOFT_SLEEPER("软卧", "2"),
+    NO_SEAT("无座", "3"),
+    HARD_SEAT("硬座", "4"),
+    MOTOR_SLEEPER("动卧", "5"),
+    ADVANCED_SOFT_SLEEPER("高级软卧", "6"),
+    FIRST_CLASS_SLEEPER("一等卧", "7"),
+    SECOND_CLASS_SLEEPER("二等卧", "8"),
+    SOFT_SEAT("软座", "9"),
+    SPECIAL_SEAT("特等座", "A"),
+    BUSINESS_SEAT("商务座", "B"),
+    FIRST_CLASS_SEAT("一等座", "C"),
+    SECOND_CLASS_SEAT("二等座", "D"),
+    OTHER("其他", "E");
+
+    private final String chineseName;
+    private final String code;
+
+    TrainseatEnum(String chineseName, String code) {
+        this.chineseName = chineseName;
+        this.code = code;
+    }
+
+    /**
+     * 根据中文名称获取枚举值
+     */
+    public static TrainseatEnum fromChineseName(String chineseName) {
+        for (TrainseatEnum type : values()) {
+            if (type.chineseName.equals(chineseName)) {
+                return type;
+            }
+        }
+        return OTHER; // 默认返回其他,或可以抛出异常
+    }
+
+    /**
+     * 根据编码获取枚举值
+     */
+    public static TrainseatEnum fromCode(String code) {
+        for (TrainseatEnum type : values()) {
+            if (type.code.equals(code)) {
+                return type;
+            }
+        }
+        return OTHER; // 默认返回其他
+    }
+
+    public String getChineseName() {
+        return chineseName;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    @Override
+    public String toString() {
+        return chineseName;
+    }
+}

+ 85 - 0
base/nckd-base-common/src/main/java/nckd/base/common/utils/InvoiceApiUtils.java

@@ -0,0 +1,85 @@
+package nckd.base.common.utils;
+
+import kd.bos.exception.KDBizException;
+import org.apache.commons.lang3.ObjectUtils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Created with IntelliJ IDEA.
+ *
+ * @Author: 赵嘉琪
+ * @Date: 2026/01/08
+ * @Description:
+ */
+public class InvoiceApiUtils {
+
+    /**
+     * 最大查询页数,当某页数据小于每页条数时停止查询
+     */
+    private static final int TOTAL_PAGE = 1000;
+
+    /**
+     * 每页查询条数
+     */
+    private static final int PAGE_SIZE = 500;
+
+
+    /**
+     * @return 获取发票明细
+     */
+    public  static List<Map<String, Object>> getInvoiceResult(Object checkingBillNo,Object rebookingTime) {
+        List<Map<String, Object>> dataList = new ArrayList<>();
+        if (Objects.isNull(rebookingTime) || Objects.isNull(checkingBillNo)) {
+            return dataList;
+        }
+        for (int i = 0; i < TOTAL_PAGE; i++) {
+            //创建接口业务数据参数
+            Map<String, Object> data = new HashMap<>();
+            //当前页
+            data.put("current", i + 1);
+            //每页条数,最多500条
+            data.put("size", PAGE_SIZE);
+            //结算单号
+            data.put("settlementNo", checkingBillNo.toString());
+            //账期
+            data.put("paymentDays", parseStringToDateWithSdfMonth(rebookingTime.toString()));
+            //企业编号
+            data.put("enterpriseNo","JXWL");
+            Map<String, Object> resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_GetInvoice", Boolean.TRUE, data);
+            //报错终止同步,等待下次计划执行
+            if ((Boolean) resp.get("fail")) {
+                throw new KDBizException(resp.get("message").toString());
+            }
+            Map<String, Object> result = (Map<String, Object>) resp.get("result");
+            List<Map<String, Object>> datas = (List<Map<String, Object>>) result.getOrDefault("datas", Collections.emptyList());
+            for (Map<String, Object> map : datas) {
+                if (map.containsKey("invoices")){
+                    List<Map<String, Object>> invoices = (List<Map<String, Object>>) map.get("invoices");
+                    dataList.addAll(invoices);
+                }
+            }
+            //当前查询数量小于分页数量时结束循环
+            if (datas.size() < PAGE_SIZE) {
+                break;
+            }
+        }
+        return dataList;
+    }
+
+    private static String parseStringToDateWithSdfMonth(String dateStr) {
+        if (ObjectUtils.isEmpty(dateStr)) {
+            return null;
+        }
+        // 每次新建SimpleDateFormat,避免线程安全问题
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
+        try {
+            return sdf.format(sdf.parse(dateStr));
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+}

+ 457 - 334
nckd-fi/src/main/java/nckd/fi/er/task/DomesticFlightSettlementTask.java

@@ -1,18 +1,27 @@
 package nckd.fi.er.task;
 
+import com.alibaba.dubbo.common.utils.CollectionUtils;
 import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.exception.KDBizException;
 import kd.bos.exception.KDException;
 import kd.bos.krpc.common.logger.Logger;
 import kd.bos.krpc.common.logger.LoggerFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
 import kd.bos.schedule.executor.AbstractTask;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.qmc.qcbd.common.constant.BosOrgConst;
+import nckd.base.common.constant.BaseFieldConst;
+import nckd.base.common.enums.CurrencyEnum;
+import nckd.base.common.enums.InvoiceTypeEnum;
 import nckd.base.common.utils.DateUtil;
+import nckd.base.common.utils.InvoiceApiUtils;
 import nckd.base.common.utils.ParamUtils;
 import nckd.base.common.utils.TripSyncUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.*;
 
@@ -24,352 +33,466 @@ import java.util.*;
  * @Description:结算单(国内机票)
  */
 public class DomesticFlightSettlementTask extends AbstractTask {
-    private static Logger log = LoggerFactory.getLogger(DomesticFlightSettlementTask.class);
+    private static final Logger log = LoggerFactory.getLogger(DomesticFlightSettlementTask.class);
+    /**
+     * 最大查询页数,当某页数据小于每页条数时停止查询
+     */
+    private static final int TOTAL_PAGE = 1000;
+
+    /**
+     * 每页查询条数
+     */
+    private static final int PAGE_SIZE = 1000;
 
     /**
-     * 总页码,不处理总数,
-     * 每当当前页码数据小于1000 停止接口查询
+     * 全量同步的起始时间
      */
-    private final static int totalPage = 1000;
+    private static final String FULL_SYNC_START_TIME = "1970-01-01 00:00:00";
 
     /**
-     * 每页条数,最多500条   实际1000条
+     * 国内机票产品类型编码
      */
-    private final static int size = 1000;
+    private static final String DOMESTIC_FLIGHT_PRODUCT_TYPE = "0100";
 
+    /**
+     * 企业卡号
+     */
+    private static final String ENTERPRISE_NO = "JXWL";
+
+    /**
+     * 外部接口名称
+     */
+    private static final String INTERFACE_NAME = "FCSET_OUTAPI_LiteGetSettlementInfo";
+
+    /**
+     * 任务执行入口
+     *
+     * @param requestContext 请求上下文
+     * @param map            任务参数映射
+     * @throws KDException 执行异常
+     */
     @Override
     public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
-        log.info("结算单(国内机票)查询接口 调度计划开始执行");
-        List<Map<String, Object>> resultLists = getResult();
-        if (ObjectUtils.isEmpty(resultLists)) {
-            log.info("结算单(国内机票)查询接口 暂无数据-----");
-            return;
+        log.info("国内机票结算单同步任务开始执行");
+
+        try {
+            // 1. 从外部接口获取国内机票结算数据
+            List<Map<String, Object>> resultLists = getResult();
+            if (ObjectUtils.isEmpty(resultLists)) {
+                log.info("未获取到国内机票结算数据,任务结束");
+                return;
+            }
+
+            log.info("成功获取到 " + resultLists.size() + " 条国内机票结算数据");
+
+            // 2. 处理获取到的数据
+            processResultData(resultLists);
+
+            log.info("国内机票结算单同步任务执行完成");
+        } catch (Exception e) {
+            log.info("国内机票结算单同步任务执行失败", e);
+            throw e;
         }
+    }
+
+
+    /**
+     * 批量处理获取到的国内机票结算数据
+     *
+     * @param resultLists 国内机票结算数据列表
+     */
+    private void processResultData(List<Map<String, Object>> resultLists) {
+        int successCount = 0;
+        int failCount = 0;
+
         for (Map<String, Object> resultMap : resultLists) {
             try {
-                // 从结果映射中提取各字段
-                extractAndProcessFields(resultMap);
+                // 提取并处理单条数据字段,保存到系统
+                List<DynamicObject> planeCheckingList = extractAndProcessFields(resultMap);
+                if (!ObjectUtils.isEmpty(planeCheckingList)) {
+                    SaveServiceHelper.save(planeCheckingList.toArray(new DynamicObject[0]));
+                    successCount++;
+                }
             } catch (Exception e) {
-                log.info("处理火车票结算数据时发生异常,数据内容: " + resultMap, e);
+                failCount++;
+                log.info("处理国内机票结算数据时发生异常,数据内容: " + resultMap, e);
             }
         }
 
+        log.info("国内机票结算数据处理完成:成功 " + successCount + " 条,失败 " + failCount + " 条");
     }
 
+
     /**
-     * 从单条数据映射中提取字段并处理
+     * 从单条数据映射中提取字段并处理,生成系统动态对象
+     * 注:此方法将外部接口数据映射到系统表单字段
      *
      * @param resultMap 单条数据映射
+     * @return 处理后的动态对象列表
      */
-    private void extractAndProcessFields(Map<String, Object> resultMap) {
-        // 1.获取接口返回值
-
-        // ===================== 订单基本信息 =====================
-        // 订单类型 (01001机票正常单, 01002机票退单, 01003机票改签单, 1酒店正常单, 2酒店退单等)
-        Object orderType = resultMap.get("orderType");
-        // 房间数
-        Object roomQuantity = resultMap.get("roomQuantity");
-        // 订单类型名称
-        Object orderName = resultMap.get("orderName");
-        // 订单号
-        Object orderNo = resultMap.get("orderNo");
-        // 原订单编号
-        Object oldOrderNo = resultMap.get("oldOrderNo");
-        // 订单状态 (已完成等)
-        Object orderStatus = resultMap.get("orderStatus");
-        // 预订时间
-        Object orderDate = resultMap.get("orderDate");
-        // 业务发生时间
-        Object rebookingtime = resultMap.get("rebookingtime");
-        // 结算生成时间
-        Object createTime = resultMap.get("createTime");
-
-        // ===================== 结算信息 =====================
-        // 结算明细主键
-        Object tmcSettlementid = resultMap.get("tmcSettlementid");
-        // 结算单号
-        Object settlementNo = resultMap.get("settlementNo");
-        // 结算批次号(对应系统账单号)
-        Object accCheckBatchNo = resultMap.get("accCheckBatchNo");
-        // 结算明细ID
-        Object subAccCheckBatchNo = resultMap.get("subAccCheckBatchNo");
-        // 大表ID
-        Object mainTableId = resultMap.get("mainTableId");
-        // 币种 (例如CNY)
-        Object settlementCurrency = resultMap.get("settlementCurrency");
-        // 结算金额
-        Object settlementAmount = resultMap.get("settlementAmount");
-        // 结算单合计金额
-        Object totalAmount = resultMap.get("totalAmount");
-
-        // ===================== 人员信息 =====================
-        // 出行人姓名
-        Object guestName = resultMap.get("guestName");
-        // 出行人名称
-        Object passengerName = resultMap.get("passengerName");
-        // 员工姓名
-        Object employeeName = resultMap.get("employeeName");
-        // 出行人工号
-        Object employeeId = resultMap.get("employeeId");
-        // 预订人姓名
-        Object reserveName = resultMap.get("reserveName");
-        // 预订人员编号
-        Object reserveId = resultMap.get("reserveId");
-        // 人员类型(可能是员工类型)
-        Object personnelType = resultMap.get("personnelType");
-
-        // ===================== 财务信息 =====================
-        // 销售价
-        Object price = resultMap.get("price");
-        // 折扣
-        Object priceRate = resultMap.get("priceRate");
-        // 含税金额
-        Object inTaxAmount = resultMap.get("inTaxAmount");
-        // 不含税金额
-        Object excludingtaxAmount = resultMap.get("excludingtaxAmount");
-        // 不含税交易金额(不含税销售价)
-        Object sellingPriceNoTax = resultMap.get("sellingPriceNoTax");
-        // 订单不含税金额
-        Object orderNoTaxAmount = resultMap.get("orderNoTaxAmount");
-        // 订单税额
-        Object orderTax = resultMap.get("orderTax");
-        // 发票税率
-        Object taxRate = resultMap.get("taxRate");
-
-        // ===================== 费用信息 =====================
-        // 员工自付金额
-        Object personalPaymentAmount = resultMap.get("personalPaymentAmount");
-        // 欠款金额
-        Object amount = resultMap.get("amount");
-        Object priceAmount = resultMap.get("priceAmount");
-        // 垫款服务费
-        Object advancePaymentAmount = resultMap.get("advancePaymentAmount");
-        // 支付类型 (0自付、1垫付)
-        Object payType = resultMap.get("payType");
-        // TMC支付类型
-        Object tmcPaymentType = resultMap.get("tmcPaymentType");
-        // 账单类型 (M月结, S服务费)
-        Object billType = resultMap.get("billType");
-
-        // ===================== 服务费信息 =====================
-        // TMC服务费(服务商服务费)
-        Object spServiceFee = resultMap.get("spServiceFee");
-        // 服务费(销售服务费)
-        Object serviceFee = resultMap.get("serviceFee");
-        // 技术服务费
-        Object technologyServiceFee = resultMap.get("technologyServiceFee");
-        // 退票费
-        Object refund = resultMap.get("refund");
-        // 改签费
-        Object rebookQueryFee = resultMap.get("rebookQueryFee");
-
-        // ===================== 项目信息 =====================
-        // 项目编号
-        Object projectNo = resultMap.get("projectNo");
-        // 项目名称
-        Object projectName = resultMap.get("projectName");
-        // 业务类型编号
-        Object businessTypeNo = resultMap.get("businessTypeNo");
-        // 业务类型名称
-        Object businessTypeName = resultMap.get("businessTypeName");
-        // 费用类型编号
-        Object feeTypeNo = resultMap.get("feeTypeNo");
-        // 费用类型名称
-        Object feeTypeName = resultMap.get("feeTypeName");
-        // 差旅类型 (1因公, 0因私)
-        Object travelType = resultMap.get("travelType");
-        // 搜索类型名称(可能是查询条件类型)
-        Object searchTypeName = resultMap.get("searchTypeName");
-
-        // ===================== 供应商信息 =====================
-        // 供应商编号
-        Object supplierNo = resultMap.get("supplierNo");
-        // 供应商名称
-        Object supplierName = resultMap.get("supplierName");
-        // 供应单号
-        Object purchaseOrderNo = resultMap.get("purchaseOrderNo");
-        // 供应商发票类型 (0/空:普票, 1:专票)
-        Object supplierInvoiceType = resultMap.get("supplierInvoiceType");
-        // 垫款商户编号
-        Object advancePaymentMerchantNo = resultMap.get("advancePaymentMerchantNo");
-        // 垫款商户名称
-        Object advancePaymentMerchantName = resultMap.get("advancePaymentMerchantName");
-
-        // ===================== 法人信息 =====================
-        // 法人公司
-        Object frgs = resultMap.get("frgs");
-        // 法人公司名称
-        Object frgsmc = resultMap.get("frgsmc");
-
-        // ===================== 行程信息 =====================
-        // 国内国际标识 (1国内, 0国际)
-        Object international = resultMap.get("international");
-        // 所在城市/出发城市名称
-        Object cityName = resultMap.get("cityName");
-        // 到达城市
-        Object arrivalCity = resultMap.get("arrivalCity");
-        // 到达城市名称/酒店所在城市
-        Object arrivalCityName = resultMap.get("arrivalCityName");
-        // 入住日期/出发时间
-        Object startTime = resultMap.get("startTime");
-        // 离店日期/到达时间
-        Object endTime = resultMap.get("endTime");
-        // 出票时间
-        Object printTicketTime = resultMap.get("printTicketTime");
-
-        // ===================== 酒店信息 =====================
-        // 酒店名称
-        Object hotelName = resultMap.get("hotelName");
-        // 酒店星级
-        Object star = resultMap.get("star");
-        // 房型中文名称
-        Object roomName = resultMap.get("roomName");
-        // 间夜数
-        Object quantity = resultMap.get("quantity");
-
-        // ===================== 机票附加费 =====================
-        // 机票建设费
-        Object airportFee = resultMap.get("airportFee");
-        // 保险费
-        Object insuranceFee = resultMap.get("insuranceFee");
-
-        // ===================== 其他字段 =====================
-        // 销售价(重复字段,可根据实际情况处理)
-        Object transAmount = resultMap.get("transAmount");
-
-        // 2.机票结算单 --国内机票 创建新的动态对象
-        DynamicObject planeCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_planecheckingbill");
-
-        // 3. 设置对应对象属性
-
-        //订单日期
-        planeCheckingBill.set("orderdate", orderType);
-        //订单性质
-        planeCheckingBill.set("isbusiness", travelType);
-        //结算类型 2 -个人现付
-        planeCheckingBill.set("producttype", "2");
-        //预订人工号
-        planeCheckingBill.set("booknum", "");
-        //预订人姓名
-        planeCheckingBill.set("bookedname", reserveName);
-        //结算发生日期
-        planeCheckingBill.set("happenddate", DateUtil.string2date((String) createTime,null));
-        //业务类型
-        planeCheckingBill.set("operationtype", businessTypeNo);
-        //订单分类
-        planeCheckingBill.set("ordersort", orderType);
-        //订单状态
-        planeCheckingBill.set("orderstatus", "5");
-        //结算金额
-        planeCheckingBill.set("totalamount", settlementAmount);
-        //币种
-        switch (settlementCurrency.toString()){
-            case "CNY":
-                planeCheckingBill.set("currency", "1");
-                break;
-            case "HKD":
-                planeCheckingBill.set("currency", "2");
-                break;
-            case "JPY":
-                planeCheckingBill.set("currency", "3");
-                break;
-            case "USD":
-                planeCheckingBill.set("currency", "4");
-                break;
-            case "EUR":
-                planeCheckingBill.set("currency", "5");
-                break;
-            case "GBP":
-                planeCheckingBill.set("currency", "6");
-                break;
-            case "AUD":
-                planeCheckingBill.set("currency", "7");
-                break;
-            case "TWD":
-                planeCheckingBill.set("currency", "8");
-                break;
-            case "MOP":
-                planeCheckingBill.set("currency", "9");
-                break;
+    private List<DynamicObject> extractAndProcessFields(Map<String, Object> resultMap) {
+        List<DynamicObject> resultLists = new ArrayList<>();
+
+        try {
+            // 1. 从结果映射中提取各字段
+            // ===================== 订单基本信息 =====================
+            // 结算单号
+            String settlementNo = getStringValue(resultMap, "settlementNo");
+            // 预订时间
+            String orderDate = getStringValue(resultMap, "orderDate");
+            // 申请单号
+            String tripNo = getStringValue(resultMap, "tripNo");
+            // 差旅类型
+            String travelType = getStringValue(resultMap, "travelType");
+            // 结算生成时间
+            String createTime = getStringValue(resultMap, "createTime");
+            // 结算金额
+            String settlementAmount = getStringValue(resultMap, "settlementAmount");
+            // 币种
+            String settlementCurrency = getStringValue(resultMap, "settlementCurrency");
+            // 结算批次号
+            String accCheckBatchNo = getStringValue(resultMap, "accCheckBatchNo");
+            // 法人公司编码
+            String frgs = getStringValue(resultMap, "frgs");
+            // 项目编号
+            String projectNo = getStringValue(resultMap, "projectNo");
+            // 国内国际标识
+            String international = getStringValue(resultMap, "international");
+            // 航空公司名称
+            String airlineCompanyName = getStringValue(resultMap, "airlineCompanyName");
+            // 票号
+            String ticketNo = getStringValue(resultMap, "ticketNo");
+            // 航班号
+            String flight = getStringValue(resultMap, "flight");
+            // 机票舱位子类
+            String subClass = getStringValue(resultMap, "subClass");
+            // 机票舱位等级
+            String cabinClass = getStringValue(resultMap, "cabinClass");
+            // 出发城市名称
+            String departCityName = getStringValue(resultMap, "departCityName");
+            // 到达城市名称
+            String arrivalCityName = getStringValue(resultMap, "arrivalCityName");
+            // 出发时间
+            String takeOffTime = getStringValue(resultMap, "takeOffTime");
+            // 到达时间
+            String arrivalTime = getStringValue(resultMap, "arrivalTime");
+            // 机票价格
+            String price = getStringValue(resultMap, "price");
+            // 折扣
+            String priceRate = getStringValue(resultMap, "priceRate");
+            // 订单税额
+            String orderTax = getStringValue(resultMap, "orderTax");
+            // 机票燃油费
+            String tax = getStringValue(resultMap, "tax");
+            // 服务费
+            String serviceFee = getStringValue(resultMap, "serviceFee");
+            // 退票费
+            String refund = getStringValue(resultMap, "refund");
+            // 改签费
+            String rebookQueryFee = getStringValue(resultMap, "rebookQueryFee");
+            // 保险费
+            String insuranceFee = getStringValue(resultMap, "insuranceFee");
+            // 机票建设费
+            String airportFee = getStringValue(resultMap, "airportFee");
+
+            // ===================== 人员信息 =====================
+            // 出行人姓名
+            String guestName = getStringValue(resultMap, "guestName");
+            // 出行人工号
+            String employeeId = getStringValue(resultMap, "employeeId");
+            // 预订人姓名
+            String reserveName = getStringValue(resultMap, "reserveName");
+            // 订单号
+            String orderNo = getStringValue(resultMap, "orderNo");
+            //业务发生时间
+            String rebookingtime = getStringValue(resultMap, "rebookingtime");
+
+            // 订单类型
+            String orderType = getStringValue(resultMap, "orderType");
+
+            // 01001机票正常单01002机票退单01003机票改签单
+            if ("01001".equals(orderType)) {
+                orderType = "O";
+            } else if ("01002".equals(orderType)) {
+                orderType = "T";
+            } else if ("01003".equals(orderType)) {
+                orderType = "G";
+            } else {
+                orderType = "";
+            }
+
+            //结算类型
+            String tmcPaymentType = getStringValue(resultMap, "tmcPaymentType");
+            if ("公司月结".equals(tmcPaymentType)) {
+                tmcPaymentType = "1";
+            } else if ("个人现付".equals(tmcPaymentType)) {
+                tmcPaymentType = "2";
+            }
+            //预订人员编号
+            String reserveId = getStringValue(resultMap, "reserveId");
+            // 2. 转换差旅类型格式
+            if ("因公".equals(travelType)) {
+                travelType = "1";
+            } else if ("因私".equals(travelType)) {
+                travelType = "0";
+            }
+            // 订单状态
+            String orderStatus = getStringValue(resultMap, "orderStatus");
+            switch (orderStatus) {
+                case "已完成":
+                    orderStatus = "USED";
+                    break;
+                case "已预订":
+                    orderStatus = "20000";
+                    break;
+                case "已出票":
+                    orderStatus = "40000";
+                    break;
+                case "取消中":
+                    orderStatus = "31000";
+                    break;
+                case "已取消":
+                    orderStatus = "30000";
+                    break;
+                case "退票中":
+                    orderStatus = "50201";
+                    break;
+                case "改签中":
+                    orderStatus = "50301";
+                    break;
+                case "已改签":
+                    orderStatus = "50302";
+                    break;
+                default:
+                    orderStatus = "9999";
+                    break;
+            }
+            // 3. 检查结算单是否已存在,存在则修改,不存在则创建
+            DynamicObject planeCheckingBill = queryPlaneCheckingBill(settlementNo);
+            boolean isNew = ObjectUtils.isEmpty(planeCheckingBill);
+
+            if (isNew) {
+                planeCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_planecheckingbill");
+                log.info("结算单号 " + settlementNo + " 不存在,创建新记录");
+            } else {
+                log.info("结算单号 " + settlementNo + " 已存在,更新记录");
+            }
+
+            // 4. 设置各字段值
+            // ===================== 基础信息 =====================
+            // 订单日期
+            planeCheckingBill.set("orderdate", DateUtil.string2date(orderDate, null));
+            // 结算单号
+            planeCheckingBill.set("ordernum", settlementNo);
+            // 订单类型,固定为"O"
+            planeCheckingBill.set("ordertype", orderType);
+            // 申请单号
+            planeCheckingBill.set("oabillnum", tripNo);
+            // 报销单号
+            planeCheckingBill.set("reimbursenum", "");
+            // 订单分类(国内/国际)
+            planeCheckingBill.set("ordersort", international);
+            // 订单性质(因公/因私)
+            planeCheckingBill.set("isbusiness", travelType);
+            // 结算类型:
+            planeCheckingBill.set("producttype", tmcPaymentType);
+
+            // 预订人
+            DynamicObject sourcebookedids = queryBosUser(reserveId);
+            planeCheckingBill.set("sourcebookedid", sourcebookedids);
+            // 预订人姓名
+            String bookedname = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
+            planeCheckingBill.set("bookedname", bookedname);
+            // 结算发生日期
+            planeCheckingBill.set("happenddate", DateUtil.string2date(createTime, null));
+            // 业务类型:2-国内机票
+            planeCheckingBill.set("operationtype", "2");
+            // 订单状态
+            planeCheckingBill.set("orderstatus",orderStatus);
+            // 父订单号
+            planeCheckingBill.set("parentordernum", orderNo);
+            // 结算金额
+            planeCheckingBill.set("totalamount", settlementAmount);
+            // ===================== 财务信息 =====================
+            // 设置币种,从枚举中获取对应的值
+            String currency = Optional.ofNullable(CurrencyEnum.getByCode(settlementCurrency))
+                    .map(CurrencyEnum::getValue)
+                    .orElse(null);
+            planeCheckingBill.set("currency", currency);
+            // 结算批次号
+            planeCheckingBill.set("batchno", accCheckBatchNo);
+            // 结算子批次号
+            planeCheckingBill.set("subbatchno", "");
+
+            // ===================== 组织信息 =====================
+            // 设置费用承担公司(根据法人公司编码查询组织信息)
+            if (StringUtils.isNotBlank(frgs)) {
+                QFilter[] orgFilter = new QFilter[]{
+                        new QFilter(BaseFieldConst.NUMBER, QCP.equals, frgs),
+                };
+                DynamicObject org = BusinessDataServiceHelper.loadSingle(BosOrgConst.BOS_ORG, "id", orgFilter);
+                if (ObjectUtils.isEmpty(org)) {
+                    planeCheckingBill.set("settlemain", "");
+                    log.info("未找到编码为 " + frgs + " 的组织信息");
+                } else {
+                    planeCheckingBill.set("settlemain", org);
+                }
+            } else {
+                planeCheckingBill.set("settlemain", "");
+            }
+            // 费用承担部门
+            planeCheckingBill.set("settledept", "");
+            // 申请人公司
+            planeCheckingBill.set("company", "");
+            // 申请人部门
+            planeCheckingBill.set("org", "");
+            // 项目
+            planeCheckingBill.set("std_project", projectNo);
+            // 成本中心
+            planeCheckingBill.set("std_costcenter", "");
+            // 外部系统结算单号
+            planeCheckingBill.set("outsettlementnum", "");
+
+            //============================航程信息=============================
+            // 航空公司名称
+            planeCheckingBill.set("airlinename", airlineCompanyName);
+            // 电子客票号
+            planeCheckingBill.set("ticketnum", ticketNo);
+            // 航班号
+            planeCheckingBill.set("flightno", flight);
+            // 舱位
+            planeCheckingBill.set("cabin", subClass);
+            // 舱位等级
+            planeCheckingBill.set("cabinclass", cabinClass);
+            // 出发城市名称
+            planeCheckingBill.set("fromcityname", departCityName);
+            // 出发日期
+            planeCheckingBill.set("takeofftime", DateUtil.string2date(takeOffTime, null));
+            // 到达城市名称
+            planeCheckingBill.set("tocityname", arrivalCityName);
+            // 到达时间
+            planeCheckingBill.set("landingtime", DateUtil.string2date(arrivalTime, null));
+            // 改签费
+            planeCheckingBill.set("endorsementamount", rebookQueryFee);
+            // 保险费
+            planeCheckingBill.set("assuranceamount", insuranceFee);
+            // 折扣(%)
+            planeCheckingBill.set("discount", priceRate);
+            // 机票价格
+            planeCheckingBill.set("ticketprice", price);
+            // 民航发展基金/税费
+            planeCheckingBill.set("airportprice", "");
+            // 税费
+            planeCheckingBill.set("tax", orderTax);
+            // 服务费
+            planeCheckingBill.set("servicefee", serviceFee);
+            // 燃油费
+            planeCheckingBill.set("fuelprice", tax);
+            // 退票费
+            planeCheckingBill.set("refundamount", refund);
+            // 其他费用-机票建设费
+            planeCheckingBill.set("otheramount", airportFee);
+
+            // 乘机人工号
+            DynamicObject travelername = queryBosUser(employeeId);
+            // 乘机人姓名
+            String travelernames = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
+            planeCheckingBill.set("sourcetravelerid", travelername);
+            planeCheckingBill.set("travelername", travelernames);
+
+            // 行程单号
+            planeCheckingBill.set("itinerarynum", "");
+            // 填开日期
+            planeCheckingBill.set("itinerarydate", "");
+            // 产品子类型
+            planeCheckingBill.set("productsontype", "");
+            // 票价开票类型
+            planeCheckingBill.set("pricebillingtype", "");
+            // 付款/付款申请单号
+            planeCheckingBill.set("paybillnum", "");
+            // 付款状态
+            planeCheckingBill.set("paybillstatus", "");
+            // 凭证号
+            planeCheckingBill.set("vouchernum", "");
+            // 记账日期
+            planeCheckingBill.set("bookeddatereq", "");
+
+
+            //=============================获取发票=================================
+            List<Map<String, Object>> invoiceResultList = InvoiceApiUtils.getInvoiceResult(settlementNo, rebookingtime);
+            if (CollectionUtils.isEmpty(invoiceResultList)) {
+                log.info("结算单号:" + settlementNo + "未查询到发票数据");
+            }else{
+                for (Map<String, Object> resultInvoiceList : invoiceResultList) {
+                    //下载地址
+                    planeCheckingBill.set("downloadlink", resultInvoiceList.get("invoiceUrl"));
+                    //内部下载地址
+                    planeCheckingBill.set("kddownloadlink", resultInvoiceList.get("invoiceUrl"));
+                    //发票流水号
+                    planeCheckingBill.set("serialno", resultInvoiceList.get("invoiceId"));
+                    //发票识别成功
+                    planeCheckingBill.set("invoiceidentityflag", true);
+                    //发票识别异常信息
+                    planeCheckingBill.set("identityerrormsg", "");
+                    // 票价开票类型
+                    String invoiceTypeCode = resultInvoiceList.get("invoiceType").toString();
+                    String invoice = InvoiceTypeEnum.getValueByCode(invoiceTypeCode);
+                    planeCheckingBill.set("pricebillingtype", invoice);
+                }
+            }
+
+
+            resultLists.add(planeCheckingBill);
+
+        } catch (Exception e) {
+            log.info("处理单条国内机票结算数据时发生异常,数据内容: " + resultMap, e);
         }
-        //结算批次号
-        planeCheckingBill.set("batchno", accCheckBatchNo);
-        //结算子批次号
-        planeCheckingBill.set("subbatchno", "");
-        //费用承担公司
-        planeCheckingBill.set("settlemain", "");
-        //费用承担部门
-        planeCheckingBill.set("settledept", "");
-        //申请人公司
-        planeCheckingBill.set("company", "");
-        //申请人部门
-        planeCheckingBill.set("org", "");
-        //项目
-        planeCheckingBill.set("std_project", projectNo);
-        //成本中心
-        planeCheckingBill.set("std_costcenter", "");
-        //外部系统结算单号
-        planeCheckingBill.set("outsettlementnum", "");
-        //火车票车票号
-        planeCheckingBill.set("trainticketnum", "");
-        //出发城市
-        planeCheckingBill.set("departcity", "");
-        //出发车站
-        planeCheckingBill.set("departaddress", "");
-        //到达城市
-        planeCheckingBill.set("arrivecity", "");
-        //到达车站
-        planeCheckingBill.set("arriveaddress", "");
-        //出发时间
-        planeCheckingBill.set("departtime", "");
-        //到达时间
-        planeCheckingBill.set("arrivetime", "");
-        //乘客
-        planeCheckingBill.set("passeger", "");
-        //乘客姓名
-        planeCheckingBill.set("passegername", "");
-        //车次
-        planeCheckingBill.set("vendorname", "");
-        //席位
-        planeCheckingBill.set("trainseat", "");
-        //火车票价
-        planeCheckingBill.set("ticketprice", "");
-        //服务费
-        planeCheckingBill.set("servicefee", "");
-        //退票费
-        planeCheckingBill.set("refundamount", "");
-        //保险费
-        planeCheckingBill.set("assuranceamount", "");
-        //下载地址
-        planeCheckingBill.set("downloadlink", "");
-        //内部下载地址
-        planeCheckingBill.set("kddownloadlink", "");
-        //发票流水号
-        planeCheckingBill.set("serialno", "");
-        //发票识别异常信息
-        planeCheckingBill.set("identityerrormsg", "");
-        //票价开票类型
-        planeCheckingBill.set("pricebillingtype", "");
-
-        //控制信息
-//        ??????。。
-        //可抵扣税额
-        planeCheckingBill.set("totaltax", "");
-        //已开票
-        planeCheckingBill.set("hasinvoice", "");
-        //付款/付款申请单号
-        planeCheckingBill.set("paybillnum", "");
-        //付款状态
-        planeCheckingBill.set("paybillstatus", "");
-        //凭证号
-        planeCheckingBill.set("vouchernum", "");
-        //记账日期
-        planeCheckingBill.set("bookeddatereq", "");
-        //记账日期
-        planeCheckingBill.set("bookeddatebu", "");
-
-        // 4.保存对象
-        SaveServiceHelper.save(new DynamicObject[]{planeCheckingBill});
+
+        return resultLists;
+    }
+
+    /**
+     * 根据员工工号查询人员信息
+     *
+     * @param employeeId
+     * @return
+     */
+    private DynamicObject queryBosUser(String employeeId) {
+        if (StringUtils.isBlank(employeeId)) {
+            log.info("未找到工号为:" + employeeId + "的人员信息");
+            return null;
+        }
+        QFilter userFilter = new QFilter("number", QCP.equals, employeeId);
+        //查询人员表
+        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle("bos_user", "id,name", userFilter.toArray());
+
+        return bosUser;
+    }
+
+    /**
+     * 从Map中安全获取字符串值,避免空指针异常
+     *
+     * @param map 数据映射
+     * @param key 键名
+     * @return 字符串值,如果不存在或为null则返回空字符串
+     */
+    private String getStringValue(Map<String, Object> map, String key) {
+        return Optional.ofNullable(map.get(key))
+                .map(Object::toString)
+                .orElse("");
+    }
+
+    /**
+     * 查询机票结算单
+     *
+     * @param settlementNo 结算单号
+     * @return 结算单对象
+     */
+    private DynamicObject queryPlaneCheckingBill(Object settlementNo) {
+        QFilter[] trainFilter = new QFilter[]{
+                new QFilter("ordernum", QCP.equals, settlementNo)
+        };
+        return BusinessDataServiceHelper.loadSingle("er_planecheckingbill", trainFilter);
     }
 
     /**
@@ -385,37 +508,37 @@ public class DomesticFlightSettlementTask extends AbstractTask {
         String nowDateString = DateUtil.date2str(nowDate, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
 
         log.info("结算单(国内机票) 同步开始时间:" + syncTime);
-
         List<Map<String, Object>> dataList = new ArrayList<>();
-        for (int i = 0; i < totalPage; i++) {
+        for (int i = 0; i < TOTAL_PAGE; i++) {
             //创建接口业务数据参数
             Map<String, Object> data = new HashMap<>();
             //结算时间始
-            data.put("dateFrom", syncTime);
+            data.put("dateFrom", "1970-01-01 00:00:00");
+//            data.put("dateFrom", syncTime);
             //结算时间止
             data.put("dateTo", nowDateString);
             //产品类别 0100 国内机票
-            data.put("searchType", "0100");
+            data.put("searchType", DOMESTIC_FLIGHT_PRODUCT_TYPE);
             //当前页
             data.put("current", i + 1);
             //每页条数,最多500条
-            data.put("size", size);
+            data.put("size", PAGE_SIZE);
             //企业卡号
-            data.put("enterpriseNo", "JXWL");
+            data.put("enterpriseNo", ENTERPRISE_NO);
             //账单类型 01-现结
-            data.put("settlementType", "01");
+//            data.put("settlementType", "01");
 
-            Map<String, Object> resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_LiteGetSettlementInfo", Boolean.FALSE, data);
+            Map<String, Object> resp = TripSyncUtils.pushApiCallResult(INTERFACE_NAME, Boolean.FALSE, data);
             //报错终止同步,等待下次计划执行
             if ((Boolean) resp.get("fail")) {
                 throw new KDBizException(resp.get("message").toString());
             }
             Map<String, Object> result = (Map<String, Object>) resp.get("result");
-            List<Map<String, Object>> resultDataList = (List<Map<String, Object>>) result.getOrDefault("dataList", Collections.emptyList());
+            List<Map<String, Object>> resultDataList = (List<Map<String, Object>>) result.getOrDefault("settlementInfos", Collections.emptyList());
             dataList.addAll(resultDataList);
 
             //当前查询数量小于分页数量时结束循环
-            if (resultDataList.size() < size) {
+            if (resultDataList.size() < PAGE_SIZE) {
                 break;
             }
         }
@@ -431,7 +554,7 @@ public class DomesticFlightSettlementTask extends AbstractTask {
         //是否全量同步
         Boolean isAll = (Boolean) sysCtrlParameter.get("nckd_settlementbillall");
         if (isAll) {
-            return "1970-01-01 00:00:00";
+            return FULL_SYNC_START_TIME;
         }
         //增量同步小时  填写整数N,同步N小时前到现在新增或修改的数据,不填默认1小时。
         int hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour")) ? 1 : (Integer) sysCtrlParameter.get("nckd_settlementbillhour");

+ 403 - 367
nckd-fi/src/main/java/nckd/fi/er/task/HotelSettlementTask.java

@@ -6,16 +6,20 @@ import kd.bos.exception.KDBizException;
 import kd.bos.exception.KDException;
 import kd.bos.krpc.common.logger.Logger;
 import kd.bos.krpc.common.logger.LoggerFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
 import kd.bos.schedule.executor.AbstractTask;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.qmc.qcbd.common.constant.BosOrgConst;
+import nckd.base.common.constant.BaseFieldConst;
+import nckd.base.common.enums.CurrencyEnum;
 import nckd.base.common.utils.DateUtil;
 import nckd.base.common.utils.ParamUtils;
 import nckd.base.common.utils.TripSyncUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
 
-import java.text.ParseException;
 import java.util.*;
 
 /**
@@ -26,395 +30,427 @@ import java.util.*;
  * @Description:结算单(酒店)
  */
 public class HotelSettlementTask extends AbstractTask {
-    private static Logger log = LoggerFactory.getLogger(HotelSettlementTask.class);
+    private static final Logger log = LoggerFactory.getLogger(HotelSettlementTask.class);
 
     /**
-     * 总页码,不处理总数,
-     * 每当当前页码数据小于1000 停止接口查询
+     * 最大查询页数,当某页数据小于每页条数时停止查询
      */
-    private final static int totalPage = 1000;
+    private static final int TOTAL_PAGE = 1000;
 
     /**
-     * 每页条数,最多500条   实际1000条
+     * 每页查询条数
      */
-    private final static int size = 1000;
+    private static final int PAGE_SIZE = 500;
 
+    /**
+     * 全量同步的起始时间
+     */
+    private static final String FULL_SYNC_START_TIME = "1970-01-01 00:00:00";
+
+    /**
+     * 酒店产品类型编码
+     */
+    private static final String HOTEL_PRODUCT_TYPE = "0300";
+
+    /**
+     * 外部接口名称
+     */
+    private static final String INTERFACE_NAME = "FCSET_OUTAPI_LiteGetSettlementInfo";
+
+    /**
+     * 企业卡号
+     */
+    private static final String ENTERPRISE_NO = "JXWL";
+
+    /**
+     * 任务执行入口
+     *
+     * @param requestContext 请求上下文
+     * @param map            任务参数映射
+     * @throws KDException 执行异常
+     */
     @Override
     public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
-        log.info("结算单(同步酒店)查询接口 调度计划开始执行");
-        List<Map<String, Object>> resultLists = getResult();
-        if (ObjectUtils.isEmpty(resultLists)) {
-            log.info("结算单(同步酒店)查询接口 暂无数据-----");
-            return;
+        log.info("酒店结算单同步任务开始执行");
+
+        try {
+            // 1. 从外部接口获取酒店结算数据
+            List<Map<String, Object>> resultLists = getResult();
+            if (ObjectUtils.isEmpty(resultLists)) {
+                log.info("未获取到酒店结算数据,任务结束");
+                return;
+            }
+
+            log.info("成功获取到 " + resultLists.size() + " 条酒店结算数据");
+
+            // 2. 处理获取到的数据
+            processResultData(resultLists);
+
+            log.info("酒店结算单同步任务执行完成");
+        } catch (Exception e) {
+            log.info("酒店结算单同步任务执行失败", e);
+            throw e;
         }
+    }
+
+    /**
+     * 批量处理获取到的酒店结算数据
+     *
+     * @param resultLists 酒店结算数据列表
+     */
+    private void processResultData(List<Map<String, Object>> resultLists) {
+        int successCount = 0;
+        int failCount = 0;
+
         for (Map<String, Object> resultMap : resultLists) {
             try {
-                // 从结果映射中提取各字段
-                extractAndProcessFields(resultMap);
+                // 提取并处理单条数据字段,保存到系统
+                List<DynamicObject> hotelCheckingList = extractAndProcessFields(resultMap);
+                if (!ObjectUtils.isEmpty(hotelCheckingList)) {
+                    SaveServiceHelper.save(hotelCheckingList.toArray(new DynamicObject[0]));
+                    successCount++;
+                }
             } catch (Exception e) {
-                log.info("处理火车票结算数据时发生异常,数据内容: " + resultMap, e);
+                failCount++;
+                log.info("处理酒店结算数据时发生异常,数据内容: " + resultMap, e);
             }
         }
 
+        log.info("酒店结算数据处理完成:成功 " + successCount + " 条,失败 " + failCount + " 条");
     }
 
     /**
-     * 从单条数据映射中提取字段并处理
+     * 从单条数据映射中提取字段并处理,生成系统动态对象
+     * 注:此方法将外部接口数据映射到系统表单字段
      *
      * @param resultMap 单条数据映射
+     * @return 处理后的动态对象列表
      */
-    private void extractAndProcessFields(Map<String, Object> resultMap) throws ParseException {
-        // 1.获取接口返回值
+    private List<DynamicObject> extractAndProcessFields(Map<String, Object> resultMap) {
+        List<DynamicObject> resultLists = new ArrayList<>();
+
+        try {
+            // 1. 从结果映射中提取各字段
+            // ===================== 订单基本信息 =====================
+            // 结算单号
+            String settlementNo = getStringValue(resultMap, "settlementNo");
+            // 预订时间
+            String orderDate = getStringValue(resultMap, "orderDate");
+            // 订单类型
+            String orderType = getStringValue(resultMap, "orderType");
+            // 申请单号
+            String tripNo = getStringValue(resultMap, "tripNo");
+            // 差旅类型
+            String travelType = getStringValue(resultMap, "travelType");
+            // 结算生成时间
+            String createTime = getStringValue(resultMap, "createTime");
+            // 结算金额
+            String settlementAmount = getStringValue(resultMap, "settlementAmount");
+            // 币种
+            String settlementCurrency = getStringValue(resultMap, "settlementCurrency");
+            // 结算批次号
+            String accCheckBatchNo = getStringValue(resultMap, "accCheckBatchNo");
+            // 法人公司编码
+            String frgs = getStringValue(resultMap, "frgs");
+            // 项目编号
+            String projectNo = getStringValue(resultMap, "projectNo");
+            // 业务类型编号
+            String businessTypeNo = getStringValue(resultMap, "businessTypeNo");
+            // 房间数
+            String roomQuantity = getStringValue(resultMap, "roomQuantity");
+            // 房间数(整数)
+            int roomQuantityInt = parseRoomQuantity(roomQuantity);
+            // 服务费
+            String serviceFee = getStringValue(resultMap, "serviceFee");
+            // 退订费
+            String refund = getStringValue(resultMap, "refund");
+            // 出行人姓名
+            String guestName = getStringValue(resultMap, "guestName");
+            // 出行人工号
+            String employeeId = getStringValue(resultMap, "employeeId");
+            // 预订人姓名
+            String reserveName = getStringValue(resultMap, "reserveName");
+            // 预订人员编号
+            String reserveId = getStringValue(resultMap, "reserveId");
+            // 供应商名称
+            String supplierName = getStringValue(resultMap, "supplierName");
+            // 供应单号
+            String purchaseOrderNo = getStringValue(resultMap, "purchaseOrderNo");
+            // 酒店所在城市
+            String arrivalCityName = getStringValue(resultMap, "arrivalCityName");
+            // 酒店名称
+            String hotelName = getStringValue(resultMap, "hotelName");
+            // 房型中文名称
+            String roomName = getStringValue(resultMap, "roomName");
+            // 入住日期
+            String startTime = getStringValue(resultMap, "startTime");
+            // 离店日期
+            String endTime = getStringValue(resultMap, "endTime");
+            //结算类型
+            String tmcPaymentType = getStringValue(resultMap, "tmcPaymentType");
+            if ("公司月结".equals(tmcPaymentType)) {
+                tmcPaymentType = "1";
+            } else if ("个人现付".equals(tmcPaymentType)) {
+                tmcPaymentType = "2";
+            }
+            // 2. 转换差旅类型格式
+            if ("因公".equals(travelType)) {
+                travelType = "1";
+            } else if ("因私".equals(travelType)) {
+                travelType = "0";
+            }
+
+            //订单状态
+            String orderStatus = getStringValue(resultMap, "orderStatus");
+            switch (orderStatus) {
+                case "待审批":
+                    orderStatus = "1";
+                    break;
+                case "待支付":
+                    orderStatus = "2";
+                    break;
+                case "待确认":
+                    orderStatus = "3";
+                    break;
+                case "已确认":
+                    orderStatus = "5";
+                    break;
+                case "满房":
+                    orderStatus = "6";
+                    break;
+                case "已离店":
+                    orderStatus = "7";
+                    break;
+                case "待退订":
+                    orderStatus = "3";
+                    break;
+                case "已退订":
+                    orderStatus = "5";
+                    break;
+                case "已取消":
+                    orderStatus = "6";
+                    break;
+                default:
+                    orderStatus = "9999";
+                    break;
+            }
 
-        // ===================== 订单基本信息 =====================
-        // 订单类型 (01001机票正常单, 01002机票退单, 01003机票改签单, 1酒店正常单, 2酒店退单等)
-        Object orderType = resultMap.get("orderType");
-        // 房间数
-        Object roomQuantity = resultMap.get("roomQuantity");
-        int roomQuantityInt = 0;
+            // 3. 检查结算单是否已存在,存在则修改,不存在则创建
+            DynamicObject hotelCheckingBill = queryHotelCheckingBill(settlementNo);
+            boolean isNew = ObjectUtils.isEmpty(hotelCheckingBill);
 
-        if (roomQuantity != null) {
-            try {
-                // 先解析为double,再转换为int
-                double doubleValue = Double.parseDouble(roomQuantity.toString());
-                roomQuantityInt = (int) doubleValue;
-
-                // 或者使用四舍五入
-                // roomQuantityInt = (int) Math.round(doubleValue);
-            } catch (NumberFormatException e) {
-                System.out.println("无法解析为数字: " + roomQuantity);
+            if (isNew) {
+                hotelCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_hotelcheckingbill");
+                log.info("创建新的酒店结算单: " + settlementNo);
+            } else {
+                log.info("更新已存在的酒店结算单: " + settlementNo);
             }
+
+            // 4. 设置各字段值
+            // ===================== 订单信息 =====================
+            // 服务商
+            hotelCheckingBill.set("server", "");
+            // 订单日期
+            hotelCheckingBill.set("orderdate", DateUtil.string2date(orderDate, null));
+            // 结算单号
+            hotelCheckingBill.set("ordernum", settlementNo);
+            // 订单类型 1酒店正常单 - O 2酒店退单 -T
+            if ("1".equals(orderType)) {
+                hotelCheckingBill.set("ordertype", "O");
+            } else if ("2".equals(orderType)) {
+                hotelCheckingBill.set("ordertype", "T");
+            } else {
+                hotelCheckingBill.set("ordertype", "");
+            }
+            // 申请单号
+            hotelCheckingBill.set("oabillnum", tripNo);
+            // 报销单号
+            hotelCheckingBill.set("reimbursenum", "");
+            // 业务类型
+            hotelCheckingBill.set("operationtype", businessTypeNo);
+            // 订单分类
+            hotelCheckingBill.set("ordersort", "");
+            // 订单性质(因公/因私)
+            hotelCheckingBill.set("isbusiness", travelType);
+            // 结算类型
+            hotelCheckingBill.set("producttype", tmcPaymentType);
+            // 预订人
+            DynamicObject sourcebookedids = queryBosUser(reserveId);
+            hotelCheckingBill.set("sourcebookedid", sourcebookedids);
+            // 预订人姓名
+            String bookedname = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
+            hotelCheckingBill.set("bookedname", bookedname);
+
+            // 结算发生日期
+            hotelCheckingBill.set("happenddate", DateUtil.string2date(createTime, null));
+            // 订单状态
+            hotelCheckingBill.set("orderstatus", orderStatus);
+            // 父订单号
+            hotelCheckingBill.set("parentordernum", "");
+
+            //币种,从枚举中获取对应的值
+            String currency = Optional.ofNullable(CurrencyEnum.getByCode(settlementCurrency))
+                    .map(CurrencyEnum::getValue)
+                    .orElse(null);
+            hotelCheckingBill.set("currency", currency);
+            // 结算金额
+            hotelCheckingBill.set("totalamount", settlementAmount);
+            // 结算批次号
+            hotelCheckingBill.set("batchno", accCheckBatchNo);
+            // 结算子批次号
+            hotelCheckingBill.set("subbatchno", "");
+
+            // 设置费用承担公司(根据法人公司编码查询组织信息)
+            if (StringUtils.isNotBlank(frgs)) {
+                QFilter[] orgFilter = new QFilter[]{
+                        new QFilter(BaseFieldConst.NUMBER, QCP.equals, frgs)
+                };
+                DynamicObject org = BusinessDataServiceHelper.loadSingle(BosOrgConst.BOS_ORG, "id", orgFilter);
+                if (ObjectUtils.isEmpty(org)) {
+                    hotelCheckingBill.set("settlemain", "");
+                    log.warn("未找到编码为: " + frgs + " 的组织信息");
+                } else {
+                    hotelCheckingBill.set("settlemain", org);
+                }
+            } else {
+                hotelCheckingBill.set("settlemain", "");
+            }
+
+            // 费用承担部门
+            hotelCheckingBill.set("settledept", "");
+            // 成本中心
+            hotelCheckingBill.set("std_costcenter", "");
+            // 申请人公司
+            hotelCheckingBill.set("company", "");
+            // 申请人部门
+            hotelCheckingBill.set("org", "");
+            // 项目
+            hotelCheckingBill.set("std_project", projectNo);
+            // 产品子类型
+            hotelCheckingBill.set("productsontype", "");
+            // 外部系统结算单号(供应单号)
+            hotelCheckingBill.set("outsettlementnum", purchaseOrderNo);
+
+            // ===================== 入住信息 =====================
+            // 入住人工号
+            DynamicObject bosUser = queryBosUser(reserveId);
+            hotelCheckingBill.set("sourcetravelerid", bosUser);
+            // 入住人姓名
+            String travelername = ObjectUtils.isEmpty(bosUser) ? "" : bosUser.getString("name");
+            hotelCheckingBill.set("travelername", travelername);
+
+            // 城市(酒店所在城市)
+            hotelCheckingBill.set("cityname", arrivalCityName);
+            // 酒店名称
+            hotelCheckingBill.set("hotelname", hotelName);
+            // 设置入住和离店日期(使用特定日期格式)
+            if (StringUtils.isNotBlank(startTime)) {
+                hotelCheckingBill.set("checkindate", DateUtil.string2date(startTime, "yyyy-MM-dd"));
+            }
+            if (StringUtils.isNotBlank(endTime)) {
+                hotelCheckingBill.set("checkoutdate", DateUtil.string2date(endTime, "yyyy-MM-dd"));
+            }
+            // 房型
+            hotelCheckingBill.set("roomstylename", roomName);
+            // 订房间数
+            hotelCheckingBill.set("roomcount", roomQuantityInt);
+            // 服务费
+            hotelCheckingBill.set("servicefee", serviceFee);
+            // 退订费
+            hotelCheckingBill.set("unbookfee", refund);
+            // 票价开票类型
+            hotelCheckingBill.set("pricebillingtype", "");
+
+            //========================= 控制信息=====================
+            // 已对平
+            hotelCheckingBill.set("isbalance", "");
+            // 备注
+            hotelCheckingBill.set("balanceremark", "");
+            // 单据状态:C
+            hotelCheckingBill.set("billstatus", "C");
+
+            //============================付款/凭证信息================================
+            //付款/付款申请单号
+            hotelCheckingBill.set("paybillnum", "");
+            //付款状态
+            hotelCheckingBill.set("paybillstatus", "");
+            //凭证号
+            hotelCheckingBill.set("vouchernum", "");
+            //记账日期
+            hotelCheckingBill.set("bookeddatereq", "");
+            resultLists.add(hotelCheckingBill);
+
+        } catch (Exception e) {
+            log.info("处理单条酒店结算数据时发生异常,数据内容: " + resultMap, e);
+            throw e;
         }
-        // 订单类型名称
-        Object orderName = resultMap.get("orderName");
-        // 订单号
-        Object orderNo = resultMap.get("orderNo");
-        // 原订单编号
-        Object oldOrderNo = resultMap.get("oldOrderNo");
-        // 订单状态 (已完成等)
-        Object orderStatus = resultMap.get("orderStatus");
-        // 预订时间
-        Object orderDate = resultMap.get("orderDate");
-        // 业务发生时间
-        Object rebookingtime = resultMap.get("rebookingtime");
-        // 结算生成时间
-        Object createTime = resultMap.get("createTime");
-
-        // ===================== 结算信息 =====================
-        // 结算明细主键
-        Object tmcSettlementid = resultMap.get("tmcSettlementid");
-        // 结算单号
-        Object settlementNo = resultMap.get("settlementNo");
-        // 结算批次号(对应系统账单号)
-        Object accCheckBatchNo = resultMap.get("accCheckBatchNo");
-        // 结算明细ID
-        Object subAccCheckBatchNo = resultMap.get("subAccCheckBatchNo");
-        // 大表ID
-        Object mainTableId = resultMap.get("mainTableId");
-        // 币种 (例如CNY)
-        Object settlementCurrency = resultMap.get("settlementCurrency");
-
-        // 结算金额
-        Object settlementAmount = resultMap.get("settlementAmount");
-        // 结算单合计金额
-        Object totalAmount = resultMap.get("totalAmount");
-
-        // ===================== 人员信息 =====================
-        // 出行人姓名
-        Object guestName = resultMap.get("guestName");
-        // 出行人名称
-        Object passengerName = resultMap.get("passengerName");
-        // 员工姓名
-        Object employeeName = resultMap.get("employeeName");
-        // 出行人工号
-        Object employeeId = resultMap.get("employeeId");
-        // 预订人姓名
-        Object reserveName = resultMap.get("reserveName");
-        // 预订人员编号
-        Object reserveId = resultMap.get("reserveId");
-        // 人员类型(可能是员工类型)
-        Object personnelType = resultMap.get("personnelType");
-
-        // ===================== 财务信息 =====================
-        // 销售价
-        Object price = resultMap.get("price");
-        // 折扣
-        Object priceRate = resultMap.get("priceRate");
-        // 含税金额
-        Object inTaxAmount = resultMap.get("inTaxAmount");
-        // 不含税金额
-        Object excludingtaxAmount = resultMap.get("excludingtaxAmount");
-        // 不含税交易金额(不含税销售价)
-        Object sellingPriceNoTax = resultMap.get("sellingPriceNoTax");
-        // 订单不含税金额
-        Object orderNoTaxAmount = resultMap.get("orderNoTaxAmount");
-        // 订单税额
-        Object orderTax = resultMap.get("orderTax");
-        // 发票税率
-        Object taxRate = resultMap.get("taxRate");
-
-        // ===================== 费用信息 =====================
-        // 员工自付金额
-        Object personalPaymentAmount = resultMap.get("personalPaymentAmount");
-        // 欠款金额
-        Object amount = resultMap.get("amount");
-        Object priceAmount = resultMap.get("priceAmount");
-        // 垫款服务费
-        Object advancePaymentAmount = resultMap.get("advancePaymentAmount");
-        // 支付类型 (0自付、1垫付)
-        Object payType = resultMap.get("payType");
-        // TMC支付类型
-        Object tmcPaymentType = resultMap.get("tmcPaymentType");
-        // 账单类型 (M月结, S服务费)
-        Object billType = resultMap.get("billType");
-
-        // ===================== 服务费信息 =====================
-        // TMC服务费(服务商服务费)
-        Object spServiceFee = resultMap.get("spServiceFee");
-        // 服务费(销售服务费)
-        Object serviceFee = resultMap.get("serviceFee");
-        // 技术服务费
-        Object technologyServiceFee = resultMap.get("technologyServiceFee");
-        // 退票费
-        Object refund = resultMap.get("refund");
-        // 改签费
-        Object rebookQueryFee = resultMap.get("rebookQueryFee");
-
-        // ===================== 项目信息 =====================
-        // 项目编号
-        Object projectNo = resultMap.get("projectNo");
-        // 项目名称
-        Object projectName = resultMap.get("projectName");
-        // 业务类型编号
-        Object businessTypeNo = resultMap.get("businessTypeNo");
-        // 业务类型名称
-        Object businessTypeName = resultMap.get("businessTypeName");
-        // 费用类型编号
-        Object feeTypeNo = resultMap.get("feeTypeNo");
-        // 费用类型名称
-        Object feeTypeName = resultMap.get("feeTypeName");
-        // 差旅类型 (1因公, 0因私)
-        Object travelType = resultMap.get("travelType");
-        if ("因公".equals(travelType)){
-            travelType = "1";
-        }else if ("因私".equals(travelType)){
-            travelType = "0";
+
+        return resultLists;
+    }
+
+    /**
+     * 根据员工工号查询人员信息
+     *
+     * @param employeeId
+     * @return
+     */
+    private DynamicObject queryBosUser(String employeeId) {
+        if (StringUtils.isBlank(employeeId)) {
+            log.info("未找到工号为:" + employeeId + "的人员信息");
+            return null;
         }
-        // 搜索类型名称(可能是查询条件类型)
-        Object searchTypeName = resultMap.get("searchTypeName");
-
-        // ===================== 供应商信息 =====================
-        // 供应商编号
-        Object supplierNo = resultMap.get("supplierNo");
-        // 供应商名称
-        Object supplierName = resultMap.get("supplierName");
-        // 供应单号
-        Object purchaseOrderNo = resultMap.get("purchaseOrderNo");
-        // 供应商发票类型 (0/空:普票, 1:专票)
-        Object supplierInvoiceType = resultMap.get("supplierInvoiceType");
-        // 垫款商户编号
-        Object advancePaymentMerchantNo = resultMap.get("advancePaymentMerchantNo");
-        // 垫款商户名称
-        Object advancePaymentMerchantName = resultMap.get("advancePaymentMerchantName");
-
-        // ===================== 法人信息 =====================
-        // 法人公司名称
-        Object frgsmc = resultMap.get("frgsmc");
-
-        // ===================== 行程信息 =====================
-        // 国内国际标识 (1国内, 0国际)
-        Object international = resultMap.get("international");
-        // 所在城市/出发城市名称
-        Object cityName = resultMap.get("cityName");
-        // 到达城市
-        Object arrivalCity = resultMap.get("arrivalCity");
-        // 到达城市名称/酒店所在城市
-        Object arrivalCityName = resultMap.get("arrivalCityName");
-        // 入住日期/出发时间
-        Object startTime = resultMap.get("startTime");
-        // 离店日期/到达时间
-        Object endTime = resultMap.get("endTime");
-        // 出票时间
-        Object printTicketTime = resultMap.get("printTicketTime");
-
-        // ===================== 酒店信息 =====================
-        // 酒店名称
-        Object hotelName = resultMap.get("hotelName");
-        // 酒店星级
-        Object star = resultMap.get("star");
-        // 房型中文名称
-        Object roomName = resultMap.get("roomName");
-        // 间夜数
-        Object quantity = resultMap.get("quantity");
-
-        // ===================== 机票附加费 =====================
-        // 机票建设费
-        Object airportFee = resultMap.get("airportFee");
-        // 保险费
-        Object insuranceFee = resultMap.get("insuranceFee");
-
-        // ===================== 其他字段 =====================
-        // 销售价(重复字段,可根据实际情况处理)
-        Object transAmount = resultMap.get("transAmount");
-
-        // 2.酒店结算单 创建新的动态对象
-        DynamicObject hotelCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_hotelcheckingbill");
-
-        //3.设置对应对象属性
-//        服务商
-        hotelCheckingBill.set("server", supplierName);
-        //订单日期
-        hotelCheckingBill.set("orderdate", DateUtil.string2date((String) orderDate,null));
-        //结算单号
-        hotelCheckingBill.set("ordernum", settlementNo);
-        //订单类型
-//        hotelCheckingBill.set("ordertype", orderType);
-        hotelCheckingBill.set("ordertype", "O");
-        //申请单号
-        hotelCheckingBill.set("oabillnum", "");
-        //报销单号
-        hotelCheckingBill.set("reimbursenum", "");
-        //业务类型
-        hotelCheckingBill.set("operationtype", businessTypeNo);
-        //订单分类
-        hotelCheckingBill.set("ordersort", orderType);
-        //订单性质
-        hotelCheckingBill.set("isbusiness", travelType);
-        //结算类型
-        hotelCheckingBill.set("producttype", "2");
-        //预订人姓名
-        hotelCheckingBill.set("bookedname", reserveName);
-        //预订人工号
-        hotelCheckingBill.set("sourcebookedid", reserveId);
-        //结算发生日期
-        hotelCheckingBill.set("happenddate", DateUtil.string2date((String) createTime,null));
-        //订单状态
-        hotelCheckingBill.set("orderstatus", "5");
-        //父订单号
-        hotelCheckingBill.set("parentordernum", "");
-
-        //币种
-        switch (settlementCurrency.toString()){
-            case "CNY":
-                hotelCheckingBill.set("currency", "1");
-                break;
-            case "HKD":
-                hotelCheckingBill.set("currency", "2");
-                break;
-            case "JPY":
-                hotelCheckingBill.set("currency", "3");
-                break;
-            case "USD":
-                hotelCheckingBill.set("currency", "4");
-                break;
-            case "EUR":
-                hotelCheckingBill.set("currency", "5");
-                break;
-            case "GBP":
-                hotelCheckingBill.set("currency", "6");
-                break;
-            case "AUD":
-                hotelCheckingBill.set("currency", "7");
-                break;
-            case "TWD":
-                hotelCheckingBill.set("currency", "8");
-                break;
-            case "MOP":
-                hotelCheckingBill.set("currency", "9");
-                break;
+        QFilter userFilter = new QFilter("number", QCP.equals, employeeId);
+        //查询人员表
+        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle("bos_user", "id,name", userFilter.toArray());
+
+        return bosUser;
+    }
+
+    /**
+     * 解析房间数量,将字符串转换为整数
+     *
+     * @param roomQuantity 房间数量字符串
+     * @return 房间数量整数
+     */
+    private int parseRoomQuantity(String roomQuantity) {
+        if (StringUtils.isBlank(roomQuantity)) {
+            return 0;
         }
+        // 先解析为double,再转换为int
+        double doubleValue = Double.parseDouble(roomQuantity);
+        return (int) doubleValue;
+    }
 
-        //结算金额
-        hotelCheckingBill.set("totalamount", settlementAmount);
-        //结算批次号
-        hotelCheckingBill.set("batchno", accCheckBatchNo);
-        //结算子批次号
-        hotelCheckingBill.set("subbatchno", "");
-        //费用承担公司
-        hotelCheckingBill.set("settlemain", "");
-        //费用承担部门
-        hotelCheckingBill.set("settledept", "");
-        //成本中心
-        hotelCheckingBill.set("std_costcenter", "");
-        //申请人公司
-        hotelCheckingBill.set("company", "");
-        //申请人部门
-        hotelCheckingBill.set("org", "");
-        //项目
-        hotelCheckingBill.set("std_project", projectNo);
-        //产品子类型
-        hotelCheckingBill.set("productsontype", "");
-        //外部系统结算单号
-        hotelCheckingBill.set("outsettlementnum", purchaseOrderNo);
-        //入住人工号
-        hotelCheckingBill.set("sourcetravelerid", employeeId);
-        //入住人
-        hotelCheckingBill.set("travelername", guestName);
-        //城市
-        hotelCheckingBill.set("cityname", arrivalCityName);
-        //酒店名称
-        hotelCheckingBill.set("hotelname", hotelName);
-        //入住日期
-        hotelCheckingBill.set("checkindate",DateUtil.string2date((String) startTime,"yyyy-MM-dd"));
-        //离店日期
-        hotelCheckingBill.set("checkoutdate", DateUtil.string2date((String) endTime,"yyyy-MM-dd"));
-        //房型
-        hotelCheckingBill.set("roomstylename", roomName);
-        //订房间数
-        hotelCheckingBill.set("roomcount", roomQuantityInt);
-
-        //服务费
-        hotelCheckingBill.set("servicefee", serviceFee);
-        //退订费
-        hotelCheckingBill.set("unbookfee", refund);
-        //票价开票类型
-        hotelCheckingBill.set("pricebillingtype", "");
-        //已对平
-        hotelCheckingBill.set("isbalance", "");
-        //备注
-        hotelCheckingBill.set("balanceremark", "");
-        //超标理由
-//        hotelCheckingBill.set("orderoverdesc", "");
-        //单据状态
-        hotelCheckingBill.set("billstatus", "C");
-        // 全部订单(er_allorderbill) 查询基础资料
-        //需要开票
-//        hotelCheckingBill.set("orderisinvoice", "");
-        //需要开票
-//        hotelCheckingBill.set("orderisinvoicerep", "");
-        //已确认
-//        hotelCheckingBill.set("orderisconfirm", "");
-        //已报销
-//        hotelCheckingBill.set("orderisrembureq", "");
-        //审批通过
-//        hotelCheckingBill.set("orderisapproverep", "");
-        //已报销
-//        hotelCheckingBill.set("orderisrembu", "");
-        //审批通过
-//        hotelCheckingBill.set("orderisapprove", "");
-        //已确认
-//        hotelCheckingBill.set("isconfirm", "");
-        //可抵扣
-//        hotelCheckingBill.set("isdeductible", "");
-        //可抵扣税额
-//        hotelCheckingBill.set("totaltax", "");
-        //已开票
-//        hotelCheckingBill.set("hasinvoice", "");
-        //付款/付款申请单号
-//        hotelCheckingBill.set("paybillnum", "");
-        //付款状态
-//        hotelCheckingBill.set("paybillstatus", "");
-        //凭证号
-//        hotelCheckingBill.set("vouchernum", "");
-        //记账日期
-//        hotelCheckingBill.set("bookeddatereq", "");
-        //记账日期
-//        hotelCheckingBill.set("bookeddatebu", "");
-
-        //4.保存对象
-        SaveServiceHelper.save(new DynamicObject[]{hotelCheckingBill});
+    /**
+     * 从Map中安全获取字符串值,避免空指针异常
+     *
+     * @param map 数据映射
+     * @param key 键名
+     * @return 字符串值,如果不存在或为null则返回空字符串
+     */
+    private String getStringValue(Map<String, Object> map, String key) {
+        return Optional.ofNullable(map.get(key))
+                .map(Object::toString)
+                .orElse("");
     }
 
+    /**
+     * 根据结算单号查询是否已存在该酒店结算单
+     * 用于判断是新增还是更新操作
+     *
+     * @param settlementNo 结算单号
+     * @return 存在的结算单动态对象,不存在则返回null
+     */
+    private DynamicObject queryHotelCheckingBill(String settlementNo) {
+        if (StringUtils.isBlank(settlementNo)) {
+            return null;
+        }
+
+        QFilter[] hotelFilter = new QFilter[]{
+                new QFilter("ordernum", QCP.equals, settlementNo)
+        };
+        return BusinessDataServiceHelper.loadSingle("er_hotelcheckingbill", hotelFilter);
+    }
 
     /**
      * 从接口获取酒店结算数据
@@ -423,7 +459,7 @@ public class HotelSettlementTask extends AbstractTask {
      */
     private List<Map<String, Object>> getResult() {
         //获取开始同步时间
-//        String syncTime = getSyncTime();
+        String syncTime = getSyncTime();
         //当前时间
         Date nowDate = new Date();
         String nowDateString = DateUtil.date2str(nowDate, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
@@ -431,7 +467,7 @@ public class HotelSettlementTask extends AbstractTask {
 //        log.info("结算单(酒店) 同步开始时间:" + syncTime);
 
         List<Map<String, Object>> dataList = new ArrayList<>();
-        for (int i = 0; i < totalPage; i++) {
+        for (int i = 0; i < TOTAL_PAGE; i++) {
             //创建接口业务数据参数
             Map<String, Object> data = new HashMap<>();
             //结算时间始
@@ -440,17 +476,17 @@ public class HotelSettlementTask extends AbstractTask {
             //结算时间止
             data.put("dateTo", nowDateString);
             //产品类别 0300 酒店
-            data.put("searchType", "0300");
+            data.put("searchType", HOTEL_PRODUCT_TYPE);
             //当前页
             data.put("current", i + 1);
             //每页条数,最多500条
-            data.put("size", size);
+            data.put("size", PAGE_SIZE);
             //企业卡号
-            data.put("enterpriseNo", "JXWL");
+            data.put("enterpriseNo", ENTERPRISE_NO);
             //账单类型 01-现结
 //            data.put("settlementType", "01");
 
-            Map<String, Object> resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_LiteGetSettlementInfo", Boolean.FALSE, data);
+            Map<String, Object> resp = TripSyncUtils.pushApiCallResult(INTERFACE_NAME, Boolean.FALSE, data);
             //报错终止同步,等待下次计划执行
             if ((Boolean) resp.get("fail")) {
                 throw new KDBizException(resp.get("message").toString());
@@ -460,7 +496,7 @@ public class HotelSettlementTask extends AbstractTask {
             dataList.addAll(resultDataList);
 
             //当前查询数量小于分页数量时结束循环
-            if (resultDataList.size() < size) {
+            if (resultDataList.size() < PAGE_SIZE) {
                 break;
             }
         }
@@ -478,7 +514,7 @@ public class HotelSettlementTask extends AbstractTask {
         //是否全量同步
         Boolean isAll = (Boolean) sysCtrlParameter.get("nckd_settlementbillall");
         if (isAll) {
-            return "1970-01-01 00:00:00";
+            return FULL_SYNC_START_TIME;
         }
         //增量同步小时  填写整数N,同步N小时前到现在新增或修改的数据,不填默认1小时。
         int hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour")) ? 1 : (Integer) sysCtrlParameter.get("nckd_settlementbillhour");

+ 462 - 323
nckd-fi/src/main/java/nckd/fi/er/task/InternationalFlightSettlementTask.java

@@ -1,18 +1,27 @@
 package nckd.fi.er.task;
 
+import com.alibaba.dubbo.common.utils.CollectionUtils;
 import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.exception.KDBizException;
 import kd.bos.exception.KDException;
 import kd.bos.krpc.common.logger.Logger;
 import kd.bos.krpc.common.logger.LoggerFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
 import kd.bos.schedule.executor.AbstractTask;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.qmc.qcbd.common.constant.BosOrgConst;
+import nckd.base.common.constant.BaseFieldConst;
+import nckd.base.common.enums.CurrencyEnum;
+import nckd.base.common.enums.InvoiceTypeEnum;
 import nckd.base.common.utils.DateUtil;
+import nckd.base.common.utils.InvoiceApiUtils;
 import nckd.base.common.utils.ParamUtils;
 import nckd.base.common.utils.TripSyncUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.*;
 
@@ -24,343 +33,472 @@ import java.util.*;
  * @Description:结算单(国际机票)
  */
 public class InternationalFlightSettlementTask extends AbstractTask {
-    private static Logger log = LoggerFactory.getLogger(InternationalFlightSettlementTask.class);
+    private static final Logger log = LoggerFactory.getLogger(InternationalFlightSettlementTask.class);
 
     /**
-     * 总页码,不处理总数,
-     * 每当当前页码数据小于1000 停止接口查询
+     * 最大查询页数,当某页数据小于每页条数时停止查询
      */
-    private final static int totalPage = 1000;
+    private static final int TOTAL_PAGE = 1000;
 
     /**
-     * 每页条数,最多500条   实际1000条
+     * 每页查询条数
      */
-    private final static int size = 1000;
+    private static final int PAGE_SIZE = 1000;
 
+    /**
+     * 全量同步的起始时间
+     */
+    private static final String FULL_SYNC_START_TIME = "1970-01-01 00:00:00";
+
+    /**
+     * 国际机票产品类型编码
+     */
+    private static final String INTERNATIONAL_FLIGHT_PRODUCT_TYPE = "0200";
+
+    /**
+     * 企业卡号
+     */
+    private static final String ENTERPRISE_NO = "JXWL";
+
+    /**
+     * 外部接口名称
+     */
+    private static final String INTERFACE_NAME = "FCSET_OUTAPI_LiteGetSettlementInfo";
+
+    /**
+     * 任务执行入口
+     *
+     * @param requestContext 请求上下文
+     * @param map            任务参数映射
+     * @throws KDException 执行异常
+     */
     @Override
     public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
-        log.info("结算单(国际机票)查询接口 调度计划开始执行");
-        List<Map<String, Object>> resultLists = getResult();
-        if (ObjectUtils.isEmpty(resultLists)) {
-            log.info("结算单(国际机票)查询接口 暂无数据-----");
-            return;
+        log.info("国际机票结算单同步任务开始执行");
+
+        try {
+            // 1. 从外部接口获取国际机票结算数据
+            List<Map<String, Object>> resultLists = getResult();
+            if (ObjectUtils.isEmpty(resultLists)) {
+                log.info("未获取到国际机票结算数据,任务结束");
+                return;
+            }
+
+            log.info("成功获取到 " + resultLists.size() + " 条国际机票结算数据");
+
+            // 2. 处理获取到的数据
+            processResultData(resultLists);
+
+            log.info("国际机票结算单同步任务执行完成");
+        } catch (Exception e) {
+            log.info("国际机票结算单同步任务执行失败", e);
+            throw e;
         }
+    }
+
+    /**
+     * 批量处理获取到的国际机票结算数据
+     *
+     * @param resultLists 国际机票结算数据列表
+     */
+    private void processResultData(List<Map<String, Object>> resultLists) {
+        int successCount = 0;
+        int failCount = 0;
+
         for (Map<String, Object> resultMap : resultLists) {
             try {
-                // 从结果映射中提取各字段
-                extractAndProcessFields(resultMap);
+                // 提取并处理单条数据字段,保存到系统
+                List<DynamicObject> planeCheckingList = extractAndProcessFields(resultMap);
+                if (!ObjectUtils.isEmpty(planeCheckingList)) {
+                    SaveServiceHelper.save(planeCheckingList.toArray(new DynamicObject[0]));
+                    successCount++;
+                }
             } catch (Exception e) {
-                log.info("处理火车票结算数据时发生异常,数据内容: " + resultMap, e);
+                failCount++;
+                log.info("处理国际机票结算数据时发生异常,数据内容: " + resultMap, e);
             }
         }
 
+        log.info("国际机票结算数据处理完成:成功 " + successCount + " 条,失败 " + failCount + " 条");
     }
 
     /**
-     * 从单条数据映射中提取字段并处理
+     * 从单条数据映射中提取字段并处理,生成系统动态对象
+     * 注:此方法将外部接口数据映射到系统表单字段
      *
      * @param resultMap 单条数据映射
+     * @return 处理后的动态对象列表
      */
-    private void extractAndProcessFields(Map<String, Object> resultMap) {
-        // 1.获取接口返回值
-
-        // ===================== 订单基本信息 =====================
-        // 订单类型 (01001机票正常单, 01002机票退单, 01003机票改签单, 1酒店正常单, 2酒店退单等)
-        Object orderType = resultMap.get("orderType");
-        // 房间数
-        Object roomQuantity = resultMap.get("roomQuantity");
-        // 订单类型名称
-        Object orderName = resultMap.get("orderName");
-        // 订单号
-        Object orderNo = resultMap.get("orderNo");
-        // 原订单编号
-        Object oldOrderNo = resultMap.get("oldOrderNo");
-        // 订单状态 (已完成等)
-        Object orderStatus = resultMap.get("orderStatus");
-        // 预订时间
-        Object orderDate = resultMap.get("orderDate");
-        // 业务发生时间
-        Object rebookingtime = resultMap.get("rebookingtime");
-        // 结算生成时间
-        Object createTime = resultMap.get("createTime");
-
-        // ===================== 结算信息 =====================
-        // 结算明细主键
-        Object tmcSettlementid = resultMap.get("tmcSettlementid");
-        // 结算单号
-        Object settlementNo = resultMap.get("settlementNo");
-        // 结算批次号(对应系统账单号)
-        Object accCheckBatchNo = resultMap.get("accCheckBatchNo");
-        // 结算明细ID
-        Object subAccCheckBatchNo = resultMap.get("subAccCheckBatchNo");
-        // 大表ID
-        Object mainTableId = resultMap.get("mainTableId");
-        // 币种 (例如CNY)
-        Object settlementCurrency = resultMap.get("settlementCurrency");
-        // 结算金额
-        Object settlementAmount = resultMap.get("settlementAmount");
-        // 结算单合计金额
-        Object totalAmount = resultMap.get("totalAmount");
-
-        // ===================== 人员信息 =====================
-        // 出行人姓名
-        Object guestName = resultMap.get("guestName");
-        // 出行人名称
-        Object passengerName = resultMap.get("passengerName");
-        // 员工姓名
-        Object employeeName = resultMap.get("employeeName");
-        // 出行人工号
-        Object employeeId = resultMap.get("employeeId");
-        // 预订人姓名
-        Object reserveName = resultMap.get("reserveName");
-        // 预订人员编号
-        Object reserveId = resultMap.get("reserveId");
-        // 人员类型(可能是员工类型)
-        Object personnelType = resultMap.get("personnelType");
-
-        // ===================== 财务信息 =====================
-        // 销售价
-        Object price = resultMap.get("price");
-        // 折扣
-        Object priceRate = resultMap.get("priceRate");
-        // 含税金额
-        Object inTaxAmount = resultMap.get("inTaxAmount");
-        // 不含税金额
-        Object excludingtaxAmount = resultMap.get("excludingtaxAmount");
-        // 不含税交易金额(不含税销售价)
-        Object sellingPriceNoTax = resultMap.get("sellingPriceNoTax");
-        // 订单不含税金额
-        Object orderNoTaxAmount = resultMap.get("orderNoTaxAmount");
-        // 订单税额
-        Object orderTax = resultMap.get("orderTax");
-        // 发票税率
-        Object taxRate = resultMap.get("taxRate");
-
-        // ===================== 费用信息 =====================
-        // 员工自付金额
-        Object personalPaymentAmount = resultMap.get("personalPaymentAmount");
-        // 欠款金额
-        Object amount = resultMap.get("amount");
-        Object priceAmount = resultMap.get("priceAmount");
-        // 垫款服务费
-        Object advancePaymentAmount = resultMap.get("advancePaymentAmount");
-        // 支付类型 (0自付、1垫付)
-        Object payType = resultMap.get("payType");
-        // TMC支付类型
-        Object tmcPaymentType = resultMap.get("tmcPaymentType");
-        // 账单类型 (M月结, S服务费)
-        Object billType = resultMap.get("billType");
-
-        // ===================== 服务费信息 =====================
-        // TMC服务费(服务商服务费)
-        Object spServiceFee = resultMap.get("spServiceFee");
-        // 服务费(销售服务费)
-        Object serviceFee = resultMap.get("serviceFee");
-        // 技术服务费
-        Object technologyServiceFee = resultMap.get("technologyServiceFee");
-        // 退票费
-        Object refund = resultMap.get("refund");
-        // 改签费
-        Object rebookQueryFee = resultMap.get("rebookQueryFee");
-
-        // ===================== 项目信息 =====================
-        // 项目编号
-        Object projectNo = resultMap.get("projectNo");
-        // 项目名称
-        Object projectName = resultMap.get("projectName");
-        // 业务类型编号
-        Object businessTypeNo = resultMap.get("businessTypeNo");
-        // 业务类型名称
-        Object businessTypeName = resultMap.get("businessTypeName");
-        // 费用类型编号
-        Object feeTypeNo = resultMap.get("feeTypeNo");
-        // 费用类型名称
-        Object feeTypeName = resultMap.get("feeTypeName");
-        // 差旅类型 (1因公, 0因私)
-        Object travelType = resultMap.get("travelType");
-        // 搜索类型名称(可能是查询条件类型)
-        Object searchTypeName = resultMap.get("searchTypeName");
-
-        // ===================== 供应商信息 =====================
-        // 供应商编号
-        Object supplierNo = resultMap.get("supplierNo");
-        // 供应商名称
-        Object supplierName = resultMap.get("supplierName");
-        // 供应单号
-        Object purchaseOrderNo = resultMap.get("purchaseOrderNo");
-        // 供应商发票类型 (0/空:普票, 1:专票)
-        Object supplierInvoiceType = resultMap.get("supplierInvoiceType");
-        // 垫款商户编号
-        Object advancePaymentMerchantNo = resultMap.get("advancePaymentMerchantNo");
-        // 垫款商户名称
-        Object advancePaymentMerchantName = resultMap.get("advancePaymentMerchantName");
-
-        // ===================== 法人信息 =====================
-        // 法人公司名称
-        Object frgsmc = resultMap.get("frgsmc");
-
-        // ===================== 行程信息 =====================
-        // 国内国际标识 (1国内, 0国际)
-        Object international = resultMap.get("international");
-        // 所在城市/出发城市名称
-        Object cityName = resultMap.get("cityName");
-        // 到达城市
-        Object arrivalCity = resultMap.get("arrivalCity");
-        // 到达城市名称/酒店所在城市
-        Object arrivalCityName = resultMap.get("arrivalCityName");
-        // 入住日期/出发时间
-        Object startTime = resultMap.get("startTime");
-        // 离店日期/到达时间
-        Object endTime = resultMap.get("endTime");
-        // 出票时间
-        Object printTicketTime = resultMap.get("printTicketTime");
-
-        // ===================== 酒店信息 =====================
-        // 酒店名称
-        Object hotelName = resultMap.get("hotelName");
-        // 酒店星级
-        Object star = resultMap.get("star");
-        // 房型中文名称
-        Object roomName = resultMap.get("roomName");
-        // 间夜数
-        Object quantity = resultMap.get("quantity");
-
-        // ===================== 机票附加费 =====================
-        // 机票建设费
-        Object airportFee = resultMap.get("airportFee");
-        // 保险费
-        Object insuranceFee = resultMap.get("insuranceFee");
-
-        // ===================== 其他字段 =====================
-        // 销售价(重复字段,可根据实际情况处理)
-        Object transAmount = resultMap.get("transAmount");
-
-        // 2.机票结算单 --国际机票 创建动态对象
-        DynamicObject planeCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_planecheckingbill");
-
-        //3.设置各字段
-        //订单日期
-        planeCheckingBill.set("orderdate", orderType);
-        //订单性质
-        planeCheckingBill.set("isbusiness", travelType);
-        //结算类型 2 -个人现付
-        planeCheckingBill.set("producttype", "2");
-        //预订人工号
-        planeCheckingBill.set("booknum", "");
-        //预订人姓名
-        planeCheckingBill.set("bookedname", reserveName);
-        //结算发生日期
-        planeCheckingBill.set("happenddate", DateUtil.string2date((String) createTime,null));
-        //业务类型
-        planeCheckingBill.set("operationtype", businessTypeNo);
-        //订单分类
-        planeCheckingBill.set("ordersort", orderType);
-        //订单状态
-        planeCheckingBill.set("orderstatus", "5");
-        //结算金额
-        planeCheckingBill.set("totalamount", settlementAmount);
-        //币种
-        switch (settlementCurrency.toString()){
-            case "CNY":
-                planeCheckingBill.set("currency", "1");
-                break;
-            case "HKD":
-                planeCheckingBill.set("currency", "2");
-                break;
-            case "JPY":
-                planeCheckingBill.set("currency", "3");
-                break;
-            case "USD":
-                planeCheckingBill.set("currency", "4");
-                break;
-            case "EUR":
-                planeCheckingBill.set("currency", "5");
-                break;
-            case "GBP":
-                planeCheckingBill.set("currency", "6");
-                break;
-            case "AUD":
-                planeCheckingBill.set("currency", "7");
-                break;
-            case "TWD":
-                planeCheckingBill.set("currency", "8");
-                break;
-            case "MOP":
-                planeCheckingBill.set("currency", "9");
-                break;
+    private List<DynamicObject> extractAndProcessFields(Map<String, Object> resultMap) {
+        List<DynamicObject> resultLists = new ArrayList<>();
+
+        try {
+            // 1. 从结果映射中提取各字段
+            // ===================== 订单基本信息 =====================
+            // 结算单号
+            String settlementNo = getStringValue(resultMap, "settlementNo");
+            // 预订时间
+            String orderDate = getStringValue(resultMap, "orderDate");
+            // 订单类型
+            String orderType = getStringValue(resultMap, "orderType");
+
+            // 01001机票正常单01002机票退单01003机票改签单
+            if ("01001".equals(orderType)) {
+                orderType = "O";
+            } else if ("01002".equals(orderType)) {
+                orderType = "T";
+            } else if ("01003".equals(orderType)) {
+                orderType = "G";
+            } else {
+                orderType = "";
+            }
+            // 申请单号
+            String tripNo = getStringValue(resultMap, "tripNo");
+            // 差旅类型
+            String travelType = getStringValue(resultMap, "travelType");
+            // 结算生成时间
+            String createTime = getStringValue(resultMap, "createTime");
+            // 结算金额
+            String settlementAmount = getStringValue(resultMap, "settlementAmount");
+            // 币种
+            String settlementCurrency = getStringValue(resultMap, "settlementCurrency");
+            // 结算批次号
+            String accCheckBatchNo = getStringValue(resultMap, "accCheckBatchNo");
+            // 法人公司编码
+            String frgs = getStringValue(resultMap, "frgs");
+            // 项目编号
+            String projectNo = getStringValue(resultMap, "projectNo");
+            // 国内国际标识
+            String international = getStringValue(resultMap, "international");
+
+            // ===================== 机票行程信息 =====================
+            // 航空公司名称
+            String airlineCompanyName = getStringValue(resultMap, "airlineCompanyName");
+            // 票号
+            String ticketNo = getStringValue(resultMap, "ticketNo");
+            // 航班号
+            String flight = getStringValue(resultMap, "flight");
+            // 机票舱位子类
+            String subClass = getStringValue(resultMap, "subClass");
+            // 机票舱位等级
+            String cabinClass = getStringValue(resultMap, "cabinClass");
+            // 出发城市名称
+            String departCityName = getStringValue(resultMap, "departCityName");
+            // 到达城市名称
+            String arrivalCityName = getStringValue(resultMap, "arrivalCityName");
+            // 出发时间
+            String takeOffTime = getStringValue(resultMap, "takeOffTime");
+            // 到达时间
+            String arrivalTime = getStringValue(resultMap, "arrivalTime");
+
+            // ===================== 费用信息 =====================
+            // 机票价格
+            String price = getStringValue(resultMap, "price");
+            // 折扣
+            String priceRate = getStringValue(resultMap, "priceRate");
+            // 订单税额
+            String orderTax = getStringValue(resultMap, "orderTax");
+            // 机票燃油费
+            String tax = getStringValue(resultMap, "tax");
+            // 服务费
+            String serviceFee = getStringValue(resultMap, "serviceFee");
+            // 退票费
+            String refund = getStringValue(resultMap, "refund");
+            // 改签费
+            String rebookQueryFee = getStringValue(resultMap, "rebookQueryFee");
+            // 保险费
+            String insuranceFee = getStringValue(resultMap, "insuranceFee");
+            // 机票建设费
+            String airportFee = getStringValue(resultMap, "airportFee");
+
+            // ===================== 人员信息 =====================
+            // 出行人姓名
+            String guestName = getStringValue(resultMap, "guestName");
+            // 出行人工号
+            String employeeId = getStringValue(resultMap, "employeeId");
+            // 预订人姓名
+            String reserveName = getStringValue(resultMap, "reserveName");
+            // 订单号
+            String orderNo = getStringValue(resultMap, "orderNo");
+            // 业务发生时间
+            String rebookingtime = getStringValue(resultMap, "rebookingtime");
+            //预订人员编号
+            String reserveId = getStringValue(resultMap, "reserveId");
+            // 订单状态
+            String orderStatus = getStringValue(resultMap, "orderStatus");
+            switch (orderStatus) {
+                case "已完成":
+                    orderStatus = "USED";
+                    break;
+                case "已预订":
+                    orderStatus = "20000";
+                    break;
+                case "已出票":
+                    orderStatus = "40000";
+                    break;
+                case "取消中":
+                    orderStatus = "31000";
+                    break;
+                case "已取消":
+                    orderStatus = "30000";
+                    break;
+                case "退票中":
+                    orderStatus = "50201";
+                    break;
+                case "改签中":
+                    orderStatus = "50301";
+                    break;
+                case "已改签":
+                    orderStatus = "50302";
+                    break;
+                default:
+                    orderStatus = "9999";
+                    break;
+            }
+
+            //结算类型
+            String tmcPaymentType = getStringValue(resultMap, "tmcPaymentType");
+            if ("公司月结".equals(tmcPaymentType)) {
+                tmcPaymentType = "1";
+            } else if ("个人现付".equals(tmcPaymentType)) {
+                tmcPaymentType = "2";
+            }
+
+            // 2. 转换差旅类型格式
+            if ("因公".equals(travelType)) {
+                travelType = "1";
+            } else if ("因私".equals(travelType)) {
+                travelType = "0";
+            }
+
+            // 3. 检查结算单是否已存在,存在则修改,不存在则创建
+            DynamicObject planeCheckingBill = queryPlaneCheckingBill(settlementNo);
+            boolean isNew = ObjectUtils.isEmpty(planeCheckingBill);
+            if (isNew) {
+                planeCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_planecheckingbill");
+                log.info("创建新的国际机票结算单: " + settlementNo);
+            } else {
+                log.info("更新已存在的国际机票结算单: " + settlementNo);
+            }
+
+            // 4. 设置各字段值
+            // ===================== 订单信息 =====================
+            // 订单日期
+            planeCheckingBill.set("orderdate", DateUtil.string2date(orderDate, null));
+            // 结算单号
+            planeCheckingBill.set("ordernum", settlementNo);
+            // 订单类型
+            planeCheckingBill.set("ordertype", orderType);
+            // 申请单号
+            planeCheckingBill.set("oabillnum", tripNo);
+            // 报销单号
+            planeCheckingBill.set("reimbursenum", "");
+            // 订单分类(国内/国际)
+            planeCheckingBill.set("ordersort", international);
+            // 订单性质(因公/因私)
+            planeCheckingBill.set("isbusiness", travelType);
+            // 结算类型
+            planeCheckingBill.set("producttype", tmcPaymentType);
+
+            // 预订人工号
+            DynamicObject sourcebookedids = queryBosUser(reserveId);
+            planeCheckingBill.set("sourcebookedid", sourcebookedids);
+            // 预订人姓名
+            String bookedname = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
+            planeCheckingBill.set("bookedname", bookedname);
+
+            // 结算发生日期
+            planeCheckingBill.set("happenddate", DateUtil.string2date(createTime, null));
+            // 业务类型:4-国际机票
+            planeCheckingBill.set("operationtype", "4");
+            // 订单状态
+            planeCheckingBill.set("orderstatus",orderStatus);
+            // 父订单号
+            planeCheckingBill.set("parentordernum", orderNo);
+            // 结算金额
+            planeCheckingBill.set("totalamount", settlementAmount);
+
+            // ===================== 财务信息 =====================
+            // 设置币种,从枚举中获取对应的值
+            String currency = Optional.ofNullable(CurrencyEnum.getByCode(settlementCurrency))
+                    .map(CurrencyEnum::getValue)
+                    .orElse(null);
+            planeCheckingBill.set("currency", currency);
+            // 结算批次号
+            planeCheckingBill.set("batchno", accCheckBatchNo);
+            // 结算子批次号
+            planeCheckingBill.set("subbatchno", "");
+
+            // ===================== 组织信息 =====================
+            // 设置费用承担公司(根据法人公司编码查询组织信息)
+            if (StringUtils.isNotBlank(frgs)) {
+                QFilter[] orgFilter = new QFilter[]{
+                        new QFilter(BaseFieldConst.NUMBER, QCP.equals, frgs),
+                };
+                DynamicObject org = BusinessDataServiceHelper.loadSingle(BosOrgConst.BOS_ORG, "id", orgFilter);
+                if (ObjectUtils.isEmpty(org)) {
+                    planeCheckingBill.set("settlemain", "");
+                    log.info("未找到编码为 " + frgs + " 的组织信息");
+                } else {
+                    planeCheckingBill.set("settlemain", org);
+                }
+            } else {
+                planeCheckingBill.set("settlemain", "");
+            }
+            // 费用承担部门
+            planeCheckingBill.set("settledept", "");
+            // 申请人公司
+            planeCheckingBill.set("company", "");
+            // 申请人部门
+            planeCheckingBill.set("org", "");
+            // 项目
+            planeCheckingBill.set("std_project", projectNo);
+            // 成本中心
+            planeCheckingBill.set("std_costcenter", "");
+            // 外部系统结算单号
+            planeCheckingBill.set("outsettlementnum", "");
+
+            // ===================== 航乘信息 =====================
+            // 航空公司名称
+            planeCheckingBill.set("airlinename", airlineCompanyName);
+            // 电子客票号
+            planeCheckingBill.set("ticketnum", ticketNo);
+            // 航班号
+            planeCheckingBill.set("flightno", flight);
+            // 舱位
+            planeCheckingBill.set("cabin", subClass);
+            // 舱位等级
+            planeCheckingBill.set("cabinclass", cabinClass);
+            // 出发城市名称
+            planeCheckingBill.set("fromcityname", departCityName);
+            // 出发日期
+            planeCheckingBill.set("takeofftime", DateUtil.string2date(takeOffTime, null));
+            // 到达城市名称
+            planeCheckingBill.set("tocityname", arrivalCityName);
+            // 到达时间
+            planeCheckingBill.set("landingtime", DateUtil.string2date(arrivalTime, null));
+            // 改签费
+            planeCheckingBill.set("endorsementamount", rebookQueryFee);
+            // 保险费
+            planeCheckingBill.set("assuranceamount", insuranceFee);
+            // 折扣(%)
+            planeCheckingBill.set("discount", priceRate);
+            // 机票价格
+            planeCheckingBill.set("ticketprice", price);
+            // 民航发展基金/税费
+            planeCheckingBill.set("airportprice", "");
+            // 税费
+            planeCheckingBill.set("tax", orderTax);
+            // 服务费
+            planeCheckingBill.set("servicefee", serviceFee);
+            // 燃油费
+            planeCheckingBill.set("fuelprice", tax);
+            // 退票费
+            planeCheckingBill.set("refundamount", refund);
+            // 其他费用-机票建设费
+            planeCheckingBill.set("otheramount", airportFee);
+            // 乘机人工号
+            DynamicObject bosUser = queryBosUser(employeeId);
+            planeCheckingBill.set("sourcetravelerid", bosUser);
+            // 乘机人
+            String travelerNames = ObjectUtils.isEmpty(bosUser) ? "" : bosUser.getString("name");
+            planeCheckingBill.set("travelername",travelerNames);
+            // 行程单号
+            planeCheckingBill.set("itinerarynum", "");
+            // 填开日期
+            planeCheckingBill.set("itinerarydate", "");
+            // 产品子类型
+            planeCheckingBill.set("productsontype", "");
+
+            //===================获取发票=====================
+            List<Map<String, Object>> invoiceResultList = InvoiceApiUtils.getInvoiceResult(settlementNo, rebookingtime);
+
+            if (CollectionUtils.isEmpty(invoiceResultList)) {
+                log.info("结算单号:" + settlementNo + "未查询到发票数据");
+            }else{
+                for (Map<String, Object> resultInvoiceList : invoiceResultList) {
+                    //下载地址
+                    planeCheckingBill.set("downloadlink", resultInvoiceList.get("invoiceUrl"));
+                    //内部下载地址
+                    planeCheckingBill.set("kddownloadlink", resultInvoiceList.get("invoiceUrl"));
+                    //发票流水号
+                    planeCheckingBill.set("serialno", resultInvoiceList.get("invoiceId"));
+                    //发票识别成功
+                    planeCheckingBill.set("invoiceidentityflag", true);
+                    //发票识别异常信息
+                    planeCheckingBill.set("identityerrormsg", resultInvoiceList.get("invoiceErrorMsg"));
+                    // 票价开票类型
+                    String invoiceTypeCode = resultInvoiceList.get("invoiceType").toString();
+                    String invoice = InvoiceTypeEnum.getValueByCode(invoiceTypeCode);
+                    planeCheckingBill.set("pricebillingtype", invoice);
+                }
+            }
+
+            //==========================付款/凭证信息=========================
+            // 付款/付款申请单号
+            planeCheckingBill.set("paybillnum", "");
+            // 付款状态
+            planeCheckingBill.set("paybillstatus", "");
+            // 凭证号
+            planeCheckingBill.set("vouchernum", "");
+            // 记账日期
+            planeCheckingBill.set("bookeddatereq", "");
+            resultLists.add(planeCheckingBill);
+        } catch (Exception e) {
+            log.info("处理单条国际机票结算数据时发生异常,数据内容: " + resultMap, e);
         }
-        //结算批次号
-        planeCheckingBill.set("batchno", accCheckBatchNo);
-        //结算子批次号
-        planeCheckingBill.set("subbatchno", "");
-        //费用承担公司
-        planeCheckingBill.set("settlemain", "");
-        //费用承担部门
-        planeCheckingBill.set("settledept", "");
-        //申请人公司
-        planeCheckingBill.set("company", "");
-        //申请人部门
-        planeCheckingBill.set("org", "");
-        //项目
-        planeCheckingBill.set("std_project", projectNo);
-        //成本中心
-        planeCheckingBill.set("std_costcenter", "");
-        //外部系统结算单号
-        planeCheckingBill.set("outsettlementnum", "");
-        //火车票车票号
-        planeCheckingBill.set("trainticketnum", "");
-        //出发城市
-        planeCheckingBill.set("departcity", cityName);
-        //出发车站
-        planeCheckingBill.set("departaddress", "");
-        //到达城市
-        planeCheckingBill.set("arrivecity", arrivalCity);
-        //到达车站
-        planeCheckingBill.set("arriveaddress", "");
-        //出发时间
-        planeCheckingBill.set("departtime", "");
-        //到达时间
-        planeCheckingBill.set("arrivetime", "");
-        //乘客
-        planeCheckingBill.set("passeger", "");
-        //乘客姓名
-        planeCheckingBill.set("passegername", "");
-        //火车票价
-        planeCheckingBill.set("ticketprice", "");
-        //服务费
-        planeCheckingBill.set("servicefee", serviceFee);
-        //退票费
-        planeCheckingBill.set("refundamount", refund);
-        //保险费
-        planeCheckingBill.set("assuranceamount", insuranceFee);
-        //下载地址
-        planeCheckingBill.set("downloadlink", "");
-        //内部下载地址
-        planeCheckingBill.set("kddownloadlink", "");
-        //发票流水号
-        planeCheckingBill.set("serialno", "");
-        //发票识别异常信息
-        planeCheckingBill.set("identityerrormsg", "");
-        //票价开票类型
-        planeCheckingBill.set("pricebillingtype", "");
-
-        //可抵扣税额
-        planeCheckingBill.set("totaltax", "");
-        //已开票
-        planeCheckingBill.set("hasinvoice", "");
-        //付款/付款申请单号
-        planeCheckingBill.set("paybillnum", "");
-        //付款状态
-        planeCheckingBill.set("paybillstatus", "");
-        //凭证号
-        planeCheckingBill.set("vouchernum", "");
-        //记账日期
-        planeCheckingBill.set("bookeddatereq", "");
-        //记账日期
-        planeCheckingBill.set("bookeddatebu", "");
-
-        //4.保存对象
-        SaveServiceHelper.save(new DynamicObject[]{planeCheckingBill});
+
+        return resultLists;
+    }
+
+
+    /**
+     * 根据员工工号查询人员信息
+     *
+     * @param employeeId
+     * @return
+     */
+    private DynamicObject queryBosUser(String employeeId) {
+        if (StringUtils.isBlank(employeeId)) {
+            log.info("未找到工号为:" + employeeId + "的人员信息");
+            return null;
+        }
+        QFilter userFilter = new QFilter("number", QCP.equals, employeeId);
+        //查询人员表
+        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle("bos_user", "id,name", userFilter.toArray());
+
+        return bosUser;
+    }
+
+    /**
+     * 从Map中安全获取字符串值,避免空指针异常
+     *
+     * @param map 数据映射
+     * @param key 键名
+     * @return 字符串值,如果不存在或为null则返回空字符串
+     */
+    private String getStringValue(Map<String, Object> map, String key) {
+        return Optional.ofNullable(map.get(key))
+                .map(Object::toString)
+                .orElse("");
+    }
+
+    /**
+     * 根据结算单号查询是否已存在该国际机票结算单
+     * 用于判断是新增还是更新操作
+     *
+     * @param settlementNo 结算单号
+     * @return 存在的结算单动态对象,不存在则返回null
+     */
+    private DynamicObject queryPlaneCheckingBill(String settlementNo) {
+        if (StringUtils.isBlank(settlementNo)) {
+            return null;
+        }
+
+        QFilter[] planeFilter = new QFilter[]{
+                new QFilter("ordernum", QCP.equals, settlementNo)
+        };
+        return BusinessDataServiceHelper.loadSingle("er_planecheckingbill", planeFilter);
     }
 
     /**
@@ -378,25 +516,26 @@ public class InternationalFlightSettlementTask extends AbstractTask {
         log.info("结算单(国际机票) 同步开始时间:" + syncTime);
 
         List<Map<String, Object>> dataList = new ArrayList<>();
-        for (int i = 0; i < totalPage; i++) {
+        for (int i = 0; i < TOTAL_PAGE; i++) {
             //创建接口业务数据参数
             Map<String, Object> data = new HashMap<>();
             //结算时间始
-            data.put("dateFrom", syncTime);
+//            data.put("dateFrom", syncTime);
+            data.put("dateFrom", "1970-01-01 00:00:00");
             //结算时间止
             data.put("dateTo", nowDateString);
             //产品类别 0200 国际机票
-            data.put("searchType", "0200");
+            data.put("searchType", INTERNATIONAL_FLIGHT_PRODUCT_TYPE);
             //当前页
             data.put("current", i + 1);
             //每页条数,最多500条
-            data.put("size", size);
+            data.put("size", PAGE_SIZE);
             //企业卡号
-            data.put("enterpriseNo", "JXWL");
+            data.put("enterpriseNo", ENTERPRISE_NO);
             //账单类型 01-现结
-            data.put("settlementType", "01");
+//            data.put("settlementType", "01");
 
-            Map<String, Object> resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_LiteGetSettlementInfo", Boolean.FALSE, data);
+            Map<String, Object> resp = TripSyncUtils.pushApiCallResult(INTERFACE_NAME, Boolean.FALSE, data);
             //报错终止同步,等待下次计划执行
             if ((Boolean) resp.get("fail")) {
                 throw new KDBizException(resp.get("message").toString());
@@ -406,7 +545,7 @@ public class InternationalFlightSettlementTask extends AbstractTask {
             dataList.addAll(resultDataList);
 
             //当前查询数量小于分页数量时结束循环
-            if (resultDataList.size() < size) {
+            if (resultDataList.size() < PAGE_SIZE) {
                 break;
             }
         }
@@ -422,7 +561,7 @@ public class InternationalFlightSettlementTask extends AbstractTask {
         //是否全量同步
         Boolean isAll = (Boolean) sysCtrlParameter.get("nckd_settlementbillall");
         if (isAll) {
-            return "1970-01-01 00:00:00";
+            return FULL_SYNC_START_TIME;
         }
         //增量同步小时  填写整数N,同步N小时前到现在新增或修改的数据,不填默认1小时。
         int hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour")) ? 1 : (Integer) sysCtrlParameter.get("nckd_settlementbillhour");

+ 421 - 333
nckd-fi/src/main/java/nckd/fi/er/task/TrainTicketSettlementTask.java

@@ -1,18 +1,28 @@
 package nckd.fi.er.task;
 
+import com.alibaba.dubbo.common.utils.CollectionUtils;
 import kd.bos.context.RequestContext;
 import kd.bos.dataentity.entity.DynamicObject;
 import kd.bos.exception.KDBizException;
 import kd.bos.exception.KDException;
 import kd.bos.krpc.common.logger.Logger;
 import kd.bos.krpc.common.logger.LoggerFactory;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
 import kd.bos.schedule.executor.AbstractTask;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
+import kd.qmc.qcbd.common.constant.BosOrgConst;
+import nckd.base.common.constant.BaseFieldConst;
+import nckd.base.common.enums.CurrencyEnum;
+import nckd.base.common.enums.InvoiceTypeEnum;
+import nckd.base.common.enums.TrainseatEnum;
 import nckd.base.common.utils.DateUtil;
+import nckd.base.common.utils.InvoiceApiUtils;
 import nckd.base.common.utils.ParamUtils;
 import nckd.base.common.utils.TripSyncUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
 
 import java.util.*;
 
@@ -36,353 +46,434 @@ public class TrainTicketSettlementTask extends AbstractTask {
      */
     private static final int PAGE_SIZE = 1000;
 
+    /**
+     * 全量同步的起始时间
+     */
+    private static final String FULL_SYNC_START_TIME = "1970-01-01 00:00:00";
+
+    /**
+     * 火车票产品类型编码
+     */
+    private static final String TRAIN_TICKET_PRODUCT_TYPE = "0600";
+
+    /**
+     * 企业卡号
+     */
+    private static final String ENTERPRISE_NO = "JXWL";
+
+    /**
+     * 结算单类型
+     */
+    private static final String SETTLEMENT_TYPE = "01";
+
+    /**
+     * 外部接口名称
+     */
+    private static final String INTERFACE_NAME = "FCSET_OUTAPI_LiteGetSettlementInfo";
+
     /**
      * 任务执行入口
      *
      * @param requestContext 请求上下文
-     * @param map 任务参数映射
+     * @param map            任务参数映射
      * @throws KDException 执行异常
      */
     @Override
     public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
-        log.info("结算单(同步火车票)查询接口 调度计划开始执行");
+        log.info("火车票结算单同步任务开始执行");
+
+        try {
+            // 1. 从外部接口获取火车票结算数据
+            List<Map<String, Object>> resultLists = getResult();
+            if (ObjectUtils.isEmpty(resultLists)) {
+                log.info("未获取到火车票结算数据,任务结束");
+                return;
+            }
+            log.info("成功获取到 " + resultLists.size() + "条火车票结算数据");
 
-        List<Map<String, Object>> resultLists = getResult();
-        if (ObjectUtils.isEmpty(resultLists)) {
-            log.info("结算单(同步火车票)查询接口 暂无数据-----");
-            return;
-        }
+            // 2. 处理获取到的数据
+            processResultData(resultLists);
 
-        processResultData(resultLists);
+            log.info("火车票结算单同步任务执行完成");
+        } catch (Exception e) {
+            log.info("火车票结算单同步任务执行失败", e);
+            throw e;
+        }
     }
 
     /**
-     * 处理获取到的火车票结算数据
+     * 批量处理获取到的火车票结算数据
      *
      * @param resultLists 火车票结算数据列表
      */
     private void processResultData(List<Map<String, Object>> resultLists) {
+        int successCount = 0;
+        int failCount = 0;
+
         for (Map<String, Object> resultMap : resultLists) {
             try {
-                // 从结果映射中提取各字段
-                extractAndProcessFields(resultMap);
+                // 提取并处理单条数据字段,保存到系统
+                List<DynamicObject> trainCheckingList = extractAndProcessFields(resultMap);
+                if (!ObjectUtils.isEmpty(trainCheckingList)) {
+                    SaveServiceHelper.save(trainCheckingList.toArray(new DynamicObject[0]));
+                    successCount++;
+                }
             } catch (Exception e) {
-                log.error("处理火车票结算数据时发生异常,数据内容: " + resultMap, e);
+                failCount++;
+                log.info("处理火车票结算数据时发生异常,数据内容: " + resultMap, e);
             }
         }
+
+        log.info("火车票结算数据处理完成:成功 " + successCount + " 条,失败 " + failCount + " 条");
     }
 
     /**
-     * 从单条数据映射中提取字段并处理
+     * 将外部接口数据映射到系统表单字段
      *
-     * @param resultMap 单条数据映射
+     * @param resultMap 数据映射
+     * @return 处理后的动态对象列表
      */
-    private void extractAndProcessFields(Map<String, Object> resultMap) {
-        // 1.获取接口返回值
-
-        // ===================== 订单基本信息 =====================
-        // 订单类型 (01001机票正常单, 01002机票退单, 01003机票改签单, 1酒店正常单, 2酒店退单等)
-        Object orderType = resultMap.get("orderType");
-        // 房间数
-        Object roomQuantity = resultMap.get("roomQuantity");
-        // 订单类型名称
-        Object orderName = resultMap.get("orderName");
-        // 订单号
-        Object orderNo = resultMap.get("orderNo");
-        // 原订单编号
-        Object oldOrderNo = resultMap.get("oldOrderNo");
-        // 订单状态 (已完成等)
-        Object orderStatus = resultMap.get("orderStatus");
-        // 预订时间
-        Object orderDate = resultMap.get("orderDate");
-        // 业务发生时间
-        Object rebookingtime = resultMap.get("rebookingtime");
-        // 结算生成时间
-        Object createTime = resultMap.get("createTime");
-
-        // ===================== 结算信息 =====================
-        // 结算明细主键
-        Object tmcSettlementid = resultMap.get("tmcSettlementid");
-        // 结算单号
-        Object settlementNo = resultMap.get("settlementNo");
-        // 结算批次号(对应系统账单号)
-        Object accCheckBatchNo = resultMap.get("accCheckBatchNo");
-        // 结算明细ID
-        Object subAccCheckBatchNo = resultMap.get("subAccCheckBatchNo");
-        // 大表ID
-        Object mainTableId = resultMap.get("mainTableId");
-        // 币种 (例如CNY)
-        Object settlementCurrency = resultMap.get("settlementCurrency");
-        // 结算金额
-        Object settlementAmount = resultMap.get("settlementAmount");
-        // 结算单合计金额
-        Object totalAmount = resultMap.get("totalAmount");
-
-        // ===================== 人员信息 =====================
-        // 出行人姓名
-        Object guestName = resultMap.get("guestName");
-        // 出行人名称
-        Object passengerName = resultMap.get("passengerName");
-        // 员工姓名
-        Object employeeName = resultMap.get("employeeName");
-        // 出行人工号
-        Object employeeId = resultMap.get("employeeId");
-        // 预订人姓名
-        Object reserveName = resultMap.get("reserveName");
-        // 预订人员编号
-        Object reserveId = resultMap.get("reserveId");
-        // 人员类型(可能是员工类型)
-        Object personnelType = resultMap.get("personnelType");
-
-        // ===================== 财务信息 =====================
-        // 销售价
-        Object price = resultMap.get("price");
-        // 折扣
-        Object priceRate = resultMap.get("priceRate");
-        // 含税金额
-        Object inTaxAmount = resultMap.get("inTaxAmount");
-        // 不含税金额
-        Object excludingtaxAmount = resultMap.get("excludingtaxAmount");
-        // 不含税交易金额(不含税销售价)
-        Object sellingPriceNoTax = resultMap.get("sellingPriceNoTax");
-        // 订单不含税金额
-        Object orderNoTaxAmount = resultMap.get("orderNoTaxAmount");
-        // 订单税额
-        Object orderTax = resultMap.get("orderTax");
-        // 发票税率
-        Object taxRate = resultMap.get("taxRate");
-
-        // ===================== 费用信息 =====================
-        // 员工自付金额
-        Object personalPaymentAmount = resultMap.get("personalPaymentAmount");
-        // 欠款金额
-        Object amount = resultMap.get("amount");
-        Object priceAmount = resultMap.get("priceAmount");
-        // 垫款服务费
-        Object advancePaymentAmount = resultMap.get("advancePaymentAmount");
-        // 支付类型 (0自付、1垫付)
-        Object payType = resultMap.get("payType");
-        // TMC支付类型
-        Object tmcPaymentType = resultMap.get("tmcPaymentType");
-        // 账单类型 (M月结, S服务费)
-        Object billType = resultMap.get("billType");
-
-        // ===================== 服务费信息 =====================
-        // TMC服务费(服务商服务费)
-        Object spServiceFee = resultMap.get("spServiceFee");
-        // 服务费(销售服务费)
-        Object serviceFee = resultMap.get("serviceFee");
-        // 技术服务费
-        Object technologyServiceFee = resultMap.get("technologyServiceFee");
-        // 退票费
-        Object refund = resultMap.get("refund");
-        // 改签费
-        Object rebookQueryFee = resultMap.get("rebookQueryFee");
-
-        // ===================== 项目信息 =====================
-        // 项目编号
-        Object projectNo = resultMap.get("projectNo");
-        // 项目名称
-        Object projectName = resultMap.get("projectName");
-        // 业务类型编号
-        Object businessTypeNo = resultMap.get("businessTypeNo");
-        // 业务类型名称
-        Object businessTypeName = resultMap.get("businessTypeName");
-        // 费用类型编号
-        Object feeTypeNo = resultMap.get("feeTypeNo");
-        // 费用类型名称
-        Object feeTypeName = resultMap.get("feeTypeName");
-        // 差旅类型 (1因公, 0因私)
-        Object travelType = resultMap.get("travelType");
-        // 搜索类型名称(可能是查询条件类型)
-        Object searchTypeName = resultMap.get("searchTypeName");
-
-        // ===================== 供应商信息 =====================
-        // 供应商编号
-        Object supplierNo = resultMap.get("supplierNo");
-        // 供应商名称
-        Object supplierName = resultMap.get("supplierName");
-        // 供应单号
-        Object purchaseOrderNo = resultMap.get("purchaseOrderNo");
-        // 供应商发票类型 (0/空:普票, 1:专票)
-        Object supplierInvoiceType = resultMap.get("supplierInvoiceType");
-        // 垫款商户编号
-        Object advancePaymentMerchantNo = resultMap.get("advancePaymentMerchantNo");
-        // 垫款商户名称
-        Object advancePaymentMerchantName = resultMap.get("advancePaymentMerchantName");
-
-        // ===================== 法人信息 =====================
-        // 法人公司名称
-        Object frgsmc = resultMap.get("frgsmc");
-
-        // ===================== 行程信息 =====================
-        // 国内国际标识 (1国内, 0国际)
-        Object international = resultMap.get("international");
-        // 所在城市/出发城市名称
-        Object cityName = resultMap.get("cityName");
-        // 到达城市
-        Object arrivalCity = resultMap.get("arrivalCity");
-        // 到达城市名称/酒店所在城市
-        Object arrivalCityName = resultMap.get("arrivalCityName");
-        // 入住日期/出发时间
-        Object startTime = resultMap.get("startTime");
-        // 离店日期/到达时间
-        Object endTime = resultMap.get("endTime");
-        // 出票时间
-        Object printTicketTime = resultMap.get("printTicketTime");
-
-        // ===================== 酒店信息 =====================
-        // 酒店名称
-        Object hotelName = resultMap.get("hotelName");
-        // 酒店星级
-        Object star = resultMap.get("star");
-        // 房型中文名称
-        Object roomName = resultMap.get("roomName");
-        // 间夜数
-        Object quantity = resultMap.get("quantity");
-
-        // ===================== 机票附加费 =====================
-        // 机票建设费
-        Object airportFee = resultMap.get("airportFee");
-        // 保险费
-        Object insuranceFee = resultMap.get("insuranceFee");
-
-        // ===================== 其他字段 =====================
-        // 销售价(重复字段,可根据实际情况处理)
-        Object transAmount = resultMap.get("transAmount");
-
-        //2. 判断当前结算单是否已经存在 存在即修改  不存在 创建动态对象 ????
-        DynamicObject trainCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_traincheckingbill");
-
-        //3. 设置各字段
-        //订单日期
-        trainCheckingBill.set("orderdate", orderType);
-        //订单性质
-        trainCheckingBill.set("isbusiness", travelType);
-        //结算类型 2 -个人现付
-        trainCheckingBill.set("producttype", "2");
-        //预订人工号
-        trainCheckingBill.set("booknum", "");
-        //预订人姓名
-        trainCheckingBill.set("bookedname", reserveName);
-        //结算发生日期
-        trainCheckingBill.set("happenddate", DateUtil.string2date((String) createTime,null));
-        //业务类型
-        trainCheckingBill.set("operationtype", businessTypeNo);
-        //订单分类
-        trainCheckingBill.set("ordersort", orderType);
-        //订单状态
-        trainCheckingBill.set("orderstatus", "5");
-        //结算金额
-        trainCheckingBill.set("totalamount", settlementAmount);
-        //币种
-        switch (settlementCurrency.toString()){
-            case "CNY":
-                trainCheckingBill.set("currency", "1");
-                break;
-            case "HKD":
-                trainCheckingBill.set("currency", "2");
-                break;
-            case "JPY":
-                trainCheckingBill.set("currency", "3");
-                break;
-            case "USD":
-                trainCheckingBill.set("currency", "4");
-                break;
-            case "EUR":
-                trainCheckingBill.set("currency", "5");
-                break;
-            case "GBP":
-                trainCheckingBill.set("currency", "6");
-                break;
-            case "AUD":
-                trainCheckingBill.set("currency", "7");
-                break;
-            case "TWD":
-                trainCheckingBill.set("currency", "8");
-                break;
-            case "MOP":
-                trainCheckingBill.set("currency", "9");
-                break;
+    private List<DynamicObject> extractAndProcessFields(Map<String, Object> resultMap) {
+        List<DynamicObject> resultLists = new ArrayList<>();
+
+        try {
+            // 1. 从结果映射中提取各字段
+            // ===================== 订单基本信息 =====================
+            // 结算单号
+            String settlementNo = getStringValue(resultMap, "settlementNo");
+            // 预订时间
+            String orderDate = getStringValue(resultMap, "orderDate");
+            // 订单类型
+            String orderType = getStringValue(resultMap, "orderType");
+            // 申请单号
+            String tripNo = getStringValue(resultMap, "tripNo");
+            // 差旅类型
+            String travelType = getStringValue(resultMap, "travelType");
+            // 结算生成时间
+            String createTime = getStringValue(resultMap, "createTime");
+            // 结算金额
+            String settlementAmount = getStringValue(resultMap, "settlementAmount");
+            // 币种
+            String settlementCurrency = getStringValue(resultMap, "settlementCurrency");
+            // 结算批次号
+            String accCheckBatchNo = getStringValue(resultMap, "accCheckBatchNo");
+            // 法人公司编码
+            String frgs = getStringValue(resultMap, "frgs");
+            // 项目编号
+            String projectNo = getStringValue(resultMap, "projectNo");
+            // 票号
+            String ticketNo = getStringValue(resultMap, "ticketNo");
+            // 出发城市名称
+            String departCityName = getStringValue(resultMap, "departCityName");
+            // 出发车站名
+            String departureStationName = getStringValue(resultMap, "departureStationName");
+            // 到达城市名称
+            String arrivalCityName = getStringValue(resultMap, "arrivalCityName");
+            // 到达车站名
+            String arrivalStationName = getStringValue(resultMap, "arrivalStationName");
+            // 出发日期时间
+            String departureDate = getStringValue(resultMap, "departureDate");
+            // 到达日期时间
+            String arrivalDate = getStringValue(resultMap, "arrivalDate");
+            // 出行人工号
+            String employeeId = getStringValue(resultMap, "employeeId");
+            // 出行人姓名
+            String guestName = getStringValue(resultMap, "guestName");
+            // 乘客姓名
+            String passengerName = getStringValue(resultMap, "passengerName");
+            // 车次
+            String trainName = getStringValue(resultMap, "trainName");
+            // 席位
+            String xwmc = getStringValue(resultMap, "xwmc");
+            // 火车票价
+            String price = getStringValue(resultMap, "price");
+            // 服务费
+            String serviceFee = getStringValue(resultMap, "serviceFee");
+            // 退票费
+            String refund = getStringValue(resultMap, "refund");
+            // 保险费
+            String insuranceFee = getStringValue(resultMap, "insuranceFee");
+            // 预订人员编号
+            String reserveId = getStringValue(resultMap, "reserveId");
+            // 预订人姓名
+            String reserveName = getStringValue(resultMap, "reserveName");
+            // 业务发生时间(用于发票查询)
+            String rebookingtime = getStringValue(resultMap, "rebookingtime");
+            //订单状态
+            String orderStatus = getStringValue(resultMap, "orderStatus");
+            switch (orderStatus) {
+                case "已出票":
+                    orderStatus = "1";
+                    break;
+                case "已改签":
+                    orderStatus = "2";
+                    break;
+                case "已退票":
+                    orderStatus = "3";
+                    break;
+                case "出票失败":
+                    orderStatus = "4";
+                    break;
+                case "出票失败退款":
+                    orderStatus = "5";
+                    break;
+                case "改签中":
+                    orderStatus = "6";
+                    break;
+                case "退票中":
+                    orderStatus = "7";
+                    break;
+                default:
+                    orderStatus = "9999";
+                    break;
+            }
+
+            //结算类型
+            String tmcPaymentType = getStringValue(resultMap, "tmcPaymentType");
+            if ("公司月结".equals(tmcPaymentType)) {
+                tmcPaymentType = "1";
+            } else if ("个人现付".equals(tmcPaymentType)) {
+                tmcPaymentType = "2";
+            }
+
+            // 2. 转换差旅类型格式
+            if ("因公".equals(travelType)) {
+                travelType = "1";
+            } else if ("因私".equals(travelType)) {
+                travelType = "0";
+            }
+
+            // 3. 检查结算单是否已存在,存在则修改,不存在则创建
+            DynamicObject trainCheckingBill = queryTraincheckingBill(settlementNo);
+            boolean isNew = ObjectUtils.isEmpty(trainCheckingBill);
+            if (isNew) {
+                trainCheckingBill = BusinessDataServiceHelper.newDynamicObject("er_traincheckingbill");
+                log.info("创建新的火车票结算单:" + settlementNo);
+            } else {
+                log.info("更新已存在的火车票结算单:" + settlementNo);
+            }
+
+            // 4. 设置各字段值
+            // ===================== 订单信息 =====================
+
+            // 订单日期
+            trainCheckingBill.set("orderdate", DateUtil.string2date(orderDate, null));
+            // 结算单号
+            trainCheckingBill.set("ordernum", settlementNo);
+
+            // 订单类型
+            if ("1".equals(orderType)){
+                trainCheckingBill.set("ordertype", "O");
+            }else if("2".equals(orderType)){
+                trainCheckingBill.set("ordertype", "T");
+            }else if("3".equals(orderType)){
+                trainCheckingBill.set("ordertype", "G");
+            }else{
+                trainCheckingBill.set("ordertype", "");
+            }
+            // 申请单号
+            trainCheckingBill.set("oabillnum", tripNo);
+            // 报销单号
+            trainCheckingBill.set("reimbursenum", "");
+            // 订单性质(因公/因私)
+            trainCheckingBill.set("isbusiness", travelType);
+            //结算类型
+            trainCheckingBill.set("producttype", tmcPaymentType);
+            // 预订人
+            DynamicObject sourcebookedids = queryBosUser(reserveId);
+            trainCheckingBill.set("sourcebookedid", sourcebookedids);
+            // 预订人姓名
+            String bookedname = ObjectUtils.isEmpty(sourcebookedids) ? "" : sourcebookedids.getString("name");
+            trainCheckingBill.set("bookedname", bookedname);
+
+            // 结算发生日期
+            trainCheckingBill.set("happenddate", DateUtil.string2date(createTime, null));
+            // 业务类型 6-国内火车
+            trainCheckingBill.set("operationtype", "6");
+            // 订单状态 1-已出票
+            trainCheckingBill.set("orderstatus", orderStatus);
+            // 订单分类
+            trainCheckingBill.set("ordersort", "1");
+
+            // 父订单号
+            trainCheckingBill.set("parentordernum", "");
+            // 结算金额
+            trainCheckingBill.set("totalamount", settlementAmount);
+
+            // 设置币种,从枚举中获取对应的值
+            String currency = Optional.ofNullable(CurrencyEnum.getByCode(settlementCurrency)).map(CurrencyEnum::getValue).orElse(null);
+            trainCheckingBill.set("currency", currency);
+
+            // 结算批次号
+            trainCheckingBill.set("batchno", accCheckBatchNo);
+            // 结算子批次号
+            trainCheckingBill.set("subbatchno", "");
+            // 设置费用承担公司(根据法人公司编码查询组织信息)
+            DynamicObject org = queryOrg(frgs);
+            //费用承担公司
+            trainCheckingBill.set("settlemain", org);
+            // 费用承担部门
+            trainCheckingBill.set("settledept", "");
+            // 申请人公司
+            trainCheckingBill.set("company", "");
+            // 申请人部门
+            trainCheckingBill.set("org", "");
+            // 项目
+            trainCheckingBill.set("std_project", projectNo);
+            // 成本中心
+            trainCheckingBill.set("std_costcenter", "");
+            // 外部系统结算单号
+            trainCheckingBill.set("outsettlementnum", "");
+
+            //====================火车信息===========================
+            // 火车票车票号
+            trainCheckingBill.set("trainticketnum", ticketNo);
+            // 出发城市
+            trainCheckingBill.set("departcity", departCityName);
+            // 出发车站
+            trainCheckingBill.set("departaddress", departureStationName);
+            // 到达城市
+            trainCheckingBill.set("arrivecity", arrivalCityName);
+            // 到达车站
+            trainCheckingBill.set("arriveaddress", arrivalStationName);
+            // 出发时间
+            trainCheckingBill.set("departtime", DateUtil.string2date(departureDate, null));
+            // 到达时间
+            trainCheckingBill.set("arrivetime", DateUtil.string2date(arrivalDate, null));
+            DynamicObject bosUser = queryBosUser(employeeId);
+            // 乘客
+            trainCheckingBill.set("passeger", bosUser);
+            // 乘客姓名
+            String passengerNames = ObjectUtils.isEmpty(bosUser) ? "" : bosUser.getString("name");
+            trainCheckingBill.set("passegername", passengerNames);
+            // 车次
+            trainCheckingBill.set("vendorname", trainName);
+            // 席位  转换为系统枚举编码
+            if (StringUtils.isNotBlank(xwmc)) {
+                TrainseatEnum seatType = TrainseatEnum.fromChineseName(xwmc);
+                if (seatType != null) {
+                    trainCheckingBill.set("trainseat", seatType.getCode());
+                }
+            }
+
+            // 火车票价
+            trainCheckingBill.set("ticketprice", price);
+            // 服务费
+            trainCheckingBill.set("servicefee", serviceFee);
+            // 退票费
+            trainCheckingBill.set("refundamount", refund);
+            // 保险费
+            trainCheckingBill.set("assuranceamount", insuranceFee);
+
+            //===================获取发票=====================
+            List<Map<String, Object>> invoiceResultList = InvoiceApiUtils.getInvoiceResult(settlementNo, rebookingtime);
+
+            if (CollectionUtils.isEmpty(invoiceResultList)) {
+                log.info("结算单号:" + settlementNo + "未查询到发票数据");
+            }else{
+                for (Map<String, Object> resultInvoiceList : invoiceResultList) {
+                    //下载地址
+                    trainCheckingBill.set("downloadlink", resultInvoiceList.get("invoiceUrl"));
+                    //内部下载地址
+                    trainCheckingBill.set("kddownloadlink", resultInvoiceList.get("invoiceUrl"));
+                    //发票流水号
+                    trainCheckingBill.set("serialno", resultInvoiceList.get("invoiceId"));
+                    //发票识别成功
+                    trainCheckingBill.set("invoiceidentityflag", true);
+                    //发票识别异常信息
+                    trainCheckingBill.set("identityerrormsg", resultInvoiceList.get("invoiceErrorMsg"));
+                    // 票价开票类型
+                    String invoiceTypeCode = resultInvoiceList.get("invoiceType").toString();
+                    String invoice = InvoiceTypeEnum.getValueByCode(invoiceTypeCode);
+                    trainCheckingBill.set("pricebillingtype", invoice);
+                }
+            }
+
+            //===========================控制信息================================
+            // 单据状态
+            trainCheckingBill.set("billstatus", "C");
+
+            //============================付款/凭证信息================================
+            //付款/付款申请单号
+            trainCheckingBill.set("paybillnum", "");
+            //付款状态
+            trainCheckingBill.set("paybillstatus", "");
+            //凭证号
+            trainCheckingBill.set("vouchernum", "");
+            //记账日期
+            trainCheckingBill.set("bookeddatereq", "");
+
+            resultLists.add(trainCheckingBill);
+        } catch (Exception e) {
+            log.info("处理单条火车票结算数据时发生异常,数据内容:" + resultMap, e);
+        }
+
+        return resultLists;
+    }
+
+    /**
+     * 根据员工工号查询人员信息
+     *
+     * @param employeeId
+     * @return
+     */
+    private DynamicObject queryBosUser(String employeeId) {
+        if (StringUtils.isBlank(employeeId)) {
+            log.info("未找到工号为:" + employeeId + "的人员信息");
+            return null;
         }
-        //结算批次号
-        trainCheckingBill.set("batchno", accCheckBatchNo);
-        //结算子批次号
-        trainCheckingBill.set("subbatchno", "");
-        //费用承担公司
-        trainCheckingBill.set("settlemain", "");
-        //费用承担部门
-        trainCheckingBill.set("settledept", "");
-        //申请人公司
-        trainCheckingBill.set("company", "");
-        //申请人部门
-        trainCheckingBill.set("org", "");
-        //项目
-        trainCheckingBill.set("std_project", projectNo);
-        //成本中心
-        trainCheckingBill.set("std_costcenter", "");
-        //外部系统结算单号
-        trainCheckingBill.set("outsettlementnum", "");
-        //火车票车票号
-        trainCheckingBill.set("trainticketnum", "");
-        //出发城市
-        trainCheckingBill.set("departcity", "");
-        //出发车站
-        trainCheckingBill.set("departaddress", "");
-        //到达城市
-        trainCheckingBill.set("arrivecity", "");
-        //到达车站
-        trainCheckingBill.set("arriveaddress", "");
-        //出发时间
-        trainCheckingBill.set("departtime", "");
-        //到达时间
-        trainCheckingBill.set("arrivetime", "");
-        //乘客
-        trainCheckingBill.set("passeger", "");
-        //乘客姓名
-        trainCheckingBill.set("passegername", "");
-        //车次
-        trainCheckingBill.set("vendorname", "");
-        //席位
-        trainCheckingBill.set("trainseat", "");
-        //火车票价
-        trainCheckingBill.set("ticketprice", "");
-        //服务费
-        trainCheckingBill.set("servicefee", "");
-        //退票费
-        trainCheckingBill.set("refundamount", "");
-        //保险费
-        trainCheckingBill.set("assuranceamount", "");
-        //下载地址
-        trainCheckingBill.set("downloadlink", "");
-        //内部下载地址
-        trainCheckingBill.set("kddownloadlink", "");
-        //发票流水号
-        trainCheckingBill.set("serialno", "");
-        //发票识别异常信息
-        trainCheckingBill.set("identityerrormsg", "");
-        //票价开票类型
-        trainCheckingBill.set("pricebillingtype", "");
-
-        //控制信息
-//        ??????。。
-        //可抵扣税额
-        trainCheckingBill.set("totaltax", "");
-        //已开票
-        trainCheckingBill.set("hasinvoice", "");
-        //付款/付款申请单号
-        trainCheckingBill.set("paybillnum", "");
-        //付款状态
-        trainCheckingBill.set("paybillstatus", "");
-        //凭证号
-        trainCheckingBill.set("vouchernum", "");
-        //记账日期
-        trainCheckingBill.set("bookeddatereq", "");
-        //记账日期
-        trainCheckingBill.set("bookeddatebu", "");
-
-        //4. 保存对象
-        SaveServiceHelper.save(new DynamicObject[]{trainCheckingBill});
+        QFilter userFilter = new QFilter("number", QCP.equals, employeeId);
+        //查询人员表
+        DynamicObject bosUser = BusinessDataServiceHelper.loadSingle("bos_user", "id,name", userFilter.toArray());
+
+        return bosUser;
+    }
+
+    /**
+     * 根据员工组织查询人员信息
+     *
+     * @param frgs
+     * @return
+     */
+    private DynamicObject queryOrg(String frgs) {
+        if (StringUtils.isBlank(frgs)) {
+            log.info(frgs + "组织编码为空");
+            return null;
+        }
+        QFilter[] orgFilter = new QFilter[]{new QFilter(BaseFieldConst.NUMBER, QCP.equals, frgs),};
+        DynamicObject org = BusinessDataServiceHelper.loadSingle(BosOrgConst.BOS_ORG, "id", orgFilter);
+        if (ObjectUtils.isEmpty(org)) {
+            return null;
+        }
+        return org;
+    }
+
+
+    /**
+     * 从Map中安全获取字符串值,避免空指针异常
+     *
+     * @param map 数据映射
+     * @param key 键名
+     * @return 字符串值,如果不存在或为null则返回空字符串
+     */
+    private String getStringValue(Map<String, Object> map, String key) {
+        return Optional.ofNullable(map.get(key)).map(Object::toString).orElse("");
+    }
+
+    /**
+     * 根据结算单号查询是否已存在该火车票结算单
+     * 用于判断是新增还是更新操作
+     *
+     * @param settlementNo 结算单号
+     * @return 存在的结算单动态对象,不存在则返回null
+     */
+    private DynamicObject queryTraincheckingBill(String settlementNo) {
+        if (StringUtils.isBlank(settlementNo)) {
+            return null;
+        }
+
+        QFilter[] trainFilter = new QFilter[]{new QFilter("ordernum", QCP.equals, settlementNo)};
+        return BusinessDataServiceHelper.loadSingle("er_traincheckingbill", trainFilter);
     }
 
     /**
@@ -398,7 +489,7 @@ public class TrainTicketSettlementTask extends AbstractTask {
         //获取当前时间字符串
         String nowDateString = DateUtil.date2str(nowDate, DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
 
-        log.info("结算单(火车票) 同步开始时间:" + syncTime);
+        log.info("结算单(火车票) 同步开始时间:" + syncTime + ",结束时间:" + nowDateString);
 
         List<Map<String, Object>> dataList = new ArrayList<>();
         for (int i = 0; i < TOTAL_PAGE; i++) {
@@ -417,31 +508,31 @@ public class TrainTicketSettlementTask extends AbstractTask {
     /**
      * 分页查询接口数据
      *
-     * @param syncTime 同步开始时间
+     * @param syncTime      同步开始时间
      * @param nowDateString 当前时间字符串
-     * @param currentPage 当前页码
+     * @param currentPage   当前页码
      * @return 当前页的数据列表
      */
     private List<Map<String, Object>> queryPageData(String syncTime, String nowDateString, int currentPage) {
         // 请求参数
         Map<String, Object> requestData = new HashMap<>();
         // 结算时间始
-        requestData.put("dateFrom", syncTime);
+        requestData.put("dateFrom", "1970-01-01 00:00:00");
         // 结算时间止
         requestData.put("dateTo", nowDateString);
         // 产品类别 0600 火车票
-        requestData.put("searchType", "0600");
+        requestData.put("searchType", TRAIN_TICKET_PRODUCT_TYPE);
         // 当前页码
         requestData.put("current", currentPage);
         // 每页数据量
         requestData.put("size", PAGE_SIZE);
         // 企业卡号
-        requestData.put("enterpriseNo", "JXWL");
+        requestData.put("enterpriseNo", ENTERPRISE_NO);
         // 账单类型 01-现结
-        requestData.put("settlementType", "01");
+//        requestData.put("settlementType", SETTLEMENT_TYPE);
 
         // 调用接口
-        Map<String, Object> resp = TripSyncUtils.pushApiCallResult("FCSET_OUTAPI_LiteGetSettlementInfo", Boolean.FALSE, requestData);
+        Map<String, Object> resp = TripSyncUtils.pushApiCallResult(INTERFACE_NAME, Boolean.FALSE, requestData);
 
         // 接口调用失败时抛出异常
         if ((Boolean) resp.get("fail")) {
@@ -449,11 +540,10 @@ public class TrainTicketSettlementTask extends AbstractTask {
         }
 
         Map<String, Object> result = (Map<String, Object>) resp.get("result");
-        return (List<Map<String, Object>>) result.getOrDefault("dataList", Collections.emptyList());
+        return (List<Map<String, Object>>) result.getOrDefault("settlementInfos", Collections.emptyList());
     }
 
 
-
     /**
      * 获取数据同步的开始时间
      *
@@ -466,13 +556,11 @@ public class TrainTicketSettlementTask extends AbstractTask {
         // 是否全量同步
         Boolean isAll = (Boolean) sysCtrlParameter.get("nckd_settlementbillall");
         if (isAll != null && isAll) {
-            return "1970-01-01 00:00:00";
+            return FULL_SYNC_START_TIME;
         }
 
         // 增量同步小时数,默认1小时
-        int hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour"))
-                ? 1
-                : (Integer) sysCtrlParameter.get("nckd_settlementbillhour");
+        int hours = ObjectUtils.isEmpty(sysCtrlParameter.get("nckd_settlementbillhour")) ? 1 : (Integer) sysCtrlParameter.get("nckd_settlementbillhour");
 
         // 计算同步开始时间(当前时间前推N小时)
         Date date = DateUtil.addHour(new Date(), -hours);