AdTheatreTvStatServiceImpl.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. package com.ylcm.sys.service.impl;
  2. import java.time.LocalDate;
  3. import java.time.LocalTime;
  4. import java.time.format.DateTimeFormatter;
  5. import java.util.*;
  6. import java.util.concurrent.CompletableFuture;
  7. import javax.annotation.Resource;
  8. import com.ylcm.sys.common.Util;
  9. import com.ylcm.sys.domain.*;
  10. import com.ylcm.sys.dto.AdTvQueryDTO;
  11. import com.ylcm.sys.mapper.AdSpecialMapper;
  12. import com.ylcm.sys.service.*;
  13. import com.ylcm.sys.vo.*;
  14. import lombok.extern.slf4j.Slf4j;
  15. import org.apache.commons.collections.CollectionUtils;
  16. import org.apache.commons.lang.StringUtils;
  17. import org.springframework.beans.BeanUtils;
  18. import org.springframework.cache.annotation.CacheEvict;
  19. import org.springframework.cache.annotation.Cacheable;
  20. import org.springframework.core.task.TaskExecutor;
  21. import org.springframework.stereotype.Service;
  22. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  23. import com.baomidou.mybatisplus.core.metadata.IPage;
  24. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  25. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  26. import com.ylcm.sys.common.EnumHelperUtil;
  27. import com.ylcm.sys.common.ProjectUtil;
  28. import com.ylcm.sys.enums.AdTheatreTimeEnum;
  29. import com.ylcm.sys.enums.MediaRankEnum;
  30. import com.ylcm.sys.form.AdTheatreAnalysisDetailQueryForm;
  31. import com.ylcm.sys.form.AdTheatreAnalysisQueryForm;
  32. import com.ylcm.sys.mapper.AdTheatreMapper;
  33. import com.ylcm.sys.mapper.AdTheatreTvStatMapper;
  34. import org.springframework.transaction.annotation.Transactional;
  35. /**
  36. * <p>
  37. * 关联电视剧数据 服务实现类
  38. * </p>
  39. *
  40. * @author admin
  41. * @since 2020-07-01
  42. */
  43. @Slf4j
  44. @Service
  45. public class AdTheatreTvStatServiceImpl extends ServiceImpl<AdTheatreTvStatMapper, AdTheatreTvStat> implements AdTheatreTvStatService {
  46. @Resource
  47. private AdTheatreMapper adTheatreMapper;
  48. @Resource
  49. private AdMediaService adMediaService;
  50. @Resource
  51. private AdTheatreTvStatService adTheatreTvStatService;
  52. @Resource
  53. private AdTheatreTvService adTheatreTvService;
  54. @Resource
  55. private AdSpecialMapper adSpecialMapper;
  56. @Resource
  57. private TaskExecutor taskExecutor;
  58. @Resource
  59. private AdTvService adTvService;
  60. @Resource
  61. private AdTheatreService adTheatreService;
  62. /**
  63. * 计算 某个频道的收视率
  64. * @param mediaName
  65. * @param theatreTime
  66. * @param startDate
  67. * @param endDate
  68. * @return
  69. */
  70. @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator")
  71. @Override
  72. public AdTheatreTvStat statByMedia(String mediaName, Integer theatreTime, String startDate, String endDate) {
  73. return baseMapper.statByMedia(mediaName, theatreTime, startDate, endDate);
  74. }
  75. @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator")
  76. @Override
  77. public IPage<AdTheatreAnalysisVO> getPage(AdTheatreAnalysisQueryForm queryForm) {
  78. if(StringUtils.isNotBlank(queryForm.getName())) {
  79. queryForm.setName(queryForm.getName().trim());
  80. }
  81. IPage<AdTheatreTvStat> adTheatreTvs = baseMapper.getPage(new Page<AdTheatreTvStat>(queryForm.getPageNo(), queryForm.getPageSize()), queryForm);
  82. IPage<AdTheatreAnalysisVO> analysisPage = new Page<AdTheatreAnalysisVO>();
  83. BeanUtils.copyProperties(adTheatreTvs, analysisPage);
  84. List<AdTheatreAnalysisVO> analysisVOs = Collections.synchronizedList(new ArrayList<AdTheatreAnalysisVO>());
  85. if (CollectionUtils.isNotEmpty(adTheatreTvs.getRecords())) {
  86. CompletableFuture[] completableFutures = adTheatreTvs.getRecords().stream().map(adTheatreTvStat -> CompletableFuture.runAsync(() -> {
  87. AdTheatreAnalysisVO adTheatreAnalysisVO = new AdTheatreAnalysisVO();
  88. BeanUtils.copyProperties(adTheatreTvStat, adTheatreAnalysisVO);
  89. AdTheatreTimeEnum adTheatreTimeEnum = EnumHelperUtil.getOneByCode(AdTheatreTimeEnum.class, adTheatreTvStat.getTheatreTime() + "");
  90. adTheatreAnalysisVO.setTheatreTimeName(adTheatreTimeEnum.getName());
  91. MediaRankEnum mediaRankEnum = EnumHelperUtil.getOneByCode(MediaRankEnum.class, adTheatreTvStat.getChannelSystem() + "");
  92. adTheatreAnalysisVO.setChannelSystem(mediaRankEnum.getName());
  93. adTheatreAnalysisVO.setRating29(Util.newScale(adTheatreAnalysisVO.getRating29(), 3));
  94. // 获取频道收视率
  95. List<LocalDate> seasons = ProjectUtil.getLocalDateByString(adTheatreTvStat.getSeason());
  96. AdTheatreTvStat mediaStat = adTheatreTvStatService.statByMedia(adTheatreTvStat.getMediaName(), adTheatreTvStat.getTheatreTime(),
  97. seasons.get(0).format(DateTimeFormatter.ISO_DATE), seasons.get(1).format(DateTimeFormatter.ISO_DATE));
  98. adTheatreAnalysisVO.setMediaDk29(mediaStat.getDk29());
  99. float mediaRating29 = mediaStat.getRating29();
  100. // 收视率保留四位小数
  101. adTheatreAnalysisVO.setMediaRating29(Util.newScale(mediaRating29, 3));
  102. adTheatreAnalysisVO.setEffect(ProjectUtil.getMediaEffect(adTheatreAnalysisVO.getRating29(), adTheatreAnalysisVO.getMediaRating29()));
  103. // 剧id
  104. AdTv adTv = adTvService.getByName(adTheatreAnalysisVO.getName());
  105. adTheatreAnalysisVO.setTvId(adTv == null ? 0 : adTv.getId());
  106. analysisVOs.add(adTheatreAnalysisVO);
  107. },taskExecutor)).toArray(CompletableFuture[]::new);
  108. CompletableFuture.allOf(completableFutures).join();
  109. analysisVOs.sort(new Comparator<AdTheatreAnalysisVO>() {
  110. @Override
  111. public int compare(AdTheatreAnalysisVO o1, AdTheatreAnalysisVO o2) {
  112. return o2.getRating29().compareTo(o1.getRating29());
  113. }
  114. });
  115. analysisPage.setRecords(analysisVOs);
  116. }
  117. return analysisPage;
  118. }
  119. @Override
  120. public IPage<AdTheatreAnalysisDetailVO> getDetailPage(AdTheatreAnalysisDetailQueryForm queryForm) {
  121. AdTvQueryDTO adTvQueryDTO = AdTvQueryDTO.from(queryForm);
  122. LambdaQueryWrapper<AdTheatre> queryWrapper = new LambdaQueryWrapper<AdTheatre>();
  123. queryWrapper.eq(AdTheatre::getName, adTvQueryDTO.getName());
  124. queryWrapper.eq(AdTheatre::getMediaName, adTvQueryDTO.getMediaName());
  125. if (!adTvQueryDTO.getStartTime().equals(ProjectUtil.MORNING_STR)) {
  126. queryWrapper.ge(AdTheatre::getShowTime, adTvQueryDTO.getStartTime());
  127. queryWrapper.lt(AdTheatre::getShowTime, adTvQueryDTO.getEndTime());
  128. } else {
  129. queryWrapper.apply("( (show_time >={0} ) or (show_time < {1}))", adTvQueryDTO.getStartTime(), adTvQueryDTO.getEndTime());
  130. }
  131. queryWrapper.ge(AdTheatre::getShowDate, adTvQueryDTO.getStartDate());
  132. queryWrapper.le(AdTheatre::getShowDate, adTvQueryDTO.getEndDate());
  133. IPage<AdTheatre> adTheatreTvs = adTheatreMapper.selectPage(new Page<AdTheatre>(queryForm.getPageNo(), queryForm.getPageSize()), queryWrapper);
  134. IPage<AdTheatreAnalysisDetailVO> analysisPage = new Page<AdTheatreAnalysisDetailVO>();
  135. BeanUtils.copyProperties(adTheatreTvs, analysisPage);
  136. List<AdTheatreAnalysisDetailVO> analysisVOs = new ArrayList<AdTheatreAnalysisDetailVO>();
  137. if (CollectionUtils.isNotEmpty(adTheatreTvs.getRecords())) {
  138. CompletableFuture[] completableFutures = adTheatreTvs.getRecords().stream().map(adTheatre -> CompletableFuture.runAsync(() -> {
  139. AdTheatreAnalysisDetailVO detailVO = new AdTheatreAnalysisDetailVO();
  140. BeanUtils.copyProperties(adTheatre, detailVO);
  141. detailVO.setProductName(adTheatre.getTypeName());
  142. detailVO.setJinxian(adTheatre.getJinxian() != null ? adTheatre.getJinxian().toString() : "");
  143. // 省网数据
  144. AdTheatreTv adTheatreTv = adTheatreTvService.getByTheatreId(adTheatre.getId());
  145. if (adTheatreTv != null) {
  146. BeanUtils.copyProperties(adTheatreTv, detailVO);
  147. }
  148. detailVO.setShowDuration(adTheatre.getDuration() == null ? "" :adTheatre.getDuration().toString());
  149. analysisVOs.add(detailVO);
  150. },taskExecutor)).toArray(CompletableFuture[]::new);
  151. CompletableFuture.allOf(completableFutures).join();
  152. analysisVOs.sort(new Comparator<AdTheatreAnalysisDetailVO>() {
  153. @Override
  154. public int compare(AdTheatreAnalysisDetailVO o1, AdTheatreAnalysisDetailVO o2) {
  155. return o1.getMediaNum().compareTo(o2.getMediaNum());
  156. }
  157. });
  158. analysisPage.setRecords(analysisVOs);
  159. }
  160. return analysisPage;
  161. }
  162. private void saveOrUpd(AdTheatreTvStat adTheatreTvStat) {
  163. LambdaQueryWrapper<AdTheatreTvStat> lambdaQueryWrapper = new LambdaQueryWrapper<AdTheatreTvStat>()
  164. .eq(AdTheatreTvStat::getName, adTheatreTvStat.getName())
  165. .eq(AdTheatreTvStat::getMediaName, adTheatreTvStat.getMediaName())
  166. .eq(AdTheatreTvStat::getTheatreTime, adTheatreTvStat.getTheatreTime())
  167. .eq(AdTheatreTvStat::getShowDate, adTheatreTvStat.getShowDate());
  168. AdTheatreTvStat domainInDb = baseMapper.selectOne(lambdaQueryWrapper);
  169. if (domainInDb == null) {
  170. baseMapper.insert(adTheatreTvStat);
  171. } else {
  172. Integer id = domainInDb.getId();
  173. BeanUtils.copyProperties(adTheatreTvStat, domainInDb);
  174. domainInDb.setId(id);
  175. baseMapper.updateById(domainInDb);
  176. }
  177. }
  178. private void delete(AdTheatre adTheatre, Integer theatreTime) {
  179. LambdaQueryWrapper<AdTheatreTvStat> lambdaQueryWrapper = new LambdaQueryWrapper<AdTheatreTvStat>()
  180. .eq(AdTheatreTvStat::getName, adTheatre.getName())
  181. .eq(AdTheatreTvStat::getMediaName, adTheatre.getMediaName())
  182. .eq(AdTheatreTvStat::getTheatreTime, theatreTime)
  183. .eq(AdTheatreTvStat::getShowDate, adTheatre.getShowDate());
  184. baseMapper.delete(lambdaQueryWrapper);
  185. }
  186. @Transactional(rollbackFor = Exception.class)
  187. @CacheEvict(value = "TheatreAnalysis", allEntries=true)
  188. @Override
  189. public void saveStatByTheatreTv(AdTheatre adTheatre) {
  190. Integer theatreTime = ProjectUtil.getTypeByLocalTime(adTheatre.getShowTime());
  191. List<LocalTime> localTimes = ProjectUtil.getLocalTimeByType(theatreTime);
  192. LambdaQueryWrapper<AdTheatre> queryWrapper = new LambdaQueryWrapper<AdTheatre>().eq(AdTheatre::getName, adTheatre.getName())
  193. .eq(AdTheatre::getMediaName, adTheatre.getMediaName())
  194. .eq(AdTheatre::getShowDate, adTheatre.getShowDate());
  195. if (!localTimes.get(0).format(DateTimeFormatter.ISO_TIME).equals(ProjectUtil.MORNING_STR)) {
  196. queryWrapper.ge(AdTheatre::getShowTime, localTimes.get(0))
  197. .lt(AdTheatre::getShowTime, localTimes.get(1));
  198. } else {
  199. queryWrapper.apply("( (show_time >={0} ) or (show_time < {1}))", localTimes.get(0), localTimes.get(1));
  200. }
  201. long start = System.currentTimeMillis();
  202. List<AdTheatre> adTheatres = adTheatreMapper.selectList(queryWrapper);
  203. long end = System.currentTimeMillis();
  204. log.info("list 耗时, {} ", end - start);
  205. if (CollectionUtils.isEmpty(adTheatres)) {
  206. log.info("AdTheatre数据为空,删掉, {}, {}", queryWrapper.getCustomSqlSegment(), queryWrapper.getParamNameValuePairs());
  207. // 没有就要删掉
  208. this.delete(adTheatre, theatreTime);
  209. } else {
  210. AdTheatreTvStat adTheatreTvStat = new AdTheatreTvStat();
  211. adTheatre.setId(null);
  212. BeanUtils.copyProperties(adTheatre, adTheatreTvStat);
  213. adTheatreTvStat.setTheatreTime(ProjectUtil.getTypeByLocalTime(adTheatre.getShowTime()));
  214. adTheatreTvStat.setSeason(ProjectUtil.getSeasonByLocalDate(adTheatre.getShowDate()));
  215. AdMedia adMedia = adMediaService.getByName(adTheatre.getMediaName());
  216. adTheatreTvStat.setChannelSystem(adMedia.getRank());
  217. float ratio29 = 0;
  218. int dk29 = 0;
  219. float ratio51 = 0;
  220. int dk51 = 0;
  221. int total = 0;
  222. int total_d = 0;
  223. // Set<Integer> tvNumSet = new HashSet<>();
  224. for(AdTheatre tmp: adTheatres) {
  225. AdTheatreTv adTheatreTv = adTheatreTvService.getByTheatreId(tmp.getId());
  226. if (adTheatreTv == null) {
  227. continue;
  228. }
  229. // if (!tvNumSet.contains(tmp.getMediaNum())) {
  230. // // 一个电视剧对应多个广告
  231. // tvNumSet.add(tmp.getMediaNum());
  232. total ++;
  233. // }
  234. if (adTheatreTv.getRating29() != null && adTheatreTv.getRating29() != 0) {
  235. total_d ++;
  236. }
  237. ratio29 += (adTheatreTv.getRating29() == null ? 0f : adTheatreTv.getRating29());
  238. dk29 += (adTheatreTv.getDk29() == null ? 0 : adTheatreTv.getDk29());
  239. ratio51 += (adTheatreTv.getRating51() == null ? 0f : adTheatreTv.getRating51());
  240. dk51 += (adTheatreTv.getDk51() == null ? 0 : adTheatreTv.getDk51());
  241. }
  242. adTheatreTvStat.setDk29(dk29);
  243. adTheatreTvStat.setRating29(ratio29);
  244. adTheatreTvStat.setDk51(dk51);
  245. adTheatreTvStat.setRating51(ratio51);
  246. adTheatreTvStat.setTvNum(total);
  247. adTheatreTvStat.setTvNumD(total_d);
  248. start = System.currentTimeMillis();
  249. saveOrUpd(adTheatreTvStat);
  250. end = System.currentTimeMillis();
  251. log.info("save 耗时, {} ", end - start);
  252. }
  253. }
  254. @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator")
  255. @Override
  256. public List<AdTheatreTopVO> getTvTop(Integer theatreTime, String startDate, String endDate) {
  257. List<AdTheatreTopVO> list = baseMapper.tvTop(theatreTime, startDate, endDate);
  258. list.stream().forEach(i -> {
  259. i.init();
  260. int count = adTheatreService.countTvNum(i.getName(), i.getMediaName(), startDate, endDate);
  261. i.setMediaNum(count);
  262. });
  263. return list;
  264. }
  265. @Cacheable(value = "TheatreAnalysis",keyGenerator = "cacheKeyGenerator")
  266. @Override
  267. public List<AdTheatreTopVO> getMediaTop(String name, Integer theatreTime, String startDate, String endDate, Integer limitSize) {
  268. limitSize = (limitSize == null ? 30 : limitSize);
  269. List<AdTheatreTopVO> list = baseMapper.mediaTop(name, theatreTime, startDate, endDate, limitSize);
  270. list.stream().forEach(i -> i.init());
  271. list.stream().forEach(i -> {
  272. MediaRankEnum mediaRankEnum = EnumHelperUtil.getOneByCode(MediaRankEnum.class, i.getMediaRank());
  273. i.setMediaRank(mediaRankEnum.getName());
  274. int count = adTheatreService.countTvNum(null, i.getMediaName(), startDate, endDate);
  275. i.setMediaNum(count);
  276. });
  277. return list;
  278. }
  279. @Override
  280. public AdTvRatioVO getTvRatioVO(AdTheatreAnalysisDetailQueryForm queryForm) {
  281. AdTvRatioVO adTvRatioVO = new AdTvRatioVO();
  282. List<AdTvRatioTrendVO> trendVOS = baseMapper.tvRatioTrend(queryForm);
  283. trendVOS.stream().forEach(i -> i.init());
  284. trendVOS.sort(new Comparator<AdTvRatioTrendVO>() {
  285. @Override
  286. public int compare(AdTvRatioTrendVO o1, AdTvRatioTrendVO o2) {
  287. return o1.getShowDate().compareTo(o2.getShowDate());
  288. }
  289. });
  290. adTvRatioVO.setTrendVOS(trendVOS);
  291. AdTheatreTv adTheatreTv = baseMapper.tvRatioPeople(AdTvQueryDTO.from(queryForm));
  292. List<AdTvRatioPeopleVO> peopleVOS = AdTvRatioPeopleVO.from(adTheatreTv);
  293. adTvRatioVO.setPeopleVOS(peopleVOS);
  294. return adTvRatioVO;
  295. }
  296. @Override
  297. public AdTvZoneVO getTvZoneVO(AdTheatreAnalysisDetailQueryForm queryForm) {
  298. AdTheatreTv adTheatreTv = baseMapper.tvRatioZone(AdTvQueryDTO.from(queryForm));
  299. List<AdTvZonePeopleVO> tvZone = AdTvZonePeopleVO.from(adTheatreTv);
  300. // 去掉电视剧
  301. queryForm.setName(null);
  302. AdTheatreTv adTheatreMedia = baseMapper.tvRatioZone(AdTvQueryDTO.from(queryForm));
  303. List<AdTvZonePeopleVO> mediaZone = AdTvZonePeopleVO.from(adTheatreMedia);
  304. AdTvZoneVO adTvZoneVO = new AdTvZoneVO();
  305. adTvZoneVO.setTvNum(tvZone);
  306. adTvZoneVO.setMediaNum(mediaZone);
  307. return adTvZoneVO;
  308. }
  309. @Override
  310. public List<AdTheatreProductDistVO> getProductVO(AdTheatreAnalysisDetailQueryForm queryForm) {
  311. return baseMapper.productDist(AdTvQueryDTO.from(queryForm));
  312. }
  313. @Override
  314. public List<AdThemeDistVO> getThemeDistVO(AdTheatreAnalysisDetailQueryForm queryForm) {
  315. AdTvQueryDTO queryDTO = AdTvQueryDTO.from(queryForm);
  316. List<AdThemeDistVO> distVOS = baseMapper.themeDist(queryForm);
  317. distVOS.sort(new Comparator<AdThemeDistVO>() {
  318. @Override
  319. public int compare(AdThemeDistVO o1, AdThemeDistVO o2) {
  320. if (o1.getRatio() > o2.getRatio()) {
  321. return -1;
  322. }
  323. if (o1.getRatio() < o2.getRatio()) {
  324. return 1;
  325. }
  326. return 0;
  327. }
  328. });
  329. distVOS.parallelStream().forEach(i -> {
  330. int total = adTheatreService.countThemeNum(i.getFirstTheme(), queryForm.getMediaName(), queryDTO.getTimeQuery(), queryForm.getStartDate(), queryForm.getEndDate());
  331. i.setTotal(total);
  332. i.setRatio(Util.newScale(i.getRatio(), 3));
  333. });
  334. return distVOS;
  335. }
  336. @CacheEvict(value = "TheatreAnalysis", allEntries=true)
  337. @Override
  338. public void batchUpdateByName(String newName, String oldName, String firstTheme, String oldFirstTheme, String secondTheme) {
  339. LambdaQueryWrapper<AdTheatreTvStat> statQueryWrapper = new LambdaQueryWrapper<AdTheatreTvStat>();
  340. statQueryWrapper.eq(AdTheatreTvStat::getName, oldName);
  341. AdTheatreTvStat adTheatreTvStat = new AdTheatreTvStat();
  342. if (!newName.equals(oldName)) {
  343. adTheatreTvStat.setName(newName);
  344. }
  345. if (!firstTheme.equals(oldFirstTheme)) {
  346. adTheatreTvStat.setFirstTheme(firstTheme);
  347. adTheatreTvStat.setSecondTheme(secondTheme);
  348. }
  349. baseMapper.update(adTheatreTvStat, statQueryWrapper);
  350. }
  351. }