前期文章
文章标题 | 地址 |
---|---|
苍穹外卖Day01——总结1 | https://lushimeng.blog.csdn.net/article/details/135466359 |
苍穹外卖Day02——总结2 | https://lushimeng.blog.csdn.net/article/details/135484126 |
苍穹外卖Day03——总结3 | https://blog.csdn.net/qq_43751200/article/details/136378883 |
苍穹外卖Day05——总结5 | https://blog.csdn.net/qq_43751200/article/details/136436080 |
苍穹外卖Day06——总结6 | https://blog.csdn.net/qq_43751200/article/details/137025980 |
苍穹外卖Day07——总结7 | https://lushimeng.blog.csdn.net/article/details/137026381 |
苍穹外卖Day8——总结8 | xx |
苍穹外卖Day10——总结10 | https://lushimeng.blog.csdn.net/article/details/137469984 |
苍穹外卖Day11——总结11 | https://lushimeng.blog.csdn.net/article/details/137518413 |
苍穹外卖Day12
- 1. 工作台展示
- 1.1 今日数据的接口设计
- 1.2 订单管理的接口设计
- 1.3 菜品总览的接口设计
- 1.4 套餐总览的接口设计
- 2. 导出运营数据Excel报表
本篇文章思路:工作台展示以及使用Apache POI进行报表输出
工作台展示整体效果:
1. 工作台展示
工作台展示的数据:
- 今日数据
- 订单管理
- 菜品总览
- 套餐总览
1.1 今日数据的接口设计
WorkSpaceController层:
/**
* 查看今日数据接口
* @return
*/
@GetMapping("/businessData")
@ApiOperation("查看今日数据接口")
public Result<BusinessDataVO> businessData(){
//获得当天的开始时间
LocalDateTime begin = LocalDateTime.now().with(LocalTime.MIN);
//获得当天的结束时间
LocalDateTime end = LocalDateTime.now().with(LocalTime.MAX);
BusinessDataVO businessDataVO = workspaceService.businessData(begin, end);
return Result.success(businessDataVO);
}
WorkSpaceService层:
/**
* 今日数据查看
* @return
*/
BusinessDataVO businessData(LocalDateTime begin, LocalDateTime end);
WorkSpaceServiceImpl层:
/**
* 今日数据查看
* @return
*/
public BusinessDataVO businessData(LocalDateTime begin, LocalDateTime end) {
/**
* 营业额:当日已完成订单的总金额
* 有效订单:当日已完成订单的数量
* 订单完成率:有效订单数 / 总订单数
* 平均客单价:营业额 / 有效订单数
* 新增用户:当日新增用户的数量
*/
Map map = new HashMap();
map.put("begin",begin);
map.put("end",end);
//查询总订单数
Integer totalOrderCount = reportMapper.getOrdersByTime(map);
map.put("status", Orders.COMPLETED);
//营业额
Double turnover = reportMapper.getTurnoverByTime(map);
turnover = turnover == null? 0.0 : turnover;
//有效订单数
Integer validOrderCount = orderMapper.countByMap(map);
Double unitPrice = 0.0;
Double orderCompletionRate = 0.0;
if(totalOrderCount != 0 && validOrderCount != 0){
//订单完成率
orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
//平均客单价
unitPrice = turnover / validOrderCount;
}
//新增用户数
Integer newUsers = userMapper.countByMap(map);
return BusinessDataVO.builder()
.turnover(turnover)
.validOrderCount(validOrderCount)
.orderCompletionRate(orderCompletionRate)
.unitPrice(unitPrice)
.newUsers(newUsers)
.build();
}
1.2 订单管理的接口设计
WorkSpaceController层:
/**
* 订单管理接口设计
* @return
*/
@GetMapping("/overviewOrders")
@ApiOperation("订单管理接口设计")
public Result<OrderOverViewVO> overviewOrders(){
OrderOverViewVO orderOverViewVO = workspaceService.overviewOrders();
return Result.success(orderOverViewVO);
}
WorkSpaceService层:
/**
* 订单管理接口设计
* @return
*/
OrderOverViewVO overviewOrders();
WorkSpaceServiceImpl层:
/**
* 订单管理接口设计
* @return
*/
public OrderOverViewVO overviewOrders() {
Map map = new HashMap();
// 待接单数量
map.put("status", Orders.TO_BE_CONFIRMED);
Integer waitingOrders = orderMapper.countByMap(map);
// 待派送数量
map.put("status", Orders.DELIVERY_IN_PROGRESS);
Integer deliveredOrders = orderMapper.countByMap(map);
// 已完成数量
map.put("status", Orders.COMPLETED);
Integer completedOrders = orderMapper.countByMap(map);
// 已取消数量
map.put("status", Orders.CANCELLED);
Integer cancelledOrders = orderMapper.countByMap(map);
// 全部订单
map.put("status", null);
Integer allOrders = orderMapper.countByMap(map);
return OrderOverViewVO.builder()
.waitingOrders(waitingOrders)
.deliveredOrders(deliveredOrders)
.completedOrders(completedOrders)
.cancelledOrders(cancelledOrders)
.allOrders(allOrders)
.build();
}
OrderMapper层:
/**
* 统计有效订单总数
* @param map
* @return
*/
Integer countByMap(Map map);
<select id="countByMap" resultType="java.lang.Integer" parameterType="java.util.Map">
select count(*) from orders
<where>
<if test="status != null">
and status = #{status}
</if>
<if test="begin != null">
and order_time >= #{begin}
</if>
<if test="end != null">
and order_time <= #{end}
</if>
</where>
</select>
1.3 菜品总览的接口设计
WorkSpaceController层:
/**
* 菜品总览接口设计
* @return
*/
@GetMapping("/overviewDishes")
@ApiOperation("菜品总览接口设计")
public Result<DishOverViewVO> overviewDishes(){
DishOverViewVO dishOverViewVO = workspaceService.overviewDishes();
return Result.success(dishOverViewVO);
}
WorkSpaceService层:
/**
* 菜品总览接口
* @return
*/
DishOverViewVO overviewDishes();
WorkSpaceServiceImpl层:
/**
* 菜品总览接口
* @return
*/
public DishOverViewVO overviewDishes() {
Integer status = 1;
Integer sold = dishMapper.countStatus(status);
status = 0;
Integer discontinued = dishMapper.countStatus(status);
return DishOverViewVO.builder()
.sold(sold)
.discontinued(discontinued)
.build();
}
DishMapper层:
/**
* 统计菜品销售状态
* @param status
* @return
*/
@Select("select count(*) from dish where status = #{status}")
Integer countStatus(Integer status);
1.4 套餐总览的接口设计
WorkSpaceController层:
/**
* 套餐总览接口设计
* @return
*/
@GetMapping("/overviewSetmeals")
@ApiOperation("菜品总览接口设计")
public Result<SetmealOverViewVO> overviewSetmeals(){
SetmealOverViewVO setmealOverViewVO = workspaceService.overviewSetmeals();
return Result.success(setmealOverViewVO);
}
WorkSpaceService层:
/**
* 套餐总览接口
* @return
*/
SetmealOverViewVO overviewSetmeals();
WorkSpaceServiceImpl层:
/**
* 套餐总览接口
* @return
*/
public SetmealOverViewVO overviewSetmeals() {
Integer status = 1;
Integer sold = setmealMapper.countStatus(status);
status = 0;
Integer discontinued = setmealMapper.countStatus(status);
return SetmealOverViewVO.builder()
.sold(sold)
.discontinued(discontinued)
.build();
}
SetmealMapper层:
/**
* 查看套餐状态
* @param status
* @return
*/
@Select("select count(*) from setmeal where status = #{status}")
Integer countStatus(Integer status);
2. 导出运营数据Excel报表
在数据统计页面,有一个数据导出的按钮,点击该按钮时,其实就会下载一个文件。这个文件实际上是一个Excel形式的文件,文件中主要包含最近30日运营相关的数据。表格的形式已经固定,主要由概览数据和明细数据两部分组成。真正导出这个报表之后,相对应的数字就会填充在表格中,就可以进行存档。
导出的Excel报表格式:
业务规则:
- 导出Excel形式的报表文件
- 导出最近30天的运营数据
Controller层: 根据接口定义,在ReportController中创建export方法
/**
* 导出运营数据报表
* @param response
*/
@GetMapping("/export")
@ApiOperation("导出运营数据报表")
public void export(HttpServletResponse response){
reportService.exportBusinessData(response);
}
Service层接口:在ReportService接口中声明导出运营数据报表的方法
/**
* 导出近30天的运营数据报表
* @param response
**/
void exportBusinessData(HttpServletResponse response);
Service层实现类:在ReportServiceImpl实现类中实现导出运营数据报表的方法,提前将资料中的运营数据报表模板.xlsx拷贝到项目的resources/template目录中
/**导出近30天的运营数据报表
* @param response
**/
public void exportBusinessData(HttpServletResponse response) {
LocalDate begin = LocalDate.now().minusDays(30);
LocalDate end = LocalDate.now().minusDays(1);
//查询概览运营数据,提供给Excel模板文件
BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(begin,LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX));
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
try {
//基于提供好的模板文件创建一个新的Excel表格对象
XSSFWorkbook excel = new XSSFWorkbook(inputStream);
//获得Excel文件中的一个Sheet页
XSSFSheet sheet = excel.getSheet("Sheet1");
sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);
//获得第4行
XSSFRow row = sheet.getRow(3);
//获取单元格
row.getCell(2).setCellValue(businessData.getTurnover());
row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
row.getCell(6).setCellValue(businessData.getNewUsers());
row = sheet.getRow(4);
row.getCell(2).setCellValue(businessData.getValidOrderCount());
row.getCell(4).setCellValue(businessData.getUnitPrice());
for (int i = 0; i < 30; i++) {
LocalDate date = begin.plusDays(i);
//准备明细数据
businessData = workspaceService.getBusinessData(LocalDateTime.of(date,LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
row = sheet.getRow(7 + i);
row.getCell(1).setCellValue(date.toString());
row.getCell(2).setCellValue(businessData.getTurnover());
row.getCell(3).setCellValue(businessData.getValidOrderCount());
row.getCell(4).setCellValue(businessData.getOrderCompletionRate());
row.getCell(5).setCellValue(businessData.getUnitPrice());
row.getCell(6).setCellValue(businessData.getNewUsers());
}
//通过输出流将文件下载到客户端浏览器中
ServletOutputStream out = response.getOutputStream();
excel.write(out);
//关闭资源
out.flush();
out.close();
excel.close();
}catch (IOException e){
e.printStackTrace();
}
}
结果展示: