工作台 (day12) 1

工作台

需求分析和设计

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

工作台展示的数据:

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

名词解释:

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

接口设计:

今日数据接口
订单管理接口
菜品总览接口
套餐总览接口
订单搜索(已完成)
各个状态的订单数量统计(已完成)

1、今日数据接口

今日数据的接口设计:
 

代码设计

1、admin/WorkSpaceController

package com.sky.controller.admin;

import com.sky.result.Result;
import com.sky.service.WorkspaceService;
import com.sky.vo.BusinessDataVO;
import com.sky.vo.DishOverViewVO;
import com.sky.vo.OrderOverViewVO;
import com.sky.vo.SetmealOverViewVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.LocalTime;

/**
 * 工作台
 */
@RestController
@RequestMapping("/admin/workspace")
@Slf4j
@Api(tags = "工作台相关接口")
public class WorkSpaceController {

    @Autowired
    private WorkspaceService workspaceService;

    /**
     * 工作台今日数据查询
     * @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.getBusinessData(begin, end);
        return Result.success(businessDataVO);
    }
}

1、WorkspaceService 

/**
     * 根据时间段统计营业数据
     * @param begin
     * @param end
     * @return
     */
    BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end);

1、WorkspaceServiceImpl

package com.sky.service.impl;

import com.sky.constant.StatusConstant;
import com.sky.entity.Orders;
import com.sky.mapper.DishMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.WorkspaceService;
import com.sky.vo.BusinessDataVO;
import com.sky.vo.DishOverViewVO;
import com.sky.vo.OrderOverViewVO;
import com.sky.vo.SetmealOverViewVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class WorkspaceServiceImpl implements WorkspaceService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 根据时间段统计营业数据
     * @param begin
     * @param end
     * @return
     */
    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);
        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();
    }

}

2、订单管理接口

 订单管理的接口设计:

代码设计

2、admin/WorkSpaceController

/**
     * 查询订单管理数据
     * @return
     */
    @GetMapping("/overviewOrders")
    @ApiOperation("查询订单管理数据")
    public Result<OrderOverViewVO> orderOverView(){
        
        return Result.success(workspaceService.getOrderOverView());
    }

2、WorkspaceService 

/**
     * 查询订单管理数据
     * @return
     */
    OrderOverViewVO getOrderOverView();

2、WorkspaceServiceImpl

/**
     * 查询订单管理数据
     *
     * @return
     */
    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();
    }

 2、OrderMapper

/**
     * 根据动态条件统计订单数量
     * @param map
     */
    Integer countByMap(Map map);

2、 OrderMapper.xml

<select id="countByMap" resultType="java.lang.Integer">
        select count(id) from orders
        <where>
            <if test="status != null">
                and status = #{status}
            </if>
            <if test="begin != null">
                and order_time &gt;= #{begin}
            </if>
            <if test="end != null">
                and order_time &lt;= #{end}
            </if>
        </where>
    </select>

3、菜品总览接口

代码设计

3、admin/WorkSpaceController

/**
     * 查询菜品总览
     * @return
     */
    @GetMapping("/overviewDishes")
    @ApiOperation("查询菜品总览")
    public Result<DishOverViewVO> dishOverView(){
        
        return Result.success(workspaceService.getDishOverView());
    }

3、WorkspaceService 

/**
     * 查询菜品总览
     * @return
     */
    DishOverViewVO getDishOverView();

3、WorkspaceServiceImpl

 /**
     * 查询菜品总览
     *
     * @return
     */
    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();
    }

3、DishMapper

/**
     * 根据条件统计菜品数量
     * @param map
     * @return
     */
    Integer countByMap(Map map);

3、 DishMapper.xml

<select id="countByMap" resultType="java.lang.Integer">
        select count(id) from dish
        <where>
            <if test="status != null"> and status = #{status} </if>
            <if test="categoryId != null"> and category_id = #{categoryId} </if>
        </where>
    </select>

4、套餐总览接口

代码设计

4、admin/WorkSpaceController

/**
     * 查询套餐总览
     * @return
     */
    @GetMapping("/overviewSetmeals")
    @ApiOperation("查询套餐总览")
    public Result<SetmealOverViewVO> setmealOverView(){
        
        return Result.success(workspaceService.getSetmealOverView());
    }

4、WorkspaceService 

/**
     * 查询套餐总览
     * @return
     */
    SetmealOverViewVO getSetmealOverView();

4、WorkspaceServiceImpl

/**
     * 查询套餐总览
     *
     * @return
     */
    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();
    }

4、SetmealMapper

/**
     * 根据条件统计套餐数量
     * @param map
     * @return
     */
    Integer countByMap(Map map);

4、SetmealMapper.java

<select id="countByMap" resultType="java.lang.Integer">
        select count(id) from setmeal
        <where>
            <if test="status != null"> and status = #{status} </if>
            <if test="categoryId != null"> and category_id = #{categoryId} </if>
        </where>
    </select>

上一节:

数据统计–图形报表(day11)-优快云博客

下一节:

数据统计–Excel报表(day12)2-优快云博客

### 工作台数据不匹配问题的解决方案 在苍穹外卖项目的 day12 阶段,工作台数据不匹配的问题通常涉及到数据查询逻辑、数据展示逻辑或数据源的不一致。以下是可能的解决方案: #### 1. **检查数据查询逻辑** - 确保 `WorkspaceService` 中的 `getBusinessData` 方法正确地根据时间段统计营业数据。例如,`begin` 和 `end` 时间的计算必须准确,并且数据库查询逻辑需要匹配这些时间条件。 - 如果查询逻辑中使用了复杂的过滤条件(如状态、分类等),确保这些条件与业务需求一致。例如,`SetmealMapper.xml` 中的 SQL 语句应正确处理 `status` 和 `categoryId` 的过滤条件 [^4]。 #### 2. **验证数据展示逻辑** - 在 `WorkspaceController` 中定义的 `businessData` 方法中,确保返回的 `BusinessDataVO` 数据结构与前端展示需求一致。例如,`begin` 和 `end` 的时间范围是否正确设置为当天的最小和最大时间 [^1]。 - 如果数据需要从多个来源聚合(如订单、菜品、套餐等),确保每个来源的数据查询逻辑正确且聚合逻辑无误。 #### 3. **调试数据源问题** - 如果数据来源于数据库,检查数据库中的数据是否符合预期。例如,订单数据是否正确记录、状态是否更新及时。 - 如果数据来源于缓存或其他外部系统,确保缓存数据数据数据同步,避免出现数据延迟或不一致的情况。 #### 4. **日志与测试** - 在关键数据查询和处理环节添加日志输出,记录中间数据,以便定位问题。例如,记录 `begin` 和 `end` 的时间值,以及查询返回的原始数据。 - 使用单元测试验证数据查询逻辑的正确性。例如,模拟不同的时间范围和过滤条件,确保返回的数据与预期一致。 #### 5. **Excel 报表生成问题** - 如果问题出现在 Excel 报表生成过程中,确保模板文件正确加载,并且数据填充逻辑无误。例如,通过 `getResourceAsStream` 正确获取模板文件的输入流,并使用 `XSSFWorkbook` 对象处理数据填充 [^3]。 - 检查数据填充的循环逻辑,确保每一天的数据正确获取并填充到对应的行和单元格中。 #### 6. **时间计算问题** - 如果数据不匹配与时间计算有关,确保 `LocalDateTime` 的处理逻辑正确。例如,在计算最近 30 天的数据时,使用 `plusDays` 方法时需确保时间范围的准确性 。 #### 示例代码 以下是一个简单的代码示例,用于验证时间范围的计算逻辑: ```java LocalDateTime todayStart = LocalDateTime.now().with(LocalTime.MIN); LocalDateTime todayEnd = LocalDateTime.now().with(LocalTime.MAX); System.out.println("Today's Start: " + todayStart); System.out.println("Today's End: " + todayEnd); ``` #### 7. **前端与后端接口一致性** - 确保前端请求的接口参数与后端定义的接口一致。例如,前端请求 `GET /businessData` 时,是否正确传递了时间范围参数。 - 使用工具(如 Postman)测试接口,验证返回的数据是否符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值