酒店

全量落地更新时间:2019/11/07 10:28

涉及接口 hotel.data.rp
demo语言: Java
开发环境:
jdk1.7以上


通过产品详情接口落地或更新酒店产品


rp全量

后端通过http协议调用艺龙的hotel.data.rp接口
public class HotelRatePlanDataApi {
    private static double version = 1.50;
    private static EnumLocal locale = EnumLocal.zh_CN;
    private static boolean isHttps = false;
    ...
    ...
    
    /**
     * 通过http工具类调用艺龙接口,将前端参数拼接为URL
     */
    public String getRatePlanData(GetRatePlanRequest condition,
        String userName, String appKey, String secretKey) {
        String url = "";
        String responseData = "";
        try{
            BaseRequest<GetRatePlanRequest> req = new BaseRequest<GetRatePlanRequest>();
            req.Version = version;
            req.Local = locale;
            req.Request = condition;
    
            //请求参数转换为Json字符串
            String str = JsonUtil.entity2Json(req);
            
            //产生签名
            long epoch = System.currentTimeMillis()/1000;
            String sig = Tool.md5(epoch + Tool.md5(str + appKey) + secretKey);
            
            //产生请求链接
            url = "http://" + serverHost + "/rest?format=json&method=hotel.data.rp";
            url += "&user="+ userName +"&timestamp=";
            url += epoch;
            url += "&signature=";
            url += sig;
            url += "&data=" + Tool.encodeUri(str);
            
            //发送请求
            responseData = HttpUtil.Send("GET", url, "", "application/json");
            
        } catch (Exception e) {
            log.info("[HotelRatePlanDataApi] 异常: " + e);
            log.info("发送的url: " + url);
            log.info("返回值: " + responseData);
        }
        return responseData;
    }

    ...
    ...
}


库存全量

后端通过http协议调用艺龙的hotel.data.inventory接口
public class HotelInventoryDataApi {
    private static double version = 1.50;
    private static EnumLocal locale = EnumLocal.zh_CN;
    private static boolean isHttps = false;
    ...
    ...
    
    /**
     * 通过http工具类调用艺龙接口,将前端参数拼接为URL
     */
    public String getInventoryData(GetInventoryRequest condition,
        String userName, String appKey, String secretKey) {
        String url = "";
        String responseData = "";
        try{
            BaseRequest<GetInventoryRequest> req = new BaseRequest<GetInventoryRequest>();
            req.Version = version;
            req.Local = locale;
            req.Request = condition;
    
            //请求参数转换为Json字符串
            String str = JsonUtil.entity2Json(req);
            
            //产生签名
            long epoch = System.currentTimeMillis()/1000;
            String sig = Tool.md5(epoch + Tool.md5(str + appKey) + secretKey);
            
            //产生请求链接
            url = "http://" + serverHost + "/rest?format=json&method=hotel.data.inventory";
            url += "&user="+ userName +"&timestamp=";
            url += epoch;
            url += "&signature=";
            url += sig;
            url += "&data=" + Tool.encodeUri(str);
            
            //发送请求
            responseData = HttpUtil.Send("GET", url, "", "application/json");
            
        } catch (Exception e) {
            log.info("[HotelInventoryDataApi] 异常: " + e);
            log.info("发送的url: " + url);
            log.info("返回值: " + responseData);
        }
        return responseData;
    }

    ...
    ...
}


价格全量

后端通过http协议调用艺龙的hotel.data.rate接口
public class HotelRateDataApi {
    private static double version = 1.50;
    private static EnumLocal locale = EnumLocal.zh_CN;
    private static boolean isHttps = false;
    ...
    ...
    
    /**
     * 通过http工具类调用艺龙接口,将前端参数拼接为URL
     */
    public String getRateData(GetRateRequest condition,
        String userName, String appKey, String secretKey) {
        String url = "";
        String responseData = "";
        try{
            BaseRequest<GetRateRequest> req = new BaseRequest<GetRateRequest>();
            req.Version = version;
            req.Local = locale;
            req.Request = condition;
    
            //请求参数转换为Json字符串
            String str = JsonUtil.entity2Json(req);
            
            //产生签名
            long epoch = System.currentTimeMillis()/1000;
            String sig = Tool.md5(epoch + Tool.md5(str + appKey) + secretKey);
            
            //产生请求链接
            url = "http://" + serverHost + "/rest?format=json&method=hotel.data.rate";
            url += "&user="+ userName +"&timestamp=";
            url += epoch;
            url += "&signature=";
            url += sig;
            url += "&data=" + Tool.encodeUri(str);
            
            //发送请求
            responseData = HttpUtil.Send("GET", url, "", "application/json");
            
        } catch (Exception e) {
            log.info("[HotelRateDataApi] 异常: " + e);
            log.info("发送的url: " + url);
            log.info("返回值: " + responseData);
        }
        return responseData;
    }

    ...
    ...
}


全量拉取任务

定义全量拉取的任务类,可以进行多线程拉取
class PullTask implements Runnable {

    private String hotelId;

    public PullTask(String hotelId) {
        this.hotelId = hotelId;
    }

    @Override
    public void run() {
        Set<Product> products= null; // 返回产品集合
        try {
            products = pull(hotelId); // 拉取三个全量接口,将返回的数据进行对应 rp、inv、rate
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


rp返回解析

将返回的json对象解析,落地或更新产品
// RP
String result_json_rp = hotelRatePlanDataApi.getRatePlanData(condition,
       userName, appKey, secretKey);
JSONObject json_rp = JSON.parseObject(result_json_rp);
if (json_rp == null || !"0".equals(json_rp.getString("Code"))){
    return null;
}
JSONArray hotels = json_rp.getJSONObject("Result").getJSONArray("Hotels");
if (hotels.isEmpty()) {
    return null;
}
JSONObject hotel = hotels.getJSONObject(0);
JSONArray ratePlans = hotel.getJSONArray("RatePlans");
if (ratePlans.isEmpty()) {
    return null;
}
for (int i = 0; i < ratePlans.size(); i++) {
    JSONObject ratePlan = ratePlans.getJSONObject(i);
    String hotelCode = ratePlan.getString("HotelCode");
    String ratePlanId = ratePlan.getString("RatePlanId");
    String ratePlanName = ratePlan.getString("RatePlanName");
    String paymentType = ratePlan.getString("PaymentType");
    String roomTypeIdsStr = ratePlan.getString("RoomTypeIds");
    String invoiceModeStr = ratePlan.getString("InvoiceMode");
    String productTypesStr = ratePlan.getString("ProductTypes");
    Integer IsPriceLimitProduct = ratePlan.getInteger("IsPriceLimitProduct");
    JSONArray customerLevelsArr = ratePlan.getJSONArray("CustomerLevel");
    // 担保或预付规则接收
    JSONArray paymentRulesArr = null;
    JSONArray valueAddsArr = ratePlan.getJSONArray("ValueAdds");
    if ("SelfPay".equals(paymentType)){
        paymentRulesArr = ratePlan.getJSONArray("GuaranteeRules");
    } else if ("Prepay".equals(paymentType)){
        paymentRulesArr = ratePlan.getJSONArray("PrepayRules");
    }

    String[] roomTypeIds = roomTypeIdsStr.split(",");
    for (String roomTypeId: roomTypeIds) {
        Product product = new Product();
        product.setHotelId(hotelId);
        product.setHotelCode(hotelCode);
        product.setRoomTypeId(roomTypeId);
        product.setRatePlanId(ratePlanId);
        product.setRatePlanName(ratePlanName);
        product.setPaymentType(paymentType);
        product.setInvoiceMode(invoiceModeStr);
        product.setProductTypes(productTypesStr);
        if (paymentRulesArr != null) {
            product.setPaymentRules(paymentRulesArr.toJSONString());
        }
        product.setValueAdds(valueAddsArr.toJSONString());
        product.setPriceLimitProduct(IsPriceLimitProduct);
        product.setCustomerLevel(customerLevelsArr != null ? customerLevelsArr.toJSONString() : null);

        String key1 = hotelCode + "_" + roomTypeId;
        if (!rts.containsKey(key1)) {
            rts.put(key1, new HashMap<String, Product>());
        }
        Map<String, Product> rps = rts.get(key1);
        rps.put(ratePlanId, product);
    }
}
...
...


库存返回解析

将返回的json对象解析,将库存信息关联到具体产品
// Inv
...
...
String result_json_inv = hotelInventoryDataApi.getInventoryData(condition,
       userName, appKey, secretKey);
JSONObject json_inv = JSON.parseObject(result_json_inv);
if (json_inv == null || !"0".equals(json_inv.getString("Code"))) {
    return null;
}

JSONArray Inventories = json_inv.getJSONObject("Result").getJSONArray("Inventories");
if (!Inventories.isEmpty()) {
    for (int i = 0; i < Inventories.size(); i++) {
        JSONObject Inventory = Inventories.getJSONObject(i);
        String hotelCode = Inventory.getString("HotelCode");
        String roomTypeId = Inventory.getString("RoomTypeId");
        String date = Inventory.getString("Date");
        boolean status = Inventory.getBoolean("Status");
        String key1 = hotelCode + "_" + roomTypeId;
        String dateKey = cutDate(date);
        Map<String, Map<String, Product>> date_rp = rt_date_rp.get(key1);
        if (date_rp != null && date_rp.containsKey(dateKey)) {
            Map<String, Product> rps = date_rp.get(dateKey);
            for (Product p : rps.values()) {
                p.setInvStatus(status);
            }
        }
    }
}
...
...


价格返回解析

将返回的json对象解析,将价格信息关联到具体产品
// Rate
...
...
String result_json_rate = hotelRateDataApi.getRateData(condition,
       userName, appKey, secretKey);
JSONObject json_rate = JSON.parseObject(result_json_rate);
if (json_rate == null || !"0".equals(json_rate.getString("Code"))) {
    return null;
}

JSONArray rates = json_rate.getJSONObject("Result").getJSONArray("Rates");
if (!rates.isEmpty()) {
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMdd");
    for (int i = 0; i < rates.size(); i++) {
        JSONObject rate = rates.getJSONObject(i);
        String hotelCode = rate.getString("HotelCode");
        String roomTypeId = rate.getString("RoomTypeId");
        String rateplanId = rate.getString("RateplanId");
        String startDate = rate.getString("StartDate");
        String endDate = rate.getString("EndDate");
        boolean status = rate.getBoolean("Status");
        double member = rate.getDouble("Member");
        double memberCost = rate.getDouble("MemberCost");
        int currencyCode = convertCurrencyCode(rate.getString("CurrencyCode"));
        String key1 = hotelCode + "_" + roomTypeId;
        Date dateFrom = dateformat.parse(cutDate(startDate));
        Date dateTo = dateformat.parse(cutDate(endDate));
        for (Date d = dateFrom; d.getTime() < dateTo.getTime() + 1;
            d = DateUtils.addDays(d, 1)) {
            String dateKey = dateformat.format(d);
            Map<String, Map<String, Product>> date_rp = rt_date_rp.get(key1);
            if (date_rp != null && date_rp.containsKey(dateKey)) {
                Map<String, Product> rps = date_rp.get(dateKey);
                if (rps != null && rps.containsKey(rateplanId)) {
                    Product p = rps.get(rateplanId);
                    p.setMemberRate(member);
                    p.setCostRate(memberCost);
                    p.setRateStatus(status);
                    p.setCurrencyCode(currencyCode);
                }
            }
        }
    }
}
...
...


保存或更新

将聚合的产品对象保存到产品表中,这里的产品是包含了rp、价格、库存状态等的实体,
注意这样冗余的数据比较多,而且不利于更新操作,建议接入方自己建立模型存储全量数据,
可以单独创建rp、价格、库存表进行数据持久化。