XuqmGroup-Server/tenant-service/src/main/java/com/xuqm/tenant/service/OperationLogService.java

113 行
4.2 KiB
Java

package com.xuqm.tenant.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xuqm.tenant.entity.OperationLogEntity;
import com.xuqm.tenant.repository.OperationLogRepository;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
@Service
public class OperationLogService {
private final OperationLogRepository repository;
private final ObjectMapper objectMapper;
public OperationLogService(OperationLogRepository repository, ObjectMapper objectMapper) {
this.repository = repository;
this.objectMapper = objectMapper;
}
public void record(String tenantId,
String moduleType,
String resourceType,
String resourceId,
String action,
Map<String, Object> detail) {
record(tenantId, moduleType, resourceType, resourceId, action, null, detail);
}
public void record(String tenantId,
String moduleType,
String resourceType,
String resourceId,
String action,
String summary,
Map<String, Object> detail) {
OperationLogEntity entity = new OperationLogEntity();
entity.setId(UUID.randomUUID().toString());
entity.setTenantId(tenantId);
entity.setModuleType(moduleType);
entity.setResourceType(resourceType);
entity.setResourceId(resourceId);
entity.setAction(action);
entity.setOperator(currentOperator());
entity.setSummary(summary);
entity.setIpAddress(resolveClientIp());
entity.setDetailJson(serialize(detail));
entity.setCreatedAt(LocalDateTime.now());
repository.save(entity);
}
public Page<OperationLogEntity> list(String tenantId, String moduleType, int page, int size) {
int safePage = Math.max(page, 0);
int safeSize = Math.min(Math.max(size, 1), 200);
PageRequest pageable = PageRequest.of(safePage, safeSize);
if (moduleType == null || moduleType.isBlank()) {
return repository.findByTenantIdOrderByCreatedAtDesc(tenantId, pageable);
}
return repository.findByTenantIdAndModuleTypeOrderByCreatedAtDesc(
tenantId,
moduleType.trim().toUpperCase(),
pageable);
}
private String currentOperator() {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth == null || auth.getName() == null || auth.getName().isBlank()) {
return "system";
}
return auth.getName();
}
private String resolveClientIp() {
try {
ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attrs == null) return null;
HttpServletRequest request = attrs.getRequest();
String ip = request.getHeader("X-Forwarded-For");
if (ip != null && !ip.isBlank()) {
ip = ip.split(",")[0].trim();
}
if (ip == null || ip.isBlank()) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.isBlank()) {
ip = request.getRemoteAddr();
}
return ip;
} catch (Exception e) {
return null;
}
}
private String serialize(Map<String, Object> detail) {
try {
Map<String, Object> payload = detail == null ? Map.of() : new LinkedHashMap<>(detail);
return objectMapper.writeValueAsString(payload);
} catch (Exception e) {
return "{}";
}
}
}