package com.dsh.guns.modular.system.audit; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** 从 other 服务读取统一账号审计日志,不经公网网关暴露内部接口。 */ @Slf4j @Component public class AccountAuditLogReader { @Resource private DiscoveryClient discoveryClient; public AuditLogPage page(long current, long size, String userAccount, String operationType) { try { List instances = discoveryClient.getInstances("mb-cloud-other"); if (instances == null || instances.isEmpty()) return AuditLogPage.empty(); StringBuilder url = new StringBuilder(instances.get(0).getUri().toString()) .append("/internal/audit-logs?current=").append(current) .append("&size=").append(Math.min(size, 200)); appendQuery(url, "userAccount", userAccount); appendQuery(url, "operationType", operationType); HttpURLConnection connection = (HttpURLConnection) new URL(url.toString()).openConnection(); connection.setConnectTimeout(2000); connection.setReadTimeout(5000); connection.setRequestMethod("GET"); try (InputStream input = connection.getInputStream()) { JSONObject body = JSON.parseObject(new String(readAll(input), StandardCharsets.UTF_8)); JSONArray records = body.getJSONArray("records"); return new AuditLogPage(toRecords(records), body.getLongValue("total")); } finally { connection.disconnect(); } } catch (Exception e) { log.warn("读取账号审计日志失败", e); return AuditLogPage.empty(); } } private static void appendQuery(StringBuilder url, String name, String value) throws Exception { if (value != null && !value.trim().isEmpty()) { url.append('&').append(name).append('=').append(URLEncoder.encode(value.trim(), "UTF-8")); } } private static byte[] readAll(InputStream input) throws Exception { byte[] buffer = new byte[4096]; int length; java.io.ByteArrayOutputStream output = new java.io.ByteArrayOutputStream(); while ((length = input.read(buffer)) != -1) output.write(buffer, 0, length); return output.toByteArray(); } @SuppressWarnings("unchecked") private static List> toRecords(JSONArray records) { if (records == null || records.isEmpty()) return Collections.emptyList(); List> result = new ArrayList>(records.size()); for (Object record : records) { if (record instanceof Map) { result.add(new LinkedHashMap((Map) record)); } } return result; } public static class AuditLogPage { private final List> records; private final long total; AuditLogPage(List> records, long total) { this.records = records; this.total = total; } static AuditLogPage empty() { return new AuditLogPage(Collections.>emptyList(), 0); } public List> getRecords() { return records; } public long getTotal() { return total; } } }