博客
关于我
黑马程序员Java项目实战《苍穹外卖》Day12
阅读量:478 次
发布时间:2019-03-06

本文共 9617 字,大约阅读时间需要 32 分钟。

苍穹外卖 - 系统开发日志

工作台开发

1.1 需求分析与设计

工作台是系统运营的数据看板,旨在为商家提供便捷的数据分析工具和操作入口,提升工作效率。

1.1.1 产品原型

工作台主要展示以下数据类别:

  • 今日数据
  • 订单管理
  • 菜品总览
  • 套餐总览
  • 订单信息

1.1.2 接口设计

通过原型图分析,确定了以下接口:

  • 今日数据接口
  • 订单管理接口
  • 菜品总览接口
  • 套餐总览接口
  • 订单搜索接口(已完成)
  • 订单状态统计接口(已完成)
  • 1.2 代码实现

    1.2.1 Controller层

    WorkSpaceController.java

    @RestController
    @RequestMapping("/admin/workspace")
    @Slf4j
    @Api(tags = "工作台相关接口")
    public class WorkSpaceController {
    @Autowired
    private WorkspaceService workspaceService;
    @GetMapping("/businessData")
    @ApiOperation("工作台今日数据查询")
    public Result
    businessData() {
    LocalDateTime begin = LocalDateTime.now().with(LocalTime.MIN);
    LocalDateTime end = LocalDateTime.now().with(LocalTime.MAX);
    BusinessDataVO businessDataVO = workspaceService.getBusinessData(begin, end);
    return Result.success(businessDataVO);
    }
    @GetMapping("/overviewOrders")
    @ApiOperation("查询订单管理数据")
    public Result
    orderOverView() {
    return Result.success(workspaceService.getOrderOverView());
    }
    @GetMapping("/overviewDishes")
    @ApiOperation("查询菜品总览")
    public Result
    dishOverView() {
    return Result.success(workspaceService.getDishOverView());
    }
    @GetMapping("/overviewSetmeals")
    @ApiOperation("查询套餐总览")
    public Result
    setmealOverView() {
    return Result.success(workspaceService.getSetmealOverView());
    }
    }

    1.2.2 Service层接口

    WorkspaceService.java

    public interface WorkspaceService {
    BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end);
    OrderOverViewVO getOrderOverView();
    DishOverViewVO getDishOverView();
    SetmealOverViewVO getSetmealOverView();
    }

    1.2.3 Service层实现类

    WorkspaceServiceImpl.java

    @Service
    @Slf4j
    public class WorkspaceServiceImpl implements WorkspaceService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    public BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {
    Map map = new HashMap<>();
    map.put("begin", begin);
    map.put("end", end);
    Integer totalOrderCount = orderMapper.countByMap(map);
    map.put("status", Orders.COMPLETED);
    Double turnover = orderMapper.sumByMap(map);
    Integer validOrderCount = orderMapper.countByMap(map);
    Double unitPrice = 0.0;
    Double orderCompletionRate = 0.0;
    if (totalOrderCount != 0 && validOrderCount != 0) {
    orderCompletionRate = validOrderCount / totalOrderCount;
    unitPrice = turnover / validOrderCount;
    }
    Integer newUsers = userMapper.countByMap(map);
    return BusinessDataVO.builder()
    .turnover(turnover)
    .validOrderCount(validOrderCount)
    .orderCompletionRate(orderCompletionRate)
    .unitPrice(unitPrice)
    .newUsers(newUsers)
    .build();
    }
    public OrderOverViewVO getOrderOverView() {
    Map map = new HashMap<>();
    map.put("begin", LocalDateTime.now().with(LocalTime.MIN));
    map.put("status", Orders.TO_BE_CONFIRMED);
    Integer waitingOrders = orderMapper.countByMap(map);
    map.put("status", Orders.CONFIRMED);
    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();
    }
    public DishOverViewVO getDishOverView() {
    Map map = new HashMap<>();
    map.put("status", StatusConstant.ENABLE);
    Integer sold = dishMapper.countByMap(map);
    map.put("status", StatusConstant.DISABLE);
    Integer discontinued = dishMapper.countByMap(map);
    return DishOverViewVO.builder()
    .sold(sold)
    .discontinued(discontinued)
    .build();
    }
    public SetmealOverViewVO getSetmealOverView() {
    Map map = new HashMap<>();
    map.put("status", StatusConstant.ENABLE);
    Integer sold = setmealMapper.countByMap(map);
    map.put("status", StatusConstant.DISABLE);
    Integer discontinued = setmealMapper.countByMap(map);
    return SetmealOverViewVO.builder()
    .sold(sold)
    .discontinued(discontinued)
    .build();
    }
    }

    Apache POI

    2.1 介绍

    Apache POI 是一个开源项目,专注于处理 Microsoft Office 文件格式。主要用于通过 Java 程序读写 Excel 文件。

    2.2 Apache POI 入门案例

    2.2.1 将数据写入Excel文件

    public class POITest {
    public static void write() throws Exception {
    XSSFWorkbook excel = new XSSFWorkbook();
    XSSFSheet sheet = excel.createSheet("itcast");
    XSSFRow row1 = sheet.createRow(0);
    row1.createCell(1).setCellValue("姓名");
    row1.createCell(2).setCellValue("城市");
    XSSFRow row2 = sheet.createRow(1);
    row2.createCell(1).setCellValue("张三");
    row2.createCell(2).setCellValue("北京");
    XSSFRow row3 = sheet.createRow(2);
    row3.createCell(1).setCellValue("李四");
    row3.createCell(2).setCellValue("上海");
    FileOutputStream out = new FileOutputStream(new File("D:\\itcast.xlsx"));
    excel.write(out);
    out.flush();
    out.close();
    excel.close();
    }
    public static void main(String[] args) throws Exception {
    write();
    }
    }

    2.2.2 读取Excel文件中的数据

    public class POITest {
    public static void read() throws Exception {
    FileInputStream in = new FileInputStream(new File("D:\\itcast.xlsx"));
    XSSFWorkbook excel = new XSSFWorkbook(in);
    XSSFSheet sheet = excel.getSheetAt(0);
    int lastRowNum = sheet.getLastRowNum();
    for (int i = 0; i <= lastRowNum; i++) {
    XSSFRow titleRow = sheet.getRow(i);
    XSSFCell cell1 = titleRow.getCell(1);
    String cellValue1 = cell1.getStringCellValue();
    XSSFCell cell2 = titleRow.getCell(2);
    String cellValue2 = cell2.getStringCellValue();
    System.out.println(cellValue1 + " " + cellValue2);
    }
    in.close();
    excel.close();
    }
    public static void main(String[] args) throws Exception {
    read();
    }
    }

    导出运营数据Excel报表

    3.1 需求分析与设计

    在数据统计页面,点击数据导出按钮后,下载包含最近30天运营数据的Excel报表。

    3.2 代码开发

    3.2.1 实现步骤

  • 设计Excel模板文件
  • 查询近30天的运营数据
  • 将数据写入模板文件
  • 通过输出流将Excel文件下载到客户端
  • 3.2.2 Controller层

    ReportController.java

    @RestController
    @RequestMapping("/report")
    @Api(tags = "报表导出相关接口")
    public class ReportController {
    @Autowired
    private ReportService reportService;
    @GetMapping("/export")
    @ApiOperation("导出运营数据报表")
    public void export(HttpServletResponse response) {
    reportService.exportBusinessData(response);
    }
    }

    3.2.3 Service层接口

    ReportService.java

    public interface ReportService {
    void exportBusinessData(HttpServletResponse response);
    }

    3.2.4 Service层实现类

    ReportServiceImpl.java

    public class ReportServiceImpl implements ReportService {
    public void exportBusinessData(HttpServletResponse response) {
    LocalDate begin = LocalDate.now().minusDays(30);
    LocalDate end = LocalDate.now().minusDays(1);
    BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(begin, LocalTime.MIN), LocalDateTime.of(end, LocalTime.MAX));
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/运营数据报表模板.xlsx");
    try {
    XSSFWorkbook excel = new XSSFWorkbook(inputStream);
    XSSFSheet sheet = excel.getSheet("Sheet1");
    sheet.getRow(1).getCell(1).setCellValue(begin + "至" + end);
    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();
    }
    }
    }

    测试与部署

    功能测试

  • 前后端联调测试
  • 接口文档测试
  • 代码提交

    将上述代码提交至项目源码仓库,完成后可通过以下步骤进行测试和部署。

    转载地址:http://mtqbz.baihongyu.com/

    你可能感兴趣的文章
    mysqldump的一些用法
    查看>>
    mysqli
    查看>>
    MySQLIntegrityConstraintViolationException异常处理
    查看>>
    mysqlreport分析工具详解
    查看>>
    MySQLSyntaxErrorException: Unknown error 1146和SQLSyntaxErrorException: Unknown error 1146
    查看>>
    Mysql_Postgresql中_geometry数据操作_st_astext_GeomFromEWKT函数_在java中转换geometry的16进制数据---PostgreSQL工作笔记007
    查看>>
    mysql_real_connect 参数注意
    查看>>
    mysql_secure_installation初始化数据库报Access denied
    查看>>
    MySQL_西安11月销售昨日未上架的产品_20161212
    查看>>
    Mysql——深入浅出InnoDB底层原理
    查看>>
    MySQL“被动”性能优化汇总
    查看>>
    MySQL、HBase 和 Elasticsearch:特点与区别详解
    查看>>
    MySQL、Redis高频面试题汇总
    查看>>
    MYSQL、SQL Server、Oracle数据库排序空值null问题及其解决办法
    查看>>
    mysql一个字段为空时使用另一个字段排序
    查看>>
    MySQL一个表A中多个字段关联了表B的ID,如何关联查询?
    查看>>
    MYSQL一直显示正在启动
    查看>>
    MySQL一站到底!华为首发MySQL进阶宝典,基础+优化+源码+架构+实战五飞
    查看>>
    MySQL万字总结!超详细!
    查看>>
    Mysql下载以及安装(新手入门,超详细)
    查看>>