酒店日志增强

This commit is contained in:
zjf committed 2026-11-08 00:14:52 +08:00
1 parent 2225e74650
commit 53f6c83b4f
3 files changed
+65 -7

No files matched your search

@@ -700,8 +700,9 @@ public class ShangyouHotelClient {
return ShangyouOrderCallResult.uncertain("取 Token 失败: " + e.getMessage(), null);
}
String url = props().resolveBizBaseUrl() + path;
log.info("shangyou order request path={} retried={} busyRound={} bodyKeys={}", path, retried, busyRound,
body.keySet());
// 完整业务体落日志(密码脱敏),便于与上游对「到底传了什么」
log.info("|上游订单请求|path={}|retried={}|busyRound={}|body={}|", path, retried, busyRound,
maskOrderBodyForLog(body));
try (HttpResponse response = HttpRequest.post(url)
.header("Authorization", "Bearer " + token)
.header("Accept", "*/*")
@@ -798,6 +799,26 @@ public class ShangyouHotelClient {
body.put("cardPassWord", props().getCardPassword());
}
/** 应用日志用:复制 body 并脱敏密码,避免明文进日志 */
private static String maskOrderBodyForLog(JSONObject body) {
if (body == null) {
return "null";
}
try {
JSONObject copy = JSON.parseObject(body.toJSONString());
if (copy.containsKey("cardPassWord")) {
copy.put("cardPassWord", "***");
}
if (copy.containsKey("cardPassword")) {
copy.put("cardPassword", "***");
}
return copy.toJSONString();
}
catch (Exception e) {
return String.valueOf(body.keySet());
}
}
private List<String> parseMemberLevels() {
if (StrUtil.isBlank(props().getMemberLevels())) {
return Collections.emptyList();
@@ -2784,7 +2784,9 @@ public class SmHotelOrderServiceImpl extends ServiceImpl<SmHotelOrderMapper, SmH
HotelUpstreamOrderGateway gateway = gatewayOpt.get();
long t0 = System.currentTimeMillis();
HotelUpstreamOrderResult query = gateway.queryByRequestNo(order.getChannelNo());
upstreamLogService.saveCall(order.getId(), gateway.channel(), "QUERY", query, order.getChannelNo(),
com.alibaba.fastjson.JSONObject queryReq = new com.alibaba.fastjson.JSONObject();
queryReq.put("requestNo", order.getChannelNo());
upstreamLogService.saveCall(order.getId(), gateway.channel(), "QUERY", query, queryReq.toJSONString(),
System.currentTimeMillis() - t0);
if (query.isUncertain() || (!query.isBizOk() && StrUtil.isBlank(query.orderId()))) {
@@ -3052,7 +3054,10 @@ public class SmHotelOrderServiceImpl extends ServiceImpl<SmHotelOrderMapper, SmH
HotelUpstreamOrderGateway gateway = gatewayOpt.get();
long t0 = System.currentTimeMillis();
HotelUpstreamOrderResult q = gateway.queryOrder(order.getPlatformNo(), order.getHotelCode());
upstreamLogService.saveCall(order.getId(), gateway.channel(), "QUERY", q, order.getPlatformNo(),
com.alibaba.fastjson.JSONObject qReq = new com.alibaba.fastjson.JSONObject();
qReq.put("orderId", order.getPlatformNo());
qReq.put("hotelId", order.getHotelCode());
upstreamLogService.saveCall(order.getId(), gateway.channel(), "QUERY", q, qReq.toJSONString(),
System.currentTimeMillis() - t0);
if (q.getContent() != null) {
applyBookStatus(order, q.getContent().getString("bookStatus"),
@@ -3699,8 +3704,12 @@ public class SmHotelOrderServiceImpl extends ServiceImpl<SmHotelOrderMapper, SmH
HotelUpstreamOrderGateway gateway = gatewayOpt.get();
long t0 = System.currentTimeMillis();
HotelUpstreamOrderResult call = gateway.cancelOrder(order.getPlatformNo(), order.getHotelCode());
com.alibaba.fastjson.JSONObject cancelReq = new com.alibaba.fastjson.JSONObject();
cancelReq.put("orderId", order.getPlatformNo());
cancelReq.put("hotelId", order.getHotelCode());
cancelReq.put("reason", reason);
upstreamLogService.saveCall(order.getId(), gateway.channel(), "CANCEL", call,
order.getPlatformNo(), System.currentTimeMillis() - t0);
cancelReq.toJSONString(), System.currentTimeMillis() - t0);
if (call.isUncertain()) {
return R.failed("上游取消不确定: " + call.getMessage());
}
@@ -1,6 +1,8 @@
package com.bsd.pjcloud.supermarket.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bsd.pjcloud.supermarket.entity.SmHotelOrderUpstreamLogEntity;
@@ -12,6 +14,7 @@ import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@Slf4j
@Service
@@ -19,7 +22,11 @@ public class SmHotelOrderUpstreamLogServiceImpl
extends ServiceImpl<SmHotelOrderUpstreamLogMapper, SmHotelOrderUpstreamLogEntity>
implements SmHotelOrderUpstreamLogService {
private static final int JSON_MAX = 8000;
/** 下单报文含 dailyPriceList,留足空间便于事后对账 */
private static final int JSON_MAX = 16000;
private static final Set<String> SECRET_KEYS = Set.of("cardPassWord", "cardPassword", "password", "secret",
"appSecret", "accessToken", "token");
@Override
public void saveCall(Long orderId, String channel, String action, HotelUpstreamOrderResult result, String reqJson,
@@ -53,7 +60,7 @@ public class SmHotelOrderUpstreamLogServiceImpl
row.setSuccess(success ? "1" : "0");
row.setBizCode(StrUtil.sub(bizCode, 0, 64));
row.setMessage(StrUtil.sub(message, 0, 500));
row.setReqJson(clip(reqJson));
row.setReqJson(clip(maskSecrets(reqJson)));
row.setRespJson(clip(respJson));
row.setCostMs(costMs);
baseMapper.insert(row);
@@ -73,6 +80,27 @@ public class SmHotelOrderUpstreamLogServiceImpl
.orderByAsc(SmHotelOrderUpstreamLogEntity::getCreateTime));
}
/** 落库前脱敏,避免 cardPassWord 等进流水 */
static String maskSecrets(String raw) {
if (StrUtil.isBlank(raw) || !StrUtil.startWith(raw.trim(), "{")) {
return raw;
}
try {
JSONObject obj = JSONUtil.parseObj(raw);
boolean changed = false;
for (String key : SECRET_KEYS) {
if (obj.containsKey(key) && obj.get(key) != null && StrUtil.isNotBlank(String.valueOf(obj.get(key)))) {
obj.set(key, "***");
changed = true;
}
}
return changed ? obj.toString() : raw;
}
catch (Exception e) {
return raw;
}
}
private static String clip(String s) {
if (s == null) {
return null;