StatisticsService.java 5.3 KB
package com.aigeo.statistics.service;

import com.aigeo.common.context.TenantContext;
import com.aigeo.statistics.dto.ActivitySummaryDTO;
import com.aigeo.statistics.dto.UsageSummaryDTO;
import com.aigeo.statistics.entity.CompanyUsageStat;
import com.aigeo.statistics.entity.UserActivityLog;
import com.aigeo.statistics.repository.CompanyUsageStatRepository;
import com.aigeo.statistics.repository.UserActivityLogRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 统计服务类
 *
 * @author AIGEO Team
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class StatisticsService {

    private final UserActivityLogRepository userActivityLogRepository;
    private final CompanyUsageStatRepository companyUsageStatRepository;

    /**
     * 获取公司活动统计摘要
     */
    public List<ActivitySummaryDTO> getActivitySummaryByCompanyId(Integer companyId, LocalDateTime startTime, LocalDateTime endTime) {
        return userActivityLogRepository.findActivitySummaryByCompanyId(companyId, startTime, endTime);
    }

    /**
     * 获取公司使用量统计摘要
     */
    public List<UsageSummaryDTO> getUsageSummaryByCompanyId(Integer companyId, LocalDate startDate, LocalDate endDate) {
        return companyUsageStatRepository.findUsageSummaryByCompanyId(companyId, startDate, endDate);
    }

    /**
     * 分页获取用户活动日志
     */
    public Page<UserActivityLog> getUserActivityLogs(Integer companyId, Pageable pageable) {
        return userActivityLogRepository.findByCompanyIdOrderByCreatedAtDesc(companyId, pageable);
    }

    /**
     * 根据活动类型获取统计
     */
    public Map<String, Long> getActivityCountByType(Integer companyId, LocalDateTime startTime, LocalDateTime endTime) {
        return userActivityLogRepository.countActivityByType(companyId, startTime, endTime);
    }

    /**
     * 记录用户活动
     */
    @Transactional
    public void recordUserActivity(Integer userId, String activityType, Map<String, Object> details, String ipAddress) {
        Integer companyId = TenantContext.getCurrentTenant();
        if (companyId == null) {
            log.warn("无法记录用户活动,租户上下文为空");
            return;
        }

        UserActivityLog activityLog = UserActivityLog.builder()
                .companyId(companyId)
                .userId(userId)
                .activityType(activityType)
                .activityDetails(details)
                .ipAddress(ipAddress)
                .createdAt(LocalDateTime.now())
                .build();

        userActivityLogRepository.save(activityLog);
        log.debug("记录用户活动: userId={}, type={}", userId, activityType);
    }

    /**
     * 更新或创建公司使用量统计
     */
    @Transactional
    public void updateCompanyUsageStat(Integer companyId, LocalDate statDate, 
                                     Integer articleCount, Long tokenUsage, Integer websiteCount) {
        Date statDateAsDate = Date.from(statDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Optional<CompanyUsageStat> existingStat = companyUsageStatRepository
                .findByCompanyIdAndStatDate(companyId, statDateAsDate);

        CompanyUsageStat stat;
        if (existingStat.isPresent()) {
            stat = existingStat.get();
            stat.setArticleCount(stat.getArticleCount() + articleCount);
            stat.setAiTokenUsage(stat.getAiTokenUsage() + tokenUsage);
            stat.setWebsiteCount(stat.getWebsiteCount() + websiteCount);
        } else {
            stat = CompanyUsageStat.builder()
                    .companyId(companyId)
                    .statDate(statDate)
                    .articleCount(articleCount)
                    .aiTokenUsage(tokenUsage)
                    .websiteCount(websiteCount)
                    .createdAt(LocalDateTime.now())
                    .build();
        }

        companyUsageStatRepository.save(stat);
        log.debug("更新公司使用量统计: companyId={}, date={}", companyId, statDate);
    }

    /**
     * 获取公司总使用量
     */
    public UsageSummaryDTO getTotalUsageByCompanyId(Integer companyId) {
        return companyUsageStatRepository.findTotalUsageByCompanyId(companyId);
    }

    /**
     * 获取最近N天的使用趋势
     */
    public List<UsageSummaryDTO> getUsageTrend(Integer companyId, int days) {
        LocalDate endDate = LocalDate.now();
        LocalDate startDate = endDate.minusDays(days);
        return getUsageSummaryByCompanyId(companyId, startDate, endDate);
    }

    /**
     * 获取活跃用户统计
     */
    public List<ActivitySummaryDTO> getActiveUserStats(Integer companyId, int days) {
        LocalDateTime endTime = LocalDateTime.now();
        LocalDateTime startTime = endTime.minusDays(days);
        return getActivitySummaryByCompanyId(companyId, startTime, endTime);
    }
}