RankLogService.java 4.66 KB
package com.tanpu.community.service;

import com.alibaba.fastjson.JSON;
import com.tanpu.common.util.JsonUtil;
import com.tanpu.community.api.beans.qo.ThemeAnalysDO;
import com.tanpu.community.api.beans.qo.TopicRankQo;
import com.tanpu.community.api.enums.RankLogTypeEnum;
import com.tanpu.community.dao.entity.community.RankLogEntity;
import com.tanpu.community.dao.mapper.community.RankLogMapper;
import com.tanpu.community.util.BizUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RankLogService {

    @Autowired
    private OSSFileService ossFileService;

    @Resource
    private RankLogMapper rankLogMapper;

    private Integer pageSize = 50;


    //话题排序日志
    @Transactional
    public void logTopicRank(List<TopicRankQo> rankList, LocalDateTime logTime, Long cost) {
        if (CollectionUtils.isEmpty(rankList)) {
            return;
        }

        Long round = rankLogMapper.selectMaxRound(RankLogTypeEnum.TOPIC.getCode());
        round = round == null ? 0L : round + 1;

        //分页插入
        for (int i = 0; i * pageSize < rankList.size(); i++) {
            int pageStart = i * pageSize;
            List<TopicRankQo> sublist = BizUtils.subList(rankList, pageStart, pageSize);
            RankLogEntity entity = RankLogEntity.builder().rankTime(logTime)
                    .type(RankLogTypeEnum.TOPIC.getCode())
                    .totalCount(rankList.size())
                    .rankCost(cost)
                    .content(JsonUtil.toJson(sublist))
                    .pageNumber(i + 1)
                    .pageSize(sublist.size())
                    .round(round)
                    .build();
            rankLogMapper.insert(entity);
        }
    }

    //主题排序日志
    @Transactional
    public void logThemeRank(List<ThemeAnalysDO> themeList, LocalDateTime logTime, Long cost) {
        if (CollectionUtils.isEmpty(themeList)) {
            return;
        }

        Long round = rankLogMapper.selectMaxRound(RankLogTypeEnum.THEME.getCode());
        round = round == null ? 0L : round + 1;

        //分页插入
        for (int i = 0; i * pageSize < themeList.size(); i++) {
            int pageStart = i * pageSize;
            List<ThemeAnalysDO> sublist = BizUtils.subList(themeList, pageStart, pageSize);
            RankLogEntity entity = RankLogEntity.builder().rankTime(logTime)
                    .type(RankLogTypeEnum.THEME.getCode())
                    .totalCount(themeList.size())
                    .rankCost(cost)
                    .content(JsonUtil.toJson(sublist))
                    .pageNumber(i + 1)
                    .pageSize(sublist.size())
                    .round(round)
                    .build();
            rankLogMapper.insert(entity);
        }
    }


    // 定时清除ranklog,并上传到oss
    public void clearRankLog() {
        LocalDateTime t = LocalDateTime.now().minusDays(7L);
        String d = t.format(DateTimeFormatter.BASIC_ISO_DATE);
        log.info("start clearRankLog job before {}", d);

        for (RankLogTypeEnum type : RankLogTypeEnum.values()) {
            int idx = 0;
            while (true) {
                List<RankLogEntity> logs = rankLogMapper.selectByTypeLimit(type.getCode(), 100);
                if (logs.isEmpty() || logs.get(0).getRankTime().isAfter(t)) {
                    break;
                }

                try {
                    String fileName = "ranklog_" + type.getCode() + "_" + idx;
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    IOUtils.writeLines(logs.stream().map(JSON::toJSONString).collect(Collectors.toList()), null, os);
                    ossFileService.uploadFileNoRecord(os.toByteArray(), fileName, ".txt", "rankLog/");

                    Thread.sleep(1000);
                } catch (Exception e) {
                    log.error("error in clearRankLog", e);
                    throw new RuntimeException(e);
                }

                // delete
                List<Long> ids = logs.stream().map(RankLogEntity::getId).collect(Collectors.toList());
                rankLogMapper.deleteBatchIds(ids);

                idx++;
            }
        }
    }

}