feat:营养分析-报表

This commit is contained in:
dzc committed 2025-10-28 10:17:03 +08:00
1 parent a7e226d419
commit c81ea9ebe7
9 files changed
+124 -8

No files matched your search

@@ -155,7 +155,7 @@ public class PanelPorductVo {
private ProductTypeItemVo zs;
}
public static List<PanelPorductVo> generatePanelCanteenList(LocalDateTime[] totalTimeList, DateRangeTypeEnum dateRangeType) {
public static List<PanelPorductVo> generatePanelPorductVoList(LocalDateTime[] totalTimeList, DateRangeTypeEnum dateRangeType) {
List<PanelPorductVo> dateList = new LinkedList<>();
LocalDate startTime = totalTimeList[0].toLocalDate();
LocalDate endTime = totalTimeList[1].toLocalDate();
@@ -7,9 +7,14 @@ import com.bsd.pjcloud.common.core.constant.enums.YesNoEnum;
import com.bsd.pjcloud.common.core.util.DateRangeTool;
import com.bsd.pjcloud.common.core.util.R;
import com.bsd.pjcloud.hard.api.constant.order.HardOrderStatusEnum;
import com.bsd.pjcloud.hard.api.dto.order.HardOrderDto;
import com.bsd.pjcloud.hard.api.dto.panel.PanelProductDto;
import com.bsd.pjcloud.hard.api.vo.hard.PanelPorductVo;
import com.bsd.pjcloud.hard.api.vo.order.HardOrderCsVo;
import com.bsd.pjcloud.hard.service.HardOrderTotalService;
import com.bsd.pjcloud.hard.service.PanelNutritionService;
import com.bsd.pjcloud.wallet.api.feign.RemoteMchService;
import com.bsd.pjcloud.wallet.api.vo.MchManageVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -21,6 +26,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@RestController
@@ -31,6 +37,9 @@ import java.util.List;
public class PanelNutritionController {
private final PanelNutritionService panelNutritionService;
private final HardOrderTotalService hardOrderTotalService;
private final RemoteMchService mchService;
@PostMapping(value = "/class-count")
@Operation(summary = "食堂用餐分类统计")
@@ -113,4 +122,24 @@ public class PanelNutritionController {
return R.ok(panelNutritionService.external(dto));
}
@PostMapping(value = "/report")
@Operation(summary = "营养分析报表")
public R<List<HardOrderCsVo>> canteenReport(@RequestBody HardOrderDto dto) {
dto.setOrderStatusCodes(HardOrderStatusEnum.getPaySuccessCodes());
dto.setMchTypeCodes(List.of(MerchantTypeEnum.SUPERMARKET.getType(), MerchantTypeEnum.SELF_SUPERMARKET.getType()));
List<Long> mchDtoIds = new ArrayList<>();
if (ObjectUtil.isNotEmpty(dto.getMerchantId())) {
List<MchManageVo> mchList = mchService.getByParentId(dto.getMerchantId()).getData();
if (ObjectUtil.isNotEmpty(mchList)) {
List<Long> mchIds = mchList.stream().map(MchManageVo::getId).toList();
mchDtoIds.add(dto.getMerchantId());
mchDtoIds.addAll(mchIds);
dto.setMerchantId(null);
dto.setMchIds(mchDtoIds);
}
}
return R.ok(hardOrderTotalService.listCs(dto));
}
}
@@ -55,6 +55,7 @@ public class PanelShopController {
}
dto.setMchTypeCodes(List.of(MerchantTypeEnum.SELF_SUPERMARKET.getType()));
dto.setHourTypeIsNull(YesNoEnum.YES.getCode());
dto.setOrderStatus(HardOrderStatusEnum.getPayPrice());
return R.ok(panelShopService.mchPayPersonCount(dto));
}
@@ -67,6 +68,7 @@ public class PanelShopController {
});
dto.setMchTypeCodes(List.of(MerchantTypeEnum.SELF_SUPERMARKET.getType()));
dto.setHourTypeIsNull(YesNoEnum.YES.getCode());
dto.setOrderStatus(HardOrderStatusEnum.getPayPrice());
return R.ok(panelShopService.mchPayCount(dto));
}
@@ -127,7 +129,21 @@ public class PanelShopController {
dto.setLimit(5L);
dto.setMchTypeCodes(List.of(MerchantTypeEnum.SELF_SUPERMARKET.getType()));
dto.setHourTypeIsNull(YesNoEnum.YES.getCode());
dto.setOrderStatus(HardOrderStatusEnum.getPayPrice());
return R.ok(panelShopService.mchPayCountTop(dto));
}
@PostMapping(value = "/today-trend")
@Operation(summary = "当天超市购买次数趋势统计")
public R<List<PanelPorductVo>> todayTrend(@RequestBody PanelProductDto dto) {
dto.setDateRangeType(DateRangeTypeEnum.TODAY);
if (ObjectUtil.isNotEmpty(dto.getDateRangeType()) && ObjectUtil.isEmpty(dto.getTotalTimeList())) {
dto.setTotalTimeList(DateRangeTool.transitionDateTypeToDateTimeList(dto.getDateRangeType()));
}
dto.setMchTypeCodes(List.of(MerchantTypeEnum.SELF_SUPERMARKET.getType()));
dto.setHourTypeIsNull(YesNoEnum.YES.getCode());
dto.setOrderStatus(HardOrderStatusEnum.getPayPrice());
return R.ok(panelShopService.todayTrend(dto));
}
}
@@ -154,6 +154,8 @@ public interface HardOrderMapper extends PjcloudBaseMapper<HardOrderEntity> {
*/
List<PanelPorductVo> groupByMch(@Param("dto") PanelProductDto dto);
List<PanelPorductVo> shopGroupByMch(@Param("dto") PanelProductDto dto);
/**
* 复购排行榜
*/
@@ -21,4 +21,9 @@ public interface PanelShopService {
* 排行榜
*/
List<PanelPorductVo> mchPayCountTop(PanelProductDto dto);
/**
* 当天超市购买次数趋势统计
*/
List<PanelPorductVo> todayTrend(PanelProductDto dto);
}
@@ -38,7 +38,7 @@ public class PanelCanteenServiceImpl implements PanelCanteenService {
@Override
public PanelPorductVo.HourTypeVo groupByTimeAndHourType(PanelProductDto dto) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelCanteenList(dto.getTotalTimeList(), dto.getDateRangeType());
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelPorductVoList(dto.getTotalTimeList(), dto.getDateRangeType());
PanelPorductVo.HourTypeVo result = new PanelPorductVo.HourTypeVo();
List<HardHourTypeEnum> hourTypeList = List.of(HardHourTypeEnum.MORNING, HardHourTypeEnum.NOONING, HardHourTypeEnum.NIGHT);
@@ -104,7 +104,7 @@ public class PanelNutritionServiceImpl implements PanelNutritionService {
PanelPorductVo.NutritionTypeVo result = new PanelPorductVo.NutritionTypeVo();
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelCanteenList(dto.getTotalTimeList(), dto.getDateRangeType());
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelPorductVoList(dto.getTotalTimeList(), dto.getDateRangeType());
List<Map<String, Object>> futureList = nutritionSetting();
// 查询配置
HardPanelSettingEntity setting = panelSettingService.getSetting();
@@ -215,7 +215,7 @@ public class PanelNutritionServiceImpl implements PanelNutritionService {
@Override
public PanelPorductVo.HourTypeVo external(PanelProductDto dto) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelCanteenList(dto.getTotalTimeList(), dto.getDateRangeType());
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelPorductVoList(dto.getTotalTimeList(), dto.getDateRangeType());
PanelPorductVo.HourTypeVo result = new PanelPorductVo.HourTypeVo();
List<HardHourTypeEnum> hourTypeList = List.of(HardHourTypeEnum.MORNING, HardHourTypeEnum.NOONING, HardHourTypeEnum.NIGHT);
@@ -15,10 +15,15 @@ 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.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@Validated
@Slf4j
@@ -35,7 +40,7 @@ public class PanelShopServiceImpl implements PanelShopService {
*/
@Override
public List<PanelPorductVo> mchPayPersonCount(PanelProductDto dto) {
List<PanelPorductVo> list = hardOrderMapper.groupByMch(dto);
List<PanelPorductVo> list = hardOrderMapper.shopGroupByMch(dto);
disposePanelCanteenVoSetMchName(list);
return list;
}
@@ -47,7 +52,7 @@ public class PanelShopServiceImpl implements PanelShopService {
public List<PanelPorductVo.ProductTypeItemVo> mchPayCount(PanelProductDto dto) {
List<PanelPorductVo.ProductTypeItemVo> result = new ArrayList<>();
// 处理时间
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelCanteenList(dto.getTotalTimeList(), dto.getDateRangeType());
List<PanelPorductVo> dateList = PanelPorductVo.generatePanelPorductVoList(dto.getTotalTimeList(), dto.getDateRangeType());
// 查询商户
MchManageDto mchDto = new MchManageDto();
mchDto.setTypesList(List.of(MerchantTypeEnum.SELF_SUPERMARKET.getType()));
@@ -59,7 +64,7 @@ public class PanelShopServiceImpl implements PanelShopService {
return entity;
}).toList();
// 查询商户订单
List<PanelPorductVo> list = hardOrderMapper.groupByMch(dto);
List<PanelPorductVo> list = hardOrderMapper.shopGroupByMch(dto);
for (PanelPorductVo.ProductTypeItemVo v : result) {
List<PanelPorductVo> targetMchTotalList = list.stream().filter(item -> ObjectUtil.equals(v.getType(), String.valueOf(item.getMchId()))).toList();
if (ObjectUtil.isEmpty(targetMchTotalList)) {
@@ -86,11 +91,48 @@ public class PanelShopServiceImpl implements PanelShopService {
*/
@Override
public List<PanelPorductVo> mchPayCountTop(PanelProductDto dto) {
List<PanelPorductVo> list = hardOrderMapper.groupByMch(dto);
List<PanelPorductVo> list = hardOrderMapper.shopGroupByMch(dto);
disposePanelCanteenVoSetMchName(list);
return list;
}
/**
* 当天超市购买次数趋势统计
*/
@Override
public List<PanelPorductVo> todayTrend(PanelProductDto dto) {
List<PanelPorductVo> result = new ArrayList<>();
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
LocalDateTime now = LocalDateTime.now();
List<List<Integer>> customHour = List.of(
// 早
List.of(7, 8),
List.of(8, 9),
// 中
List.of(11, 12),
List.of(12, 13),
// 晚
List.of(17, 18),
List.of(18, 19)
);
customHour.stream().map(customList -> CompletableFuture.runAsync(() -> {
RequestContextHolder.setRequestAttributes(requestAttributes);
Integer targetHour = customList.get(0);
PanelProductDto queryDto = PanelProductDto
.builder()
.totalTimeList(new LocalDateTime[]{
now.withHour(targetHour).withMinute(0).withSecond(0),
now.withHour(targetHour).withMinute(59).withSecond(59)
})
.build();
List<PanelPorductVo> sqlList = hardOrderMapper.shopGroupByTimeAndHourType(queryDto);
PanelPorductVo build = PanelPorductVo.builder().hourType(customList.get(0) + "-" + customList.get(1)).personCount(0L).order(targetHour).build();
if (ObjectUtil.isNotEmpty(sqlList)) build.setPersonCount(sqlList.get(0).getPersonCount());
result.add(build);
})).toList().forEach(CompletableFuture::join);
return result.stream().sorted(Comparator.comparingInt(PanelPorductVo::getOrder)).toList();
}
private void disposePanelCanteenVoSetMchName(List<PanelPorductVo> list) {
if (ObjectUtil.isEmpty(list)) return;
// 商户名
@@ -747,6 +747,28 @@
</if>
</select>
<select id="shopGroupByMch" resultType="com.bsd.pjcloud.hard.api.vo.hard.PanelPorductVo">
select o.merchant_id as mchId,
sum(c.product_count) as buyProductCount,
SUM(c.total_price) as totalPrice,
count(distinct o.id) as buyCount,
count(distinct o.user_id) as personCount
from hard_order o
left join hard_parent_car p on p.id = o.parent_car_id
left join hard_car c on c.parent_car_id = p.id
<where>
<include refid="groupWhereByPanelProductDto"/>
<if test="dto.hourTypeIsNull == null">
and o.hour_type is not null and o.hour_type not in ('-1', 'null')
</if>
</where>
group by o.merchant_id
order by sum(c.product_count) desc
<if test="dto.limit != null">
limit #{dto.limit}
</if>
</select>
<select id="repurchase" resultType="com.bsd.pjcloud.hard.api.vo.hard.PanelPorductVo">
select o.merchant_id as mchId,
c.product_name as productName,