营养分析
This commit is contained in:
@ -24,10 +24,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
@ -117,7 +114,12 @@ public class MemberUserController {
|
||||
convertSet(pageResult.getList(), MemberUserDO::getGroupId));
|
||||
return success(MemberUserConvert.INSTANCE.convertPage(pageResult, tags, levels, groups));
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/heat")
|
||||
@Operation(summary = "获得会员热量分析")
|
||||
@PreAuthorize("@ss.hasPermission('member:user:query')")
|
||||
public CommonResult<List<Map>> getUserHeat(@RequestParam("userId") Long userId,
|
||||
@RequestParam(value = "days")Integer days){
|
||||
return success(memberUserService.getUserHeat(userId,days));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 会员用户 Service 接口
|
||||
@ -207,4 +208,7 @@ public interface MemberUserService {
|
||||
*/
|
||||
List<AppNutritionWeekVO> NutritionWeek(String start, String end);
|
||||
|
||||
List<Map> getUserHeat(Long userId,Integer days);
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,21 @@
|
||||
package cn.iocoder.yudao.module.member.service.user;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.date.DateField;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.map.MapBuilder;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.*;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserUpdateReqVO;
|
||||
@ -28,11 +32,15 @@ import cn.iocoder.yudao.module.member.dal.dataobject.order.DishOrderDO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.orderdetail.OrderDetailDO;
|
||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||
import cn.iocoder.yudao.module.member.dal.mysql.card.CardMapper;
|
||||
import cn.iocoder.yudao.module.member.dal.mysql.order.DishOrderMapper;
|
||||
import cn.iocoder.yudao.module.member.dal.mysql.orderdetail.OrderDetailMapper;
|
||||
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
|
||||
import cn.iocoder.yudao.module.member.enums.TimePeriodEnum;
|
||||
import cn.iocoder.yudao.module.member.mq.producer.user.MemberUserProducer;
|
||||
import cn.iocoder.yudao.module.member.service.order.OrderService;
|
||||
import cn.iocoder.yudao.module.member.service.orderdetail.OrderDetailService;
|
||||
import cn.iocoder.yudao.module.system.api.dishesnutrition.DishesNutritionApi;
|
||||
import cn.iocoder.yudao.module.system.api.dishesnutrition.dto.DishesNutritionRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
||||
import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
|
||||
@ -49,12 +57,12 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
@ -70,6 +78,12 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
|
||||
@Valid
|
||||
@Slf4j
|
||||
public class MemberUserServiceImpl implements MemberUserService {
|
||||
@Resource
|
||||
private DishOrderMapper dishOrderMapper;
|
||||
@Resource
|
||||
private OrderDetailMapper orderDetailMapper;
|
||||
@Resource
|
||||
private DishesNutritionApi dishesNutritionApil;
|
||||
|
||||
@Resource
|
||||
private MemberUserMapper memberUserMapper;
|
||||
@ -528,4 +542,97 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||
result.add(sundayVO);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map> getUserHeat(Long userId, Integer days) {
|
||||
//判断是一天与一周
|
||||
if(days==7){
|
||||
LocalDateTime endDate = LocalDateTimeUtil.now();
|
||||
LocalDateTime offset = LocalDateTimeUtil.offset(endDate, -7, ChronoUnit.DAYS);
|
||||
LocalDateTime startDate = LocalDateTimeUtil.beginOfDay(offset);
|
||||
return suggestion(userId,startDate,endDate,Boolean.TRUE);
|
||||
}else{
|
||||
LocalDateTime endDate = LocalDateTimeUtil.now();
|
||||
LocalDateTime startDate = LocalDateTimeUtil.beginOfDay(endDate);
|
||||
return suggestion(userId,startDate,endDate,Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
public List<Map> suggestion(Long userId,LocalDateTime startDate,LocalDateTime endDate,Boolean bol) {
|
||||
//查询今天的订单
|
||||
List<Long> collect = dishOrderMapper.selectList(new LambdaQueryWrapperX<DishOrderDO>()
|
||||
.eqIfPresent(DishOrderDO::getUserId, userId)
|
||||
.eq(DishOrderDO::getOrderStatus, DishOrderDO.COMPLETE)
|
||||
.betweenIfPresent(DishOrderDO::getCreateTime, startDate, endDate))
|
||||
.stream()
|
||||
.map(DishOrderDO::getId)
|
||||
.collect(Collectors.toList());
|
||||
if(ObjectUtil.isEmpty(collect)){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
//获取今天购买的菜品id
|
||||
List<OrderDetailDO> orderDetailDOS = orderDetailMapper.selectList(new LambdaQueryWrapperX<OrderDetailDO>()
|
||||
.inIfPresent(OrderDetailDO::getOrderId, collect));
|
||||
//热量求和统计方便 科学膳食小建议
|
||||
double sum = orderDetailDOS
|
||||
.stream()
|
||||
.mapToDouble(OrderDetailDO::getHeat).sum();
|
||||
//获取菜品id
|
||||
List<Long> collect1 = orderDetailDOS.stream()
|
||||
.map(OrderDetailDO::getDishesId)
|
||||
.collect(Collectors.toList());
|
||||
//获取菜品营养信息
|
||||
List<DishesNutritionRespDTO> dishesList=new ArrayList<>();
|
||||
collect1.forEach(x-> dishesList.addAll(dishesNutritionApil.getDishesList(x)));
|
||||
//根据营养名称进行分组
|
||||
Map<String, List<DishesNutritionRespDTO>> map = dishesList.stream()
|
||||
.collect(Collectors.groupingBy(DishesNutritionRespDTO::getNutritionName));
|
||||
List<DishesNutritionRespDTO> list=new ArrayList<>();
|
||||
for (Map.Entry<String, List<DishesNutritionRespDTO>> entry : map.entrySet()) {
|
||||
DishesNutritionRespDTO dto = new DishesNutritionRespDTO();
|
||||
//计算当前菜品
|
||||
List<DishesNutritionRespDTO> value = entry.getValue();
|
||||
//当前营养的总和
|
||||
BigDecimal sum1 = value.stream()
|
||||
.map(x -> new BigDecimal(x.getNutritionNumber()))
|
||||
// 使用reduce聚合函数,实现累加器
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
dto.setNutritionName(entry.getKey());
|
||||
dto.setNutritionNumber(sum1.toString());
|
||||
list.add(dto);
|
||||
}
|
||||
this.computePercentage(list);
|
||||
//转map
|
||||
List<Map> maps = BeanUtil.copyToList(list, Map.class);
|
||||
//判断是否需要 科学膳食小建议
|
||||
if(Boolean.TRUE.equals(bol)){
|
||||
Map<String, String> build = MapUtil.builder(new HashMap<String, String>()).build();
|
||||
if(sum<=5000){
|
||||
build.put("prompt","您本周摄入的热量不达标,饮食均衡才能保证每天活动的能量和营养素供应充足,减肥也要吃饱,吃好哦。建议多吃肉类、水果以及根茎类的蔬菜。以上建议不成为医疗建议");
|
||||
}else if(sum>=10000){
|
||||
build.put("prompt","您本周摄入的热量达标,饮食均衡才能保证每天活动的能量和营养素供应充足,减肥也要吃饱,吃好哦。建议多吃谷类、水果以及根茎类的蔬菜。以上建议不成为医疗建议");
|
||||
}else{
|
||||
build.put("prompt","您本周摄入的热量超标,饮食均衡才能保证每天活动的能量和营养素供应充足,减肥也要吃饱,吃好哦。建议多吃水果,少吃肉类以及根茎类的蔬菜。以上建议不成为医疗建议");
|
||||
}
|
||||
maps.add(build);
|
||||
}
|
||||
return maps;
|
||||
}
|
||||
public void computePercentage(List<DishesNutritionRespDTO> list){
|
||||
//获取所有营养数量
|
||||
double sum1 = list.stream().mapToDouble(m -> Double.parseDouble(m.getNutritionNumber())).sum();
|
||||
BigDecimal sum= BigDecimal.valueOf(sum1);
|
||||
BigDecimal bigDecimal = new BigDecimal(0);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if(i < (list.size()-1)){
|
||||
DishesNutritionRespDTO dto = list.get(i);
|
||||
BigDecimal bigDecimal1 = new BigDecimal(dto.getNutritionNumber());
|
||||
BigDecimal div = NumberUtil.div(bigDecimal1, sum, 4);
|
||||
BigDecimal mul = NumberUtil.mul(div, 100);
|
||||
bigDecimal=bigDecimal.add(mul);
|
||||
list.get(i).setNutritionPer(mul.floatValue()+"%");
|
||||
}else{
|
||||
list.get(i).setNutritionPer(NumberUtil.sub(100,bigDecimal).doubleValue()+"%");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.system.api.dishesnutrition;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.module.system.api.dishesnutrition.dto.DishesNutritionRespDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜品营养 Service 接口
|
||||
*
|
||||
* @author 开发账号
|
||||
*/
|
||||
public interface DishesNutritionApi {
|
||||
/**
|
||||
* @Description: 根据菜品id 获取菜品营养
|
||||
* @Author: qjq
|
||||
* @Date: 2024/4/2 16:58
|
||||
* @return
|
||||
*/
|
||||
public List<DishesNutritionRespDTO> getDishesList(Long ids);
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.system.api.dishesnutrition.dto;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* 菜品营养 DO
|
||||
*
|
||||
* @author 开发账号
|
||||
*/
|
||||
|
||||
@Data
|
||||
public class DishesNutritionRespDTO {
|
||||
/**
|
||||
* 营养名称
|
||||
*/
|
||||
private String nutritionName;
|
||||
/**
|
||||
* 营养数量
|
||||
*/
|
||||
private String nutritionNumber;
|
||||
/**
|
||||
* 菜品重量
|
||||
*/
|
||||
private String dishesNumber;
|
||||
/**
|
||||
* 菜品编号
|
||||
*/
|
||||
private Long dishesId;
|
||||
/**
|
||||
* 营养占比
|
||||
*/
|
||||
private String nutritionPer;
|
||||
|
||||
}
|
@ -182,4 +182,6 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode DISHES_NUTRITION_NOT_EXISTS = new ErrorCode(1_002_034_002, "菜品营养不存在");
|
||||
// ========== 门店 流水 1_002_035_002 ==========
|
||||
ErrorCode DISHES_RAW_NOT_EXISTS = new ErrorCode(1_002_035_002, "菜品原材料不存在");
|
||||
// ========== 门店 流水 1_002_036_002 ==========
|
||||
ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(1_002_035_002, "营业统计不存在");
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package cn.iocoder.yudao.module.system.api.dishesnutrition;
|
||||
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.system.api.dishesnutrition.dto.DishesNutritionRespDTO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dishesnutrition.DishesNutritionDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.dishesnutrition.DishesNutritionMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 菜品营养 Service 接口
|
||||
*
|
||||
* @author 开发账号
|
||||
*/
|
||||
@Service
|
||||
public class DishesNutritionApiImpl implements DishesNutritionApi {
|
||||
|
||||
@Resource
|
||||
private DishesNutritionMapper dishesNutritionMapper;
|
||||
/**
|
||||
* @param ids
|
||||
* @return
|
||||
* @Description: 根据菜品id 获取菜品营养
|
||||
* @Author: qjq
|
||||
* @Date: 2024/4/2 16:58
|
||||
*/
|
||||
@Override
|
||||
public List<DishesNutritionRespDTO> getDishesList(Long ids) {
|
||||
return BeanUtils.toBean(dishesNutritionMapper.selectList(new LambdaQueryWrapperX<DishesNutritionDO>()
|
||||
.eqIfPresent(DishesNutritionDO::getDishesId,ids)),DishesNutritionRespDTO.class);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user