|
@@ -3,12 +3,14 @@ package com.fs.live.service.impl;
|
|
|
|
|
|
|
|
import com.fs.common.core.domain.R;
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.redis.RedisCache;
|
|
import com.fs.common.core.redis.RedisCache;
|
|
|
|
|
+import com.fs.common.exception.ServiceException;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
import com.fs.common.utils.DateUtils;
|
|
|
import com.fs.common.utils.spring.SpringUtils;
|
|
import com.fs.common.utils.spring.SpringUtils;
|
|
|
import com.fs.hisStore.domain.FsUserScrm;
|
|
import com.fs.hisStore.domain.FsUserScrm;
|
|
|
import com.fs.hisStore.mapper.FsUserScrmMapper;
|
|
import com.fs.hisStore.mapper.FsUserScrmMapper;
|
|
|
import com.fs.live.domain.*;
|
|
import com.fs.live.domain.*;
|
|
|
import com.fs.live.mapper.*;
|
|
import com.fs.live.mapper.*;
|
|
|
|
|
+import com.fs.live.param.LiveDataCompanyParam;
|
|
|
import com.fs.live.param.LiveDataParam;
|
|
import com.fs.live.param.LiveDataParam;
|
|
|
import com.fs.live.service.ILiveDataService;
|
|
import com.fs.live.service.ILiveDataService;
|
|
|
import com.fs.live.service.ILiveUserFavoriteService;
|
|
import com.fs.live.service.ILiveUserFavoriteService;
|
|
@@ -21,14 +23,12 @@ import com.fs.company.mapper.CompanyMapper;
|
|
|
import com.fs.company.mapper.CompanyUserMapper;
|
|
import com.fs.company.mapper.CompanyUserMapper;
|
|
|
import com.fs.course.domain.FsUserCompanyUser;
|
|
import com.fs.course.domain.FsUserCompanyUser;
|
|
|
import com.fs.course.mapper.FsUserCompanyUserMapper;
|
|
import com.fs.course.mapper.FsUserCompanyUserMapper;
|
|
|
-import com.fs.his.domain.FsUser;
|
|
|
|
|
-import com.fs.his.mapper.FsUserMapper;
|
|
|
|
|
import com.fs.hisStore.domain.FsStoreProductScrm;
|
|
import com.fs.hisStore.domain.FsStoreProductScrm;
|
|
|
import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
|
|
import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
+import java.util.function.BiConsumer;
|
|
|
|
|
|
|
|
import com.github.pagehelper.PageInfo;
|
|
import com.github.pagehelper.PageInfo;
|
|
|
-import io.swagger.models.auth.In;
|
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
@@ -39,9 +39,11 @@ import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
import java.math.RoundingMode;
|
|
|
import java.time.DayOfWeek;
|
|
import java.time.DayOfWeek;
|
|
|
import java.time.LocalDate;
|
|
import java.time.LocalDate;
|
|
|
|
|
+import java.time.ZoneId;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
+import java.time.temporal.ChronoUnit;
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
|
+import java.util.concurrent.*;
|
|
|
|
|
|
|
|
import static com.fs.common.constant.LiveKeysConstant.*;
|
|
import static com.fs.common.constant.LiveKeysConstant.*;
|
|
|
|
|
|
|
@@ -195,10 +197,7 @@ public class LiveDataServiceImpl implements ILiveDataService {
|
|
|
@Override
|
|
@Override
|
|
|
public List<LiveDataListVo> exportLiveData(LiveDataParam param){
|
|
public List<LiveDataListVo> exportLiveData(LiveDataParam param){
|
|
|
List<Live> lives = liveMapper.listLiveData(param);
|
|
List<Live> lives = liveMapper.listLiveData(param);
|
|
|
- int total = liveMapper.listLiveDataCount(param);
|
|
|
|
|
-
|
|
|
|
|
if (lives == null || lives.isEmpty()) {
|
|
if (lives == null || lives.isEmpty()) {
|
|
|
- LiveDataStatisticsVo statistics = new LiveDataStatisticsVo();
|
|
|
|
|
return Collections.emptyList();
|
|
return Collections.emptyList();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -210,11 +209,6 @@ public class LiveDataServiceImpl implements ILiveDataService {
|
|
|
// 查询统计数据(根据live_watch_user表查询用户的在线时长,计算平均时长
|
|
// 查询统计数据(根据live_watch_user表查询用户的在线时长,计算平均时长
|
|
|
// 根据live_video的文件时长,判断用户的完课情况
|
|
// 根据live_video的文件时长,判断用户的完课情况
|
|
|
// 根据live_order查询直播间的销量额和订单数)
|
|
// 根据live_order查询直播间的销量额和订单数)
|
|
|
- LiveDataStatisticsVo statistics = baseMapper.selectLiveDataStatistics(liveIds);
|
|
|
|
|
- if (statistics == null) {
|
|
|
|
|
- statistics = new LiveDataStatisticsVo();
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
// 查询列表数据(每个直播间的详细统计数据)
|
|
// 查询列表数据(每个直播间的详细统计数据)
|
|
|
List<LiveDataListVo> liveDataList = baseMapper.selectLiveDataListByLiveIds(liveIds);
|
|
List<LiveDataListVo> liveDataList = baseMapper.selectLiveDataListByLiveIds(liveIds);
|
|
|
if (liveDataList == null) {
|
|
if (liveDataList == null) {
|
|
@@ -222,6 +216,268 @@ public class LiveDataServiceImpl implements ILiveDataService {
|
|
|
}
|
|
}
|
|
|
return liveDataList;
|
|
return liveDataList;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /** 时间范围最大天数(一个月) */
|
|
|
|
|
+ private static final int MAX_DAYS = 31;
|
|
|
|
|
+ /** 分段查询步长(天) */
|
|
|
|
|
+ private static final int SEGMENT_STEP_DAYS = 7;
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<LiveDataCompanyVO> listLiveDataCompany(LiveDataCompanyParam param) {
|
|
|
|
|
+ Date startDate = param.getStartDate();
|
|
|
|
|
+ Date endDate = param.getEndDate();
|
|
|
|
|
+ if (startDate == null || endDate == null) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ LocalDate start = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
|
|
+ LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
|
|
|
|
+ long daysBetween = ChronoUnit.DAYS.between(start, end) + 1;
|
|
|
|
|
+
|
|
|
|
|
+ // 超过31天直接返回报错,时间范围最大一个月
|
|
|
|
|
+ if (daysBetween > MAX_DAYS) {
|
|
|
|
|
+ throw new ServiceException("查询时间范围不能超过31天,当前为" + daysBetween + "天");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 超过7天使用多线程分段查询
|
|
|
|
|
+ if (daysBetween > SEGMENT_STEP_DAYS) {
|
|
|
|
|
+ return listLiveDataCompanyBySegment(param, start, end, daysBetween);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return queryLiveDataCompanyByDateRange(param);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 多线程分段查询:步长7天,等待各段数据返回后合并
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<LiveDataCompanyVO> listLiveDataCompanyBySegment(LiveDataCompanyParam param,
|
|
|
|
|
+ LocalDate start, LocalDate end, long totalDays) {
|
|
|
|
|
+ List<LocalDate[]> segments = new ArrayList<>();
|
|
|
|
|
+ LocalDate segmentStart = start;
|
|
|
|
|
+ while (segmentStart.isBefore(end) || segmentStart.isEqual(end)) {
|
|
|
|
|
+ LocalDate segmentEnd = segmentStart.plusDays(SEGMENT_STEP_DAYS - 1);
|
|
|
|
|
+ if (segmentEnd.isAfter(end)) {
|
|
|
|
|
+ segmentEnd = end;
|
|
|
|
|
+ }
|
|
|
|
|
+ segments.add(new LocalDate[]{segmentStart, segmentEnd});
|
|
|
|
|
+ segmentStart = segmentEnd.plusDays(1);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ExecutorService executor = Executors.newFixedThreadPool(Math.min(segments.size(), 8));
|
|
|
|
|
+ List<Future<List<LiveDataCompanyVO>>> futures = new ArrayList<>();
|
|
|
|
|
+ try {
|
|
|
|
|
+ for (LocalDate[] seg : segments) {
|
|
|
|
|
+ LiveDataCompanyParam segmentParam = new LiveDataCompanyParam();
|
|
|
|
|
+ segmentParam.setCompanyName(param.getCompanyName());
|
|
|
|
|
+ segmentParam.setCompanyIds(param.getCompanyIds());
|
|
|
|
|
+ segmentParam.setStartDate(Date.from(seg[0].atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
|
|
|
|
+ segmentParam.setEndDate(Date.from(seg[1].atStartOfDay(ZoneId.systemDefault()).toInstant()));
|
|
|
|
|
+
|
|
|
|
|
+ Future<List<LiveDataCompanyVO>> future = executor.submit(() -> queryLiveDataCompanyByDateRange(segmentParam));
|
|
|
|
|
+ futures.add(future);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<List<LiveDataCompanyVO>> segmentResults = new ArrayList<>();
|
|
|
|
|
+ for (Future<List<LiveDataCompanyVO>> future : futures) {
|
|
|
|
|
+ segmentResults.add(future.get(60, TimeUnit.SECONDS));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return mergeSegmentResults(segmentResults);
|
|
|
|
|
+ } catch (ExecutionException e) {
|
|
|
|
|
+ log.error("分公司直播数据分段查询异常", e);
|
|
|
|
|
+ throw new RuntimeException("分公司直播数据查询失败:" + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
|
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
|
|
+ log.error("分公司直播数据分段查询被中断", e);
|
|
|
|
|
+ throw new RuntimeException("分公司直播数据查询被中断");
|
|
|
|
|
+ } catch (TimeoutException e) {
|
|
|
|
|
+ log.error("分公司直播数据分段查询超时", e);
|
|
|
|
|
+ throw new ServiceException("查询超时,请缩小时间范围后重试");
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ executor.shutdown();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 合并分段查询结果:按分公司汇总各分段统计数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<LiveDataCompanyVO> mergeSegmentResults(List<List<LiveDataCompanyVO>> segmentResults) {
|
|
|
|
|
+ Map<Long, LiveDataCompanyVO> resultMap = new HashMap<>();
|
|
|
|
|
+ for (List<LiveDataCompanyVO> list : segmentResults) {
|
|
|
|
|
+ if (list == null) continue;
|
|
|
|
|
+ for (LiveDataCompanyVO source : list) {
|
|
|
|
|
+ if (source == null || source.getCompanyId() == null) continue;
|
|
|
|
|
+ LiveDataCompanyVO target = resultMap.computeIfAbsent(source.getCompanyId(), k -> {
|
|
|
|
|
+ LiveDataCompanyVO vo = new LiveDataCompanyVO();
|
|
|
|
|
+ vo.setCompanyId(source.getCompanyId());
|
|
|
|
|
+ vo.setCompanyName(source.getCompanyName());
|
|
|
|
|
+ vo.setTotalAttendanceCount(0L);
|
|
|
|
|
+ vo.setTotalCompleteCount(0L);
|
|
|
|
|
+ vo.setLiveAttendanceCount(0L);
|
|
|
|
|
+ vo.setLiveCompleteCount(0L);
|
|
|
|
|
+ vo.setReplayAttendanceCount(0L);
|
|
|
|
|
+ vo.setReplayCompleteCount(0L);
|
|
|
|
|
+ vo.setOrderCount(0L);
|
|
|
|
|
+ vo.setOrderUserCount(0L);
|
|
|
|
|
+ vo.setEmployeeCount(0L);
|
|
|
|
|
+ vo.setGmv(BigDecimal.ZERO);
|
|
|
|
|
+ vo.setTotalCompleteRate(0.0);
|
|
|
|
|
+ vo.setLiveCompleteRate(0.0);
|
|
|
|
|
+ vo.setReplayCompleteRate(0.0);
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ });
|
|
|
|
|
+ // 累加各分段数据
|
|
|
|
|
+ target.setTotalAttendanceCount((target.getTotalAttendanceCount() == null ? 0L : target.getTotalAttendanceCount())
|
|
|
|
|
+ + (source.getTotalAttendanceCount() == null ? 0L : source.getTotalAttendanceCount()));
|
|
|
|
|
+ target.setTotalCompleteCount((target.getTotalCompleteCount() == null ? 0L : target.getTotalCompleteCount())
|
|
|
|
|
+ + (source.getTotalCompleteCount() == null ? 0L : source.getTotalCompleteCount()));
|
|
|
|
|
+ target.setLiveAttendanceCount((target.getLiveAttendanceCount() == null ? 0L : target.getLiveAttendanceCount())
|
|
|
|
|
+ + (source.getLiveAttendanceCount() == null ? 0L : source.getLiveAttendanceCount()));
|
|
|
|
|
+ target.setLiveCompleteCount((target.getLiveCompleteCount() == null ? 0L : target.getLiveCompleteCount())
|
|
|
|
|
+ + (source.getLiveCompleteCount() == null ? 0L : source.getLiveCompleteCount()));
|
|
|
|
|
+ target.setReplayAttendanceCount((target.getReplayAttendanceCount() == null ? 0L : target.getReplayAttendanceCount())
|
|
|
|
|
+ + (source.getReplayAttendanceCount() == null ? 0L : source.getReplayAttendanceCount()));
|
|
|
|
|
+ target.setReplayCompleteCount((target.getReplayCompleteCount() == null ? 0L : target.getReplayCompleteCount())
|
|
|
|
|
+ + (source.getReplayCompleteCount() == null ? 0L : source.getReplayCompleteCount()));
|
|
|
|
|
+ target.setOrderCount((target.getOrderCount() == null ? 0L : target.getOrderCount())
|
|
|
|
|
+ + (source.getOrderCount() == null ? 0L : source.getOrderCount()));
|
|
|
|
|
+ target.setOrderUserCount((target.getOrderUserCount() == null ? 0L : target.getOrderUserCount())
|
|
|
|
|
+ + (source.getOrderUserCount() == null ? 0L : source.getOrderUserCount()));
|
|
|
|
|
+ target.setGmv(roundGmv((target.getGmv() == null ? BigDecimal.ZERO : target.getGmv())
|
|
|
|
|
+ .add(source.getGmv() == null ? BigDecimal.ZERO : source.getGmv())));
|
|
|
|
|
+ if (target.getEmployeeCount() == null && source.getEmployeeCount() != null) {
|
|
|
|
|
+ target.setEmployeeCount(source.getEmployeeCount());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ for (LiveDataCompanyVO vo : resultMap.values()) {
|
|
|
|
|
+ long totalAttend = vo.getTotalAttendanceCount() == null ? 0L : vo.getTotalAttendanceCount();
|
|
|
|
|
+ long totalComplete = vo.getTotalCompleteCount() == null ? 0L : vo.getTotalCompleteCount();
|
|
|
|
|
+ long liveAttend = vo.getLiveAttendanceCount() == null ? 0L : vo.getLiveAttendanceCount();
|
|
|
|
|
+ long liveComplete = vo.getLiveCompleteCount() == null ? 0L : vo.getLiveCompleteCount();
|
|
|
|
|
+ long replayAttend = vo.getReplayAttendanceCount() == null ? 0L : vo.getReplayAttendanceCount();
|
|
|
|
|
+ long replayComplete = vo.getReplayCompleteCount() == null ? 0L : vo.getReplayCompleteCount();
|
|
|
|
|
+ vo.setTotalCompleteRate(roundRate(totalAttend > 0 ? totalComplete * 100.0 / totalAttend : 0.0));
|
|
|
|
|
+ vo.setLiveCompleteRate(roundRate(liveAttend > 0 ? liveComplete * 100.0 / liveAttend : 0.0));
|
|
|
|
|
+ vo.setReplayCompleteRate(roundRate(replayAttend > 0 ? replayComplete * 100.0 / replayAttend : 0.0));
|
|
|
|
|
+ vo.setGmv(roundGmv(vo.getGmv()));
|
|
|
|
|
+ }
|
|
|
|
|
+ return resultMap.values().stream()
|
|
|
|
|
+ .sorted(Comparator.comparing(vo -> Optional.ofNullable(vo.getCompanyName()).orElse("")))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /** 百分比四舍五入保留2位小数 */
|
|
|
|
|
+ private static double roundRate(double rate) {
|
|
|
|
|
+ return Math.round(rate * 100.0) / 100.0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /** GMV四舍五入保留2位小数 */
|
|
|
|
|
+ private static BigDecimal roundGmv(BigDecimal gmv) {
|
|
|
|
|
+ return gmv == null ? BigDecimal.ZERO : gmv.setScale(2, RoundingMode.HALF_UP);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从到课/完课等查询结果中提取公司ID集合(去重)
|
|
|
|
|
+ */
|
|
|
|
|
+ @SafeVarargs
|
|
|
|
|
+ private final List<Long> buildCompanyIdsFromResults(List<LiveDataCompanyVO>... lists) {
|
|
|
|
|
+ Set<Long> companyIds = new HashSet<>();
|
|
|
|
|
+ for (List<LiveDataCompanyVO> list : lists) {
|
|
|
|
|
+ if (list == null) continue;
|
|
|
|
|
+ for (LiveDataCompanyVO vo : list) {
|
|
|
|
|
+ if (vo != null && vo.getCompanyId() != null) {
|
|
|
|
|
+ companyIds.add(vo.getCompanyId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return new ArrayList<>(companyIds);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按日期范围查询分公司直播数据(单段,供分段或直接调用)
|
|
|
|
|
+ */
|
|
|
|
|
+ private List<LiveDataCompanyVO> queryLiveDataCompanyByDateRange(LiveDataCompanyParam param) {
|
|
|
|
|
+ List<Long> liveIds = baseMapper.selectLiveIdsByCompanyParam(param);
|
|
|
|
|
+ if (liveIds == null || liveIds.isEmpty()) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<LiveDataCompanyVO> attendanceList = baseMapper.selectAttendanceCountByCompany(liveIds, param.getCompanyIds());
|
|
|
|
|
+ List<LiveDataCompanyVO> completeList = baseMapper.selectCompleteCountByCompany(liveIds, param.getCompanyIds());
|
|
|
|
|
+ List<LiveDataCompanyVO> liveAttendList = baseMapper.selectLiveAttendCountByCompany(liveIds, param.getCompanyIds());
|
|
|
|
|
+ List<LiveDataCompanyVO> liveCompleteList = baseMapper.selectLiveCompleteCountByCompany(liveIds, param.getCompanyIds());
|
|
|
|
|
+ List<LiveDataCompanyVO> replayAttendList = baseMapper.selectReplayAttendCountByCompany(liveIds, param.getCompanyIds());
|
|
|
|
|
+ List<LiveDataCompanyVO> replayCompleteList = baseMapper.selectReplayCompleteCountByCompany(liveIds, param.getCompanyIds());
|
|
|
|
|
+ // 从上面查询结果中提取公司ID集合,供后续GMV和员工数查询使用
|
|
|
|
|
+ List<Long> companyIdsFromResult = buildCompanyIdsFromResults(
|
|
|
|
|
+ attendanceList, completeList, liveAttendList, liveCompleteList, replayAttendList, replayCompleteList);
|
|
|
|
|
+ List<LiveDataCompanyVO> gmvAndOrderList = baseMapper.selectCompanyOrderAndGmv(liveIds, companyIdsFromResult);
|
|
|
|
|
+ List<LiveDataCompanyVO> empCountList = baseMapper.selectCompanyEmployeeCountByLiveIds(liveIds, companyIdsFromResult);
|
|
|
|
|
+
|
|
|
|
|
+ Map<Long, LiveDataCompanyVO> resultMap = new HashMap<>();
|
|
|
|
|
+ BiConsumer<List<LiveDataCompanyVO>, BiConsumer<LiveDataCompanyVO, LiveDataCompanyVO>> merge =
|
|
|
|
|
+ (vos, setter) -> {
|
|
|
|
|
+ if (vos == null) return;
|
|
|
|
|
+ for (LiveDataCompanyVO source : vos) {
|
|
|
|
|
+ if (source == null || source.getCompanyId() == null) continue;
|
|
|
|
|
+ LiveDataCompanyVO target = resultMap.computeIfAbsent(source.getCompanyId(), k -> {
|
|
|
|
|
+ LiveDataCompanyVO vo = new LiveDataCompanyVO();
|
|
|
|
|
+ vo.setCompanyId(source.getCompanyId());
|
|
|
|
|
+ vo.setCompanyName(source.getCompanyName());
|
|
|
|
|
+ vo.setTotalAttendanceCount(0L);
|
|
|
|
|
+ vo.setTotalCompleteCount(0L);
|
|
|
|
|
+ vo.setLiveAttendanceCount(0L);
|
|
|
|
|
+ vo.setLiveCompleteCount(0L);
|
|
|
|
|
+ vo.setReplayAttendanceCount(0L);
|
|
|
|
|
+ vo.setReplayCompleteCount(0L);
|
|
|
|
|
+ vo.setOrderCount(0L);
|
|
|
|
|
+ vo.setOrderUserCount(0L);
|
|
|
|
|
+ vo.setEmployeeCount(0L);
|
|
|
|
|
+ vo.setGmv(BigDecimal.ZERO);
|
|
|
|
|
+ vo.setTotalCompleteRate(0.0);
|
|
|
|
|
+ vo.setLiveCompleteRate(0.0);
|
|
|
|
|
+ vo.setReplayCompleteRate(0.0);
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ });
|
|
|
|
|
+ setter.accept(target, source);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ merge.accept(attendanceList, (t, s) -> t.setTotalAttendanceCount(s.getTotalAttendanceCount() == null ? 0L : s.getTotalAttendanceCount()));
|
|
|
|
|
+ merge.accept(completeList, (t, s) -> t.setTotalCompleteCount(s.getTotalCompleteCount() == null ? 0L : s.getTotalCompleteCount()));
|
|
|
|
|
+ merge.accept(liveAttendList, (t, s) -> t.setLiveAttendanceCount(s.getLiveAttendanceCount() == null ? 0L : s.getLiveAttendanceCount()));
|
|
|
|
|
+ merge.accept(liveCompleteList, (t, s) -> t.setLiveCompleteCount(s.getLiveCompleteCount() == null ? 0L : s.getLiveCompleteCount()));
|
|
|
|
|
+ merge.accept(replayAttendList, (t, s) -> t.setReplayAttendanceCount(s.getReplayAttendanceCount() == null ? 0L : s.getReplayAttendanceCount()));
|
|
|
|
|
+ merge.accept(replayCompleteList, (t, s) -> t.setReplayCompleteCount(s.getReplayCompleteCount() == null ? 0L : s.getReplayCompleteCount()));
|
|
|
|
|
+ merge.accept(gmvAndOrderList, (t, s) -> {
|
|
|
|
|
+ t.setGmv(roundGmv(s.getGmv() == null ? BigDecimal.ZERO : s.getGmv()));
|
|
|
|
|
+ t.setOrderCount(s.getOrderCount() == null ? 0L : s.getOrderCount());
|
|
|
|
|
+ t.setOrderUserCount(s.getOrderUserCount() == null ? 0L : s.getOrderUserCount());
|
|
|
|
|
+ });
|
|
|
|
|
+ merge.accept(empCountList, (t, s) -> t.setEmployeeCount(s.getEmployeeCount() == null ? 0L : s.getEmployeeCount()));
|
|
|
|
|
+
|
|
|
|
|
+ for (LiveDataCompanyVO vo : resultMap.values()) {
|
|
|
|
|
+ long totalAttend = vo.getTotalAttendanceCount() == null ? 0L : vo.getTotalAttendanceCount();
|
|
|
|
|
+ long totalComplete = vo.getTotalCompleteCount() == null ? 0L : vo.getTotalCompleteCount();
|
|
|
|
|
+ long liveAttend = vo.getLiveAttendanceCount() == null ? 0L : vo.getLiveAttendanceCount();
|
|
|
|
|
+ long liveComplete = vo.getLiveCompleteCount() == null ? 0L : vo.getLiveCompleteCount();
|
|
|
|
|
+ long replayAttend = vo.getReplayAttendanceCount() == null ? 0L : vo.getReplayAttendanceCount();
|
|
|
|
|
+ long replayComplete = vo.getReplayCompleteCount() == null ? 0L : vo.getReplayCompleteCount();
|
|
|
|
|
+ vo.setTotalCompleteRate(roundRate(totalAttend > 0 ? totalComplete * 100.0 / totalAttend : 0.0));
|
|
|
|
|
+ vo.setLiveCompleteRate(roundRate(liveAttend > 0 ? liveComplete * 100.0 / liveAttend : 0.0));
|
|
|
|
|
+ vo.setReplayCompleteRate(roundRate(replayAttend > 0 ? replayComplete * 100.0 / replayAttend : 0.0));
|
|
|
|
|
+ vo.setGmv(roundGmv(vo.getGmv()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return resultMap.values().stream()
|
|
|
|
|
+ .sorted(Comparator.comparing(vo -> Optional.ofNullable(vo.getCompanyName()).orElse("")))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 查询直播数据
|
|
* 查询直播数据
|
|
|
*
|
|
*
|