|
@@ -10,14 +10,18 @@ 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.common.utils.ParseUtils;
|
|
|
import com.fs.live.param.LiveDataCompanyParam;
|
|
import com.fs.live.param.LiveDataCompanyParam;
|
|
|
import com.fs.live.param.LiveDataParam;
|
|
import com.fs.live.param.LiveDataParam;
|
|
|
|
|
+import com.fs.live.param.LiveRoomStudentParam;
|
|
|
import com.fs.live.service.ILiveDataService;
|
|
import com.fs.live.service.ILiveDataService;
|
|
|
import com.fs.live.service.ILiveUserFavoriteService;
|
|
import com.fs.live.service.ILiveUserFavoriteService;
|
|
|
import com.fs.live.service.ILiveUserFollowService;
|
|
import com.fs.live.service.ILiveUserFollowService;
|
|
|
import com.fs.live.service.ILiveUserLikeService;
|
|
import com.fs.live.service.ILiveUserLikeService;
|
|
|
import com.fs.live.service.ILiveWatchUserService;
|
|
import com.fs.live.service.ILiveWatchUserService;
|
|
|
import com.fs.live.vo.*;
|
|
import com.fs.live.vo.*;
|
|
|
|
|
+import com.fs.live.vo.LiveRoomStudentQueryVO;
|
|
|
|
|
+import com.fs.live.vo.LiveRoomStudentVO;
|
|
|
import com.fs.company.domain.Company;
|
|
import com.fs.company.domain.Company;
|
|
|
import com.fs.company.domain.CompanyUser;
|
|
import com.fs.company.domain.CompanyUser;
|
|
|
import com.fs.company.mapper.CompanyMapper;
|
|
import com.fs.company.mapper.CompanyMapper;
|
|
@@ -33,6 +37,7 @@ import com.fs.hisStore.vo.FsStoreOrderItemVO;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
import java.util.function.BiConsumer;
|
|
import java.util.function.BiConsumer;
|
|
|
|
|
|
|
|
|
|
+import com.github.pagehelper.PageHelper;
|
|
|
import com.github.pagehelper.PageInfo;
|
|
import com.github.pagehelper.PageInfo;
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
@@ -51,6 +56,7 @@ import java.util.*;
|
|
|
import java.util.concurrent.*;
|
|
import java.util.concurrent.*;
|
|
|
|
|
|
|
|
import static com.fs.common.constant.LiveKeysConstant.*;
|
|
import static com.fs.common.constant.LiveKeysConstant.*;
|
|
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -256,6 +262,314 @@ public class LiveDataServiceImpl implements ILiveDataService {
|
|
|
return queryLiveDataCompanyByDateRange(param);
|
|
return queryLiveDataCompanyByDateRange(param);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public LiveStatisticsOverviewVO getLiveStatisticsOverview(List<Long> liveIds) {
|
|
|
|
|
+ LiveStatisticsOverviewVO vo = new LiveStatisticsOverviewVO();
|
|
|
|
|
+ if (liveIds == null || liveIds.isEmpty()) {
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 1. 先从 live_data 查询已有缓存的直播间
|
|
|
|
|
+ List<LiveData> cachedList = liveDataMapper.selectLiveDataOverviewByLiveIds(liveIds);
|
|
|
|
|
+ Set<Long> cachedLiveIds = cachedList == null ? Collections.emptySet()
|
|
|
|
|
+ : cachedList.stream().map(LiveData::getLiveId).filter(Objects::nonNull).collect(Collectors.toSet());
|
|
|
|
|
+ List<Long> needCalcIds = liveIds.stream().filter(id -> !cachedLiveIds.contains(id)).collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 对未缓存的直播间进行统计并保存到 live_data
|
|
|
|
|
+ if (!needCalcIds.isEmpty()) {
|
|
|
|
|
+ for (Long liveId : needCalcIds) {
|
|
|
|
|
+ LiveData overviewData = calculateAndSaveOverviewForLive(Collections.singletonList(liveId));
|
|
|
|
|
+ if (overviewData != null) {
|
|
|
|
|
+ cachedList = cachedList == null ? new ArrayList<>() : cachedList;
|
|
|
|
|
+ overviewData.setLiveId(liveId);
|
|
|
|
|
+ cachedList.add(overviewData);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 聚合所有直播间数据(来自缓存 + 新计算的)
|
|
|
|
|
+ if (cachedList == null || cachedList.isEmpty()) {
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+ long beforeLiveUv = 0, totalWatchUv = 0, over10MinCount = 0, totalWatchMinutes = 0;
|
|
|
|
|
+ long watchTotalSeconds = 0, watchUserCount = 0;
|
|
|
|
|
+ long replayWatchUv = 0, replayVisitPv = 0, replayOnlyCount = 0, replayTotalMinutes = 0;
|
|
|
|
|
+ long replayTotalSeconds = 0, replayUserCount = 0;
|
|
|
|
|
+ long completeCount = 0, subscribeCount = 0, lotteryCount = 0, lotteryJoinCount = 0, lotteryWinCount = 0;
|
|
|
|
|
+ long paidUserCount = 0, unpaidUserCount = 0, totalProductQty = 0;
|
|
|
|
|
+ BigDecimal totalGmv = BigDecimal.ZERO;
|
|
|
|
|
+ for (LiveData ld : cachedList) {
|
|
|
|
|
+ beforeLiveUv += nullToZero(ld.getOverviewBeforeLiveUv());
|
|
|
|
|
+ totalWatchUv += nullToZero(ld.getOverviewTotalWatchUv());
|
|
|
|
|
+ over10MinCount += nullToZero(ld.getOverviewOver10MinCount());
|
|
|
|
|
+ totalWatchMinutes += nullToZero(ld.getOverviewTotalWatchMinutes());
|
|
|
|
|
+ watchTotalSeconds += nullToZero(ld.getOverviewWatchTotalSeconds());
|
|
|
|
|
+ watchUserCount += nullToZero(ld.getOverviewWatchUserCount());
|
|
|
|
|
+ replayWatchUv += nullToZero(ld.getOverviewReplayWatchUv());
|
|
|
|
|
+ replayVisitPv += nullToZero(ld.getOverviewReplayVisitPv());
|
|
|
|
|
+ replayOnlyCount += nullToZero(ld.getOverviewReplayOnlyCount());
|
|
|
|
|
+ replayTotalMinutes += nullToZero(ld.getOverviewReplayTotalMinutes());
|
|
|
|
|
+ replayTotalSeconds += nullToZero(ld.getOverviewReplayTotalSeconds());
|
|
|
|
|
+ replayUserCount += nullToZero(ld.getOverviewReplayUserCount());
|
|
|
|
|
+ completeCount += nullToZero(ld.getOverviewCompleteCount());
|
|
|
|
|
+ subscribeCount += nullToZero(ld.getOverviewSubscribeCount());
|
|
|
|
|
+ lotteryCount += nullToZero(ld.getOverviewLotteryCount());
|
|
|
|
|
+ lotteryJoinCount += nullToZero(ld.getOverviewLotteryJoinCount());
|
|
|
|
|
+ lotteryWinCount += nullToZero(ld.getOverviewLotteryWinCount());
|
|
|
|
|
+ paidUserCount += nullToZero(ld.getOverviewPaidUserCount());
|
|
|
|
|
+ unpaidUserCount += nullToZero(ld.getOverviewUnpaidUserCount());
|
|
|
|
|
+ totalProductQty += nullToZero(ld.getOverviewTotalProductQty());
|
|
|
|
|
+ if (ld.getOverviewTotalGmv() != null) {
|
|
|
|
|
+ totalGmv = totalGmv.add(ld.getOverviewTotalGmv());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ vo.setBeforeLiveUv(beforeLiveUv);
|
|
|
|
|
+ vo.setTotalWatchUv(totalWatchUv);
|
|
|
|
|
+ vo.setOver10MinCount(over10MinCount);
|
|
|
|
|
+ vo.setTotalWatchMinutes(totalWatchMinutes);
|
|
|
|
|
+ vo.setAvgWatchMinutes(calcAvgMinutes(watchTotalSeconds, watchUserCount));
|
|
|
|
|
+ vo.setReplayWatchUv(replayWatchUv);
|
|
|
|
|
+ vo.setReplayVisitPv(replayVisitPv);
|
|
|
|
|
+ vo.setReplayOnlyCount(replayOnlyCount);
|
|
|
|
|
+ vo.setReplayTotalMinutes(replayTotalMinutes);
|
|
|
|
|
+ vo.setReplayAvgMinutes(calcAvgMinutes(replayTotalSeconds, replayUserCount));
|
|
|
|
|
+ vo.setCompleteCount(completeCount);
|
|
|
|
|
+ vo.setSubscribeCount(subscribeCount);
|
|
|
|
|
+ vo.setLotteryCount(lotteryCount);
|
|
|
|
|
+ vo.setLotteryJoinCount(lotteryJoinCount);
|
|
|
|
|
+ vo.setLotteryWinCount(lotteryWinCount);
|
|
|
|
|
+ vo.setPaidUserCount(paidUserCount);
|
|
|
|
|
+ vo.setUnpaidUserCount(unpaidUserCount);
|
|
|
|
|
+ vo.setTotalGmv(totalGmv);
|
|
|
|
|
+ vo.setTotalProductQty(totalProductQty);
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 对指定直播间进行统计,保存到 live_data,并返回 LiveData
|
|
|
|
|
+ */
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public LiveData calculateAndSaveOverviewForLive(List<Long> liveIds) {
|
|
|
|
|
+ if (liveIds == null || liveIds.isEmpty()) return null;
|
|
|
|
|
+ CompletableFuture<Long> fBeforeLiveUv = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewBeforeLiveUv(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fTotalWatchUv = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewTotalWatchUv(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fOver10MinCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewOver10MinCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fWatchTotalSeconds = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewWatchTotalSeconds(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fWatchUserCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewWatchUserCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fReplayWatchUv = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewReplayWatchUv(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fReplayVisitPv = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewReplayVisitPv(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fReplayOnlyCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewReplayOnlyCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fReplayTotalSeconds = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewReplayTotalSeconds(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fReplayUserCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewReplayUserCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fCompleteCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewCompleteCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fSubscribeCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewSubscribeCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fLotteryCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewLotteryCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fLotteryJoinCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewLotteryJoinCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fLotteryWinCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewLotteryWinCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fPaidUserCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewPaidUserCount(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fUnpaidUserCount = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewUnpaidUserCount(liveIds));
|
|
|
|
|
+ CompletableFuture<BigDecimal> fTotalGmv = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewTotalGmv(liveIds));
|
|
|
|
|
+ CompletableFuture<Long> fTotalProductQty = CompletableFuture.supplyAsync(() -> liveDataMapper.selectOverviewTotalProductQty(liveIds));
|
|
|
|
|
+
|
|
|
|
|
+ CompletableFuture.allOf(fBeforeLiveUv, fTotalWatchUv, fOver10MinCount, fWatchTotalSeconds, fWatchUserCount,
|
|
|
|
|
+ fReplayWatchUv, fReplayVisitPv, fReplayOnlyCount, fReplayTotalSeconds, fReplayUserCount,
|
|
|
|
|
+ fCompleteCount, fSubscribeCount, fLotteryCount, fLotteryJoinCount, fLotteryWinCount,
|
|
|
|
|
+ fPaidUserCount, fUnpaidUserCount, fTotalGmv, fTotalProductQty).join();
|
|
|
|
|
+
|
|
|
|
|
+ Long watchTotalSeconds = fWatchTotalSeconds.join();
|
|
|
|
|
+ Long watchUserCount = fWatchUserCount.join();
|
|
|
|
|
+ Long replayTotalSeconds = fReplayTotalSeconds.join();
|
|
|
|
|
+ Long replayUserCount = fReplayUserCount.join();
|
|
|
|
|
+ long totalWatchMinutes = nullToZero(watchTotalSeconds) / 60;
|
|
|
|
|
+ long replayTotalMinutes = nullToZero(replayTotalSeconds) / 60;
|
|
|
|
|
+
|
|
|
|
|
+ LiveData ld = new LiveData();
|
|
|
|
|
+ ld.setLiveId(liveIds.get(0));
|
|
|
|
|
+ ld.setOverviewBeforeLiveUv(fBeforeLiveUv.join());
|
|
|
|
|
+ ld.setOverviewTotalWatchUv(fTotalWatchUv.join());
|
|
|
|
|
+ ld.setOverviewOver10MinCount(fOver10MinCount.join());
|
|
|
|
|
+ ld.setOverviewTotalWatchMinutes(totalWatchMinutes);
|
|
|
|
|
+ ld.setOverviewWatchTotalSeconds(watchTotalSeconds);
|
|
|
|
|
+ ld.setOverviewWatchUserCount(watchUserCount);
|
|
|
|
|
+ ld.setOverviewReplayWatchUv(fReplayWatchUv.join());
|
|
|
|
|
+ ld.setOverviewReplayVisitPv(fReplayVisitPv.join());
|
|
|
|
|
+ ld.setOverviewReplayOnlyCount(fReplayOnlyCount.join());
|
|
|
|
|
+ ld.setOverviewReplayTotalMinutes(replayTotalMinutes);
|
|
|
|
|
+ ld.setOverviewReplayTotalSeconds(replayTotalSeconds);
|
|
|
|
|
+ ld.setOverviewReplayUserCount(replayUserCount);
|
|
|
|
|
+ ld.setOverviewCompleteCount(fCompleteCount.join());
|
|
|
|
|
+ ld.setOverviewSubscribeCount(fSubscribeCount.join());
|
|
|
|
|
+ ld.setOverviewLotteryCount(fLotteryCount.join());
|
|
|
|
|
+ ld.setOverviewLotteryJoinCount(fLotteryJoinCount.join());
|
|
|
|
|
+ ld.setOverviewLotteryWinCount(fLotteryWinCount.join());
|
|
|
|
|
+ ld.setOverviewPaidUserCount(fPaidUserCount.join());
|
|
|
|
|
+ ld.setOverviewUnpaidUserCount(fUnpaidUserCount.join());
|
|
|
|
|
+ ld.setOverviewTotalGmv(fTotalGmv.join());
|
|
|
|
|
+ ld.setOverviewTotalProductQty(fTotalProductQty.join());
|
|
|
|
|
+
|
|
|
|
|
+ // 保存到 live_data:先尝试 update,无行则 insert
|
|
|
|
|
+ int updated = liveDataMapper.updateLiveDataOverview(ld);
|
|
|
|
|
+ if (updated == 0) {
|
|
|
|
|
+ liveDataMapper.insertLiveDataOverview(ld);
|
|
|
|
|
+ }
|
|
|
|
|
+ return ld;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private long nullToZero(Long v) {
|
|
|
|
|
+ return v == null ? 0L : v;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private BigDecimal calcAvgMinutes(long totalSeconds, long userCount) {
|
|
|
|
|
+ if (userCount <= 0) return BigDecimal.ZERO;
|
|
|
|
|
+ return BigDecimal.valueOf(totalSeconds)
|
|
|
|
|
+ .divide(BigDecimal.valueOf(60 * userCount), 2, RoundingMode.HALF_UP);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public LiveEntryTrendVO getLiveEntryTrend(List<Long> liveIds) {
|
|
|
|
|
+ LiveEntryTrendVO vo = new LiveEntryTrendVO();
|
|
|
|
|
+ if (liveIds == null || liveIds.isEmpty()) {
|
|
|
|
|
+ vo.setXAxis(Collections.singletonList("开播前"));
|
|
|
|
|
+ vo.setSeries(Collections.emptyList());
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+ List<Map<String, Object>> rawList = liveDataMapper.selectLiveEntryTrendRawData(liveIds);
|
|
|
|
|
+ if (rawList == null || rawList.isEmpty()) {
|
|
|
|
|
+ vo.setXAxis(Collections.singletonList("开播前"));
|
|
|
|
|
+ vo.setSeries(Collections.emptyList());
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 时间桶:开播前, 0min, 5min, 10min, ... (步长5分钟,最多到120分钟)
|
|
|
|
|
+ int stepMinutes = 5;
|
|
|
|
|
+ int maxMinutes = 120;
|
|
|
|
|
+ List<String> xAxis = new ArrayList<>();
|
|
|
|
|
+ xAxis.add("开播前");
|
|
|
|
|
+ for (int m = 0; m <= maxMinutes; m += stepMinutes) {
|
|
|
|
|
+ xAxis.add(m + "min");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 按 liveId 分组,每个直播间一条折线(累计进入人数)
|
|
|
|
|
+ Map<String, Map<Integer, Integer>> liveBucketCount = new LinkedHashMap<>();
|
|
|
|
|
+ for (Map<String, Object> row : rawList) {
|
|
|
|
|
+ Object liveIdObj = row.get("liveId");
|
|
|
|
|
+ Object liveNameObj = row.get("liveName");
|
|
|
|
|
+ Object startTimeObj = row.get("startTime");
|
|
|
|
|
+ Object entryTimeObj = row.get("entryTime");
|
|
|
|
|
+ if (liveIdObj == null || startTimeObj == null || entryTimeObj == null) continue;
|
|
|
|
|
+ long liveId = ((Number) liveIdObj).longValue();
|
|
|
|
|
+ String liveName = liveNameObj != null ? liveNameObj.toString() : String.valueOf(liveId);
|
|
|
|
|
+ String seriesKey = liveId + "|" + liveName;
|
|
|
|
|
+ Date startTime = toDate(startTimeObj);
|
|
|
|
|
+ Date entryTime = toDate(entryTimeObj);
|
|
|
|
|
+ if (startTime == null || entryTime == null) continue;
|
|
|
|
|
+ long diffMinutes = (entryTime.getTime() - startTime.getTime()) / (60 * 1000);
|
|
|
|
|
+ int bucketIdx;
|
|
|
|
|
+ if (diffMinutes < 0) {
|
|
|
|
|
+ bucketIdx = 0; // 开播前
|
|
|
|
|
+ } else {
|
|
|
|
|
+ int m = (int) Math.min(diffMinutes, maxMinutes);
|
|
|
|
|
+ bucketIdx = 1 + (m / stepMinutes); // 1-based, 0 is 开播前
|
|
|
|
|
+ }
|
|
|
|
|
+ liveBucketCount
|
|
|
|
|
+ .computeIfAbsent(seriesKey, k -> new LinkedHashMap<>())
|
|
|
|
|
+ .merge(bucketIdx, 1, Integer::sum);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 转为累计值并生成 series
|
|
|
|
|
+ List<LiveEntryTrendSeriesVO> seriesList = new ArrayList<>();
|
|
|
|
|
+ for (Map.Entry<String, Map<Integer, Integer>> e : liveBucketCount.entrySet()) {
|
|
|
|
|
+ String[] parts = e.getKey().split("\\|", 2);
|
|
|
|
|
+ String name = parts.length > 1 ? parts[1] + "(" + parts[0] + ")" : parts[0];
|
|
|
|
|
+ Map<Integer, Integer> countMap = e.getValue();
|
|
|
|
|
+ List<Integer> data = new ArrayList<>(xAxis.size());
|
|
|
|
|
+ int cumulative = 0;
|
|
|
|
|
+ for (int i = 0; i < xAxis.size(); i++) {
|
|
|
|
|
+ cumulative += countMap.getOrDefault(i, 0);
|
|
|
|
|
+ data.add(cumulative);
|
|
|
|
|
+ }
|
|
|
|
|
+ seriesList.add(new LiveEntryTrendSeriesVO(name, data));
|
|
|
|
|
+ }
|
|
|
|
|
+ vo.setXAxis(xAxis);
|
|
|
|
|
+ vo.setSeries(seriesList);
|
|
|
|
|
+ return vo;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R listLiveRoomStudents(LiveRoomStudentParam param) {
|
|
|
|
|
+ if (param == null) {
|
|
|
|
|
+ param = new LiveRoomStudentParam();
|
|
|
|
|
+ }
|
|
|
|
|
+ if (param.getPageNum() == null || param.getPageNum() < 1) {
|
|
|
|
|
+ param.setPageNum(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (param.getPageSize() == null || param.getPageSize() < 1) {
|
|
|
|
|
+ param.setPageSize(10);
|
|
|
|
|
+ }
|
|
|
|
|
+ PageHelper.startPage(param.getPageNum(), param.getPageSize());
|
|
|
|
|
+ List<LiveRoomStudentQueryVO> queryList = liveDataMapper.selectLiveRoomStudentList(param);
|
|
|
|
|
+ PageInfo<LiveRoomStudentQueryVO> pageInfo = new PageInfo<>(queryList);
|
|
|
|
|
+ List<LiveRoomStudentVO> resultList = new ArrayList<>();
|
|
|
|
|
+ if (queryList != null) {
|
|
|
|
|
+ for (LiveRoomStudentQueryVO q : queryList) {
|
|
|
|
|
+ LiveRoomStudentVO vo = new LiveRoomStudentVO();
|
|
|
|
|
+ vo.setAvatar(q.getAvatar());
|
|
|
|
|
+ vo.setUserName(q.getUserName());
|
|
|
|
|
+ vo.setLiveName(q.getLiveName());
|
|
|
|
|
+ vo.setSalesName(q.getSalesName());
|
|
|
|
|
+ vo.setUserCreateTime(q.getUserCreateTime());
|
|
|
|
|
+ vo.setContact(ParseUtils.parsePhone(q.getPhone()));
|
|
|
|
|
+ resultList.add(vo);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return R.ok().put("rows", resultList).put("total", pageInfo.getTotal());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R listProductCompareStats(com.fs.live.param.ProductCompareParam param) {
|
|
|
|
|
+ if (param == null || param.getLiveIds() == null || param.getLiveIds().isEmpty()) {
|
|
|
|
|
+ return R.ok().put("rows", Collections.emptyList()).put("total", 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (param.getPageNum() == null || param.getPageNum() < 1) {
|
|
|
|
|
+ param.setPageNum(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (param.getPageSize() == null || param.getPageSize() < 1) {
|
|
|
|
|
+ param.setPageSize(10);
|
|
|
|
|
+ }
|
|
|
|
|
+ PageHelper.startPage(param.getPageNum(), param.getPageSize());
|
|
|
|
|
+ List<com.fs.live.vo.ProductCompareVO> list = liveDataMapper.selectProductCompareList(param);
|
|
|
|
|
+ PageInfo<com.fs.live.vo.ProductCompareVO> pageInfo = new PageInfo<>(list);
|
|
|
|
|
+ return R.ok().put("rows", pageInfo.getList()).put("total", pageInfo.getTotal());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public List<com.fs.live.vo.InviteSalesOptionVO> listInviteSalesOptions(List<Long> liveIds) {
|
|
|
|
|
+ if (liveIds == null || liveIds.isEmpty()) {
|
|
|
|
|
+ return Collections.emptyList();
|
|
|
|
|
+ }
|
|
|
|
|
+ return liveDataMapper.selectInviteSalesOptions(liveIds);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public R listInviteCompareStats(com.fs.live.param.InviteCompareParam param) {
|
|
|
|
|
+ if (param == null || param.getLiveIds() == null || param.getLiveIds().isEmpty()) {
|
|
|
|
|
+ return R.ok().put("rows", Collections.emptyList()).put("total", 0);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (param.getPageNum() == null || param.getPageNum() < 1) {
|
|
|
|
|
+ param.setPageNum(1);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (param.getPageSize() == null || param.getPageSize() < 1) {
|
|
|
|
|
+ param.setPageSize(10);
|
|
|
|
|
+ }
|
|
|
|
|
+ PageHelper.startPage(param.getPageNum(), param.getPageSize());
|
|
|
|
|
+ List<com.fs.live.vo.InviteCompareVO> list = liveDataMapper.selectInviteCompareList(param);
|
|
|
|
|
+ PageInfo<com.fs.live.vo.InviteCompareVO> pageInfo = new PageInfo<>(list);
|
|
|
|
|
+ return R.ok().put("rows", pageInfo.getList()).put("total", pageInfo.getTotal());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private Date toDate(Object val) {
|
|
|
|
|
+ if (val == null) return null;
|
|
|
|
|
+ if (val instanceof Date) return (Date) val;
|
|
|
|
|
+ if (val instanceof java.sql.Timestamp) return new Date(((java.sql.Timestamp) val).getTime());
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 多线程分段查询:步长7天,等待各段数据返回后合并
|
|
* 多线程分段查询:步长7天,等待各段数据返回后合并
|
|
|
*/
|
|
*/
|