2025.5.9 spring task实现付款超时自动取消订单 每日凌晨自动设置完成配送中的订单 websocket来单提醒
This commit is contained in:
parent
2dd3f86132
commit
ba00630535
@ -0,0 +1,6 @@
|
||||
package com.sky.exception;
|
||||
|
||||
public class TemplateNotFoundException extends BaseException{
|
||||
public TemplateNotFoundException(){}
|
||||
public TemplateNotFoundException(String msg){super(msg);}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.sky.controller.admin;
|
||||
|
||||
import com.sky.result.Result;
|
||||
import com.sky.service.ReportService;
|
||||
import com.sky.vo.OrderReportVO;
|
||||
import com.sky.vo.SalesTop10ReportVO;
|
||||
import com.sky.vo.TurnoverReportVO;
|
||||
import com.sky.vo.UserReportVO;
|
||||
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.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 数据统计相关接口
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/admin/report")
|
||||
@Api(tags = "数据统计相关接口")
|
||||
@Slf4j
|
||||
public class ReportController {
|
||||
|
||||
@Autowired
|
||||
private ReportService reportService;
|
||||
|
||||
/**
|
||||
* 营业额统计
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/turnoverStatistics")
|
||||
@ApiOperation("营业额统计")
|
||||
public Result<TurnoverReportVO> turnoverStatistics(
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){
|
||||
log.info("营业额数据统计:{},{}",begin,end);
|
||||
return Result.success(reportService.getTurnoverStatistics(begin,end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户统计
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/userStatistics")
|
||||
@ApiOperation("用户统计")
|
||||
public Result<UserReportVO> userStatistics(
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){
|
||||
log.info("用户数据统计:{},{}",begin,end);
|
||||
return Result.success(reportService.getUserStatistics(begin,end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单统计
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/ordersStatistics")
|
||||
@ApiOperation("订单统计")
|
||||
public Result<OrderReportVO> ordersStatistics(
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){
|
||||
log.info("订单数据统计:{},{}",begin,end);
|
||||
return Result.success(reportService.getOrderStatistics(begin,end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 销量排名top10
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/top10")
|
||||
@ApiOperation("销量排名top10")
|
||||
public Result<SalesTop10ReportVO> top10(
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end){
|
||||
log.info("销量排名top10:{},{}",begin,end);
|
||||
return Result.success(reportService.getSalesTop10(begin,end));
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出运营数据报表
|
||||
* @param response
|
||||
*/
|
||||
@GetMapping("/export")
|
||||
@ApiOperation("导出运营数据报表")
|
||||
public void export(HttpServletResponse response){
|
||||
reportService.exportBusinessData(response);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询订单管理数据
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/overviewOrders")
|
||||
@ApiOperation("查询订单管理数据")
|
||||
public Result<OrderOverViewVO> orderOverView(){
|
||||
return Result.success(workspaceService.getOrderOverView());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询菜品总览
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/overviewDishes")
|
||||
@ApiOperation("查询菜品总览")
|
||||
public Result<DishOverViewVO> dishOverView(){
|
||||
return Result.success(workspaceService.getDishOverView());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询套餐总览
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/overviewSetmeals")
|
||||
@ApiOperation("查询套餐总览")
|
||||
public Result<SetmealOverViewVO> setmealOverView(){
|
||||
return Result.success(workspaceService.getSetmealOverView());
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface DishMapper {
|
||||
@ -53,4 +54,11 @@ public interface DishMapper {
|
||||
* 菜品分页查询
|
||||
*/
|
||||
Page<DishVO> pageQuery(DishPageQueryDTO dishPageQueryDTO);
|
||||
|
||||
/**
|
||||
* 根据条件统计菜品数量
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
Integer countByMap(Map map);
|
||||
}
|
||||
|
@ -19,11 +19,12 @@ public interface OrderMapper {
|
||||
void insert(Orders order);
|
||||
|
||||
/**
|
||||
* 根据订单号查询订单
|
||||
* 根据订单号和用户id查询订单
|
||||
* @param orderNumber
|
||||
* @param userId
|
||||
*/
|
||||
@Select("select * from orders where number = #{orderNumber}")
|
||||
Orders getByNumber(String orderNumber);
|
||||
@Select("select * from orders where number = #{orderNumber} and user_id= #{userId}")
|
||||
Orders getByNumberAndUserId(String orderNumber, Long userId);
|
||||
|
||||
/**
|
||||
* 修改订单信息
|
||||
@ -31,14 +32,6 @@ public interface OrderMapper {
|
||||
*/
|
||||
void update(Orders orders);
|
||||
|
||||
/**
|
||||
* 根据订单状态和下单时间查询订单
|
||||
* @param status
|
||||
* @param orderTime
|
||||
* @return
|
||||
*/
|
||||
@Select("select * from orders where status = #{status} and order_time < #{orderTime}")
|
||||
List<Orders> getByStatusAndOrderTimeLT(Integer status, LocalDateTime orderTime);
|
||||
|
||||
/**
|
||||
* 分页条件查询并按下单时间排序
|
||||
@ -59,4 +52,35 @@ public interface OrderMapper {
|
||||
*/
|
||||
@Select("select count(id) from orders where status = #{status}")
|
||||
Integer countStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 根据订单状态和下单时间查询订单
|
||||
* @param status
|
||||
* @param orderTime
|
||||
* @return
|
||||
*/
|
||||
@Select("select * from orders where status = #{status} and order_time < #{orderTime}")
|
||||
List<Orders> getByStatusAndOrderTimeLT(Integer status, LocalDateTime orderTime);
|
||||
|
||||
/**
|
||||
* 根据动态条件统计营业额数据
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
Double sumByMap(Map map);
|
||||
|
||||
/**
|
||||
* 根据动态条件统计订单数量
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
Integer countByMap(Map map);
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的销量排名前10
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
List<GoodsSalesDTO> getSalesTop10(LocalDateTime begin,LocalDateTime end);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface SetmealMapper {
|
||||
@ -69,4 +70,11 @@ public interface SetmealMapper {
|
||||
"from setmeal_dish sd left join dish d on sd.dish_id = d.id " +
|
||||
"where sd.setmeal_id = #{setmealId}")
|
||||
List<DishItemVO> getDishItemBySetmealId(Long setmealId);
|
||||
|
||||
/**
|
||||
* 根据条件统计套餐数量
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
Integer countByMap(Map map);
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import com.sky.entity.User;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface UserMapper {
|
||||
@Select("select * from user where openid=#{openid}")
|
||||
@ -17,4 +19,11 @@ public interface UserMapper {
|
||||
@Select("select * from user where id=#{userId}")
|
||||
|
||||
User getById(Long userId);
|
||||
|
||||
/**
|
||||
* 根据动态条件统计用户数量
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
Integer countByMap(Map map);
|
||||
}
|
||||
|
50
sky-server/src/main/java/com/sky/service/ReportService.java
Normal file
50
sky-server/src/main/java/com/sky/service/ReportService.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.sky.service;
|
||||
|
||||
import com.sky.vo.OrderReportVO;
|
||||
import com.sky.vo.SalesTop10ReportVO;
|
||||
import com.sky.vo.TurnoverReportVO;
|
||||
import com.sky.vo.UserReportVO;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.time.LocalDate;
|
||||
|
||||
public interface ReportService {
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的营业额数据
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end);
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的用户数据
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
UserReportVO getUserStatistics(LocalDate begin, LocalDate end);
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的订单数据
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end);
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的销量排名前10
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end);
|
||||
|
||||
/**
|
||||
* 导出运营数据报表
|
||||
* @param response
|
||||
*/
|
||||
void exportBusinessData(HttpServletResponse response);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.sky.service;
|
||||
|
||||
import com.sky.vo.BusinessDataVO;
|
||||
import com.sky.vo.DishOverViewVO;
|
||||
import com.sky.vo.OrderOverViewVO;
|
||||
import com.sky.vo.SetmealOverViewVO;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public interface WorkspaceService {
|
||||
|
||||
/**
|
||||
* 根据时间段统计营业数据
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end);
|
||||
|
||||
/**
|
||||
* 查询订单管理数据
|
||||
* @return
|
||||
*/
|
||||
OrderOverViewVO getOrderOverView();
|
||||
|
||||
/**
|
||||
* 查询菜品总览
|
||||
* @return
|
||||
*/
|
||||
DishOverViewVO getDishOverView();
|
||||
|
||||
/**
|
||||
* 查询套餐总览
|
||||
* @return
|
||||
*/
|
||||
SetmealOverViewVO getSetmealOverView();
|
||||
|
||||
}
|
@ -225,8 +225,11 @@ public class OrderServiceImpl implements OrderService {
|
||||
*/
|
||||
public void paySuccess(String outTradeNo) {
|
||||
|
||||
// 根据订单号查询订单
|
||||
Orders ordersDB = orderMapper.getByNumber(outTradeNo);
|
||||
// 当前登录用户id
|
||||
Long userId = BaseContext.getCurrentId();
|
||||
|
||||
// 根据订单号查询当前用户的订单
|
||||
Orders ordersDB = orderMapper.getByNumberAndUserId(outTradeNo, userId);
|
||||
|
||||
// 根据订单id更新订单的状态、支付方式、支付状态、结账时间
|
||||
Orders orders = Orders.builder()
|
||||
|
@ -0,0 +1,305 @@
|
||||
package com.sky.service.impl;
|
||||
|
||||
import com.sky.constant.OrdersConstant;
|
||||
import com.sky.dto.GoodsSalesDTO;
|
||||
|
||||
import com.sky.exception.TemplateNotFoundException;
|
||||
import com.sky.mapper.OrderMapper;
|
||||
import com.sky.mapper.UserMapper;
|
||||
import com.sky.service.ReportService;
|
||||
import com.sky.service.WorkspaceService;
|
||||
import com.sky.vo.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class ReportServiceImpl implements ReportService {
|
||||
|
||||
@Autowired
|
||||
private OrderMapper orderMapper;
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
@Autowired
|
||||
private WorkspaceService workspaceService;
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的营业额数据
|
||||
*
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) {
|
||||
//当前集合用于存放从begin到end范围内的每天的日期
|
||||
List<LocalDate> dateList = new ArrayList<>();
|
||||
|
||||
dateList.add(begin);
|
||||
|
||||
while (!begin.equals(end)) {
|
||||
//日期计算,计算指定日期的后一天对应的日期
|
||||
begin = begin.plusDays(1);
|
||||
dateList.add(begin);
|
||||
}
|
||||
|
||||
//存放每天的营业额
|
||||
List<Double> turnoverList = new ArrayList<>();
|
||||
for (LocalDate date : dateList) {
|
||||
//查询date日期对应的营业额数据,营业额是指:状态为“已完成”的订单金额合计
|
||||
LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
|
||||
LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
|
||||
|
||||
// select sum(amount) from orders where order_time > beginTime and order_time < endTime and status = 5
|
||||
Map map = new HashMap();
|
||||
map.put("begin", beginTime);
|
||||
map.put("end", endTime);
|
||||
map.put("status", OrdersConstant.COMPLETED);
|
||||
Double turnover = orderMapper.sumByMap(map);
|
||||
turnover = turnover == null ? 0.0 : turnover;
|
||||
turnoverList.add(turnover);
|
||||
}
|
||||
|
||||
//封装返回结果
|
||||
return TurnoverReportVO
|
||||
.builder()
|
||||
.dateList(StringUtils.join(dateList, ","))
|
||||
.turnoverList(StringUtils.join(turnoverList, ","))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的用户数据
|
||||
*
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) {
|
||||
//存放从begin到end之间的每天对应的日期
|
||||
List<LocalDate> dateList = new ArrayList<>();
|
||||
|
||||
dateList.add(begin);
|
||||
|
||||
while (!begin.equals(end)) {
|
||||
begin = begin.plusDays(1);
|
||||
dateList.add(begin);
|
||||
}
|
||||
|
||||
//存放每天的新增用户数量 select count(id) from user where create_time < ? and create_time > ?
|
||||
List<Integer> newUserList = new ArrayList<>();
|
||||
//存放每天的总用户数量 select count(id) from user where create_time < ?
|
||||
List<Integer> totalUserList = new ArrayList<>();
|
||||
|
||||
for (LocalDate date : dateList) {
|
||||
LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
|
||||
LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
|
||||
|
||||
Map map = new HashMap();
|
||||
map.put("end", endTime);
|
||||
|
||||
//总用户数量
|
||||
Integer totalUser = userMapper.countByMap(map);
|
||||
|
||||
map.put("begin", beginTime);
|
||||
//新增用户数量
|
||||
Integer newUser = userMapper.countByMap(map);
|
||||
|
||||
totalUserList.add(totalUser);
|
||||
newUserList.add(newUser);
|
||||
}
|
||||
|
||||
//封装结果数据
|
||||
return UserReportVO
|
||||
.builder()
|
||||
.dateList(StringUtils.join(dateList, ","))
|
||||
.totalUserList(StringUtils.join(totalUserList, ","))
|
||||
.newUserList(StringUtils.join(newUserList, ","))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的订单数据
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) {
|
||||
//存放从begin到end之间的每天对应的日期
|
||||
List<LocalDate> dateList = new ArrayList<>();
|
||||
|
||||
dateList.add(begin);
|
||||
|
||||
while (!begin.equals(end)) {
|
||||
begin = begin.plusDays(1);
|
||||
dateList.add(begin);
|
||||
}
|
||||
|
||||
//存放每天的订单总数
|
||||
List<Integer> orderCountList = new ArrayList<>();
|
||||
//存放每天的有效订单数
|
||||
List<Integer> validOrderCountList = new ArrayList<>();
|
||||
|
||||
//遍历dateList集合,查询每天的有效订单数和订单总数
|
||||
for (LocalDate date : dateList) {
|
||||
//查询每天的订单总数 select count(id) from orders where order_time > ? and order_time < ?
|
||||
LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
|
||||
LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
|
||||
Integer orderCount = getOrderCount(beginTime, endTime, null);
|
||||
|
||||
//查询每天的有效订单数 select count(id) from orders where order_time > ? and order_time < ? and status = 5
|
||||
Integer validOrderCount = getOrderCount(beginTime, endTime, OrdersConstant.COMPLETED);
|
||||
|
||||
orderCountList.add(orderCount);
|
||||
validOrderCountList.add(validOrderCount);
|
||||
}
|
||||
|
||||
//计算时间区间内的订单总数量
|
||||
Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).get();
|
||||
|
||||
//计算时间区间内的有效订单数量
|
||||
Integer validOrderCount = validOrderCountList.stream().reduce(Integer::sum).get();
|
||||
|
||||
Double orderCompletionRate = 0.0;
|
||||
if(totalOrderCount != 0){
|
||||
//计算订单完成率
|
||||
orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
|
||||
}
|
||||
|
||||
return OrderReportVO.builder()
|
||||
.dateList(StringUtils.join(dateList,","))
|
||||
.orderCountList(StringUtils.join(orderCountList,","))
|
||||
.validOrderCountList(StringUtils.join(validOrderCountList,","))
|
||||
.totalOrderCount(totalOrderCount)
|
||||
.validOrderCount(validOrderCount)
|
||||
.orderCompletionRate(orderCompletionRate)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件统计订单数量
|
||||
* @param begin
|
||||
* @param end
|
||||
* @param status
|
||||
* @return
|
||||
*/
|
||||
private Integer getOrderCount(LocalDateTime begin, LocalDateTime end, Integer status){
|
||||
Map map = new HashMap();
|
||||
map.put("begin",begin);
|
||||
map.put("end",end);
|
||||
map.put("status",status);
|
||||
|
||||
return orderMapper.countByMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计指定时间区间内的销量排名前10
|
||||
* @param begin
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public SalesTop10ReportVO getSalesTop10(LocalDate begin, LocalDate end) {
|
||||
LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
|
||||
LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
|
||||
|
||||
List<GoodsSalesDTO> salesTop10 = orderMapper.getSalesTop10(beginTime, endTime);
|
||||
List<String> names = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
|
||||
String nameList = StringUtils.join(names, ",");
|
||||
|
||||
List<Integer> numbers = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
|
||||
String numberList = StringUtils.join(numbers, ",");
|
||||
|
||||
//封装返回结果数据
|
||||
return SalesTop10ReportVO
|
||||
.builder()
|
||||
.nameList(nameList)
|
||||
.numberList(numberList)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出运营数据报表
|
||||
* @param response
|
||||
*/
|
||||
public void exportBusinessData(HttpServletResponse response) {
|
||||
//1. 查询数据库,获取营业数据---查询最近30天的运营数据
|
||||
LocalDate dateBegin = LocalDate.now().minusDays(30);
|
||||
LocalDate dateEnd = LocalDate.now().minusDays(1);
|
||||
|
||||
//查询概览数据
|
||||
BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX));
|
||||
|
||||
//2. 通过POI将数据写入到Excel文件中
|
||||
InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/data_template.xlsx");
|
||||
if (in == null) {
|
||||
throw new TemplateNotFoundException("找不到模板文件:template/data_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 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());
|
||||
}
|
||||
|
||||
//3. 通过输出流将Excel文件下载到客户端浏览器
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
excel.write(out);
|
||||
|
||||
//关闭资源
|
||||
out.close();
|
||||
excel.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,165 @@
|
||||
package com.sky.service.impl;
|
||||
|
||||
import com.sky.constant.OrdersConstant;
|
||||
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", OrdersConstant.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();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询订单管理数据
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public OrderOverViewVO getOrderOverView() {
|
||||
Map map = new HashMap();
|
||||
map.put("begin", LocalDateTime.now().with(LocalTime.MIN));
|
||||
map.put("status", OrdersConstant.TO_BE_CONFIRMED);
|
||||
|
||||
//待接单
|
||||
Integer waitingOrders = orderMapper.countByMap(map);
|
||||
|
||||
//待派送
|
||||
map.put("status", OrdersConstant.CONFIRMED);
|
||||
Integer deliveredOrders = orderMapper.countByMap(map);
|
||||
|
||||
//已完成
|
||||
map.put("status", OrdersConstant.COMPLETED);
|
||||
Integer completedOrders = orderMapper.countByMap(map);
|
||||
|
||||
//已取消
|
||||
map.put("status", OrdersConstant.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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询菜品总览
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询套餐总览
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
}
|
@ -57,4 +57,15 @@
|
||||
</where>
|
||||
order by create_time desc
|
||||
</select>
|
||||
<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>
|
||||
</mapper>
|
@ -66,4 +66,46 @@
|
||||
</where>
|
||||
order by order_time desc
|
||||
</select>
|
||||
<select id="sumByMap" resultType="java.lang.Double">
|
||||
select sum(amount) from orders
|
||||
<where>
|
||||
<if test="begin != null">
|
||||
and order_time > #{begin}
|
||||
</if>
|
||||
<if test="end != null">
|
||||
and order_time < #{end}
|
||||
</if>
|
||||
<if test="status != null">
|
||||
and status = #{status}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="countByMap" resultType="java.lang.Integer">
|
||||
select count(id) from orders
|
||||
<where>
|
||||
<if test="begin != null">
|
||||
and order_time > #{begin}
|
||||
</if>
|
||||
<if test="end != null">
|
||||
and order_time < #{end}
|
||||
</if>
|
||||
<if test="status != null">
|
||||
and status = #{status}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<select id="getSalesTop10" resultType="com.sky.dto.GoodsSalesDTO">
|
||||
select od.name, sum(od.number) number
|
||||
from order_detail od,orders o
|
||||
where od.order_id = o.id and o.status = 5
|
||||
<if test="begin != null">
|
||||
and o.order_time > #{begin}
|
||||
</if>
|
||||
<if test="end != null">
|
||||
and o.order_time < #{end}
|
||||
</if>
|
||||
group by od.name
|
||||
order by number desc
|
||||
limit 0,10
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -57,4 +57,15 @@
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
<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>
|
||||
</mapper>
|
@ -7,4 +7,15 @@
|
||||
insert into user (openid, name, phone, sex, id_number, avatar, create_time)
|
||||
values (#{openid}, #{name}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime})
|
||||
</insert>
|
||||
<select id="countByMap" resultType="java.lang.Integer">
|
||||
select count(id) from user
|
||||
<where>
|
||||
<if test="begin != null">
|
||||
and create_time > #{begin}
|
||||
</if>
|
||||
<if test="end != null">
|
||||
and create_time < #{end}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
BIN
sky-server/src/main/resources/template/data_template.xlsx
Normal file
BIN
sky-server/src/main/resources/template/data_template.xlsx
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user