From c044b6dd024b6884a4f39bc56e4873c95b13fe02 Mon Sep 17 00:00:00 2001
From: admin <weikou2014>
Date: 星期四, 22 八月 2019 11:59:00 +0800
Subject: [PATCH] 免单更改
---
fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoBaoUtil.java | 349 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 266 insertions(+), 83 deletions(-)
diff --git a/fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoBaoUtil.java b/fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoBaoUtil.java
index cdc37bc..253f227 100644
--- a/fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoBaoUtil.java
+++ b/fanli/src/main/java/com/yeshi/fanli/util/taobao/TaoBaoUtil.java
@@ -1,7 +1,6 @@
package com.yeshi.fanli.util.taobao;
import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.net.URLEncoder;
@@ -29,6 +28,7 @@
import org.springframework.stereotype.Component;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
+import org.yeshi.utils.BigDecimalUtil;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.NumberUtil;
import org.yeshi.utils.entity.ProxyIP;
@@ -39,7 +39,6 @@
import com.google.gson.reflect.TypeToken;
import com.yeshi.fanli.entity.common.ImageInfo;
import com.yeshi.fanli.entity.goods.CommonGoods;
-import com.yeshi.fanli.entity.taobao.ScanHistory;
import com.yeshi.fanli.entity.taobao.SearchFilter;
import com.yeshi.fanli.entity.taobao.TaoBaoCoupon;
import com.yeshi.fanli.entity.taobao.TaoBaoGoodsBrief;
@@ -51,7 +50,10 @@
import com.yeshi.fanli.entity.taobao.TaoBaoQuanInfo;
import com.yeshi.fanli.entity.taobao.TaoBaoSearchNav;
import com.yeshi.fanli.entity.taobao.TaoBaoSearchResult;
+import com.yeshi.fanli.entity.taobao.TaoBaoShop;
import com.yeshi.fanli.entity.taobao.TaoBaoUnionConfig;
+import com.yeshi.fanli.entity.taobao.dataoke.DaTaoKeDetail;
+import com.yeshi.fanli.entity.taobao.dataoke.DaTaoKeDetailV2;
import com.yeshi.fanli.exception.taobao.TaobaoGoodsDownException;
import com.yeshi.fanli.log.LogHelper;
import com.yeshi.fanli.service.inter.goods.TaoBaoLinkService;
@@ -61,6 +63,7 @@
import com.yeshi.fanli.util.Constant;
import com.yeshi.fanli.util.MoneyBigDecimalUtil;
import com.yeshi.fanli.util.StringUtil;
+import com.yeshi.fanli.util.TaoBaoConstant;
import com.yeshi.fanli.util.TaoBaoHttpUtil;
import com.yeshi.fanli.util.TimeUtil;
@@ -693,14 +696,22 @@
tg.setBiz30day(tb.getBiz30day());
tg.setSalesCount(TaoBaoUtil.getSaleCount(tb.getBiz30day()));
tg.setTitle(tb.getTitle());
- tg.setPictUrl(TbImgUtil.getTBSize320Img(tb.getPictUrl()));
+ if (!StringUtil.isNullOrEmpty(tb.getPictUrlWhite()))
+ tg.setPictUrl(TbImgUtil.getTBSize320Img(tb.getPictUrlWhite()));
+ else
+ tg.setPictUrl(TbImgUtil.getTBSize320Img(tb.getPictUrl()));
tg.setZkPrice(tb.getZkPrice());
tg.setAuctionUrl(tb.getAuctionUrl());
tg.setReservePrice(tb.getReservePrice());
tg.setUserType(tb.getUserType());
tg.setShopTitle(tb.getShopTitle());
+ tg.setTkRate(tb.getTkRate());
+ tg.setSellerId(tb.getSellerId());
tg.setState(tb.getState()); // 鐘舵�侊細2018-12-03
- if (tb.getCouponAmount().compareTo(BigDecimal.valueOf(0)) == 1) {
+ if (tb.getCouponAmount().compareTo(BigDecimal.valueOf(0)) > 0) {
+
+ tg.setCoupon(true);// 鏈夊埜
+
TaoBaoQuanInfo quanInfo = new TaoBaoQuanInfo();
quanInfo.setCouponAmount(tb.getCouponAmount());
String couponEffectiveEndTime = tb.getCouponEffectiveEndTime();
@@ -711,7 +722,7 @@
quanInfo.setCouponLeftCount(tb.getCouponLeftCount());
quanInfo.setCouponLink(
TaoBaoCouponUtil.getCoupleUrl(tb.getCouponActivityId(), pid, tb.getAuctionId() + ""));
- quanInfo.setCouponPrice(tb.getZkPrice().subtract(tb.getTkCommFee()));
+ quanInfo.setCouponPrice(MoneyBigDecimalUtil.sub(tg.getZkPrice(), tb.getCouponAmount()));
quanInfo.setCouponStartFee(tb.getCouponStartFee());
quanInfo.setCouponTotalCount(tb.getCouponTotalCount());
tg.setTaoBaoQuanInfo(quanInfo);
@@ -754,6 +765,17 @@
tg.setTaoBaoHongBaoInfo(hongBaoInfo);
+ tg.setMoneyType(1);
+ tg.setSalesType(1);
+ // 娴嬭瘯浣跨敤
+ // tg.setSalesType(Math.random() > 0.5 ? tg.getSalesType() : 3);
+ // if(Constant.IS_TEST)
+ // {
+ // List<ClientTextStyleVO> labels = new ArrayList<>();
+ // labels.add(new ClientTextStyleVO("鏍囩鍐呭", "#F14242"));
+ // labels.add(new ClientTextStyleVO("鏍囩鍐呭", "#00FF00"));
+ // tg.setLabels(labels);
+ // }
return tg;
}
@@ -997,6 +1019,17 @@
}
tg.setTaoBaoHongBaoInfo(hongBaoInfo);
+ tg.setMoneyType(1);
+ tg.setSalesType(1);
+ // 娴嬭瘯浣跨敤
+ // tg.setMoneyType(Math.random() > 0.5 ? 1 : 2);
+ // tg.setSalesType(Math.random() > 0.5 ? 1 : 2);
+ // tg.setSalesType(Math.random() > 0.5 ? tg.getSalesType() : 3);
+ // List<ClientTextStyleVO> labels = new ArrayList<>();
+ // labels.add(new ClientTextStyleVO("鏍囩鍐呭", "#F14242"));
+ // labels.add(new ClientTextStyleVO("鏍囩鍐呭", "#000000"));
+ // tg.setLabels(labels);
+
return tg;
}
@@ -1017,53 +1050,6 @@
return presult.getTaoBaoGoodsBriefs().get(0);
} else
return null;
- }
-
- public static TaoBaoGoodsBrief getTaoBaoGoodsBrief(ScanHistory sh) {
- TaoBaoGoodsBrief tb = new TaoBaoGoodsBrief();
- Field[] fields = tb.getClass().getDeclaredFields();
- Field[] shFields = sh.getClass().getDeclaredFields();
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- field.setAccessible(true);
- try {
- for (Field target : shFields) {
- target.setAccessible(true);
- if (target.getName().equalsIgnoreCase(field.getName())) {
- field.set(tb, target.get(sh));
- break;
- }
- }
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- return tb;
- }
-
- public static ScanHistory getScanHistory(TaoBaoGoodsBrief tb) {
- ScanHistory sh = new ScanHistory();
- Field[] fields = tb.getClass().getDeclaredFields();
- Field[] shFields = sh.getClass().getDeclaredFields();
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- field.setAccessible(true);
- try {
- for (Field target : shFields) {
- target.setAccessible(true);
- if (target.getName().equalsIgnoreCase(field.getName())) {
- target.set(sh, field.get(tb));
- break;
- }
- }
- } catch (IllegalArgumentException e) {
- } catch (IllegalAccessException e) {
- }
- }
-
- return sh;
}
public static List<String> getSuguestSearch(String key) {
@@ -1355,6 +1341,10 @@
* @return
*/
public static String getGoodsHongBaoInfo(TaoBaoGoodsBrief goodsBrief, BigDecimal rate) {
+ // if (goodsBrief != null && goodsBrief.getMaterialLibType() != null &&
+ // goodsBrief.getMaterialLibType() == 0)
+ // return "楼0.00";
+ // else
return "楼" + getGoodsHongBaoMoney(goodsBrief, rate).toString();
}
@@ -1366,10 +1356,14 @@
* @return
*/
public static BigDecimal getGoodsHongBaoMoney(TaoBaoGoodsBrief goodsBrief, BigDecimal rate) {
+ BigDecimal money = null;
+
if (StringUtil.isNullOrEmpty(goodsBrief.getCouponInfo())
|| goodsBrief.getCouponInfo().trim().equalsIgnoreCase("鏃�")) {
- return goodsBrief.getZkPrice().multiply(goodsBrief.getTkRate()).divide(new BigDecimal(10000)).multiply(rate)
- .setScale(2, BigDecimal.ROUND_DOWN);
+ money = MoneyBigDecimalUtil.mul(
+ MoneyBigDecimalUtil.mul(MoneyBigDecimalUtil.mul(goodsBrief.getZkPrice(), goodsBrief.getTkRate()),
+ new BigDecimal("0.01")),
+ MoneyBigDecimalUtil.div(rate, new BigDecimal(100)));
} else// 鏈夊埜
{
List<BigDecimal> list = TaoBaoCouponUtil.getCouponInfo(goodsBrief.getCouponInfo());
@@ -1378,13 +1372,17 @@
if (startFee.compareTo(goodsBrief.getZkPrice()) <= 0
&& goodsBrief.getZkPrice().compareTo(couponAccount) > 0) {
BigDecimal finalPrice = goodsBrief.getZkPrice().subtract(couponAccount);
- return finalPrice.multiply(goodsBrief.getTkRate()).divide(new BigDecimal(10000)).multiply(rate)
- .setScale(2, BigDecimal.ROUND_DOWN);
+ money = MoneyBigDecimalUtil.mul(MoneyBigDecimalUtil
+ .mul(MoneyBigDecimalUtil.mul(finalPrice, goodsBrief.getTkRate()), new BigDecimal("0.01")),
+ MoneyBigDecimalUtil.div(rate, new BigDecimal(100)));
+
} else {// 涓嶈兘鐢ㄥ埜
- return goodsBrief.getZkPrice().multiply(goodsBrief.getTkRate()).divide(new BigDecimal(10000))
- .multiply(rate).setScale(2, BigDecimal.ROUND_DOWN);
+ money = MoneyBigDecimalUtil.mul(MoneyBigDecimalUtil.mul(
+ MoneyBigDecimalUtil.mul(goodsBrief.getZkPrice(), goodsBrief.getTkRate()),
+ new BigDecimal("0.01")), MoneyBigDecimalUtil.div(rate, new BigDecimal(100)));
}
}
+ return BigDecimalUtil.getWithNoZera(money);
}
// }
@@ -1418,30 +1416,7 @@
*/
public static BigDecimal getShareGoodsHongBaoInfo(TaoBaoGoodsBrief goodsBrief, BigDecimal rate) {
-
- // 璁$畻杩斿埄
- // 鏃犲埜
- if (StringUtil.isNullOrEmpty(goodsBrief.getCouponInfo()) || goodsBrief.getCouponInfo().contains("鏃�")) {
- return goodsBrief.getZkPrice().multiply(goodsBrief.getTkRate()).divide(new BigDecimal(10000)).multiply(rate)
- .setScale(2, BigDecimal.ROUND_DOWN);
-
- } else// 鏈夊埜
- {
- List<BigDecimal> list = TaoBaoCouponUtil.getCouponInfo(goodsBrief.getCouponInfo());
- BigDecimal startFee = list.get(0);
- BigDecimal couponAccount = list.get(1);
- if (startFee.compareTo(goodsBrief.getZkPrice()) <= 0
- && goodsBrief.getZkPrice().compareTo(couponAccount) > 0) {
- BigDecimal finalPrice = goodsBrief.getZkPrice().subtract(couponAccount);
- return finalPrice.multiply(goodsBrief.getTkRate()).divide(new BigDecimal(10000)).multiply(rate)
- .setScale(2, BigDecimal.ROUND_DOWN);
-
- } else {// 涓嶈兘鐢ㄥ埜
- return goodsBrief.getZkPrice().multiply(goodsBrief.getTkRate()).divide(new BigDecimal(10000))
- .multiply(rate).setScale(2, BigDecimal.ROUND_DOWN);
- }
-
- }
+ return getGoodsHongBaoMoney(goodsBrief, rate);
}
/**
@@ -1706,6 +1681,62 @@
return taoBaoGoods;
}
+ public static TaoBaoGoodsBrief convert(DaTaoKeDetail detail) {
+ TaoBaoGoodsBrief taoBaoGoods = new TaoBaoGoodsBrief();
+ taoBaoGoods.setAuctionId(detail.getGoodsId());
+ taoBaoGoods.setBiz30day(detail.getSalesNum());
+ taoBaoGoods.setCouponAmount(detail.getQuanPrice());
+ taoBaoGoods.setCouponInfo(String.format("婊�%s鍏冨噺%s鍏�", detail.getQuanCondition(),
+ MoneyBigDecimalUtil.getWithNoZera(detail.getQuanPrice())));
+ taoBaoGoods.setCouponLeftCount(detail.getQuanSurplus());
+ taoBaoGoods.setCouponStartFee(new BigDecimal(detail.getQuanCondition()));
+ if (detail.getQuanReceive() != null)
+ taoBaoGoods.setCouponTotalCount(detail.getQuanSurplus() + detail.getQuanReceive());
+ taoBaoGoods.setPictUrl(detail.getPic());
+ taoBaoGoods.setPictUrlWhite(detail.getPic());
+ taoBaoGoods.setSellerId(detail.getSellerId());
+ taoBaoGoods.setShopTitle("");
+ taoBaoGoods.setTitle(detail.getdTitle());
+ taoBaoGoods.setUserType(detail.getIsTmall());
+ taoBaoGoods.setZkPrice(detail.getOrgPrice());
+ taoBaoGoods.setTkRate(detail.getCommission());
+ taoBaoGoods.setTkCommFee(new BigDecimal("0"));
+ taoBaoGoods.setState(0);
+ return taoBaoGoods;
+ }
+
+ public static TaoBaoGoodsBrief convert(DaTaoKeDetailV2 detail) {
+ TaoBaoGoodsBrief taoBaoGoods = new TaoBaoGoodsBrief();
+ taoBaoGoods.setAuctionId(detail.getGoodsId());
+ taoBaoGoods.setBiz30day(detail.getMonthSales());
+ taoBaoGoods.setCouponAmount(detail.getCouponPrice());
+ taoBaoGoods.setCouponInfo(String.format("婊�%s鍏冨噺%s鍏�", detail.getCouponConditions(),
+ MoneyBigDecimalUtil.getWithNoZera(detail.getCouponPrice())));
+ if (detail.getCouponTotalNum() != null && detail.getCouponReceiveNum() != null)
+ taoBaoGoods.setCouponLeftCount(detail.getCouponTotalNum() - detail.getCouponReceiveNum());
+ else
+ taoBaoGoods.setCouponLeftCount(0);
+ taoBaoGoods.setCouponStartFee(detail.getOriginalPrice());
+ taoBaoGoods.setCouponTotalCount(detail.getCouponTotalNum());
+ taoBaoGoods.setPictUrl(detail.getMainPic());
+ taoBaoGoods.setPictUrlWhite(detail.getMainPic());
+ if (taoBaoGoods.getPictUrl() != null && !taoBaoGoods.getPictUrl().startsWith("http"))
+ taoBaoGoods.setPictUrl("https:" + taoBaoGoods.getPictUrl());
+
+ if (taoBaoGoods.getPictUrlWhite() != null && !taoBaoGoods.getPictUrlWhite().startsWith("http"))
+ taoBaoGoods.setPictUrlWhite("https:" + taoBaoGoods.getPictUrlWhite());
+
+ taoBaoGoods.setSellerId(detail.getSellerId());
+ taoBaoGoods.setShopTitle(detail.getShopName());
+ taoBaoGoods.setTitle(detail.getDtitle());
+ taoBaoGoods.setUserType(detail.getShopType());
+ taoBaoGoods.setZkPrice(detail.getOriginalPrice());
+ taoBaoGoods.setTkRate(detail.getCommissionRate());
+ taoBaoGoods.setTkCommFee(new BigDecimal("0"));
+ taoBaoGoods.setState(0);
+ return taoBaoGoods;
+ }
+
/**
* 鑾峰彇娣樺疂鑱旂洘鐨勬巿鏉冮摼鎺�
*
@@ -1716,13 +1747,14 @@
* @param uid-鐢ㄦ埛ID
* @return
*/
- public static String getTaoBaoUnionAuthUrl(String appKey, String callBackUrl, Long uid) {
+ public static String getTaoBaoUnionAuthUrl(String appKey, String callBackUrl, Long uid, String source) {
if (uid == null)
return null;
long timestamp = System.currentTimeMillis();
JSONObject json = new JSONObject();
json.put("u", uid);
json.put("t", timestamp);
+ json.put("s", source);
String url = null;
try {
url = String.format(
@@ -1735,6 +1767,157 @@
return url;
}
+ public static TaoBaoGoodsBrief getSimpleGoodsBrief(Long actionId) {
+ JSONObject data = new JSONObject();
+ data.put("itemNumId", actionId + "");
+
+ String url = "";
+ try {
+ url = String.format("https://acs.m.taobao.com/h5/mtop.taobao.detail.getdetail/6.0/?data=%s",
+ URLEncoder.encode(data.toString(), "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ String result = HttpUtil.get(url);
+ JSONObject resultOBJ = JSONObject.fromObject(result);
+ if (resultOBJ.optJSONObject("data") != null) {
+ data = resultOBJ.optJSONObject("data");
+ JSONObject item = data.optJSONObject("item");
+ JSONObject seller = data.optJSONObject("seller");
+ TaoBaoGoodsBrief goods = new TaoBaoGoodsBrief();
+ goods.setAuctionId(item.optLong("itemId"));
+ goods.setTitle(item.optString("title"));
+ if (item.optJSONArray("images") != null && item.optJSONArray("images").size() > 0) {
+ String picture = item.optJSONArray("images").optString(0);
+ goods.setPictUrl(picture.startsWith("http") ? picture : "https:" + picture);
+ }
+ goods.setSellerId(seller.optLong("shopId"));
+ String shopType = seller.optString("shopType");
+ if ("B".equalsIgnoreCase(shopType)) {
+ goods.setUserType(1);
+ } else
+ goods.setUserType(0);
+
+ goods.setShopTitle(seller.optString("shopName"));
+ return goods;
+ }
+ return null;
+ }
+
+ /**
+ * 鏍规嵁鍟嗗搧ID鑾峰彇搴楅摵璇︽儏
+ *
+ * @param auctionId
+ * @return
+ */
+ public static TaoBaoShop getTaoBaoShopDetailByAuctionId(Long auctionId) {
+ JSONObject data = new JSONObject();
+ data.put("itemNumId", auctionId + "");
+
+ String url = "";
+ try {
+ url = String.format("https://acs.m.taobao.com/h5/mtop.taobao.detail.getdetail/6.0/?data=%s",
+ URLEncoder.encode(data.toString(), "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ String result = HttpUtil.get(url);
+
+ TaoBaoShop shop = new TaoBaoShop();
+
+ try {
+ JSONObject resultJson = JSONObject.fromObject(result);
+ JSONObject dataJson = resultJson.optJSONObject("data");
+ JSONObject sellerJson = dataJson.optJSONObject("seller");
+
+ shop.setGoodRatePercentage(new BigDecimal(sellerJson.optString("goodRatePercentage").replace("%", "")));
+
+ LogHelper.test("鍗栧淇℃伅:" + result);
+ shop.setId(sellerJson.optLong("userId"));
+ JSONArray array = sellerJson.optJSONArray("evaluates");
+ for (int i = 0; i < array.size(); i++) {
+ JSONObject item = array.optJSONObject(i);
+ if ("瀹濊礉鎻忚堪".equalsIgnoreCase(item.optString("title").trim())) {
+ shop.setScoreGoods(new BigDecimal(item.optString("score").trim()));
+ shop.setScoreGoodsD(new BigDecimal(item.optString("level").trim()));
+ } else if ("鍗栧鏈嶅姟".equalsIgnoreCase(item.optString("title").trim())) {
+ shop.setScoreSeller(new BigDecimal(item.optString("score").trim()));
+ shop.setScoreSellerD(new BigDecimal(item.optString("level").trim()));
+ } else if ("鐗╂祦鏈嶅姟".equalsIgnoreCase(item.optString("title").trim())) {
+ shop.setScoreLogistics(new BigDecimal(item.optString("score").trim()));
+ shop.setScoreLogisticsD(new BigDecimal(item.optString("level").trim()));
+ }
+ }
+
+ shop.setSellerNick(sellerJson.optString("sellerNick"));
+ shop.setShopIcon("https:" + sellerJson.optString("shopIcon"));
+ shop.setShopId(sellerJson.optLong("shopId"));
+ shop.setShopName(sellerJson.optString("shopName"));
+ if ("B".equalsIgnoreCase(sellerJson.optString("sellerType")))
+ shop.setUserType(1);
+ else
+ shop.setUserType(0);
+
+ shop.setShopLink(TaoBaoUtil.getShopLink(shop.getId()));
+ } catch (Exception e) {
+ // if (1 > 0)
+ // return null;
+ try {
+ TaoBaoGoodsBrief goods = TaoKeApiUtil.getSimpleGoodsInfo(auctionId);
+ shop.setId(goods.getSellerId());
+ shop.setShopName(goods.getShopTitle());
+ shop.setUserType(goods.getUserType());
+ } catch (Exception e1) {
+ shop.setId(1L);
+ shop.setShopName("");
+ shop.setUserType(0);
+ }
+
+ shop.setGoodRatePercentage(new BigDecimal(100));
+ shop.setScoreGoods(new BigDecimal("4.9"));
+ shop.setScoreGoodsD(new BigDecimal("0"));
+ shop.setScoreSeller(new BigDecimal("4.9"));
+ shop.setScoreSellerD(new BigDecimal("0"));
+ shop.setScoreLogistics(new BigDecimal("4.9"));
+ shop.setScoreLogisticsD(new BigDecimal("0"));
+ shop.setSellerNick("");
+ shop.setShopIcon("https:");
+ shop.setShopLink(TaoBaoUtil.getShopLink(shop.getId()));
+ }
+
+ return shop;
+ }
+
+ /**
+ * 鏍规嵁鍗栧id鑾峰彇搴楅摵閾炬帴
+ *
+ * @param sellerId
+ * @return
+ */
+ public static String getShopLink(Long sellerId) {
+ return "http://store.taobao.com/shop/view_shop.htm?user_number_id=" + sellerId;
+ }
+
+ /**
+ * 鏄惁鍙互鍔犲叆娣樼ぜ閲戠殑棰勯�夊晢鍝佸簱
+ *
+ * @param v2
+ * @return
+ */
+ public static boolean canAddToTLJBuyGoods(TaoBaoGoodsBrief goods) {
+ BigDecimal tljMoney = getShareGoodsHongBaoInfo(goods, TaoBaoConstant.OWN_BUY_WITHOUT_FANLI_RATE);
+ // 涓嶈兘灏忎簬1鍧�
+ if (tljMoney.compareTo(new BigDecimal(1)) < 0 || tljMoney.compareTo(new BigDecimal(10)) > 0)
+ return false;
+
+ // 鍒稿悗浠蜂笉鑳藉ぇ浜�150
+ if (getAfterUseCouplePrice(goods).compareTo(new BigDecimal(150)) > 0)
+ return false;
+
+ return true;
+ }
+
public static void main(String[] args) {
String s = channelMap.get("3");
System.out.println(s);
--
Gitblit v1.8.0