食堂数据总览 代码优化

This commit is contained in:
jjLv 2025-05-16 11:20:02 +08:00
parent 62ce2a9810
commit cb456f0b72
3 changed files with 165 additions and 40 deletions

View File

@ -2,21 +2,13 @@ package com.bonus.canteen.core.dataScreening.controller;
import com.bonus.canteen.core.dataScreening.dto.DataScreenDTO; import com.bonus.canteen.core.dataScreening.dto.DataScreenDTO;
import com.bonus.canteen.core.dataScreening.service.DataScreeningService; import com.bonus.canteen.core.dataScreening.service.DataScreeningService;
import com.bonus.canteen.core.device.domain.DeviceBind;
import com.bonus.canteen.core.device.service.IDeviceBindService;
import com.bonus.common.core.utils.poi.ExcelUtil;
import com.bonus.common.core.web.controller.BaseController; import com.bonus.common.core.web.controller.BaseController;
import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.core.web.page.TableDataInfo;
import com.bonus.common.log.annotation.SysLog;
import com.bonus.common.log.enums.OperaType;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import javax.annotation.Resource;
import java.util.List;
/** /**
* 设备绑定多档口子Controller * 设备绑定多档口子Controller
@ -28,7 +20,7 @@ import java.util.List;
@RestController @RestController
@RequestMapping("/dataScreening") @RequestMapping("/dataScreening")
public class DataScreeningController extends BaseController { public class DataScreeningController extends BaseController {
@Autowired @Resource
private DataScreeningService service; private DataScreeningService service;
@ApiOperation(value = "获取数据总览(今日营业额、订单等)") @ApiOperation(value = "获取数据总览(今日营业额、订单等)")

View File

@ -2,25 +2,68 @@ package com.bonus.canteen.core.dataScreening.mapper;
import com.bonus.canteen.core.dataScreening.vo.EchartsVO; import com.bonus.canteen.core.dataScreening.vo.EchartsVO;
import com.bonus.canteen.core.dataScreening.vo.SingleModelVO; import com.bonus.canteen.core.dataScreening.vo.SingleModelVO;
import com.bonus.common.core.web.domain.AjaxResult;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
/**
* @author 19814
*/
public interface DataScreeningMapper { public interface DataScreeningMapper {
/**
* 获取数据总览今日营业额订单等
* @param date 日期
* @param type 11 消费机 2 预定餐 4 商超
* @return 数据总览对象
*/
SingleModelVO selectTurnover(@Param("date") String date,@Param("type") int type); SingleModelVO selectTurnover(@Param("date") String date,@Param("type") int type);
/**
* 获取订单数
* @param date 日期
* @param type 11 消费机 2 预定餐 4 商超
* @return 订单对象
*/
SingleModelVO selectOrder(@Param("date") String date,@Param("type") int type); SingleModelVO selectOrder(@Param("date") String date,@Param("type") int type);
/**
* 获取人数
* @param date 日期
* @param type 11 消费机 2 预定餐 4 商超
* @return 人数对象
*/
SingleModelVO selectPerson(@Param("date") String date,@Param("type") int type); SingleModelVO selectPerson(@Param("date") String date,@Param("type") int type);
/**
* 获取菜品销量
* @param date 日期
* @return 菜品销量对象
*/
SingleModelVO selectDish(@Param("date")String date); SingleModelVO selectDish(@Param("date")String date);
/**
* 获取食堂订单及销量趋势
* @param startDate 开始日期
* @param endDate 结束日期
* @return 订单及销量对象
*/
List<EchartsVO> getCanteenOrdersAndSalesTrends(@Param("startDate")String startDate, @Param("endDate")String endDate); List<EchartsVO> getCanteenOrdersAndSalesTrends(@Param("startDate")String startDate, @Param("endDate")String endDate);
/**
* 获取商超订单及销量趋势
* @param startDate 开始日期
* @param endDate 结束日期
* @return 订单及销量对象
*/
List<EchartsVO> getSupermarketOrderAndSalesTrend(@Param("startDate")String startDate, @Param("endDate")String endDate); List<EchartsVO> getSupermarketOrderAndSalesTrend(@Param("startDate")String startDate, @Param("endDate")String endDate);
/**
* 获取本月菜品销量排名
* @param startDate 开始日期
* @param endDate 结束日期
* @return 菜品销量对象
*/
List<SingleModelVO> getThisMonthDishSalesRanking(@Param("startDate")String startDate, @Param("endDate")String endDate); List<SingleModelVO> getThisMonthDishSalesRanking(@Param("startDate")String startDate, @Param("endDate")String endDate);
/**
* 获取订单类型占比
* @param startDate 开始日期
* @param endDate 结束日期
* @param type 11 消费机 2 预定餐 4 商超
* @return 订单类型占比对象
*/
SingleModelVO selectOrderByDate(@Param("startDate")String startDate, @Param("endDate")String endDate, @Param("type") int type); SingleModelVO selectOrderByDate(@Param("startDate")String startDate, @Param("endDate")String endDate, @Param("type") int type);
} }

View File

@ -6,20 +6,37 @@ import com.bonus.canteen.core.dataScreening.vo.EchartsVO;
import com.bonus.canteen.core.dataScreening.vo.SingleModelVO; import com.bonus.canteen.core.dataScreening.vo.SingleModelVO;
import com.bonus.common.core.utils.DateUtils; import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.web.domain.AjaxResult; import com.bonus.common.core.web.domain.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/**
* @author 19814
*/
@Service @Service
public class DataScreeningServiceImpl implements DataScreeningService { public class DataScreeningServiceImpl implements DataScreeningService {
@Autowired @Resource
private DataScreeningMapper mapper; private DataScreeningMapper mapper;
private static final Logger log = LoggerFactory.getLogger(DataScreeningServiceImpl.class);
private static final String TURNOVER = "Turnover";
private static final String ORDER = "Order";
private static final String PERSON = "Person";
private static final String DISH = "Dish";
/**
* 获取数据总览
*
* @return 数据总览结果
*/
@Override @Override
public AjaxResult getDataScreeningModel() { public AjaxResult getDataScreeningModel() {
List<SingleModelVO> list = new ArrayList<>(); List<SingleModelVO> list = new ArrayList<>();
@ -27,16 +44,26 @@ public class DataScreeningServiceImpl implements DataScreeningService {
String yesterday = getLastDate(-1); String yesterday = getLastDate(-1);
// 查询各项数据 // 查询各项数据
addSingleItem("今日食堂营业额(元)", currentDate, yesterday, list, 11, "Turnover"); addSingleItem("今日食堂营业额(元)", currentDate, yesterday, list, 11, TURNOVER);
addSingleItem("今日食堂订单量(个)", currentDate, yesterday, list, 11, "Order"); addSingleItem("今日食堂订单量(个)", currentDate, yesterday, list, 11, ORDER);
addSingleItem("今日就餐人数(个)", currentDate, yesterday, list, 11, "Person"); addSingleItem("今日就餐人数(个)", currentDate, yesterday, list, 11, PERSON);
addSingleItem("今日菜品数量(个)", currentDate, yesterday, list, -1, "Dish"); addSingleItem("今日菜品数量(个)", currentDate, yesterday, list, -1, DISH);
addSingleItem("今日超市营业额(元)", currentDate, yesterday, list, 4, "Turnover"); addSingleItem("今日超市营业额(元)", currentDate, yesterday, list, 4, TURNOVER);
addSingleItem("今日超市订单量(个)", currentDate, yesterday, list, 4, "Order"); addSingleItem("今日超市订单量(个)", currentDate, yesterday, list, 4, ORDER);
return AjaxResult.success(list); return AjaxResult.success(list);
} }
/**
* 添加单项数据
*
* @param name 名称
* @param currentDate 今日日期
* @param yesterdayData 昨日日期
* @param list 数据列表
* @param orderType 订单类型
* @param type 数据类型
*/
private void addSingleItem(String name, String currentDate, String yesterdayData, List<SingleModelVO> list, int orderType, String type) { private void addSingleItem(String name, String currentDate, String yesterdayData, List<SingleModelVO> list, int orderType, String type) {
SingleModelVO today = fetchDataByType(currentDate, orderType, type); SingleModelVO today = fetchDataByType(currentDate, orderType, type);
SingleModelVO yesterday = fetchDataByType(yesterdayData, orderType, type); SingleModelVO yesterday = fetchDataByType(yesterdayData, orderType, type);
@ -46,21 +73,36 @@ public class DataScreeningServiceImpl implements DataScreeningService {
list.add(today); list.add(today);
} }
/**
* 根据数据类型获取数据
*
* @param date 日期
* @param orderType 订单类型
* @param type 数据类型
* @return 数据
*/
private SingleModelVO fetchDataByType(String date, int orderType, String type) { private SingleModelVO fetchDataByType(String date, int orderType, String type) {
switch (type) { switch (type) {
case "Order": case ORDER:
return mapper.selectOrder(date, orderType); return mapper.selectOrder(date, orderType);
case "Turnover": case TURNOVER:
return mapper.selectTurnover(date, orderType); return mapper.selectTurnover(date, orderType);
case "Person": case PERSON:
return mapper.selectPerson(date, orderType); return mapper.selectPerson(date, orderType);
case "Dish": case DISH:
return mapper.selectDish(date); return mapper.selectDish(date);
default: default:
return new SingleModelVO(); return new SingleModelVO();
} }
} }
/**
* 计算今日与昨日的比率
*
* @param today 今日数据
* @param yesterday 昨日数据
* @param type 数据类型
*/
private void calculateRate(SingleModelVO today, SingleModelVO yesterday, String type) { private void calculateRate(SingleModelVO today, SingleModelVO yesterday, String type) {
BigDecimal yesterdayNum = Optional.ofNullable(yesterday.getNum()).orElse(BigDecimal.ZERO); BigDecimal yesterdayNum = Optional.ofNullable(yesterday.getNum()).orElse(BigDecimal.ZERO);
BigDecimal todayNum = Optional.ofNullable(today.getNum()).orElse(BigDecimal.ZERO); BigDecimal todayNum = Optional.ofNullable(today.getNum()).orElse(BigDecimal.ZERO);
@ -69,29 +111,46 @@ public class DataScreeningServiceImpl implements DataScreeningService {
today.setRate(todayNum.compareTo(BigDecimal.ZERO) == 0 ? "0.0" : "100.0"); today.setRate(todayNum.compareTo(BigDecimal.ZERO) == 0 ? "0.0" : "100.0");
} else { } else {
BigDecimal rate = todayNum.subtract(yesterdayNum) BigDecimal rate = todayNum.subtract(yesterdayNum)
.divide(yesterdayNum, 4, BigDecimal.ROUND_HALF_UP) .divide(yesterdayNum, 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100)); .multiply(BigDecimal.valueOf(100));
today.setRate(String.format("%.2f", rate)); today.setRate(String.format("%.2f", rate));
} }
if ("Turnover".equals(type)) { if (TURNOVER.equals(type)) {
today.setNum(todayNum.divide(BigDecimal.valueOf(100))); today.setNum(todayNum.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
} }
} }
/**
* 获取食堂订单及销量趋势
*
* @param dataScreenDTO 数据筛选DTO
* @return 订单及销量趋势结果
*/
@Override @Override
public AjaxResult getCanteenOrdersAndSalesTrends(DataScreenDTO dataScreenDTO) { public AjaxResult getCanteenOrdersAndSalesTrends(DataScreenDTO dataScreenDTO) {
return getOrdersAndSalesTrends(dataScreenDTO, true); return getOrdersAndSalesTrends(dataScreenDTO, true);
} }
/**
* 获取商超订单及销量趋势
*
* @param dataScreenDTO 数据筛选DTO
* @return 订单及销量趋势结果
*/
@Override @Override
public AjaxResult getSupermarketOrderAndSalesTrend(DataScreenDTO dataScreenDTO) { public AjaxResult getSupermarketOrderAndSalesTrend(DataScreenDTO dataScreenDTO) {
return getOrdersAndSalesTrends(dataScreenDTO, false); return getOrdersAndSalesTrends(dataScreenDTO, false);
} }
/**
* 获取食堂订单及销量趋势
*
* @param dataScreenDTO 数据筛选DTO
* @return 订单及销量趋势结果
*/
private AjaxResult getOrdersAndSalesTrends(DataScreenDTO dataScreenDTO, boolean isCanteen) { private AjaxResult getOrdersAndSalesTrends(DataScreenDTO dataScreenDTO, boolean isCanteen) {
String date = getLastDate(dataScreenDTO.getType().equals("2") ? -29 : -6); String date = getLastDate("2".equals(dataScreenDTO.getType()) ? -29 : -6);
List<EchartsVO> list = isCanteen List<EchartsVO> list = isCanteen
? mapper.getCanteenOrdersAndSalesTrends(date, DateUtils.getDate()) ? mapper.getCanteenOrdersAndSalesTrends(date, DateUtils.getDate())
: mapper.getSupermarketOrderAndSalesTrend(date, DateUtils.getDate()); : mapper.getSupermarketOrderAndSalesTrend(date, DateUtils.getDate());
@ -104,7 +163,7 @@ public class DataScreeningServiceImpl implements DataScreeningService {
EchartsVO echartsVO = dataMap.getOrDefault(dateStr, new EchartsVO()); EchartsVO echartsVO = dataMap.getOrDefault(dateStr, new EchartsVO());
echartsVO.setOrderDate(dateStr); echartsVO.setOrderDate(dateStr);
echartsVO.setSalesValue(Optional.ofNullable(echartsVO.getSalesValue()) echartsVO.setSalesValue(Optional.ofNullable(echartsVO.getSalesValue())
.map(value -> new BigDecimal(value).divide(BigDecimal.valueOf(100)).toString()) .map(value -> new BigDecimal(value).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP).toString())
.orElse("0")); .orElse("0"));
echartsVO.setOrderValue(Optional.ofNullable(echartsVO.getOrderValue()).orElse("0")); echartsVO.setOrderValue(Optional.ofNullable(echartsVO.getOrderValue()).orElse("0"));
return echartsVO; return echartsVO;
@ -113,15 +172,25 @@ public class DataScreeningServiceImpl implements DataScreeningService {
return AjaxResult.success(result); return AjaxResult.success(result);
} }
/**
* 获取本日菜品销量排名
*
* @return 本日菜品销量排名结果
*/
@Override @Override
public AjaxResult getThisMonthDishSalesRanking() { public AjaxResult getThisMonthDishSalesRanking() {
String date = getLastDate(-29); String date = getLastDate(-29);
return AjaxResult.success(mapper.getThisMonthDishSalesRanking(date, DateUtils.getDate())); return AjaxResult.success(mapper.getThisMonthDishSalesRanking(date, DateUtils.getDate()));
} }
/**
* 获取订单类型占比
*
* @param dataScreenDTO 数据筛选DTO
* @return 订单类型占比结果
*/
@Override @Override
public AjaxResult getProportionOfOrderTypes(DataScreenDTO dataScreenDTO) { public AjaxResult getProportionOfOrderTypes(DataScreenDTO dataScreenDTO) {
String date = getLastDate(dataScreenDTO.getType().equals("2") ? -29 : -6); String date = getLastDate("2".equals(dataScreenDTO.getType()) ? -29 : -6);
SingleModelVO superMarketOrder = mapper.selectOrderByDate(date,DateUtils.getDate(), 4); SingleModelVO superMarketOrder = mapper.selectOrderByDate(date,DateUtils.getDate(), 4);
SingleModelVO canteenOrder = mapper.selectOrderByDate(date,DateUtils.getDate(), 11); SingleModelVO canteenOrder = mapper.selectOrderByDate(date,DateUtils.getDate(), 11);
SingleModelVO preOrderMealOrder = mapper.selectOrderByDate(date,DateUtils.getDate(), 2); SingleModelVO preOrderMealOrder = mapper.selectOrderByDate(date,DateUtils.getDate(), 2);
@ -133,16 +202,29 @@ public class DataScreeningServiceImpl implements DataScreeningService {
calculateProportion(preOrderMealOrder, total, "外卖订单"); calculateProportion(preOrderMealOrder, total, "外卖订单");
return AjaxResult.success(Arrays.asList(superMarketOrder, canteenOrder, preOrderMealOrder)); return AjaxResult.success(Arrays.asList(superMarketOrder, canteenOrder, preOrderMealOrder));
} }
/**
* 计算订单占比
*
* @param order 订单
* @param total 总订单量
* @param name 订单名称
*/
private void calculateProportion(SingleModelVO order, BigDecimal total, String name) { private void calculateProportion(SingleModelVO order, BigDecimal total, String name) {
order.setName(name); order.setName(name);
if (total.compareTo(BigDecimal.ZERO) == 0) { if (total.compareTo(BigDecimal.ZERO) == 0) {
order.setRate("0.0"); order.setRate("0.0");
} else { } else {
BigDecimal rate = order.getNum().divide(total, 4, BigDecimal.ROUND_HALF_UP) BigDecimal rate = order.getNum().divide(total, 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100)); .multiply(BigDecimal.valueOf(100));
order.setRate(String.format("%.2f", rate)); order.setRate(String.format("%.2f", rate));
} }
} }
/**
* 获取指定日期的指定格式
*
* @param day 相对天数
* @return 日期字符串
*/
public static String getLastDate(int day) { public static String getLastDate(int day) {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
// 日期减去一天 // 日期减去一天
@ -151,6 +233,14 @@ public class DataScreeningServiceImpl implements DataScreeningService {
return sdf.format(calendar.getTime()); return sdf.format(calendar.getTime());
} }
/**
* 获取指定日期范围内的所有日期
*
* @param startStr 开始日期字符串
* @param endStr 结束日期字符串
* @param pattern 日期格式
* @return 日期列表
*/
public static List<String> getDatesBetween(String startStr, String endStr, String pattern) { public static List<String> getDatesBetween(String startStr, String endStr, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern); SimpleDateFormat sdf = new SimpleDateFormat(pattern);
List<String> dates = new ArrayList<>(); List<String> dates = new ArrayList<>();
@ -164,7 +254,7 @@ public class DataScreeningServiceImpl implements DataScreeningService {
calendar.add(Calendar.DATE, 1); calendar.add(Calendar.DATE, 1);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.error("日期转换异常", e);
} }
return dates; return dates;
} }