feat:营养分析
This commit is contained in:
1 parent
ab3cffc35d
commit
a4ace0f6e6
7 files changed
+254
-5
No files matched your search
+15
@@ -24,6 +24,21 @@ public class HardPanelSettingShare {
|
||||
*/
|
||||
private List<Long> topExcludeCategoryIds;
|
||||
|
||||
/**
|
||||
* 荤菜菜品分类id
|
||||
*/
|
||||
private List<Long> hcCategoryIds;
|
||||
|
||||
/**
|
||||
* 素菜菜品分类id
|
||||
*/
|
||||
private List<Long> scCategoryIds;
|
||||
|
||||
/**
|
||||
* 主食菜品分类id
|
||||
*/
|
||||
private List<Long> zsCategoryIds;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+26
-1
@@ -24,6 +24,11 @@ public class PanelPorductVo {
|
||||
*/
|
||||
private String classifyName;
|
||||
|
||||
/**
|
||||
* 分类key
|
||||
*/
|
||||
private String classifyKey;
|
||||
|
||||
/**
|
||||
* 分类ID
|
||||
*/
|
||||
@@ -113,7 +118,6 @@ public class PanelPorductVo {
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class HourTypeVo {
|
||||
|
||||
/**
|
||||
* 早
|
||||
*/
|
||||
@@ -130,6 +134,27 @@ public class PanelPorductVo {
|
||||
private ProductTypeItemVo evening;
|
||||
}
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class NutritionTypeVo {
|
||||
/**
|
||||
* 荤菜
|
||||
*/
|
||||
private ProductTypeItemVo hc;
|
||||
|
||||
/**
|
||||
* 素菜
|
||||
*/
|
||||
private ProductTypeItemVo sc;
|
||||
|
||||
/**
|
||||
* 主食
|
||||
*/
|
||||
private ProductTypeItemVo zs;
|
||||
}
|
||||
|
||||
public static List<PanelPorductVo> generatePanelCanteenList(LocalDateTime[] totalTimeList, DateRangeTypeEnum dateRangeType) {
|
||||
List<PanelPorductVo> dateList = new LinkedList<>();
|
||||
LocalDate startTime = totalTimeList[0].toLocalDate();
|
||||
|
||||
+20
@@ -48,4 +48,24 @@ public class PanelNutritionController {
|
||||
return R.ok(panelNutritionService.cuisineTop(dto));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/nutrition/by-time")
|
||||
@Operation(summary = "营养分析(按照购买时间统计)")
|
||||
public R<PanelPorductVo.NutritionTypeVo> nutritionByTime(@RequestBody PanelProductDto dto) {
|
||||
if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isEmpty(dto.getTotalTimeList())) {
|
||||
dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType()));
|
||||
}
|
||||
dto.setMchTypeCodes(List.of(MerchantTypeEnum.CANTEEN.getType()));
|
||||
return R.ok(panelNutritionService.nutritionByTime(dto));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/nutrition/total")
|
||||
@Operation(summary = "营养分析(总数统计)")
|
||||
public R<List<PanelPorductVo>> nutritionTotal(@RequestBody PanelProductDto dto) {
|
||||
if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isEmpty(dto.getTotalTimeList())) {
|
||||
dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType()));
|
||||
}
|
||||
dto.setMchTypeCodes(List.of(MerchantTypeEnum.CANTEEN.getType()));
|
||||
return R.ok(panelNutritionService.nutritionTotal(dto));
|
||||
}
|
||||
|
||||
}
|
||||
+4
@@ -139,6 +139,10 @@ public interface HardOrderMapper extends PjcloudBaseMapper<HardOrderEntity> {
|
||||
/**
|
||||
* 用餐数据统计(根据时间段和日期分类统计)
|
||||
*/
|
||||
PanelPorductVo groupCount(@Param("dto") PanelProductDto dto);
|
||||
|
||||
List<PanelPorductVo> groupByTime(@Param("dto") PanelProductDto dto);
|
||||
|
||||
List<PanelPorductVo> groupByTimeAndHourType(@Param("dto") PanelProductDto dto);
|
||||
|
||||
List<PanelPorductVo> groupByMonthAndHourType(@Param("dto") PanelProductDto dto);
|
||||
|
||||
+9
@@ -21,4 +21,13 @@ public interface PanelNutritionService {
|
||||
*/
|
||||
List<PanelPorductVo> cuisineTop(PanelProductDto dto);
|
||||
|
||||
/**
|
||||
* 营养分析(按照购买时间统计)
|
||||
*/
|
||||
PanelPorductVo.NutritionTypeVo nutritionByTime(PanelProductDto dto);
|
||||
|
||||
/**
|
||||
* 营养分析(总数统计)
|
||||
*/
|
||||
List<PanelPorductVo> nutritionTotal(PanelProductDto dto);
|
||||
}
|
||||
+107
@@ -1,5 +1,6 @@
|
||||
package com.bsd.pjcloud.hard.service.impl.panel;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductByClassifyDto;
|
||||
import com.bsd.pjcloud.hard.api.dto.order.app.HardAppProductLikeTopDto;
|
||||
@@ -18,8 +19,13 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Validated
|
||||
@Slf4j
|
||||
@@ -80,4 +86,105 @@ public class PanelNutritionServiceImpl implements PanelNutritionService {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 营养分析(按照购买时间统计)
|
||||
*/
|
||||
@Override
|
||||
public PanelPorductVo.NutritionTypeVo nutritionByTime(PanelProductDto dto) {
|
||||
PanelPorductVo.NutritionTypeVo result = new PanelPorductVo.NutritionTypeVo();
|
||||
|
||||
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelCanteenList(dto.getTotalTimeList(), dto.getDateRangeType());
|
||||
List<Map<String, Object>> futureList = nutritionSetting();
|
||||
// 查询配置
|
||||
HardPanelSettingEntity setting = panelSettingService.getSetting();
|
||||
if (ObjectUtil.isNotEmpty(setting) && ObjectUtil.isNotEmpty(setting.getNutritionSetting())) {
|
||||
HardPanelSettingShare.NutritionSetting nutritionSetting = setting.getNutritionSetting();
|
||||
if (ObjectUtil.isNotEmpty(nutritionSetting)) {
|
||||
if (ObjectUtil.isNotEmpty(nutritionSetting.getHcCategoryIds())) {
|
||||
futureList.get(0).put("classify", nutritionSetting.getHcCategoryIds());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(nutritionSetting.getScCategoryIds())) {
|
||||
futureList.get(1).put("classify", nutritionSetting.getScCategoryIds());
|
||||
}
|
||||
if (ObjectUtil.isNotEmpty(nutritionSetting.getZsCategoryIds())) {
|
||||
futureList.get(2).put("classify", nutritionSetting.getZsCategoryIds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (CompletableFuture<Void> voidCompletableFuture : futureList.stream().map(map -> CompletableFuture.runAsync(() -> {
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||
String key = (String) map.get("key");
|
||||
String name = (String) map.get("name");
|
||||
List<Long> classify = (List<Long>) map.get("classify");
|
||||
PanelProductDto queryDto = BeanUtil.toBean(dto, PanelProductDto.class);
|
||||
queryDto.setClassifyIds(classify);
|
||||
List<PanelPorductVo> sqlList = hardOrderMapper.groupByTime(queryDto);
|
||||
// 处理查询出来的数据
|
||||
List<PanelPorductVo> resultList = BeanUtil.copyToList(dateList, PanelPorductVo.class);
|
||||
for (PanelPorductVo v : resultList) {
|
||||
sqlList.stream().filter(item -> ObjectUtil.equals(item.getTime(), v.getTime())).forEach(target -> {
|
||||
v.setHourType(target.getHourType());
|
||||
v.setPersonCount(target.getPersonCount());
|
||||
v.setBuyCount(target.getBuyCount());
|
||||
v.setBuyProductCount(target.getBuyProductCount());
|
||||
v.setTotalPrice(target.getTotalPrice());
|
||||
});
|
||||
}
|
||||
// 组装数据
|
||||
PanelPorductVo.ProductTypeItemVo vo = PanelPorductVo.ProductTypeItemVo.builder().list(resultList).type(key).typeStr(name).build();
|
||||
switch (key) {
|
||||
case "hc":
|
||||
result.setHc(vo);
|
||||
break;
|
||||
case "sc":
|
||||
result.setSc(vo);
|
||||
break;
|
||||
case "zs":
|
||||
result.setZs(vo);
|
||||
break;
|
||||
}
|
||||
})).toList()) {
|
||||
voidCompletableFuture.join();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 营养分析(总数统计)
|
||||
*/
|
||||
@Override
|
||||
public List<PanelPorductVo> nutritionTotal(PanelProductDto dto) {
|
||||
List<PanelPorductVo> list = new ArrayList<>();
|
||||
|
||||
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
||||
List<Map<String, Object>> futureList = nutritionSetting();
|
||||
|
||||
for (CompletableFuture<Void> voidCompletableFuture : futureList.stream().map(map -> CompletableFuture.runAsync(() -> {
|
||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||
String key = (String) map.get("key");
|
||||
String name = (String) map.get("name");
|
||||
List<Long> classify = (List<Long>) map.get("classify");
|
||||
PanelProductDto queryDto = BeanUtil.toBean(dto, PanelProductDto.class);
|
||||
queryDto.setClassifyIds(classify);
|
||||
PanelPorductVo totalVo = hardOrderMapper.groupCount(queryDto);
|
||||
totalVo.setClassifyName(name);
|
||||
totalVo.setClassifyKey(key);
|
||||
list.add(totalVo);
|
||||
})).toList()) {
|
||||
voidCompletableFuture.join();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> nutritionSetting() {
|
||||
return List.of(
|
||||
Map.of("key", "hc", "name", "荤菜", "classify", new ArrayList<Long>(), "order", 0),
|
||||
Map.of("key", "sc", "name", "素菜", "classify", new ArrayList<Long>(), "order", 1),
|
||||
Map.of("key", "zs", "name", "主食", "classify", new ArrayList<Long>(), "order", 2)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
+73
-4
@@ -550,6 +550,71 @@
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="groupCount" resultType="com.bsd.pjcloud.hard.api.vo.hard.PanelPorductVo">
|
||||
select SUM(a.product_count) as buyProductCount,
|
||||
SUM(a.total_price) as totalPrice,
|
||||
count(distinct o.id) as buyCount,
|
||||
count(distinct o.user_id) as personCount
|
||||
from hard_car a
|
||||
inner join hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
|
||||
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0' and o.hour_type is not null and
|
||||
o.hour_type not in ('-1', 'null')
|
||||
<if test="dto.hourTypeIsNull == null">
|
||||
and o.hour_type is not null and o.hour_type not in ('-1', 'null')
|
||||
</if>
|
||||
<where>
|
||||
a.del_flag = '0'
|
||||
<if test="dto.totalTimeList != null and dto.totalTimeList.length == 2">
|
||||
and o.create_time between #{dto.totalTimeList[0]} and #{dto.totalTimeList[1]}
|
||||
</if>
|
||||
<if test="dto.hourType != null and dto.hourType != '' ">
|
||||
and o.hour_type = #{dto.hourType}
|
||||
</if>
|
||||
<if test="dto.mchTypeCodes != null and dto.mchTypeCodes.size() != 0">
|
||||
and o.merchant_type in
|
||||
<foreach collection="dto.mchTypeCodes" item="v" open="(" close=")" separator=",">
|
||||
#{v}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="groupByTime" resultType="com.bsd.pjcloud.hard.api.vo.hard.PanelPorductVo">
|
||||
select
|
||||
date(o.create_time) as time,
|
||||
o.hour_type as hourType,
|
||||
SUM(a.product_count) as buyProductCount,
|
||||
SUM(a.total_price) as totalPrice,
|
||||
count(distinct o.id) as buyCount,
|
||||
count(distinct o.user_id) as personCount
|
||||
from hard_car a
|
||||
inner join hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
|
||||
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0'
|
||||
<if test="dto.hourTypeIsNull == null">
|
||||
and o.hour_type is not null and o.hour_type not in ('-1', 'null')
|
||||
</if>
|
||||
<where>
|
||||
a.del_flag = '0'
|
||||
<if test="dto.totalTimeList != null and dto.totalTimeList.length == 2">
|
||||
and o.create_time between #{dto.totalTimeList[0]} and #{dto.totalTimeList[1]}
|
||||
</if>
|
||||
<if test="dto.hourType != null and dto.hourType != '' ">
|
||||
and o.hour_type = #{dto.hourType}
|
||||
</if>
|
||||
<if test="dto.mchTypeCodes != null and dto.mchTypeCodes.size() != 0">
|
||||
and o.merchant_type in
|
||||
<foreach collection="dto.mchTypeCodes" item="v" open="(" close=")" separator=",">
|
||||
#{v}
|
||||
</foreach>
|
||||
</if>
|
||||
</where>
|
||||
group by date(o.create_time)
|
||||
order by date(o.create_time) desc
|
||||
<if test="dto.limit != null">
|
||||
limit #{dto.limit}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="groupByTimeAndHourType" resultType="com.bsd.pjcloud.hard.api.vo.hard.PanelPorductVo">
|
||||
select
|
||||
date(o.create_time) as time,
|
||||
@@ -560,8 +625,10 @@
|
||||
count(distinct o.user_id) as personCount
|
||||
from hard_car a
|
||||
inner join hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
|
||||
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0' and o.hour_type is not null and
|
||||
o.hour_type not in ('-1', 'null')
|
||||
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0'
|
||||
<if test="dto.hourTypeIsNull == null">
|
||||
and o.hour_type is not null and o.hour_type not in ('-1', 'null')
|
||||
</if>
|
||||
<where>
|
||||
a.del_flag = '0'
|
||||
<if test="dto.totalTimeList != null and dto.totalTimeList.length == 2">
|
||||
@@ -594,8 +661,10 @@
|
||||
count(distinct o.user_id) as personCount
|
||||
from hard_car a
|
||||
inner join hard_parent_car p on a.parent_car_id = p.id and p.del_flag = '0'
|
||||
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0' and o.hour_type is not null and
|
||||
o.hour_type not in ('-1', 'null')
|
||||
inner join hard_order o on o.parent_car_id = p.id and o.del_flag = '0'
|
||||
<if test="dto.hourTypeIsNull == null">
|
||||
and o.hour_type is not null and o.hour_type not in ('-1', 'null')
|
||||
</if>
|
||||
<where>
|
||||
a.del_flag = '0'
|
||||
<if test="dto.totalTimeList != null and dto.totalTimeList.length == 2">
|
||||
|
||||
Reference in new issue
Block a user