手表接口修改
This commit is contained in:
+36
-2
@@ -1,18 +1,23 @@
|
|||||||
package com.renkang.watch.vo.UserData.res;
|
package com.renkang.watch.vo.UserData.res;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.renkang.watch.WatchH5IndexItemNewVo;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/** 用户统计数据
|
/**
|
||||||
|
* 用户统计数据
|
||||||
|
*
|
||||||
* @author stan
|
* @author stan
|
||||||
* @since 2024-11-04 16:33
|
* @since 2024-11-04 16:33
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class UserStat {
|
public class UserStat {
|
||||||
/** 数据类型:0=心率 1=血氧 2=压力 3=体温 4=睡眠 */
|
/**
|
||||||
|
* 数据类型:0=心率 1=血氧 2=压力 3=体温 4=睡眠
|
||||||
|
*/
|
||||||
private String type;
|
private String type;
|
||||||
private BigDecimal latest;
|
private BigDecimal latest;
|
||||||
private BigDecimal max;
|
private BigDecimal max;
|
||||||
@@ -21,4 +26,33 @@ public class UserStat {
|
|||||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||||
private Date latestTime;
|
private Date latestTime;
|
||||||
|
|
||||||
|
public UserStat() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserStat(WatchH5IndexItemNewVo watchH5IndexItemNewVo) {
|
||||||
|
switch (watchH5IndexItemNewVo.getWdType()) {
|
||||||
|
case "sleep":
|
||||||
|
this.type = "4";
|
||||||
|
break;
|
||||||
|
case "heart_rate":
|
||||||
|
this.type = "0";
|
||||||
|
break;
|
||||||
|
case "stress":
|
||||||
|
this.type = "2";
|
||||||
|
break;
|
||||||
|
case "spo2":
|
||||||
|
this.type = "1";
|
||||||
|
break;
|
||||||
|
case "temperature":
|
||||||
|
this.type = "3";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.latest = BigDecimal.valueOf(Double.parseDouble(watchH5IndexItemNewVo.getDataValue()));
|
||||||
|
this.max = BigDecimal.valueOf(Double.parseDouble(watchH5IndexItemNewVo.getDataMax()));
|
||||||
|
this.min = BigDecimal.valueOf(Double.parseDouble(watchH5IndexItemNewVo.getDataMin()));
|
||||||
|
this.avg = BigDecimal.valueOf(Double.parseDouble(watchH5IndexItemNewVo.getDataAvg()));
|
||||||
|
this.latestTime = watchH5IndexItemNewVo.getDataDate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+167
-32
@@ -7,6 +7,8 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
|
import com.renkang.watch.WatchH5IndexItemNewVo;
|
||||||
import com.renkang.watch.api.bean.response.UserWatchInfo;
|
import com.renkang.watch.api.bean.response.UserWatchInfo;
|
||||||
import com.renkang.watch.api.service.WatchDataApiService;
|
import com.renkang.watch.api.service.WatchDataApiService;
|
||||||
import com.renkang.watch.dto.WatchDataWorkoutDTO;
|
import com.renkang.watch.dto.WatchDataWorkoutDTO;
|
||||||
@@ -24,6 +26,7 @@ import com.renkang.watch.vo.UserData.res.bodyTemperature.BodyTempStat;
|
|||||||
import com.renkang.watch.vo.UserData.res.bodyTemperature.BodyTempStatRes;
|
import com.renkang.watch.vo.UserData.res.bodyTemperature.BodyTempStatRes;
|
||||||
import com.renkang.watch.vo.UserData.res.heartRate.WatchDataHeartRateRes;
|
import com.renkang.watch.vo.UserData.res.heartRate.WatchDataHeartRateRes;
|
||||||
import com.renkang.watch.vo.UserData.res.sleep.WatchDataSleepRes;
|
import com.renkang.watch.vo.UserData.res.sleep.WatchDataSleepRes;
|
||||||
|
import com.renkang.watch.vo.WatchH5IndexItemVo;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.system.vo.LoginUser;
|
import org.jeecg.common.system.vo.LoginUser;
|
||||||
@@ -32,25 +35,25 @@ import org.jeecg.common.util.RedisUtil;
|
|||||||
import org.jeecg.global.GlobalUtils;
|
import org.jeecg.global.GlobalUtils;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.task.AsyncTaskExecutor;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class WatchDataApiServiceImpl implements WatchDataApiService {
|
public class WatchDataApiServiceImpl implements WatchDataApiService {
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WatchDataWorkoutMapper watchDataWorkoutMapper;
|
private WatchDataWorkoutMapper watchDataWorkoutMapper;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WatchStatUserInfoDayHeartRateMapper watchStatUserInfoDayHeartRateMapper;
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WatchDataHeartRateMapper watchDataHeartRateMapper;
|
private WatchDataHeartRateMapper watchDataHeartRateMapper;
|
||||||
|
|
||||||
@@ -62,9 +65,6 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WatchStatUserInfoDaySpo2ServiceImpl watchStatUserInfoDaySpo2ServiceImpl;
|
private WatchStatUserInfoDaySpo2ServiceImpl watchStatUserInfoDaySpo2ServiceImpl;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private WatchStatUserInfoDaySleepMapper watchStatUserInfoDaySleepMapper;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WatchDataSleepNewMinuteMapper watchDataSleepNewMinuteMapper;
|
private WatchDataSleepNewMinuteMapper watchDataSleepNewMinuteMapper;
|
||||||
|
|
||||||
@@ -98,7 +98,6 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IWatchDataTemperatureService watchDataTemperatureService;
|
private IWatchDataTemperatureService watchDataTemperatureService;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private IWatchDataStressService watchDataStressService;
|
private IWatchDataStressService watchDataStressService;
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -108,6 +107,10 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private WatchUserDataMapper watchUserDataMapper;
|
private WatchUserDataMapper watchUserDataMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private WatchStatUserInfoDayHeartRateMapper watchStatUserInfoDayHeartRateMapper;
|
||||||
|
@Autowired
|
||||||
|
private WatchStatUserInfoDaySleepMapper watchStatUserInfoDaySleepMapper;
|
||||||
|
@Autowired
|
||||||
private WatchStatUserInfoDaySpo2Mapper watchStatUserInfoDaySpo2Mapper;
|
private WatchStatUserInfoDaySpo2Mapper watchStatUserInfoDaySpo2Mapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private WatchStatUserInfoDayStressMapper watchStatUserInfoDayStressMapper;
|
private WatchStatUserInfoDayStressMapper watchStatUserInfoDayStressMapper;
|
||||||
@@ -120,6 +123,31 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
|||||||
/** 用户统计全量数据 Redis 缓存 key 前缀 */
|
/** 用户统计全量数据 Redis 缓存 key 前缀 */
|
||||||
private static final String USER_STAT_ALL_CACHE_KEY = "watch:userStatAll:";
|
private static final String USER_STAT_ALL_CACHE_KEY = "watch:userStatAll:";
|
||||||
|
|
||||||
|
private AsyncTaskExecutor asyncTaskExecutor;
|
||||||
|
|
||||||
|
public AsyncTaskExecutor getAsyncTaskExecutor() {
|
||||||
|
if (asyncTaskExecutor == null) {
|
||||||
|
initAsyncExecutor();
|
||||||
|
}
|
||||||
|
return asyncTaskExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
initAsyncExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initAsyncExecutor() {
|
||||||
|
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
|
||||||
|
taskExecutor.setCorePoolSize(150);
|
||||||
|
taskExecutor.setMaxPoolSize(500);
|
||||||
|
taskExecutor.setQueueCapacity(500);
|
||||||
|
taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
|
||||||
|
taskExecutor.setThreadNamePrefix("watch-latest-pool1-");
|
||||||
|
taskExecutor.initialize();
|
||||||
|
asyncTaskExecutor = taskExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<Map<String,Object>> selectSportCostListApi() {
|
public Result<Map<String,Object>> selectSportCostListApi() {
|
||||||
LoginUser loginUser = GlobalUtils.getLoginUser();
|
LoginUser loginUser = GlobalUtils.getLoginUser();
|
||||||
@@ -866,39 +894,146 @@ public class WatchDataApiServiceImpl implements WatchDataApiService {
|
|||||||
// 命中 Redis 缓存直接返回
|
// 命中 Redis 缓存直接返回
|
||||||
Object cached = redisUtil.get(cacheKey);
|
Object cached = redisUtil.get(cacheKey);
|
||||||
if (cached != null) {
|
if (cached != null) {
|
||||||
//noinspection unchecked
|
|
||||||
return (List<UserStat>) cached;
|
return (List<UserStat>) cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 并行异步查询5种数据,thenApply 在任务完成时立即绑定 type,与顺序无关
|
// 构建「数据类型 → 异步查询 Future」映射,消除 switch-case 冗余
|
||||||
CompletableFuture<UserStat> heartRateFuture = CompletableFuture.supplyAsync(() -> handleHeartRate(userId, date))
|
Map<String, CompletableFuture<WatchH5IndexItemNewVo>> futureMap = new HashMap<>();
|
||||||
.thenApply(stat -> setType(stat, "0"));
|
futureMap.put("sleep", CompletableFuture.supplyAsync(() -> latestSleepData(userId), getAsyncTaskExecutor()));
|
||||||
CompletableFuture<UserStat> bloodOxygenFuture = CompletableFuture.supplyAsync(() -> handleBloodOxygen(userId, date))
|
futureMap.put("heart_rate", CompletableFuture.supplyAsync(() -> latestHeartRateData(userId), getAsyncTaskExecutor()));
|
||||||
.thenApply(stat -> setType(stat, "1"));
|
futureMap.put("spo2", CompletableFuture.supplyAsync(() -> latestSpo2Data(userId), getAsyncTaskExecutor()));
|
||||||
CompletableFuture<UserStat> stressFuture = CompletableFuture.supplyAsync(() -> handleStress(userId, date))
|
futureMap.put("stress", CompletableFuture.supplyAsync(() -> latestStressData(userId), getAsyncTaskExecutor()));
|
||||||
.thenApply(stat -> setType(stat, "2"));
|
futureMap.put("temperature", CompletableFuture.supplyAsync(() -> latestTempData(userId), getAsyncTaskExecutor()));
|
||||||
CompletableFuture<UserStat> bodyTempFuture = CompletableFuture.supplyAsync(() -> handleBodyTemperature(userId, date))
|
|
||||||
.thenApply(stat -> setType(stat, "3"));
|
|
||||||
CompletableFuture<UserStat> sleepFuture = CompletableFuture.supplyAsync(() -> handleSleep(userId, date))
|
|
||||||
.thenApply(stat -> setType(stat, "4"));
|
|
||||||
|
|
||||||
// 等待所有子任务完成
|
// 等待全部异步查询完成
|
||||||
CompletableFuture.allOf(heartRateFuture, bloodOxygenFuture, stressFuture, bodyTempFuture, sleepFuture).join();
|
CompletableFuture.allOf(futureMap.values().toArray(new CompletableFuture[0])).join();
|
||||||
|
|
||||||
// 组装结果列表,每条数据已在异步阶段绑定好 type
|
// 转为顺序流遍历,避免并行流写入 ArrayList 的线程安全问题
|
||||||
List<UserStat> result = Arrays.asList(
|
List<WatchH5IndexItemNewVo> list = new ArrayList<>();
|
||||||
heartRateFuture.join(),
|
emptyItems().sequential().forEach(itemVo -> {
|
||||||
bloodOxygenFuture.join(),
|
CompletableFuture<WatchH5IndexItemNewVo> future = futureMap.get(itemVo.getWdType());
|
||||||
stressFuture.join(),
|
// steps 等暂无对应查询的类型直接跳过
|
||||||
bodyTempFuture.join(),
|
if (future == null) {
|
||||||
sleepFuture.join()
|
return;
|
||||||
);
|
}
|
||||||
|
WatchH5IndexItemNewVo data = future.join();
|
||||||
|
if (data == null) {
|
||||||
|
data = new WatchH5IndexItemNewVo();
|
||||||
|
}
|
||||||
|
// 将模板字段(wdType、wdTypeName、阈值)合并到结果对象
|
||||||
|
data.fieldCopy(itemVo);
|
||||||
|
// 睡眠数据特殊处理:dataValue 为空时补 "0"
|
||||||
|
if ("sleep".equals(itemVo.getWdType()) && StrUtil.isEmpty(data.getDataValue())) {
|
||||||
|
data.setDataValue("0");
|
||||||
|
}
|
||||||
|
list.add(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
List<UserStat> result = list.stream().map(UserStat::new).collect(Collectors.toList());
|
||||||
|
|
||||||
// 写入 Redis 缓存,TTL=3分钟(180秒)
|
// 写入 Redis 缓存,TTL=3分钟(180秒)
|
||||||
redisUtil.set(cacheKey, result, 180);
|
redisUtil.set(cacheKey, result, 180);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream<WatchH5IndexItemVo> emptyItems() {
|
||||||
|
//睡眠
|
||||||
|
WatchH5IndexItemVo sleepVo = new WatchH5IndexItemVo();
|
||||||
|
sleepVo.setWdType("sleep");
|
||||||
|
//步数
|
||||||
|
WatchH5IndexItemVo stepsVo = new WatchH5IndexItemVo();
|
||||||
|
stepsVo.setWdType("steps");
|
||||||
|
//心率
|
||||||
|
WatchH5IndexItemVo hearRateVo = new WatchH5IndexItemVo();
|
||||||
|
hearRateVo.setWdType("heart_rate");
|
||||||
|
//压力
|
||||||
|
WatchH5IndexItemVo stressVo = new WatchH5IndexItemVo();
|
||||||
|
stressVo.setWdType("stress");
|
||||||
|
//血氧饱和度
|
||||||
|
WatchH5IndexItemVo spo2Vo = new WatchH5IndexItemVo();
|
||||||
|
spo2Vo.setWdType("spo2");
|
||||||
|
//体温
|
||||||
|
WatchH5IndexItemVo tempVo = new WatchH5IndexItemVo();
|
||||||
|
tempVo.setWdType("temperature");
|
||||||
|
List<WatchH5IndexItemVo> list = Arrays.asList(sleepVo, stepsVo, hearRateVo, stressVo, spo2Vo, tempVo);
|
||||||
|
return list.parallelStream()
|
||||||
|
.peek(itemVo -> {
|
||||||
|
itemVo.setWarnMin("0.0");
|
||||||
|
itemVo.setWarnMax("0.0");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private WatchH5IndexItemNewVo latestSleepData(String userId) {
|
||||||
|
MPJLambdaWrapper<WatchStatUserInfoDaySleep> wrapper = new MPJLambdaWrapper<>();
|
||||||
|
//因为睡眠详情页取的是长睡时长作为当天的睡眠时间 , 所以这里保持一致并没有取当天的睡眠总时长
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySleep::getLongDurationTotal,WatchH5IndexItemNewVo::getDataValue);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySleep::getLongDurationTotal,WatchH5IndexItemNewVo::getDataMax);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySleep::getShortDurationTotal,WatchH5IndexItemNewVo::getDataMin);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySleep::getDataDate,WatchH5IndexItemNewVo::getDataDate);
|
||||||
|
wrapper.eq(WatchStatUserInfoDaySleep::getUserId, userId);
|
||||||
|
wrapper.orderByDesc(WatchStatUserInfoDaySleep::getDataDate);
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
return watchStatUserInfoDaySleepMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WatchH5IndexItemNewVo latestHeartRateData(String userId) {
|
||||||
|
MPJLambdaWrapper<WatchStatUserInfoDayHeartRate> wrapper = new MPJLambdaWrapper<>();
|
||||||
|
// 必须是watch_stat_user_info_day_heart_rate表中new_data字段启用后才能这样查
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayHeartRate::getDataDate,WatchH5IndexItemNewVo::getDataDate);
|
||||||
|
wrapper.eq(WatchStatUserInfoDayHeartRate::getUserId, userId);
|
||||||
|
wrapper.orderByDesc(WatchStatUserInfoDayHeartRate::getDataDate);
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
return watchStatUserInfoDayHeartRateMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WatchH5IndexItemNewVo latestSpo2Data(String userId) {
|
||||||
|
MPJLambdaWrapper<WatchStatUserInfoDaySpo2> wrapper = new MPJLambdaWrapper<>();
|
||||||
|
// 必须是watch_stat_user_info_day_spo2表中new_data字段启用后才能这样查
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySpo2::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySpo2::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySpo2::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySpo2::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDaySpo2::getDataDate,WatchH5IndexItemNewVo::getDataDate);
|
||||||
|
wrapper.eq(WatchStatUserInfoDaySpo2::getUserId, userId);
|
||||||
|
wrapper.orderByDesc(WatchStatUserInfoDaySpo2::getDataDate);
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
return watchStatUserInfoDaySpo2Mapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WatchH5IndexItemNewVo latestStressData(String userId) {
|
||||||
|
MPJLambdaWrapper<WatchStatUserInfoDayStress> wrapper = new MPJLambdaWrapper<>();
|
||||||
|
// 必须是watch_stat_user_info_day_stress表中new_data字段启用后才能这样查
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayStress::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayStress::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayStress::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayStress::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayStress::getDataDate,WatchH5IndexItemNewVo::getDataDate);
|
||||||
|
wrapper.eq(WatchStatUserInfoDayStress::getUserId, userId);
|
||||||
|
wrapper.orderByDesc(WatchStatUserInfoDayStress::getDataDate);
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
return watchStatUserInfoDayStressMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private WatchH5IndexItemNewVo latestTempData(String userId) {
|
||||||
|
MPJLambdaWrapper<WatchStatUserInfoDayTemp> wrapper = new MPJLambdaWrapper<>();
|
||||||
|
// 必须是watch_stat_user_info_day_temp表中new_data字段启用后才能这样查
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayTemp::getNewValue,WatchH5IndexItemNewVo::getDataValue);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayTemp::getMaxValue,WatchH5IndexItemNewVo::getDataMax);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayTemp::getMinValue,WatchH5IndexItemNewVo::getDataMin);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayTemp::getAvgValue,WatchH5IndexItemNewVo::getDataAvg);
|
||||||
|
wrapper.selectAs(WatchStatUserInfoDayTemp::getDataDate,WatchH5IndexItemNewVo::getDataDate);
|
||||||
|
wrapper.eq(WatchStatUserInfoDayTemp::getUserId, userId);
|
||||||
|
wrapper.orderByDesc(WatchStatUserInfoDayTemp::getDataDate);
|
||||||
|
wrapper.last("limit 1");
|
||||||
|
return watchStatUserInfoDayTempMapper.selectJoinOne(WatchH5IndexItemNewVo.class,wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean userHaveWatch(String userId) {
|
public Boolean userHaveWatch(String userId) {
|
||||||
if (StrUtil.isBlank(userId)) {
|
if (StrUtil.isBlank(userId)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user