package com.ylcm.sys.service.impl; import java.time.LocalDate; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CompletableFuture; import javax.annotation.Resource; import com.ylcm.sys.common.Util; import com.ylcm.sys.domain.*; import com.ylcm.sys.dto.AdTvQueryDTO; import com.ylcm.sys.mapper.AdSpecialMapper; import com.ylcm.sys.service.*; import com.ylcm.sys.vo.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.core.task.TaskExecutor; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ylcm.sys.common.EnumHelperUtil; import com.ylcm.sys.common.ProjectUtil; import com.ylcm.sys.enums.AdTheatreTimeEnum; import com.ylcm.sys.enums.MediaRankEnum; import com.ylcm.sys.form.AdTheatreAnalysisDetailQueryForm; import com.ylcm.sys.form.AdTheatreAnalysisQueryForm; import com.ylcm.sys.mapper.AdTheatreMapper; import com.ylcm.sys.mapper.AdTheatreTvStatMapper; import org.springframework.transaction.annotation.Transactional; /** *

* 关联电视剧数据 服务实现类 *

* * @author admin * @since 2020-07-01 */ @Slf4j @Service public class AdTheatreTvStatServiceImpl extends ServiceImpl implements AdTheatreTvStatService { @Resource private AdTheatreMapper adTheatreMapper; @Resource private AdMediaService adMediaService; @Resource private AdTheatreTvStatService adTheatreTvStatService; @Resource private AdTheatreTvService adTheatreTvService; @Resource private AdSpecialMapper adSpecialMapper; @Resource private TaskExecutor taskExecutor; @Resource private AdTvService adTvService; @Resource private AdTheatreService adTheatreService; /** * 计算 某个频道的收视率 * @param mediaName * @param theatreTime * @param startDate * @param endDate * @return */ @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator") @Override public AdTheatreTvStat statByMedia(String mediaName, Integer theatreTime, String startDate, String endDate) { return baseMapper.statByMedia(mediaName, theatreTime, startDate, endDate); } @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator") @Override public IPage getPage(AdTheatreAnalysisQueryForm queryForm) { if(StringUtils.isNotBlank(queryForm.getName())) { queryForm.setName(queryForm.getName().trim()); } IPage adTheatreTvs = baseMapper.getPage(new Page(queryForm.getPageNo(), queryForm.getPageSize()), queryForm); IPage analysisPage = new Page(); BeanUtils.copyProperties(adTheatreTvs, analysisPage); List analysisVOs = Collections.synchronizedList(new ArrayList()); if (CollectionUtils.isNotEmpty(adTheatreTvs.getRecords())) { CompletableFuture[] completableFutures = adTheatreTvs.getRecords().stream().map(adTheatreTvStat -> CompletableFuture.runAsync(() -> { AdTheatreAnalysisVO adTheatreAnalysisVO = new AdTheatreAnalysisVO(); BeanUtils.copyProperties(adTheatreTvStat, adTheatreAnalysisVO); AdTheatreTimeEnum adTheatreTimeEnum = EnumHelperUtil.getOneByCode(AdTheatreTimeEnum.class, adTheatreTvStat.getTheatreTime() + ""); adTheatreAnalysisVO.setTheatreTimeName(adTheatreTimeEnum.getName()); MediaRankEnum mediaRankEnum = EnumHelperUtil.getOneByCode(MediaRankEnum.class, adTheatreTvStat.getChannelSystem() + ""); adTheatreAnalysisVO.setChannelSystem(mediaRankEnum.getName()); adTheatreAnalysisVO.setRating29(Util.newScale(adTheatreAnalysisVO.getRating29(), 3)); // 获取频道收视率 List seasons = ProjectUtil.getLocalDateByString(adTheatreTvStat.getSeason()); AdTheatreTvStat mediaStat = adTheatreTvStatService.statByMedia(adTheatreTvStat.getMediaName(), adTheatreTvStat.getTheatreTime(), seasons.get(0).format(DateTimeFormatter.ISO_DATE), seasons.get(1).format(DateTimeFormatter.ISO_DATE)); adTheatreAnalysisVO.setMediaDk29(mediaStat.getDk29()); float mediaRating29 = mediaStat.getRating29(); // 收视率保留四位小数 adTheatreAnalysisVO.setMediaRating29(Util.newScale(mediaRating29, 3)); adTheatreAnalysisVO.setEffect(ProjectUtil.getMediaEffect(adTheatreAnalysisVO.getRating29(), adTheatreAnalysisVO.getMediaRating29())); // 剧id AdTv adTv = adTvService.getByName(adTheatreAnalysisVO.getName()); adTheatreAnalysisVO.setTvId(adTv == null ? 0 : adTv.getId()); analysisVOs.add(adTheatreAnalysisVO); },taskExecutor)).toArray(CompletableFuture[]::new); CompletableFuture.allOf(completableFutures).join(); analysisVOs.sort(new Comparator() { @Override public int compare(AdTheatreAnalysisVO o1, AdTheatreAnalysisVO o2) { return o2.getRating29().compareTo(o1.getRating29()); } }); analysisPage.setRecords(analysisVOs); } return analysisPage; } @Override public IPage getDetailPage(AdTheatreAnalysisDetailQueryForm queryForm) { AdTvQueryDTO adTvQueryDTO = AdTvQueryDTO.from(queryForm); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(AdTheatre::getName, adTvQueryDTO.getName()); queryWrapper.eq(AdTheatre::getMediaName, adTvQueryDTO.getMediaName()); if (!adTvQueryDTO.getStartTime().equals(ProjectUtil.MORNING_STR)) { queryWrapper.ge(AdTheatre::getShowTime, adTvQueryDTO.getStartTime()); queryWrapper.lt(AdTheatre::getShowTime, adTvQueryDTO.getEndTime()); } else { queryWrapper.apply("( (show_time >={0} ) or (show_time < {1}))", adTvQueryDTO.getStartTime(), adTvQueryDTO.getEndTime()); } queryWrapper.ge(AdTheatre::getShowDate, adTvQueryDTO.getStartDate()); queryWrapper.le(AdTheatre::getShowDate, adTvQueryDTO.getEndDate()); IPage adTheatreTvs = adTheatreMapper.selectPage(new Page(queryForm.getPageNo(), queryForm.getPageSize()), queryWrapper); IPage analysisPage = new Page(); BeanUtils.copyProperties(adTheatreTvs, analysisPage); List analysisVOs = new ArrayList(); if (CollectionUtils.isNotEmpty(adTheatreTvs.getRecords())) { CompletableFuture[] completableFutures = adTheatreTvs.getRecords().stream().map(adTheatre -> CompletableFuture.runAsync(() -> { AdTheatreAnalysisDetailVO detailVO = new AdTheatreAnalysisDetailVO(); BeanUtils.copyProperties(adTheatre, detailVO); detailVO.setProductName(adTheatre.getTypeName()); detailVO.setJinxian(adTheatre.getJinxian() != null ? adTheatre.getJinxian().toString() : ""); // 省网数据 AdTheatreTv adTheatreTv = adTheatreTvService.getByTheatreId(adTheatre.getId()); if (adTheatreTv != null) { BeanUtils.copyProperties(adTheatreTv, detailVO); } detailVO.setShowDuration(adTheatre.getDuration() == null ? "" :adTheatre.getDuration().toString()); analysisVOs.add(detailVO); },taskExecutor)).toArray(CompletableFuture[]::new); CompletableFuture.allOf(completableFutures).join(); analysisVOs.sort(new Comparator() { @Override public int compare(AdTheatreAnalysisDetailVO o1, AdTheatreAnalysisDetailVO o2) { return o1.getMediaNum().compareTo(o2.getMediaNum()); } }); analysisPage.setRecords(analysisVOs); } return analysisPage; } private void saveOrUpd(AdTheatreTvStat adTheatreTvStat) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper() .eq(AdTheatreTvStat::getName, adTheatreTvStat.getName()) .eq(AdTheatreTvStat::getMediaName, adTheatreTvStat.getMediaName()) .eq(AdTheatreTvStat::getTheatreTime, adTheatreTvStat.getTheatreTime()) .eq(AdTheatreTvStat::getShowDate, adTheatreTvStat.getShowDate()); AdTheatreTvStat domainInDb = baseMapper.selectOne(lambdaQueryWrapper); if (domainInDb == null) { baseMapper.insert(adTheatreTvStat); } else { Integer id = domainInDb.getId(); BeanUtils.copyProperties(adTheatreTvStat, domainInDb); domainInDb.setId(id); baseMapper.updateById(domainInDb); } } private void delete(AdTheatre adTheatre, Integer theatreTime) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper() .eq(AdTheatreTvStat::getName, adTheatre.getName()) .eq(AdTheatreTvStat::getMediaName, adTheatre.getMediaName()) .eq(AdTheatreTvStat::getTheatreTime, theatreTime) .eq(AdTheatreTvStat::getShowDate, adTheatre.getShowDate()); baseMapper.delete(lambdaQueryWrapper); } @Transactional(rollbackFor = Exception.class) @CacheEvict(value = "TheatreAnalysis", allEntries=true) @Override public void saveStatByTheatreTv(AdTheatre adTheatre) { Integer theatreTime = ProjectUtil.getTypeByLocalTime(adTheatre.getShowTime()); List localTimes = ProjectUtil.getLocalTimeByType(theatreTime); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().eq(AdTheatre::getName, adTheatre.getName()) .eq(AdTheatre::getMediaName, adTheatre.getMediaName()) .eq(AdTheatre::getShowDate, adTheatre.getShowDate()); if (!localTimes.get(0).format(DateTimeFormatter.ISO_TIME).equals(ProjectUtil.MORNING_STR)) { queryWrapper.ge(AdTheatre::getShowTime, localTimes.get(0)) .lt(AdTheatre::getShowTime, localTimes.get(1)); } else { queryWrapper.apply("( (show_time >={0} ) or (show_time < {1}))", localTimes.get(0), localTimes.get(1)); } long start = System.currentTimeMillis(); List adTheatres = adTheatreMapper.selectList(queryWrapper); long end = System.currentTimeMillis(); log.info("list 耗时, {} ", end - start); if (CollectionUtils.isEmpty(adTheatres)) { log.info("AdTheatre数据为空,删掉, {}, {}", queryWrapper.getCustomSqlSegment(), queryWrapper.getParamNameValuePairs()); // 没有就要删掉 this.delete(adTheatre, theatreTime); } else { AdTheatreTvStat adTheatreTvStat = new AdTheatreTvStat(); adTheatre.setId(null); BeanUtils.copyProperties(adTheatre, adTheatreTvStat); adTheatreTvStat.setTheatreTime(ProjectUtil.getTypeByLocalTime(adTheatre.getShowTime())); adTheatreTvStat.setSeason(ProjectUtil.getSeasonByLocalDate(adTheatre.getShowDate())); AdMedia adMedia = adMediaService.getByName(adTheatre.getMediaName()); adTheatreTvStat.setChannelSystem(adMedia.getRank()); float ratio29 = 0; int dk29 = 0; float ratio51 = 0; int dk51 = 0; int total = 0; int total_d = 0; // Set tvNumSet = new HashSet<>(); for(AdTheatre tmp: adTheatres) { AdTheatreTv adTheatreTv = adTheatreTvService.getByTheatreId(tmp.getId()); if (adTheatreTv == null) { continue; } // if (!tvNumSet.contains(tmp.getMediaNum())) { // // 一个电视剧对应多个广告 // tvNumSet.add(tmp.getMediaNum()); total ++; // } if (adTheatreTv.getRating29() != null && adTheatreTv.getRating29() != 0) { total_d ++; } ratio29 += (adTheatreTv.getRating29() == null ? 0f : adTheatreTv.getRating29()); dk29 += (adTheatreTv.getDk29() == null ? 0 : adTheatreTv.getDk29()); ratio51 += (adTheatreTv.getRating51() == null ? 0f : adTheatreTv.getRating51()); dk51 += (adTheatreTv.getDk51() == null ? 0 : adTheatreTv.getDk51()); } adTheatreTvStat.setDk29(dk29); adTheatreTvStat.setRating29(ratio29); adTheatreTvStat.setDk51(dk51); adTheatreTvStat.setRating51(ratio51); adTheatreTvStat.setTvNum(total); adTheatreTvStat.setTvNumD(total_d); start = System.currentTimeMillis(); saveOrUpd(adTheatreTvStat); end = System.currentTimeMillis(); log.info("save 耗时, {} ", end - start); } } @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator") @Override public List getTvTop(Integer theatreTime, String startDate, String endDate) { List list = baseMapper.tvTop(theatreTime, startDate, endDate); list.stream().forEach(i -> { i.init(); int count = adTheatreService.countTvNum(i.getName(), i.getMediaName(), startDate, endDate); i.setMediaNum(count); }); return list; } @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator") @Override public List getMediaTop(String name, Integer theatreTime, String startDate, String endDate, Integer limitSize) { limitSize = (limitSize == null ? 30 : limitSize); List list = baseMapper.mediaTop(name, theatreTime, startDate, endDate, limitSize); list.stream().forEach(i -> i.init()); list.stream().forEach(i -> { MediaRankEnum mediaRankEnum = EnumHelperUtil.getOneByCode(MediaRankEnum.class, i.getMediaRank()); i.setMediaRank(mediaRankEnum.getName()); int count = adTheatreService.countTvNum(null, i.getMediaName(), startDate, endDate); i.setMediaNum(count); }); return list; } @Override public AdTvRatioVO getTvRatioVO(AdTheatreAnalysisDetailQueryForm queryForm) { AdTvRatioVO adTvRatioVO = new AdTvRatioVO(); List trendVOS = baseMapper.tvRatioTrend(queryForm); trendVOS.stream().forEach(i -> i.init()); trendVOS.sort(new Comparator() { @Override public int compare(AdTvRatioTrendVO o1, AdTvRatioTrendVO o2) { return o1.getShowDate().compareTo(o2.getShowDate()); } }); adTvRatioVO.setTrendVOS(trendVOS); AdTheatreTv adTheatreTv = baseMapper.tvRatioPeople(AdTvQueryDTO.from(queryForm)); List peopleVOS = AdTvRatioPeopleVO.from(adTheatreTv); adTvRatioVO.setPeopleVOS(peopleVOS); return adTvRatioVO; } @Override public AdTvZoneVO getTvZoneVO(AdTheatreAnalysisDetailQueryForm queryForm) { AdTheatreTv adTheatreTv = baseMapper.tvRatioZone(AdTvQueryDTO.from(queryForm)); List tvZone = AdTvZonePeopleVO.from(adTheatreTv); // 去掉电视剧 queryForm.setName(null); AdTheatreTv adTheatreMedia = baseMapper.tvRatioZone(AdTvQueryDTO.from(queryForm)); List mediaZone = AdTvZonePeopleVO.from(adTheatreMedia); AdTvZoneVO adTvZoneVO = new AdTvZoneVO(); adTvZoneVO.setTvNum(tvZone); adTvZoneVO.setMediaNum(mediaZone); return adTvZoneVO; } @Override public List getProductVO(AdTheatreAnalysisDetailQueryForm queryForm) { return baseMapper.productDist(AdTvQueryDTO.from(queryForm)); } @Override public List getThemeDistVO(AdTheatreAnalysisDetailQueryForm queryForm) { AdTvQueryDTO queryDTO = AdTvQueryDTO.from(queryForm); List distVOS = baseMapper.themeDist(queryForm); distVOS.sort(new Comparator() { @Override public int compare(AdThemeDistVO o1, AdThemeDistVO o2) { if (o1.getRatio() > o2.getRatio()) { return -1; } if (o1.getRatio() < o2.getRatio()) { return 1; } return 0; } }); distVOS.parallelStream().forEach(i -> { int total = adTheatreService.countThemeNum(i.getFirstTheme(), queryForm.getMediaName(), queryDTO.getTimeQuery(), queryForm.getStartDate(), queryForm.getEndDate()); i.setTotal(total); i.setRatio(Util.newScale(i.getRatio(), 3)); }); return distVOS; } @CacheEvict(value = "TheatreAnalysis", allEntries=true) @Override public void batchUpdateByName(String newName, String oldName, String firstTheme, String oldFirstTheme, String secondTheme) { LambdaQueryWrapper statQueryWrapper = new LambdaQueryWrapper(); statQueryWrapper.eq(AdTheatreTvStat::getName, oldName); AdTheatreTvStat adTheatreTvStat = new AdTheatreTvStat(); if (!newName.equals(oldName)) { adTheatreTvStat.setName(newName); } if (!firstTheme.equals(oldFirstTheme)) { adTheatreTvStat.setFirstTheme(firstTheme); adTheatreTvStat.setSecondTheme(secondTheme); } baseMapper.update(adTheatreTvStat, statQueryWrapper); } }