skyline 1 rok temu
rodzic
commit
493ab8a80c

+ 1 - 1
admin-web/src/views/admin/station/device/index.vue

@@ -106,7 +106,7 @@ const state = reactive({
     // {label: '设备名称', prop: 'deviceName', width: 180, query: true, type: 'text', resizable: true, fixed: 'left'},
     // {label: '产品key', prop: 'productKey', width: 180, query: true, type: 'text', resizable: true},
     {label: '状态', prop: 'state', width: 90,query: true, type: 'dict', conf: {dict: 'WashDevice.status'}, resizable: true},
-    {label: '设备状态', prop: 'fsmState', width: 90, query: true, type: 'text', resizable: true},
+    // {label: '设备状态', prop: 'fsmState', width: 90, query: true, type: 'text', resizable: true},
     {
       label: '运行时长', prop: 'uptimeMs', width: 100, query: false, type: 'render', resizable: true,
       render: (h: any, row: any) => {

+ 29 - 0
car-wash-admin/src/main/java/com/kym/admin/controller/StatController.java

@@ -0,0 +1,29 @@
+package com.kym.admin.controller;
+
+import com.kym.common.R;
+import com.kym.common.controller.IController;
+import com.kym.service.StatService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * 统计数据
+ */
+@RestController
+@RequestMapping("/stat")
+public class StatController extends IController {
+
+    private final StatService statService;
+
+    public StatController(StatService statService) {
+        this.statService = statService;
+    }
+
+    @PostMapping("/dashboard")
+    public R<?> dashboard() {
+        return R.success(statService.dashboard());
+    }
+
+}

+ 46 - 0
car-wash-admin/src/main/java/com/kym/admin/jobs/StatJob.java

@@ -0,0 +1,46 @@
+package com.kym.admin.jobs;
+
+import com.kym.entity.DailyStat;
+import com.kym.service.DailyStatService;
+import com.kym.service.UserService;
+import com.kym.service.WashOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDate;
+
+/**
+ * 数据统计定时任务
+ */
+@Component
+@Slf4j
+public class StatJob {
+
+    private final UserService userService;
+
+    private final WashOrderService washOrderService;
+
+    private final DailyStatService dailyStatService;
+
+    public StatJob(UserService userService, WashOrderService washOrderService, DailyStatService dailyStatService) {
+        this.userService = userService;
+        this.washOrderService = washOrderService;
+        this.dailyStatService = dailyStatService;
+    }
+
+    /**
+     * 统计前一天的消费金额,注册人数,订单数量
+     * 每天凌晨00:30执行一次
+     */
+    @Scheduled(cron = "0 30 0 * * ?")
+    public void generateDailyStat() {
+        LocalDate yesterday = LocalDate.now().minusDays(1);
+        DailyStat stat = new DailyStat();
+        stat.setConsumption(washOrderService.sumAmountByDate(yesterday));
+        stat.setRegistrations(userService.countByDailyRegister(yesterday));
+        stat.setOrdersCount(washOrderService.countOrdersCountByDate(yesterday));
+        dailyStatService.save(stat);
+    }
+
+}

+ 44 - 0
car-wash-entity/src/main/java/com/kym/entity/DailyStat.java

@@ -0,0 +1,44 @@
+package com.kym.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.kym.entity.BaseEntity;
+import java.io.Serializable;
+import java.time.LocalDate;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 日统计表
+ * </p>
+ *
+ * @author skyline
+ * @since 2025-02-19
+ */
+@Getter
+@Setter
+@TableName("t_daily_stat")
+public class DailyStat extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 统计日期
+     */
+    private LocalDate statDate;
+
+    /**
+     * 消费金额(分)
+     */
+    private Integer consumption;
+
+    /**
+     * 注册用户数量
+     */
+    private Integer registrations;
+
+    /**
+     * 订单数量
+     */
+    private Integer ordersCount;
+}

+ 81 - 0
car-wash-entity/src/main/java/com/kym/entity/vo/DashboardVo.java

@@ -0,0 +1,81 @@
+package com.kym.entity.vo;
+
+/**
+ * 数据看板
+ */
+public class DashboardVo {
+    /**
+     * 当日收益金额
+     */
+    private Integer todayIncome;
+
+    /**
+     * 当月收益金额
+     */
+    private Integer monthIncome;
+
+    /**
+     * 累计收益金额
+     */
+    private Integer totalIncome;
+
+    /**
+     * 当日消费金额
+     */
+    private Integer todayConsumptionAmount;
+
+    /**
+     * 当月消费金额
+     */
+    private Integer monthConsumptionAmount;
+
+    /**
+     * 累计消费金额
+     */
+    private Integer totalConsumptionAmount;
+
+    /**
+     * 当日注册会员数量
+     */
+    private Integer todayRegisteredMembers;
+
+    /**
+     * 当月注册会员数量
+     */
+    private Integer monthRegisteredMembers;
+
+    /**
+     * 累计注册会员数量
+     */
+    private Integer totalRegisteredMembers;
+
+    /**
+     * 当日洗车订单数量
+     */
+    private Integer todayWashOrders;
+
+    /**
+     * 当月洗车订单数量
+     */
+    private Integer monthWashOrders;
+
+    /**
+     * 累计洗车订单数量
+     */
+    private Integer totalWashOrders;
+
+    /**
+     * 今日平均洗车单价
+     */
+    private Integer avgOrderPrice;
+
+    /**
+     * 平均洗车时长(秒)
+     */
+    private Integer avgOrderDuration;
+
+    /**
+     * 今日平均洗车频率(次/人/月)
+     */
+    private Double avgWashFrequency;
+}

+ 16 - 0
car-wash-mapper/src/main/java/com/kym/mapper/DailyStatMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper;
+
+import com.kym.entity.DailyStat;
+import com.kym.mapper.mybatisplus.MyBaseMapper;
+
+/**
+ * <p>
+ * 日统计表 Mapper 接口
+ * </p>
+ *
+ * @author skyline
+ * @since 2025-02-19
+ */
+public interface DailyStatMapper extends MyBaseMapper<DailyStat> {
+
+}

+ 18 - 0
car-wash-mapper/src/main/resources/mappers/DailyStatMapper.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kym.mapper.DailyStatMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.DailyStat">
+        <result column="stat_date" property="statDate" />
+        <result column="consumption" property="consumption" />
+        <result column="registrations" property="registrations" />
+        <result column="orders_count" property="ordersCount" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        stat_date, consumption, registrations, orders_count
+    </sql>
+
+</mapper>

+ 18 - 0
car-wash-miniapp/src/main/java/com/kym/admin/controller/DailyStatController.java

@@ -0,0 +1,18 @@
+package com.kym.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 日统计表 前端控制器
+ * </p>
+ *
+ * @author skyline
+ * @since 2025-02-19
+ */
+@RestController
+@RequestMapping("/daily-stat")
+public class DailyStatController {
+
+}

+ 16 - 0
car-wash-service/src/main/java/com/kym/service/DailyStatService.java

@@ -0,0 +1,16 @@
+package com.kym.service;
+
+import com.kym.entity.DailyStat;
+import com.kym.service.mybatisplus.MyBaseService;
+
+/**
+ * <p>
+ * 日统计表 服务类
+ * </p>
+ *
+ * @author skyline
+ * @since 2025-02-19
+ */
+public interface DailyStatService extends MyBaseService<DailyStat> {
+
+}

+ 32 - 0
car-wash-service/src/main/java/com/kym/service/StatService.java

@@ -0,0 +1,32 @@
+package com.kym.service;
+
+import com.kym.common.R;
+import com.kym.entity.vo.DashboardVo;
+
+import java.math.BigDecimal;
+import java.time.Duration;
+
+/**
+ * 统计
+ */
+public interface StatService {
+
+    // 实时指标
+    Integer getTodayConsumption();
+    Integer getTodayRegistrations();
+
+    // 缓存指标(5分钟刷新)
+    Integer getMonthConsumption();
+    Integer getMonthRegistrations();
+
+    // 历史指标(每日预计算)
+    Integer getTotalConsumption();
+    Integer getTotalRegistrations();
+
+    // 复合指标
+    Integer getAvgPrice();
+    Integer getAvgDuration();
+    Double getAvgFrequency();
+
+    DashboardVo dashboard();
+}

+ 6 - 0
car-wash-service/src/main/java/com/kym/service/UserService.java

@@ -9,6 +9,8 @@ import com.kym.entity.User;
 import com.kym.entity.queryParams.WxLoginParams;
 import com.kym.entity.vo.UserVo;
 
+import java.time.LocalDate;
+
 /**
  * <p>
  * 用户表 服务类
@@ -28,4 +30,8 @@ public interface UserService extends MPJBaseService<User> {
     R<?> wxLogin(WxLoginParams params);
 
     PageBean<CustomUserVo> listCustomUser(CommonQueryParam params);
+
+    Integer countByDailyRegister(LocalDate statDay);
+
+    Integer countMonthRegister(LocalDate statDay);
 }

+ 11 - 0
car-wash-service/src/main/java/com/kym/service/WashOrderService.java

@@ -8,6 +8,8 @@ import com.kym.entity.queryParams.WashOrderQueryParams;
 import com.kym.entity.vo.WashOrderVo;
 import com.kym.service.mybatisplus.MyBaseService;
 
+import java.time.LocalDate;
+
 /**
  * <p>
  * 洗车订单表 服务类
@@ -29,4 +31,13 @@ public interface WashOrderService extends MyBaseService<WashOrder> {
     Object list(WashOrderQueryParams query);
 
     Object detail(long id);
+
+    Integer sumAmountByDate(LocalDate statDay);
+
+    Integer sumMonthAmount(LocalDate statDay);
+
+    Integer countOrdersCountByDate(LocalDate statDay);
+
+    Integer countMonthOrdersCount(LocalDate statDay);
+
 }

+ 20 - 0
car-wash-service/src/main/java/com/kym/service/impl/DailyStatServiceImpl.java

@@ -0,0 +1,20 @@
+package com.kym.service.impl;
+
+import com.kym.entity.DailyStat;
+import com.kym.mapper.DailyStatMapper;
+import com.kym.service.DailyStatService;
+import com.kym.service.mybatisplus.MyBaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 日统计表 服务实现类
+ * </p>
+ *
+ * @author skyline
+ * @since 2025-02-19
+ */
+@Service
+public class DailyStatServiceImpl extends MyBaseServiceImpl<DailyStatMapper, DailyStat> implements DailyStatService {
+
+}

+ 114 - 0
car-wash-service/src/main/java/com/kym/service/impl/StatServiceImpl.java

@@ -0,0 +1,114 @@
+package com.kym.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.kym.entity.WashOrder;
+import com.kym.entity.vo.DashboardVo;
+import com.kym.service.StatService;
+import com.kym.service.UserService;
+import com.kym.service.WashOrderService;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
+
+
+/**
+ * 统计
+ */
+@Service
+public class StatServiceImpl implements StatService {
+    private final UserService userService;
+    private WashOrderService washOrderService;
+
+    public StatServiceImpl(UserService userService) {
+        this.userService = userService;
+    }
+
+    @Override
+    public Integer getTodayConsumption() {
+        return washOrderService.sumAmountByDate(LocalDate.now());
+    }
+
+    @Override
+    public Integer getTodayRegistrations() {
+        return userService.countByDailyRegister(LocalDate.now());
+    }
+
+    @Override
+    public Integer getMonthConsumption() {
+        return washOrderService.sumMonthAmount(LocalDate.now());
+    }
+
+    @Override
+    public Integer getMonthRegistrations() {
+        return userService.countMonthRegister(LocalDate.now());
+    }
+
+    @Override
+    public Integer getTotalConsumption() {
+        return null;
+    }
+
+    @Override
+    public Integer getTotalRegistrations() {
+        return (int) userService.count();
+    }
+
+    /**
+     * 当月订单平均消费金额
+     *
+     * @return
+     */
+    @Override
+    public Integer getAvgPrice() {
+        int totalAmount = washOrderService.sumMonthAmount(LocalDate.now());
+        int totalOrders = washOrderService.countMonthOrdersCount(LocalDate.now());
+        return totalOrders == 0 ? 0 : totalAmount / totalOrders;
+    }
+
+    /**
+     * 平均洗车时长
+     *
+     * @return
+     */
+    @Override
+    public Integer getAvgDuration() {
+        var startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+        var endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+        LambdaQueryWrapper<WashOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ge(WashOrder::getStartTime, startTime);
+        wrapper.gt(WashOrder::getStartTime, endTime);
+        var list = washOrderService.list(wrapper);
+        if (!list.isEmpty()) {
+            var totalSeconds = list.stream().mapToInt(WashOrder::getTotalSeconds).sum();
+            return totalSeconds / list.size();
+        }
+        return null;
+    }
+
+
+    /**
+     * 当月用户平均洗车频率
+     *
+     * @return
+     */
+    @Override
+    public Double getAvgFrequency() {
+        var startTime = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+        var endTime = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+        LambdaQueryWrapper<WashOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ge(WashOrder::getStartTime, startTime);
+        wrapper.gt(WashOrder::getStartTime, endTime);
+        var list = washOrderService.list(wrapper);
+        // 洗车人数
+        var users = list.stream().distinct().map(WashOrder::getUserId).count();
+        return users == 0 ? 0 : (double) Math.round((double) list.size() / users * 100) / 100;
+    }
+
+    @Override
+    public DashboardVo dashboard() {
+        DashboardVo dashboardVo = new DashboardVo();
+        return dashboardVo;
+    }
+}

+ 37 - 12
car-wash-service/src/main/java/com/kym/service/impl/UserServiceImpl.java

@@ -1,6 +1,7 @@
 package com.kym.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.github.pagehelper.PageHelper;
@@ -12,11 +13,7 @@ import com.kym.common.enums.WxApi;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.HttpUtil;
-import com.kym.entity.Account;
-import com.kym.entity.Cars;
-import com.kym.entity.MpRelation;
-import com.kym.entity.User;
-import com.kym.entity.RefundLog;
+import com.kym.entity.*;
 import com.kym.entity.common.PageBean;
 import com.kym.entity.queryParams.CommonQueryParam;
 import com.kym.entity.queryParams.WxLoginParams;
@@ -25,13 +22,7 @@ import com.kym.entity.vo.UserVo;
 import com.kym.entity.wechat.WxPhoneNum;
 import com.kym.mapper.MpRelationMapper;
 import com.kym.mapper.UserMapper;
-import com.kym.service.ActivityService;
-import com.kym.service.BannerService;
-import com.kym.service.RechargeRightsService;
-import com.kym.service.AccountService;
-import com.kym.service.CarsService;
-import com.kym.service.RefundLogService;
-import com.kym.service.UserService;
+import com.kym.service.*;
 import lombok.SneakyThrows;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -41,7 +32,10 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -274,4 +268,35 @@ public class UserServiceImpl extends MPJBaseServiceImpl<UserMapper, User> implem
     }
 
 
+    /**
+     * 统计指定日期注册用户数量
+     *
+     * @param statDay
+     * @return
+     */
+    @Override
+    public Integer countByDailyRegister(LocalDate statDay) {
+        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ge(User::getCreateTime, LocalDateTime.of(statDay, LocalTime.MIN));
+        wrapper.gt(User::getCreateTime, LocalDateTime.of(statDay, LocalTime.MAX));
+        return (int) count(wrapper);
+    }
+
+    /**
+     * 统计指定日期当月注册用户数量
+     *
+     * @param statDay
+     * @return
+     */
+    @Override
+    public Integer countMonthRegister(LocalDate statDay) {
+        var startTime = statDay.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+        var endTime = statDay.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ge(User::getCreateTime, startTime);
+        wrapper.gt(User::getCreateTime, endTime);
+        return (int) count(wrapper);
+    }
+
+
 }

+ 73 - 7
car-wash-service/src/main/java/com/kym/service/impl/WashOrderServiceImpl.java

@@ -1,30 +1,34 @@
 package com.kym.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.github.pagehelper.PageHelper;
 import com.github.yulichang.toolkit.JoinWrappers;
 import com.github.yulichang.wrapper.MPJLambdaWrapper;
 import com.kym.common.exception.BusinessException;
 import com.kym.common.utils.CommUtil;
 import com.kym.common.utils.OrderUtils;
-import com.kym.entity.common.PageBean;
-import com.kym.entity.common.PageParams;
 import com.kym.entity.Account;
 import com.kym.entity.User;
 import com.kym.entity.WashOrder;
+import com.kym.entity.common.PageBean;
+import com.kym.entity.common.PageParams;
 import com.kym.entity.queryParams.DeviceQueryParams;
 import com.kym.entity.queryParams.WashOrderQueryParams;
 import com.kym.entity.vo.WashOrderVo;
 import com.kym.mapper.WashOrderMapper;
-import com.kym.service.awoara.AwoaraService;
-import com.kym.service.cache.KymCache;
 import com.kym.service.AccountService;
 import com.kym.service.WashOrderService;
+import com.kym.service.awoara.AwoaraService;
+import com.kym.service.cache.KymCache;
 import com.kym.service.mybatisplus.MyBaseServiceImpl;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
 import java.util.List;
 
 /**
@@ -129,8 +133,8 @@ public class WashOrderServiceImpl extends MyBaseServiceImpl<WashOrderMapper, Was
         WashOrder order = lambdaQuery()
                 .eq(WashOrder::getOrderId, params.getOrderId())
                 .one();
-        if(null!=params.getUserId()){
-            CommUtil.asserts(null!=order && order.getUserId().equals(StpUtil.getLoginIdAsLong()),
+        if (null != params.getUserId()) {
+            CommUtil.asserts(null != order && order.getUserId().equals(StpUtil.getLoginIdAsLong()),
                     "订单不存在或您没有权限查看该订单!");
         }
         return order;
@@ -165,7 +169,7 @@ public class WashOrderServiceImpl extends MyBaseServiceImpl<WashOrderMapper, Was
         MPJLambdaWrapper<WashOrder> wrapper = JoinWrappers.lambda(WashOrder.class)
                 .selectAsClass(WashOrder.class, WashOrderVo.class)
                 .selectAs(User::getMobilePhone, WashOrderVo::getMobilePhone)
-                .leftJoin(User.class, User::getId,WashOrder::getUserId)
+                .leftJoin(User.class, User::getId, WashOrder::getUserId)
                 .eq(CommUtil.isNotEmptyAndNull(params.getUserId()), WashOrder::getUserId, params.getUserId())
                 .eq(CommUtil.isNotEmptyAndNull(params.getMobilePhone()), User::getMobilePhone, params.getMobilePhone())
                 .eq(CommUtil.isNotEmptyAndNull(params.getOrderStatus()), WashOrder::getOrderStatus, params.getOrderStatus())
@@ -183,5 +187,67 @@ public class WashOrderServiceImpl extends MyBaseServiceImpl<WashOrderMapper, Was
     public WashOrder detail(long id) {
         return getById(id);
     }
+
+    /**
+     * 统计指定日期消费金额
+     *
+     * @param statDay
+     * @return
+     */
+    @Override
+    public Integer sumAmountByDate(LocalDate statDay) {
+        LambdaQueryWrapper<WashOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(WashOrder::getAmount);
+        wrapper.ge(WashOrder::getStartTime, LocalDateTime.of(statDay, LocalTime.MIN));
+        wrapper.gt(WashOrder::getStartTime, LocalDateTime.of(statDay, LocalTime.MAX));
+        return list(wrapper).stream().mapToInt(WashOrder::getAmount).sum();
+    }
+
+    /**
+     * 统计指定日期当月总消费金额
+     *
+     * @param statDay
+     * @return
+     */
+    @Override
+    public Integer sumMonthAmount(LocalDate statDay) {
+        var startTime = statDay.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+        var endTime = statDay.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+        LambdaQueryWrapper<WashOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.select(WashOrder::getAmount);
+        wrapper.ge(WashOrder::getStartTime, startTime);
+        wrapper.gt(WashOrder::getStartTime, endTime);
+        return list(wrapper).stream().mapToInt(WashOrder::getAmount).sum();
+    }
+
+    /**
+     * 统计指定日期订单数量
+     *
+     * @param statDay
+     * @return
+     */
+    @Override
+    public Integer countOrdersCountByDate(LocalDate statDay) {
+        LambdaQueryWrapper<WashOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ge(WashOrder::getStartTime, LocalDateTime.of(statDay, LocalTime.MIN));
+        wrapper.gt(WashOrder::getStartTime, LocalDateTime.of(statDay, LocalTime.MAX));
+        return (int) count(wrapper);
+    }
+
+    /**
+     * 统计指定日期订单数量
+     *
+     * @param statDay
+     * @return
+     */
+    @Override
+    public Integer countMonthOrdersCount(LocalDate statDay) {
+        var startTime = statDay.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
+        var endTime = statDay.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
+        LambdaQueryWrapper<WashOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.ge(WashOrder::getStartTime, startTime);
+        wrapper.gt(WashOrder::getStartTime, endTime);
+        return (int) count(wrapper);
+    }
     //endregion
 }