【烘焙坊项目】后端搭建(14) - 工作台&导出数据报表

一、工作台

1.1 需求分析和设计

1.1.1分析

工作台是系统运营的数据看板,并提供快捷操作入口,可以有效提高商家工作效率

工作台展示的数据:

  • 今日数据
营业额 有效订单 订单完成率 平均客单价 新增用户
已完成订单总金额 已完成订单的数量 有效订单数/总订单数*100% 营业额/有效订单数 新增用户的数量
  • 订单管理

  • 菜品总览

  • 套餐总览

  • 订单信息

1.1.2查看接口文档

1.1.2.1查询今日运营数据
1.1.2.2查询订单管理数据
1.1.2.3查询套餐总览数据
1.1.2.4查询菜品总览数据

1.2 代码开发

1.2.1查询今日运营数据

controller层

service层

java 复制代码
@Service
@Slf4j
public class WorkspaceServiceImpl implements WorkspaceService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ReportService reportService;
    @Autowired
    private OrderMapper orderMapper;

    /**
     * 查询今日数据
     * @return
     */
    @Override
    public BusinessDataVO businessDate() {
        Map map = new HashMap();
        LocalDate date = LocalDate.now();
        LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
        map.put("beginTime", beginTime);
        map.put("endTime", endTime);

        OrderReportVO orderReportVO = reportService.getStatisticsReport(date,date);
        Double orderCompletionRate = orderReportVO.getOrderCompletionRate();//订单完成率

        map.put("status", Orders.COMPLETED);
        Double turnover = orderMapper.sumByMap(map);
        turnover = turnover == null ? 0.0 : turnover;//营业额

        Integer validOrder = orderMapper.countOrderByMap(map);//每日有效订单数

        Double unitPrice;
        if( validOrder == null || validOrder == 0 ){
            unitPrice = 0.0;
        }else{
            unitPrice = turnover/validOrder;//平均客单价
        }

        BusinessDataVO  businessDataVO = BusinessDataVO
                .builder()
                .newUsers(userMapper.countByMap(map))//新增用户数
                .orderCompletionRate(orderCompletionRate)
                .turnover(turnover)
                .validOrderCount(validOrder)
                .unitPrice(unitPrice)
                .build();


        return businessDataVO;
    }
}

1.2.2查询订单管理数据

controller层

service层

我在这里把map时间封装了

1.2.3查询套餐总览数据

conreoller层

service层

dao层

1.2.4查询菜品总览数据

conreoller层

service层

dao层

1.3 功能测试

通过

二、Apache POI

2.1介绍

Apache POI是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用POI在Java程序中对Miscrosoft Office各种文件进行读写操作。

一般情况下,POI都是用于操作Excel文件

Apache POI的应用场景:

银行网银系统导出交易明细

各种业务系统导出Excel报表

批量导入业务数据

使用需要导入maven坐标

java 复制代码
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.16</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.16</version>
</dependency>

三、导出运营数据Excel报表

3.1 需求分析和设计

业务规则:

导出Excel形式报表文件

导出最近30天的运营数据

查看接口文档:

注意:当前接口没有返回数据,因为报表导出功能本质上是文件下载,服务端会通过输出流将Excel文件下载到客户端浏览器。

3.2 代码开发

实现步骤:

1.设计Excel模板文件

2.查询近30天的运营数据

3.将查询到的运营数据写入模板文件

4.通过输出流将Excel文件下载到客户端浏览器

为了代码复用,这里我将上面自己写的"今日运营数据"的service进行了修改,现在可以查询任意日期的运营数据

java 复制代码
/**
     * 根据传入日期查询数据
     * @return
     */
    @Override
    public BusinessDataVO businessDate(LocalDateTime begin,LocalDateTime end) {
        /*LocalDate date = LocalDate.now();
        Map map = mapTime();
        OrderReportVO orderReportVO = reportService.getStatisticsReport(date,date);
        Double orderCompletionRate = orderReportVO.getOrderCompletionRate();//订单完成率*/
        Map map = new HashMap();
        map.put("beginTime",begin);
        map.put("endTime",end);

        //查询总订单数
        Integer totalOrderCount = orderMapper.countOrderByMap(map);

        map.put("status",Orders.COMPLETED);
        Double turnover = orderMapper.sumByMap(map);
        turnover = turnover == null ? 0.0 : turnover;//营业额

        Integer validOrder = orderMapper.countOrderByMap(map);//每日有效订单数

        Double unitPrice;
        Double orderCompletion = 0.0;
        if( validOrder == null || validOrder == 0 ){
            unitPrice = 0.0;
        }else{
            unitPrice = turnover/validOrder;//平均客单价
            orderCompletion = validOrder.doubleValue()/totalOrderCount;//订单完成率
        }
        BusinessDataVO  businessDataVO = BusinessDataVO
                .builder()
                .newUsers(userMapper.countByMap(map))//新增用户数
                .orderCompletionRate(orderCompletion)
                .turnover(turnover)
                .validOrderCount(validOrder)
                .unitPrice(unitPrice)
                .build();
        return businessDataVO;
    }

controller层

service层

java 复制代码
 /**
     * 导出运营数据报表
     * @param response
     */
    @Override
    public void exportBusinessData(HttpServletResponse response) {
        //1.查询数据库,获取营业数据--查询最近30天的运营数据
        LocalDate dateBegin = LocalDate.now().minusDays(30);
        LocalDate dateEnd = LocalDate.now().minusDays(1);
        //查询概览数据
        BusinessDataVO businessDataVO = workspaceService.businessDate(
                LocalDateTime.of(dateBegin, LocalTime.MIN),
                LocalDateTime.of(dateEnd, LocalTime.MAX));
        //2.通过POI将数据写入到Excel文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");

        try {
            //基于模板文件创建一个新的Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(in);

            //获取表格文件的Sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");

            //填充数据--时间
            sheet.getRow(1).getCell(1).setCellValue("时间:"+dateBegin+"至"+dateEnd);

            //获得第4行
            XSSFRow row = sheet.getRow(3);
            row.getCell(2).setCellValue(businessDataVO.getTurnover());
            row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
            row.getCell(6).setCellValue(businessDataVO.getNewUsers());

            //获得第5行
            row = sheet.getRow(4);
            row.getCell(2).setCellValue(businessDataVO.getValidOrderCount());
            row.getCell(4).setCellValue(businessDataVO.getUnitPrice());

            //填充明细数据
            for(int i = 0 ; i < 30 ; i++){
                LocalDate date = dateBegin.plusDays(i);
                //查询某一天的营业数据
                BusinessDataVO businessDate = workspaceService.businessDate(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(businessDate.getTurnover());
                row.getCell(3).setCellValue(businessDate.getValidOrderCount());
                row.getCell(4).setCellValue(businessDate.getOrderCompletionRate());
                row.getCell(5).setCellValue(businessDate.getUnitPrice());
                row.getCell(6).setCellValue(businessDate.getNewUsers());
            }

            //3.通过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            //4.关闭资源
            out.close();
            excel.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3.3 功能测试

通过!

四、小结

本项目充分提高了我的代码能力,真正从看得懂->能自己写,面对接口文档有思路,明白该怎么下手,报错时这样找错、改进。历经17天,除了最开始的项目后端框架和微信小程序前端是引入的之外其他的全为手写,认真实现每一样接口,充分理解并完成,完善。借用ai工具qoder实现前端代码,进行各种测试和交互,体验前端代码的操作和运行,提高自己的代码水平。感谢坚持不放弃的自己,以下还有几个问题需要解决

问题1,员工密码开发未完成

问题2,订单状态为"未接单"时永远不会被清理

问题3,当前端收到新订单时工作台页面不会及时刷新

后续考虑接入ai作为网页商户助手进行交互。小程序端需要考虑版本问题和小程序前端代码问题,如果可行我也会进行尝试。现在,我需要去好好睡一觉了,晚安。

相关推荐
小杍随笔2 小时前
【Rust 语言编程知识与应用:闭包详解】
开发语言·后端·rust
非凡的小笨鱼2 小时前
IDEA找不到类编译不通过的解决方案
java·maven·intellij-idea
共享家95272 小时前
Java入门( 异常 )
java·开发语言·php
Dfreedom.2 小时前
机器学习经典算法全景解析与演进脉络(无监督学习篇)
人工智能·学习·算法·机器学习·无监督学习
standovon2 小时前
SQL SERVER 登陆错误:18456
java
大傻^2 小时前
Spring AI Alibaba 文档智能处理:PDF、Markdown知识入库全链路
java·人工智能·spring·pdf·知识图谱·springai·springaialibaba
Yan-英杰2 小时前
TypeScript+React 全栈生态实战:从架构选型到工程落地,告别开发踩坑
javascript·学习·typescript
421!2 小时前
ESP32学习笔记之GPIO
开发语言·笔记·单片机·嵌入式硬件·学习·算法·fpga开发
小璐资源网2 小时前
从源码看ArrayList与LinkedList的性能差异
后端