优化记录日志功能
This commit is contained in:
@@ -8,6 +8,8 @@ public class BillSyncSnapshot
|
||||
private String bizId;
|
||||
private String requestJson;
|
||||
private String responseJson;
|
||||
private String status;
|
||||
private String errorMessage;
|
||||
private String updatedAt;
|
||||
|
||||
public String getDocId()
|
||||
@@ -60,6 +62,26 @@ public class BillSyncSnapshot
|
||||
this.responseJson = responseJson;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getErrorMessage()
|
||||
{
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
public void setErrorMessage(String errorMessage)
|
||||
{
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public String getUpdatedAt()
|
||||
{
|
||||
return updatedAt;
|
||||
|
||||
@@ -49,21 +49,25 @@ public class EsBillSearchStore implements IBillSearchStore
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(String logType, String bizId, String requestJson, String responseJson)
|
||||
public void save(String logType, String bizId, String requestJson, String responseJson, String status,
|
||||
String errorMessage)
|
||||
{
|
||||
if (StringUtils.isEmpty(logType) || StringUtils.isEmpty(bizId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
String docId = EsLogType.docId(logType, bizId);
|
||||
Date now = new Date();
|
||||
String docId = EsLogType.docId(logType, bizId, now);
|
||||
try
|
||||
{
|
||||
JSONObject doc = new JSONObject();
|
||||
doc.put("logType", logType.trim());
|
||||
doc.put("bizId", bizId.trim());
|
||||
doc.put("status", StringUtils.isEmpty(status) ? EsBizLogSupport.STATUS_SUCCESS : status.trim());
|
||||
doc.put("error", StringUtils.isEmpty(errorMessage) ? null : errorMessage);
|
||||
doc.put("request", parseOrRaw(requestJson));
|
||||
doc.put("response", parseOrRaw(responseJson));
|
||||
doc.put("updatedAt", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
doc.put("updatedAt", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now));
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<String> entity = new HttpEntity<String>(doc.toJSONString(), headers);
|
||||
@@ -82,7 +86,12 @@ public class EsBillSearchStore implements IBillSearchStore
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return getByDocId(EsLogType.docId(logType, bizId));
|
||||
BillSearchPage page = search(logType, bizId, null, 1, 1);
|
||||
if (page.getRows() == null || page.getRows().isEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return page.getRows().get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,7 +128,7 @@ public class EsBillSearchStore implements IBillSearchStore
|
||||
}
|
||||
|
||||
@Override
|
||||
public BillSearchPage search(String logType, String bizId, int pageNum, int pageSize)
|
||||
public BillSearchPage search(String logType, String bizId, String status, int pageNum, int pageSize)
|
||||
{
|
||||
BillSearchPage page = new BillSearchPage();
|
||||
if (pageNum < 1)
|
||||
@@ -143,7 +152,7 @@ public class EsBillSearchStore implements IBillSearchStore
|
||||
sortItem.put("updatedAt.keyword", sortOpt);
|
||||
sort.add(sortItem);
|
||||
body.put("sort", sort);
|
||||
body.put("query", buildQuery(logType, bizId));
|
||||
body.put("query", buildQuery(logType, bizId, status));
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
HttpEntity<String> entity = new HttpEntity<String>(body.toJSONString(), headers);
|
||||
@@ -210,14 +219,18 @@ public class EsBillSearchStore implements IBillSearchStore
|
||||
snap.setRequestJson(toJsonString(source.get("request")));
|
||||
snap.setResponseJson(toJsonString(source.get("response")));
|
||||
snap.setUpdatedAt(source.getString("updatedAt"));
|
||||
String status = source.getString("status");
|
||||
snap.setStatus(StringUtils.isEmpty(status) ? EsBizLogSupport.STATUS_SUCCESS : status);
|
||||
snap.setErrorMessage(source.getString("error"));
|
||||
return snap;
|
||||
}
|
||||
|
||||
private JSONObject buildQuery(String logType, String bizId)
|
||||
private JSONObject buildQuery(String logType, String bizId, String status)
|
||||
{
|
||||
JSONArray filters = new JSONArray();
|
||||
addTerm(filters, "logType", logType);
|
||||
addWildcard(filters, "bizId", bizId);
|
||||
addTerm(filters, "status", status);
|
||||
if (filters.isEmpty())
|
||||
{
|
||||
JSONObject matchAll = new JSONObject();
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.ruoyi.price.search;
|
||||
|
||||
import java.util.UUID;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.sign.Md5Utils;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteRequest;
|
||||
|
||||
/** Helpers for ES business logs (success / fail). */
|
||||
public final class EsBizLogSupport
|
||||
{
|
||||
public static final String STATUS_SUCCESS = "SUCCESS";
|
||||
public static final String STATUS_FAIL = "FAIL";
|
||||
|
||||
private static final int ERROR_MAX = 2000;
|
||||
|
||||
private EsBizLogSupport()
|
||||
{
|
||||
}
|
||||
|
||||
public static String requestJson(Object request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
JSONObject obj = JSON.parseObject(JSON.toJSONString(request));
|
||||
if (obj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
obj.remove("apiCode");
|
||||
return obj.toJSONString();
|
||||
}
|
||||
|
||||
public static String failResponseJson(String errorMessage)
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
obj.put("success", Boolean.FALSE);
|
||||
obj.put("msg", errorMessage);
|
||||
return obj.toJSONString();
|
||||
}
|
||||
|
||||
public static String errorText(Throwable e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return "UNKNOWN_ERROR";
|
||||
}
|
||||
String msg = e.getMessage();
|
||||
if (StringUtils.isEmpty(msg))
|
||||
{
|
||||
msg = e.getClass().getSimpleName();
|
||||
}
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null && StringUtils.isNotEmpty(cause.getMessage())
|
||||
&& (msg == null || !msg.contains(cause.getMessage())))
|
||||
{
|
||||
msg = msg + " | " + cause.getMessage();
|
||||
}
|
||||
return cut(msg);
|
||||
}
|
||||
|
||||
public static String cut(String msg)
|
||||
{
|
||||
if (msg == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
String text = msg.trim();
|
||||
if (text.length() > ERROR_MAX)
|
||||
{
|
||||
return text.substring(0, ERROR_MAX);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public static String billBizId(TmsPriceBillRequest request)
|
||||
{
|
||||
if (request != null && StringUtils.isNotEmpty(request.getOrderNo()))
|
||||
{
|
||||
return request.getOrderNo().trim();
|
||||
}
|
||||
return "FAIL-" + UUID.randomUUID();
|
||||
}
|
||||
|
||||
public static String billFailBizId(TmsPriceBillRequest request)
|
||||
{
|
||||
return billBizId(request);
|
||||
}
|
||||
|
||||
public static String quoteFailBizId(TmsPriceQuoteRequest request)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
return "FAIL-" + UUID.randomUUID();
|
||||
}
|
||||
String raw = nvl(request.getCustomerCode()) + "|" + nvl(request.getCustomerId()) + "|"
|
||||
+ nvl(request.getProductCode()) + "|" + nvl(request.getCountryCode()) + "|"
|
||||
+ nvl(request.getCountryName()) + "|" + nvl(request.getWeight()) + "|"
|
||||
+ nvl(request.getBizDate());
|
||||
return "FAIL-" + Md5Utils.hash(raw);
|
||||
}
|
||||
|
||||
public static void saveFail(IBillSearchStore store, String logType, String bizId, Object request, Throwable e)
|
||||
{
|
||||
saveFail(store, logType, bizId, request, errorText(e));
|
||||
}
|
||||
|
||||
public static void saveFail(IBillSearchStore store, String logType, String bizId, Object request, String errorMessage)
|
||||
{
|
||||
if (store == null || StringUtils.isEmpty(logType) || StringUtils.isEmpty(bizId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
String msg = cut(errorMessage);
|
||||
store.save(logType, bizId, requestJson(request), failResponseJson(msg), STATUS_FAIL, msg);
|
||||
}
|
||||
|
||||
private static String nvl(Object value)
|
||||
{
|
||||
return value == null ? "" : String.valueOf(value).trim();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.ruoyi.price.search;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/** Common ES business-log types. */
|
||||
public final class EsLogType
|
||||
{
|
||||
@@ -10,10 +13,23 @@ public final class EsLogType
|
||||
{
|
||||
}
|
||||
|
||||
/** One document per bizId + write time. */
|
||||
public static String docId(String logType, String bizId)
|
||||
{
|
||||
return docId(logType, bizId, new Date());
|
||||
}
|
||||
|
||||
public static String docId(String logType, String bizId, Date at)
|
||||
{
|
||||
String type = logType == null ? "" : logType.trim();
|
||||
String id = bizId == null ? "" : bizId.trim();
|
||||
return type + "_" + id;
|
||||
Date time = at == null ? new Date() : at;
|
||||
String ts = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(time);
|
||||
String uniq = Long.toHexString(System.nanoTime());
|
||||
if (uniq.length() > 6)
|
||||
{
|
||||
uniq = uniq.substring(uniq.length() - 6);
|
||||
}
|
||||
return type + "_" + id + "_" + ts + "_" + uniq;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,16 @@ package com.ruoyi.price.search;
|
||||
*/
|
||||
public interface IBillSearchStore
|
||||
{
|
||||
void save(String logType, String bizId, String requestJson, String responseJson);
|
||||
default void save(String logType, String bizId, String requestJson, String responseJson)
|
||||
{
|
||||
save(logType, bizId, requestJson, responseJson, EsBizLogSupport.STATUS_SUCCESS, null);
|
||||
}
|
||||
|
||||
void save(String logType, String bizId, String requestJson, String responseJson, String status, String errorMessage);
|
||||
|
||||
BillSyncSnapshot get(String logType, String bizId);
|
||||
|
||||
BillSyncSnapshot getByDocId(String docId);
|
||||
|
||||
BillSearchPage search(String logType, String bizId, int pageNum, int pageSize);
|
||||
BillSearchPage search(String logType, String bizId, String status, int pageNum, int pageSize);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ package com.ruoyi.price.search;
|
||||
public class NoopBillSearchStore implements IBillSearchStore
|
||||
{
|
||||
@Override
|
||||
public void save(String logType, String bizId, String requestJson, String responseJson)
|
||||
public void save(String logType, String bizId, String requestJson, String responseJson, String status,
|
||||
String errorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,7 +24,7 @@ public class NoopBillSearchStore implements IBillSearchStore
|
||||
}
|
||||
|
||||
@Override
|
||||
public BillSearchPage search(String logType, String bizId, int pageNum, int pageSize)
|
||||
public BillSearchPage search(String logType, String bizId, String status, int pageNum, int pageSize)
|
||||
{
|
||||
return new BillSearchPage();
|
||||
}
|
||||
|
||||
+19
-77
@@ -23,7 +23,7 @@ import com.ruoyi.price.domain.vo.TmsPriceQuoteFeeLine;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.ruoyi.price.mapper.PrcBillFeeMapper;
|
||||
import com.ruoyi.price.mapper.PrcBillMapper;
|
||||
import com.ruoyi.price.search.BillSyncSnapshot;
|
||||
import com.ruoyi.price.search.EsBizLogSupport;
|
||||
import com.ruoyi.price.search.EsLogType;
|
||||
import com.ruoyi.price.search.IBillSearchStore;
|
||||
import com.ruoyi.price.service.IPrcBillService;
|
||||
@@ -48,20 +48,28 @@ public class PrcBillServiceImpl implements IPrcBillService
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public TmsPriceQuoteResult bill(TmsPriceBillRequest request)
|
||||
{
|
||||
if (request == null || StringUtils.isEmpty(request.getOrderNo()))
|
||||
try
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.orderNoRequired"));
|
||||
if (request == null || StringUtils.isEmpty(request.getOrderNo()))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.orderNoRequired"));
|
||||
}
|
||||
request.setOrderNo(request.getOrderNo().trim());
|
||||
if (StringUtils.isEmpty(request.getBizDate()))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired"));
|
||||
}
|
||||
Date bizDate = resolveBizDate(request.getBizDate());
|
||||
BigDecimal weight = request.getWeight();
|
||||
TmsPriceQuoteResult result = tmsPriceQuoteService.calculate(request);
|
||||
persistBill(request, weight, bizDate, result);
|
||||
return result;
|
||||
}
|
||||
request.setOrderNo(request.getOrderNo().trim());
|
||||
if (StringUtils.isEmpty(request.getBizDate()))
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired"));
|
||||
EsBizLogSupport.saveFail(billSearchStore, EsLogType.BILL, EsBizLogSupport.billFailBizId(request), request, e);
|
||||
throw e;
|
||||
}
|
||||
Date bizDate = resolveBizDate(request.getBizDate());
|
||||
BigDecimal weight = request.getWeight();
|
||||
TmsPriceQuoteResult result = tmsPriceQuoteService.calculate(request);
|
||||
persistBill(request, weight, bizDate, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -261,31 +269,9 @@ public class PrcBillServiceImpl implements IPrcBillService
|
||||
}
|
||||
}
|
||||
r.setFeeDetails(lines);
|
||||
fillSnapshotFromSearch(r, bill);
|
||||
return r;
|
||||
}
|
||||
|
||||
private void fillSnapshotFromSearch(TmsPriceQuoteResult r, PrcBill bill)
|
||||
{
|
||||
BillSyncSnapshot snap = billSearchStore.get(EsLogType.BILL, bill.getOrderNo());
|
||||
if (snap != null && StringUtils.isNotEmpty(snap.getRequestJson()))
|
||||
{
|
||||
r.setRequestJson(snap.getRequestJson());
|
||||
}
|
||||
else
|
||||
{
|
||||
r.setRequestJson(rebuildRequestJson(bill));
|
||||
}
|
||||
if (snap != null && StringUtils.isNotEmpty(snap.getResponseJson()))
|
||||
{
|
||||
r.setResponseJson(snap.getResponseJson());
|
||||
}
|
||||
else
|
||||
{
|
||||
r.setResponseJson(toResponseJson(r));
|
||||
}
|
||||
}
|
||||
|
||||
private void fillResultOrder(TmsPriceQuoteResult r, PrcBill bill)
|
||||
{
|
||||
r.setTrackingNo(bill.getTrackingNo());
|
||||
@@ -328,42 +314,6 @@ public class PrcBillServiceImpl implements IPrcBillService
|
||||
return obj.toJSONString();
|
||||
}
|
||||
|
||||
private String rebuildRequestJson(PrcBill bill)
|
||||
{
|
||||
JSONObject obj = new JSONObject();
|
||||
putIfNotNull(obj, "orderNo", bill.getOrderNo());
|
||||
putIfNotNull(obj, "trackingNo", bill.getTrackingNo());
|
||||
putIfNotNull(obj, "customerId", bill.getCustomerId());
|
||||
putIfNotNull(obj, "customerCode", bill.getCustomerCode());
|
||||
putIfNotNull(obj, "customerName", bill.getCustomerName());
|
||||
putIfNotNull(obj, "productCode", bill.getProductCode());
|
||||
putIfNotNull(obj, "countryCode", bill.getCountryCode());
|
||||
putIfNotNull(obj, "countryName", bill.getCountryName());
|
||||
putIfNotNull(obj, "weight", bill.getWeight());
|
||||
if (bill.getBizDate() != null)
|
||||
{
|
||||
obj.put("bizDate", new SimpleDateFormat("yyyy-MM-dd").format(bill.getBizDate()));
|
||||
}
|
||||
putIfNotNull(obj, "tmsId", bill.getTmsId());
|
||||
putIfNotNull(obj, "pieces", bill.getPieces());
|
||||
putIfNotNull(obj, "actualWeight", bill.getActualWeight());
|
||||
putIfNotNull(obj, "volume", bill.getVolume());
|
||||
putIfNotNull(obj, "volumeWeight", bill.getVolumeWeight());
|
||||
putIfNotNull(obj, "pkgLength", bill.getPkgLength());
|
||||
putIfNotNull(obj, "pkgWidth", bill.getPkgWidth());
|
||||
putIfNotNull(obj, "pkgHeight", bill.getPkgHeight());
|
||||
putIfNotNull(obj, "shipperName", bill.getShipperName());
|
||||
putIfNotNull(obj, "consigneeName", bill.getConsigneeName());
|
||||
putIfNotNull(obj, "destPostcode", bill.getDestPostcode());
|
||||
putIfNotNull(obj, "warehouseCode", bill.getWarehouseCode());
|
||||
if (bill.getOrderTime() != null)
|
||||
{
|
||||
obj.put("orderTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(bill.getOrderTime()));
|
||||
}
|
||||
putIfNotNull(obj, "orderRemark", bill.getOrderRemark());
|
||||
return obj.toJSONString();
|
||||
}
|
||||
|
||||
private JSONObject parseJsonObject(String json)
|
||||
{
|
||||
if (StringUtils.isEmpty(json))
|
||||
@@ -380,14 +330,6 @@ public class PrcBillServiceImpl implements IPrcBillService
|
||||
}
|
||||
}
|
||||
|
||||
private void putIfNotNull(JSONObject obj, String key, Object value)
|
||||
{
|
||||
if (value != null && !(value instanceof String && ((String) value).isEmpty()))
|
||||
{
|
||||
obj.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
private Date resolveBizDate(String bizDate)
|
||||
{
|
||||
if (StringUtils.isEmpty(bizDate))
|
||||
|
||||
+15
@@ -39,6 +39,7 @@ import com.ruoyi.price.mapper.PrcPriceSetMapper;
|
||||
import com.ruoyi.price.mapper.PrcQuoteFeeMapper;
|
||||
import com.ruoyi.price.mapper.PrcQuoteMapper;
|
||||
import com.ruoyi.price.mapper.PrcSurchargeRelMapper;
|
||||
import com.ruoyi.price.search.EsBizLogSupport;
|
||||
import com.ruoyi.price.search.EsLogType;
|
||||
import com.ruoyi.price.search.IBillSearchStore;
|
||||
import com.ruoyi.price.service.ITmsPriceQuoteService;
|
||||
@@ -92,6 +93,20 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public TmsPriceQuoteResult quote(TmsPriceQuoteRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
return quoteInternal(request);
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
{
|
||||
EsBizLogSupport.saveFail(billSearchStore, EsLogType.QUOTE, EsBizLogSupport.quoteFailBizId(request),
|
||||
request, e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private TmsPriceQuoteResult quoteInternal(TmsPriceQuoteRequest request)
|
||||
{
|
||||
validateRequest(request);
|
||||
Date bizDate = resolveBizDate(request.getBizDate());
|
||||
|
||||
Reference in New Issue
Block a user