Browse Source

2025-11-05

接口日志管理
master
fengyuan_yang 8 months ago
parent
commit
d38217b31c
  1. 25
      src/main/java/com/gaotao/config/RestTemplateConfig.java
  2. 11
      src/main/java/com/gaotao/modules/sys/controller/InterfaceLogController.java
  3. 21
      src/main/java/com/gaotao/modules/sys/dao/ApiInterfaceDao.java
  4. 20
      src/main/java/com/gaotao/modules/sys/dao/InterfaceLogDao.java
  5. 41
      src/main/java/com/gaotao/modules/sys/entity/ApiInterfaceEntity.java
  6. 5
      src/main/java/com/gaotao/modules/sys/service/InterfaceLogService.java
  7. 289
      src/main/java/com/gaotao/modules/sys/service/impl/InterfaceLogServiceImpl.java
  8. 25
      src/main/resources/mapper/sys/ApiInterfaceDao.xml
  9. 48
      src/main/resources/mapper/sys/InterfaceLogDao.xml

25
src/main/java/com/gaotao/config/RestTemplateConfig.java

@ -0,0 +1,25 @@
package com.gaotao.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
/**
* RestTemplate配置
*/
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
// 设置连接超时时间毫秒
factory.setConnectTimeout(30000);
// 设置读取超时时间毫秒
factory.setReadTimeout(60000);
return new RestTemplate(factory);
}
}

11
src/main/java/com/gaotao/modules/sys/controller/InterfaceLogController.java

@ -68,6 +68,17 @@ public class InterfaceLogController {
return interfaceLogService.retryBatch(ids);
}
/**
* 批量手动重试接口
*/
@PostMapping("/retryInterface")
public R retryInterface(@RequestBody Map<String, Object> params) {
@SuppressWarnings("unchecked")
java.util.List<Map<String, Object>> retryList = (java.util.List<Map<String, Object>>) params.get("retryList");
return interfaceLogService.batchRetryInterface(retryList);
}
}

21
src/main/java/com/gaotao/modules/sys/dao/ApiInterfaceDao.java

@ -0,0 +1,21 @@
package com.gaotao.modules.sys.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gaotao.modules.sys.entity.ApiInterfaceEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 接口配置Dao
*/
@Mapper
public interface ApiInterfaceDao extends BaseMapper<ApiInterfaceEntity> {
/**
* 根据sitebuNo和interfaceName查询接口配置
*/
ApiInterfaceEntity getByInterfaceName(@Param("site") String site,
@Param("buNo") String buNo,
@Param("interfaceName") String interfaceName);
}

20
src/main/java/com/gaotao/modules/sys/dao/InterfaceLogDao.java

@ -28,6 +28,26 @@ public interface InterfaceLogDao extends BaseMapper<ApiLogEntity> {
* 批量删除
*/
int deleteBatch(@Param("ids") Long[] ids);
/**
* 根据sitebuNorequestIdrequestGroupId查询api_log记录
*/
Map<String, Object> getApiLog(@Param("site") String site,
@Param("buNo") String buNo,
@Param("requestId") String requestId,
@Param("requestGroupId") Integer requestGroupId);
/**
* 更新接口重试信息
*/
int updateRetryInfo(@Param("site") String site,
@Param("buNo") String buNo,
@Param("requestId") String requestId,
@Param("requestGroupId") Integer requestGroupId,
@Param("statusCode") String statusCode,
@Param("message") String message,
@Param("lastResponseData") String lastResponseData,
@Param("retryCount") Integer retryCount);
}

41
src/main/java/com/gaotao/modules/sys/entity/ApiInterfaceEntity.java

@ -0,0 +1,41 @@
package com.gaotao.modules.sys.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* 接口配置表
*/
@Data
@TableName("api_Interface")
public class ApiInterfaceEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 站点
*/
private String site;
/**
* 业务单元编号
*/
private String buNo;
/**
* 接口名称
*/
private String interfaceName;
/**
* 接口IP
*/
private String interfaceIp;
/**
* 接口路径
*/
private String interfaceValue;
}

5
src/main/java/com/gaotao/modules/sys/service/InterfaceLogService.java

@ -29,6 +29,11 @@ public interface InterfaceLogService {
* 批量重试接口
*/
R retryBatch(Long[] ids);
/**
* 批量手动重试接口
*/
R batchRetryInterface(java.util.List<Map<String, Object>> retryList);
}

289
src/main/java/com/gaotao/modules/sys/service/impl/InterfaceLogServiceImpl.java

@ -1,16 +1,22 @@
package com.gaotao.modules.sys.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gaotao.common.utils.PageUtils;
import com.gaotao.common.utils.R;
import com.gaotao.modules.sys.dao.ApiInterfaceDao;
import com.gaotao.modules.sys.dao.ApiLogValuesDetailDao;
import com.gaotao.modules.sys.dao.ApiLogValuesHeadDao;
import com.gaotao.modules.sys.dao.InterfaceLogDao;
import com.gaotao.modules.sys.entity.ApiInterfaceEntity;
import com.gaotao.modules.sys.service.InterfaceLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import java.util.*;
@ -31,6 +37,12 @@ public class InterfaceLogServiceImpl implements InterfaceLogService {
@Autowired
private ApiLogValuesDetailDao apiLogValuesDetailDao;
@Autowired
private ApiInterfaceDao apiInterfaceDao;
@Autowired
private RestTemplate restTemplate;
@Override
public PageUtils queryPage(Map<String, Object> params) {
// 获取分页参数
@ -146,6 +158,283 @@ public class InterfaceLogServiceImpl implements InterfaceLogService {
return R.error("批量重试失败: " + e.getMessage());
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public R batchRetryInterface(List<Map<String, Object>> retryList) {
try {
if (retryList == null || retryList.isEmpty()) {
return R.error("请选择要重试的记录");
}
logger.info("批量手动重试接口开始,记录数: {}", retryList.size());
int successCount = 0;
int failureCount = 0;
int errorCount = 0;
List<Map<String, Object>> detailResults = new ArrayList<>();
// 遍历每个需要重试的记录
for (Map<String, Object> retryItem : retryList) {
String site = (String) retryItem.get("site");
String buNo = (String) retryItem.get("buNo");
String requestId = (String) retryItem.get("requestId");
Integer requestGroupId = retryItem.get("requestGroupId") != null ?
Integer.parseInt(retryItem.get("requestGroupId").toString()) : null;
String interfaceName = (String) retryItem.get("interfaceName");
Map<String, Object> detailResult = new LinkedHashMap<>();
detailResult.put("interfaceName", interfaceName);
detailResult.put("requestId", requestId);
try {
// 调用单个重试方法
R result = retrySingleInterface(site, buNo, requestId, requestGroupId);
if (result.get("code").equals(0)) {
@SuppressWarnings("unchecked")
Map<String, Object> retryResult = (Map<String, Object>) result.get("result");
String flag = (String) retryResult.get("flag");
if ("success".equalsIgnoreCase(flag)) {
successCount++;
detailResult.put("status", "success");
detailResult.put("u8CCode", retryResult.get("u8CCode"));
detailResult.put("message", "调用成功");
} else {
failureCount++;
detailResult.put("status", "failure");
detailResult.put("message", retryResult.get("errMsg"));
}
} else {
failureCount++;
detailResult.put("status", "failure");
detailResult.put("message", result.get("msg"));
}
} catch (Exception e) {
errorCount++;
detailResult.put("status", "error");
detailResult.put("message", "重试异常: " + e.getMessage());
logger.error("重试接口异常,requestId: {}", requestId, e);
}
detailResults.add(detailResult);
}
logger.info("批量手动重试完成,成功: {}, 失败: {}, 异常: {}", successCount, failureCount, errorCount);
// 返回批量结果
Map<String, Object> batchResult = new HashMap<>();
batchResult.put("successCount", successCount);
batchResult.put("failureCount", failureCount);
batchResult.put("errorCount", errorCount);
batchResult.put("totalCount", retryList.size());
batchResult.put("details", detailResults);
return R.ok().put("result", batchResult);
} catch (Exception e) {
logger.error("批量手动重试接口失败", e);
return R.error("批量手动重试失败: " + e.getMessage());
}
}
/**
* 重试单个接口
*/
private R retrySingleInterface(String site, String buNo, String requestId, Integer requestGroupId) {
try {
logger.info("手动重试接口开始,site: {}, buNo: {}, requestId: {}, requestGroupId: {}",
site, buNo, requestId, requestGroupId);
// 1. 查询api_log记录
Map<String, Object> apiLog = interfaceLogDao.getApiLog(site, buNo, requestId, requestGroupId);
if (apiLog == null) {
logger.error("未找到接口日志记录");
return R.error("未找到接口日志记录");
}
String interfaceName = (String) apiLog.get("interfaceName");
Integer retryCount = apiLog.get("retryCount") != null ? (Integer) apiLog.get("retryCount") : 0;
logger.info("查询到接口名称: {}, 当前重试次数: {}", interfaceName, retryCount);
// 2. 查询api_Interface获取接口IP和路径
ApiInterfaceEntity apiInterface = apiInterfaceDao.getByInterfaceName(site, buNo, interfaceName);
if (apiInterface == null) {
logger.error("未找到接口配置,interfaceName: {}", interfaceName);
return R.error("未找到接口配置: " + interfaceName);
}
String interfaceUrl = "http://" + apiInterface.getInterfaceIp() + apiInterface.getInterfaceValue();
logger.info("接口URL: {}", interfaceUrl);
// 3. 查询api_log_values_head主表数据
Map<String, Object> headData = apiLogValuesHeadDao.queryHead(site, buNo, requestId, requestGroupId);
// 4. 查询api_log_values_detail明细数据
List<Map<String, Object>> detailList = apiLogValuesDetailDao.queryDetailList(site, buNo, requestId, requestGroupId);
// 5. 构造JSON请求体
Map<String, Object> requestBody = new LinkedHashMap<>();
// 5.1 处理主表数据orderref1-20
if (headData != null) {
for (int i = 1; i <= 20; i++) {
String key = "orderref" + i;
Object value = headData.get(key);
if (value != null && !value.toString().trim().isEmpty()) {
// 根据字段位置映射到实际的字段名
String fieldName = getFieldName(i, true);
requestBody.put(fieldName, value);
}
}
}
// 5.2 处理明细数据
if (detailList != null && !detailList.isEmpty()) {
List<Map<String, Object>> detailResultList = new ArrayList<>();
for (Map<String, Object> detail : detailList) {
Map<String, Object> detailItem = new LinkedHashMap<>();
for (int i = 1; i <= 20; i++) {
String key = "orderref" + i;
Object value = detail.get(key);
if (value != null && !value.toString().trim().isEmpty()) {
// 根据字段位置映射到实际的字段名
String fieldName = getFieldName(i, false);
detailItem.put(fieldName, value);
}
}
if (!detailItem.isEmpty()) {
detailResultList.add(detailItem);
}
}
if (!detailResultList.isEmpty()) {
requestBody.put("DetailList", detailResultList);
}
}
logger.info("构造的请求体: {}", JSON.toJSONString(requestBody));
// 6. 调用外部接口
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> requestEntity = new HttpEntity<>(JSON.toJSONString(requestBody), headers);
String statusCode = "ERROR";
String message = "";
String lastResponseData = "";
try {
ResponseEntity<String> response = restTemplate.exchange(
interfaceUrl,
HttpMethod.POST,
requestEntity,
String.class
);
lastResponseData = response.getBody();
logger.info("接口返回: {}", lastResponseData);
// 7. 解析返回结果
JSONObject responseJson = JSON.parseObject(lastResponseData);
String flag = responseJson.getString("Flag");
if ("success".equalsIgnoreCase(flag)) {
statusCode = "SUCCESS";
message = "接口调用成功";
String u8CCode = responseJson.getString("U8CCode");
if (u8CCode != null && !u8CCode.isEmpty()) {
message += ",U8单号: " + u8CCode;
}
} else {
statusCode = "FAILURE";
message = responseJson.getString("ErrMsg");
if (message == null || message.isEmpty()) {
message = "接口调用失败";
}
}
} catch (Exception e) {
statusCode = "ERROR";
message = "接口调用异常: " + e.getMessage();
lastResponseData = e.toString();
logger.error("调用外部接口异常", e);
}
// 8. 更新api_log记录
int updateCount = interfaceLogDao.updateRetryInfo(
site, buNo, requestId, requestGroupId,
statusCode, message, lastResponseData, retryCount + 1
);
logger.info("更新接口日志记录,更新条数: {}", updateCount);
// 9. 返回结果
Map<String, Object> result = new HashMap<>();
result.put("flag", "success".equalsIgnoreCase(statusCode) ? "success" : "failure");
result.put("u8CCode", "");
result.put("errMsg", message);
if (lastResponseData != null && !lastResponseData.isEmpty()) {
try {
JSONObject responseJson = JSON.parseObject(lastResponseData);
if (responseJson.containsKey("U8CCode")) {
result.put("u8CCode", responseJson.getString("U8CCode"));
}
} catch (Exception ignored) {
}
}
return R.ok().put("result", result);
} catch (Exception e) {
logger.error("手动重试接口失败", e);
return R.error("手动重试失败: " + e.getMessage());
}
}
/**
* 根据字段位置获取实际的字段名
* 这个映射关系需要根据实际接口文档来配置
*/
private String getFieldName(int position, boolean isHead) {
if (isHead) {
// 主表字段映射
switch (position) {
case 1: return "MESCCode";
case 2: return "KdType";
case 3: return "DDate";
case 4: return "CRdCode";
case 5: return "CMemo";
case 6: return "CWhCode";
case 7: return "CCusOAddress";
case 8: return "CDepCode";
default: return "orderref" + position;
}
} else {
// 明细表字段映射
switch (position) {
case 1: return "MESIrowNo";
case 2: return "OutCode";
case 3: return "OutIrowNo";
case 4: return "CInvCode";
case 5: return "IQuantity";
case 6: return "CBatch";
case 7: return "CbMemo";
case 8: return "CWhCode";
case 9: return "OutMocode";
case 10: return "OutIrowNo_zj";
case 11: return "NumberOfCases";
default: return "orderref" + position;
}
}
}
}

25
src/main/resources/mapper/sys/ApiInterfaceDao.xml

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gaotao.modules.sys.dao.ApiInterfaceDao">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.gaotao.modules.sys.entity.ApiInterfaceEntity" id="apiInterfaceMap">
<result property="site" column="site"/>
<result property="buNo" column="bu_no"/>
<result property="interfaceName" column="interface_name"/>
<result property="interfaceIp" column="interface_IP"/>
<result property="interfaceValue" column="interface_value"/>
</resultMap>
<!-- 根据接口名称查询接口配置 -->
<select id="getByInterfaceName" resultMap="apiInterfaceMap">
SELECT site, bu_no, interface_name, interface_IP, interface_value
FROM api_Interface WITH(NOLOCK)
WHERE site = #{site}
AND bu_no = #{buNo}
AND interface_name = #{interfaceName}
</select>
</mapper>

48
src/main/resources/mapper/sys/InterfaceLogDao.xml

@ -114,6 +114,54 @@
</foreach>
</delete>
<!-- 查询单条api_log记录 -->
<select id="getApiLog" resultType="map">
SELECT
id,
site,
bu_no AS buNo,
request_id AS requestId,
interface_name AS interfaceName,
request_group_id AS requestGroupId,
re_document_no AS reDocumentNo,
re_document_type AS reDocumentType,
order_no AS orderNo,
seq_no AS seqNo,
status_code AS statusCode,
message,
request_data AS requestData,
source_system AS sourceSystem,
target_system AS targetSystem,
need_retry_flag AS needRetryFlag,
retry_count AS retryCount,
max_retry_count AS maxRetryCount,
retry_interval AS retryInterval,
next_retry_time AS nextRetryTime,
last_retry_time AS lastRetryTime,
last_response_data AS lastResponseData,
created_by AS createdBy,
created_date AS createdDate
FROM api_log WITH(NOLOCK)
WHERE site = #{site}
AND bu_no = #{buNo}
AND request_id = #{requestId}
AND request_group_id = #{requestGroupId}
</select>
<!-- 更新接口重试信息 -->
<update id="updateRetryInfo">
UPDATE api_log
SET status_code = #{statusCode},
message = #{message},
last_response_data = #{lastResponseData},
retry_count = #{retryCount},
last_retry_time = GETDATE()
WHERE site = #{site}
AND bu_no = #{buNo}
AND request_id = #{requestId}
AND request_group_id = #{requestGroupId}
</update>
</mapper>
Loading…
Cancel
Save