食堂数据总览 代码优化

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.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.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.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import javax.annotation.Resource;
/**
* 设备绑定多档口子Controller
@ -28,7 +20,7 @@ import java.util.List;
@RestController
@RequestMapping("/dataScreening")
public class DataScreeningController extends BaseController {
@Autowired
@Resource
private DataScreeningService service;
@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.SingleModelVO;
import com.bonus.common.core.web.domain.AjaxResult;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 19814
*/
public interface DataScreeningMapper {
/**
* 获取数据总览今日营业额订单等
* @param date 日期
* @param type 11 消费机 2 预定餐 4 商超
* @return 数据总览对象
*/
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);
/**
* 获取人数
* @param date 日期
* @param type 11 消费机 2 预定餐 4 商超
* @return 人数对象
*/
SingleModelVO selectPerson(@Param("date") String date,@Param("type") int type);
/**
* 获取菜品销量
* @param date 日期
* @return 菜品销量对象
*/
SingleModelVO selectDish(@Param("date")String date);
/**
* 获取食堂订单及销量趋势
* @param startDate 开始日期
* @param endDate 结束日期
* @return 订单及销量对象
*/
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);
/**
* 获取本月菜品销量排名
* @param startDate 开始日期
* @param endDate 结束日期
* @return 菜品销量对象
*/
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);
}

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