package com.xuqm.tenant.service; import com.fasterxml.jackson.databind.ObjectMapper; import com.xuqm.tenant.entity.OperationLogEntity; import com.xuqm.tenant.repository.OperationLogRepository; 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 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 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.setDetailJson(serialize(detail)); entity.setCreatedAt(LocalDateTime.now()); repository.save(entity); } public Page 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 serialize(Map detail) { try { Map payload = detail == null ? Map.of() : new LinkedHashMap<>(detail); return objectMapper.writeValueAsString(payload); } catch (Exception e) { return "{}"; } } }