|
@@ -0,0 +1,242 @@
|
|
|
|
|
+package com.fs.comm.service;
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.fs.comm.auth.CommSession;
|
|
|
|
|
+import com.fs.comm.context.CommAuthContext;
|
|
|
|
|
+import com.fs.comm.domain.CommGatewayApiLog;
|
|
|
|
|
+import com.fs.comm.dto.CommCallSendRequest;
|
|
|
|
|
+import com.fs.comm.dto.CommSmsSendRequest;
|
|
|
|
|
+import com.fs.comm.model.CommGatewayBillingQuote;
|
|
|
|
|
+import com.fs.common.exception.ServiceException;
|
|
|
|
|
+import com.fs.common.utils.ServletUtils;
|
|
|
|
|
+import com.fs.common.utils.StringUtils;
|
|
|
|
|
+import com.fs.common.utils.ip.IpUtils;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
+
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 通讯网关 API 调用日志记录(主库)
|
|
|
|
|
+ */
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Service
|
|
|
|
|
+public class CommGatewayApiLogRecorder {
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private ICommGatewayApiLogService commGatewayApiLogService;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private CommGatewayBillingService commGatewayBillingService;
|
|
|
|
|
+
|
|
|
|
|
+ public void recordCallAttempt(Long companyId, Long tenantId, CommCallSendRequest request,
|
|
|
|
|
+ CommApiRecordResult result, String calleePhone, String callerPhone,
|
|
|
|
|
+ Long gatewayId, long startMs) {
|
|
|
|
|
+ record(buildBaseLog(companyId, tenantId, CommGatewayApiLog.API_TYPE_CALL, "/comm/call/send",
|
|
|
|
|
+ request, result, calleePhone, callerPhone, gatewayId, startMs));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void recordSmsAttempt(Long companyId, Long tenantId, CommSmsSendRequest request,
|
|
|
|
|
+ CommApiRecordResult result, String calleePhone, String callerPhone,
|
|
|
|
|
+ Long gatewayId, long startMs) {
|
|
|
|
|
+ record(buildBaseLog(companyId, tenantId, CommGatewayApiLog.API_TYPE_SMS, "/comm/sms/send",
|
|
|
|
|
+ request, result, calleePhone, callerPhone, gatewayId, startMs));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private CommGatewayApiLog buildBaseLog(Long companyId, Long tenantId, String apiType, String apiPath,
|
|
|
|
|
+ Object request, CommApiRecordResult result, String calleePhone,
|
|
|
|
|
+ String callerPhone, Long gatewayId, long startMs) {
|
|
|
|
|
+ CommSession session = CommAuthContext.get();
|
|
|
|
|
+ CommGatewayApiLog logEntity = new CommGatewayApiLog();
|
|
|
|
|
+ logEntity.setTenantId(tenantId);
|
|
|
|
|
+ logEntity.setCompanyId(companyId);
|
|
|
|
|
+ if (session != null) {
|
|
|
|
|
+ logEntity.setCompanyUserId(session.getCompanyUserId());
|
|
|
|
|
+ logEntity.setCallerAccount(session.getAccount());
|
|
|
|
|
+ logEntity.setAuthScope(session.getScope());
|
|
|
|
|
+ }
|
|
|
|
|
+ fillCompanyUserIdFromRequest(logEntity, request);
|
|
|
|
|
+ logEntity.setApiType(apiType);
|
|
|
|
|
+ logEntity.setApiPath(apiPath);
|
|
|
|
|
+ logEntity.setRequestBody(JSON.toJSONString(request));
|
|
|
|
|
+ logEntity.setDurationMs((int) (System.currentTimeMillis() - startMs));
|
|
|
|
|
+ try {
|
|
|
|
|
+ logEntity.setClientIp(IpUtils.getIpAddr(ServletUtils.getRequest()));
|
|
|
|
|
+ } catch (Exception ignored) {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (result != null) {
|
|
|
|
|
+ logEntity.setResponseBody(result.getResponseBody());
|
|
|
|
|
+ logEntity.setResultCode(result.getResultCode());
|
|
|
|
|
+ logEntity.setResultMsg(result.getResultMsg());
|
|
|
|
|
+ logEntity.setSuccess(result.isSuccess() ? 1 : 0);
|
|
|
|
|
+ logEntity.setLimitHit(result.isLimitHit() ? 1 : 0);
|
|
|
|
|
+ logEntity.setLimitReason(result.getLimitReason());
|
|
|
|
|
+ logEntity.setCalleePhone(result.getCalleePhone());
|
|
|
|
|
+ logEntity.setCallerPhone(result.getCallerPhone());
|
|
|
|
|
+ logEntity.setGatewayId(result.getGatewayId());
|
|
|
|
|
+ applyBilling(logEntity, tenantId, apiType, result.isSuccess());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ applyFallbackFields(logEntity, calleePhone, callerPhone, gatewayId, "调用未正常返回结果");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (StringUtils.isBlank(logEntity.getCalleePhone()) && StringUtils.isNotBlank(calleePhone)) {
|
|
|
|
|
+ logEntity.setCalleePhone(calleePhone);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (StringUtils.isBlank(logEntity.getCallerPhone()) && StringUtils.isNotBlank(callerPhone)) {
|
|
|
|
|
+ logEntity.setCallerPhone(callerPhone);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (logEntity.getGatewayId() == null && gatewayId != null) {
|
|
|
|
|
+ logEntity.setGatewayId(gatewayId);
|
|
|
|
|
+ }
|
|
|
|
|
+ return logEntity;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void applyBilling(CommGatewayApiLog logEntity, Long tenantId, String apiType, boolean success) {
|
|
|
|
|
+ logEntity.setBillingUnit(apiType);
|
|
|
|
|
+ if (!success) {
|
|
|
|
|
+ logEntity.setBillingAmount(BigDecimal.ZERO);
|
|
|
|
|
+ logEntity.setCostPrice(BigDecimal.ZERO);
|
|
|
|
|
+ logEntity.setCalcPrice(BigDecimal.ZERO);
|
|
|
|
|
+ logEntity.setBillingQuantity(0);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ CommGatewayBillingQuote quote = commGatewayBillingService.resolveQuote(tenantId, apiType, 1);
|
|
|
|
|
+ logEntity.setCostPrice(quote.getCostPrice());
|
|
|
|
|
+ logEntity.setCalcPrice(quote.getCalcPrice());
|
|
|
|
|
+ logEntity.setBillingQuantity(quote.getBillingQuantity());
|
|
|
|
|
+ logEntity.setBillingAmount(quote.getBillingAmount());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fillCompanyUserIdFromRequest(CommGatewayApiLog logEntity, Object request) {
|
|
|
|
|
+ if (logEntity.getCompanyUserId() != null || request == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (request instanceof CommCallSendRequest) {
|
|
|
|
|
+ logEntity.setCompanyUserId(((CommCallSendRequest) request).getCompanyUserId());
|
|
|
|
|
+ } else if (request instanceof CommSmsSendRequest) {
|
|
|
|
|
+ logEntity.setCompanyUserId(((CommSmsSendRequest) request).getCompanyUserId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void applyFallbackFields(CommGatewayApiLog logEntity, String calleePhone, String callerPhone,
|
|
|
|
|
+ Long gatewayId, String message) {
|
|
|
|
|
+ logEntity.setCalleePhone(calleePhone);
|
|
|
|
|
+ logEntity.setCallerPhone(callerPhone);
|
|
|
|
|
+ logEntity.setGatewayId(gatewayId);
|
|
|
|
|
+ logEntity.setSuccess(0);
|
|
|
|
|
+ logEntity.setLimitHit(0);
|
|
|
|
|
+ logEntity.setResultCode(500);
|
|
|
|
|
+ logEntity.setResultMsg(message);
|
|
|
|
|
+ logEntity.setBillingAmount(BigDecimal.ZERO);
|
|
|
|
|
+ logEntity.setCostPrice(BigDecimal.ZERO);
|
|
|
|
|
+ logEntity.setCalcPrice(BigDecimal.ZERO);
|
|
|
|
|
+ logEntity.setBillingQuantity(0);
|
|
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
|
|
+ body.put("code", 500);
|
|
|
|
|
+ body.put("msg", message);
|
|
|
|
|
+ logEntity.setResponseBody(JSON.toJSONString(body));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void record(CommGatewayApiLog logEntity) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ commGatewayApiLogService.saveLog(logEntity);
|
|
|
|
|
+ } catch (Exception ex) {
|
|
|
|
|
+ log.error("写入通讯网关调用日志失败", ex);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public CommApiRecordResult buildLimitFailure(ServiceException ex, String calleePhone, String callerPhone, Long gatewayId) {
|
|
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
|
|
+ body.put("code", 500);
|
|
|
|
|
+ body.put("msg", ex.getMessage());
|
|
|
|
|
+ return CommApiRecordResult.builder()
|
|
|
|
|
+ .success(false)
|
|
|
|
|
+ .limitHit(true)
|
|
|
|
|
+ .limitReason(ex.getMessage())
|
|
|
|
|
+ .resultCode(500)
|
|
|
|
|
+ .resultMsg(ex.getMessage())
|
|
|
|
|
+ .responseBody(JSON.toJSONString(body))
|
|
|
|
|
+ .calleePhone(calleePhone)
|
|
|
|
|
+ .callerPhone(callerPhone)
|
|
|
|
|
+ .gatewayId(gatewayId)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public CommApiRecordResult buildSuccess(Object data, String calleePhone, String callerPhone, Long gatewayId) {
|
|
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
|
|
+ body.put("code", 200);
|
|
|
|
|
+ body.put("msg", "success");
|
|
|
|
|
+ body.put("data", data);
|
|
|
|
|
+ return CommApiRecordResult.builder()
|
|
|
|
|
+ .success(true)
|
|
|
|
|
+ .limitHit(false)
|
|
|
|
|
+ .resultCode(200)
|
|
|
|
|
+ .resultMsg("success")
|
|
|
|
|
+ .responseBody(JSON.toJSONString(body))
|
|
|
|
|
+ .calleePhone(calleePhone)
|
|
|
|
|
+ .callerPhone(callerPhone)
|
|
|
|
|
+ .gatewayId(gatewayId)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public CommApiRecordResult buildFailure(ServiceException ex, String calleePhone, String callerPhone, Long gatewayId) {
|
|
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
|
|
+ body.put("code", 500);
|
|
|
|
|
+ body.put("msg", ex.getMessage());
|
|
|
|
|
+ return CommApiRecordResult.builder()
|
|
|
|
|
+ .success(false)
|
|
|
|
|
+ .limitHit(false)
|
|
|
|
|
+ .resultCode(500)
|
|
|
|
|
+ .resultMsg(ex.getMessage())
|
|
|
|
|
+ .responseBody(JSON.toJSONString(body))
|
|
|
|
|
+ .calleePhone(calleePhone)
|
|
|
|
|
+ .callerPhone(callerPhone)
|
|
|
|
|
+ .gatewayId(gatewayId)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static class CommApiRecordResult {
|
|
|
|
|
+ private boolean success;
|
|
|
|
|
+ private boolean limitHit;
|
|
|
|
|
+ private Integer resultCode;
|
|
|
|
|
+ private String resultMsg;
|
|
|
|
|
+ private String responseBody;
|
|
|
|
|
+ private String limitReason;
|
|
|
|
|
+ private String calleePhone;
|
|
|
|
|
+ private String callerPhone;
|
|
|
|
|
+ private Long gatewayId;
|
|
|
|
|
+
|
|
|
|
|
+ public static CommApiRecordResultBuilder builder() {
|
|
|
|
|
+ return new CommApiRecordResultBuilder();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public boolean isSuccess() { return success; }
|
|
|
|
|
+ public boolean isLimitHit() { return limitHit; }
|
|
|
|
|
+ public Integer getResultCode() { return resultCode; }
|
|
|
|
|
+ public String getResultMsg() { return resultMsg; }
|
|
|
|
|
+ public String getResponseBody() { return responseBody; }
|
|
|
|
|
+ public String getLimitReason() { return limitReason; }
|
|
|
|
|
+ public String getCalleePhone() { return calleePhone; }
|
|
|
|
|
+ public String getCallerPhone() { return callerPhone; }
|
|
|
|
|
+ public Long getGatewayId() { return gatewayId; }
|
|
|
|
|
+
|
|
|
|
|
+ public static class CommApiRecordResultBuilder {
|
|
|
|
|
+ private final CommApiRecordResult target = new CommApiRecordResult();
|
|
|
|
|
+
|
|
|
|
|
+ public CommApiRecordResultBuilder success(boolean success) { target.success = success; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder limitHit(boolean limitHit) { target.limitHit = limitHit; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder resultCode(Integer resultCode) { target.resultCode = resultCode; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder resultMsg(String resultMsg) { target.resultMsg = resultMsg; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder responseBody(String responseBody) { target.responseBody = responseBody; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder limitReason(String limitReason) { target.limitReason = limitReason; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder calleePhone(String calleePhone) { target.calleePhone = calleePhone; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder callerPhone(String callerPhone) { target.callerPhone = callerPhone; return this; }
|
|
|
|
|
+ public CommApiRecordResultBuilder gatewayId(Long gatewayId) { target.gatewayId = gatewayId; return this; }
|
|
|
|
|
+ public CommApiRecordResult build() { return target; }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|