From 9000957563be202efdd550abdd023ae243e9f7f6 Mon Sep 17 00:00:00 2001 From: LiShu <2945621619@qq.com> Date: Wed, 4 Dec 2024 22:18:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E7=9A=84=E5=A4=A7=E8=87=B4=E6=9E=B6=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/CommonController.java | 57 +++ .../sky/controller/admin/OrderController.java | 91 ++++ .../notify/PayNotifyController.java | 118 +++++ .../sky/controller/user/OrderController.java | 96 ++++ .../com/sky/mapper/AddressBookMapper.java | 4 + .../main/java/com/sky/mapper/DishMapper.java | 4 + .../com/sky/mapper/OrderDetailMapper.java | 22 + .../main/java/com/sky/mapper/OrderMapper.java | 67 +++ .../java/com/sky/mapper/SetmealMapper.java | 4 + .../com/sky/mapper/ShoppingCartMapper.java | 4 + .../main/java/com/sky/mapper/UserMapper.java | 4 + .../java/com/sky/service/OrderService.java | 57 +++ .../java/com/sky/service/ReportService.java | 32 ++ .../com/sky/service/WorkspaceService.java | 38 ++ .../sky/service/impl/OrderServiceImpl.java | 424 ++++++++++++++++++ .../sky/service/impl/ReportServiceImpl.java | 247 ++++++++++ .../service/impl/WorkspaceServiceImpl.java | 164 +++++++ .../com/sky/websocket/WebSocketServer.java | 72 +++ .../resources/mapper/OrderDetailMapper.xml | 14 + .../src/main/resources/mapper/OrderMapper.xml | 118 +++++ 20 files changed, 1637 insertions(+) create mode 100644 sky-server/src/main/java/com/sky/controller/admin/CommonController.java create mode 100644 sky-server/src/main/java/com/sky/controller/admin/OrderController.java create mode 100644 sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java create mode 100644 sky-server/src/main/java/com/sky/controller/user/OrderController.java create mode 100644 sky-server/src/main/java/com/sky/mapper/AddressBookMapper.java create mode 100644 sky-server/src/main/java/com/sky/mapper/DishMapper.java create mode 100644 sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java create mode 100644 sky-server/src/main/java/com/sky/mapper/OrderMapper.java create mode 100644 sky-server/src/main/java/com/sky/mapper/SetmealMapper.java create mode 100644 sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java create mode 100644 sky-server/src/main/java/com/sky/mapper/UserMapper.java create mode 100644 sky-server/src/main/java/com/sky/service/OrderService.java create mode 100644 sky-server/src/main/java/com/sky/service/ReportService.java create mode 100644 sky-server/src/main/java/com/sky/service/WorkspaceService.java create mode 100644 sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java create mode 100644 sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java create mode 100644 sky-server/src/main/java/com/sky/service/impl/WorkspaceServiceImpl.java create mode 100644 sky-server/src/main/java/com/sky/websocket/WebSocketServer.java create mode 100644 sky-server/src/main/resources/mapper/OrderDetailMapper.xml create mode 100644 sky-server/src/main/resources/mapper/OrderMapper.xml diff --git a/sky-server/src/main/java/com/sky/controller/admin/CommonController.java b/sky-server/src/main/java/com/sky/controller/admin/CommonController.java new file mode 100644 index 0000000..1a21ca5 --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/admin/CommonController.java @@ -0,0 +1,57 @@ +package com.sky.controller.admin; + +import com.sky.constant.MessageConstant; +import com.sky.result.Result; +import com.sky.utils.AliOssUtil; +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.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.util.UUID; + + +/* +* 通用注解 +* */ +@RestController +@RequestMapping("/admin/common") +@Api(tags = "通用接口") +@Slf4j +public class CommonController +{ + + @Autowired + private AliOssUtil aliOssUtil; + + @PostMapping("upload") + @ApiOperation("文件上传") + public Result upload(MultipartFile file) { + log.info("文件上传:{}",file); + + + try { + //原始文件名 + String originalFilename = file.getOriginalFilename(); + //获取拓展名 + String extension = originalFilename.substring(originalFilename.lastIndexOf(".")); + //新文件名称 + String objectName = UUID.randomUUID().toString() + extension; + //文件请求路径 + String filepath = null; + filepath = aliOssUtil.upload(file.getBytes(),objectName); + + return Result.success(filepath); + } catch (IOException e) { + log.error("文件上传失败:{}",e); + } + + return Result.error(MessageConstant.UPLOAD_FAILED); + + } +} diff --git a/sky-server/src/main/java/com/sky/controller/admin/OrderController.java b/sky-server/src/main/java/com/sky/controller/admin/OrderController.java new file mode 100644 index 0000000..d6b39bf --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/admin/OrderController.java @@ -0,0 +1,91 @@ +package com.sky.controller.admin; + +import com.sky.dto.OrdersCancelDTO; +import com.sky.dto.OrdersConfirmDTO; +import com.sky.dto.OrdersPageQueryDTO; +import com.sky.dto.OrdersRejectionDTO; +import com.sky.result.PageResult; +import com.sky.result.Result; +import com.sky.service.OrderService; +import com.sky.vo.OrderStatisticsVO; +import com.sky.vo.OrderVO; +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.*; + +@RestController("adminOrderController") +@RequestMapping("/admin/order") +@Api(tags = "管理端订单相关接口") +@Slf4j +public class OrderController { + + @Autowired + private OrderService orderService; + @GetMapping("/conditionSearch") + @ApiOperation("订单搜索") + public Result search(OrdersPageQueryDTO ordersPageQueryDTO){ + log.info("订单搜索:{}",ordersPageQueryDTO); + PageResult page = orderService.searchOrder(ordersPageQueryDTO); + return Result.success(page); + } + + @GetMapping("/statistics") + @ApiOperation("各个状态的订单数量统计") + public Result statistic(){ + OrderStatisticsVO orderStatisticsVO = orderService.statistics(); + return Result.success(orderStatisticsVO); + } + + @GetMapping("/details/{id}") + @ApiOperation("查询订单详情") + public Result details(@PathVariable Long id){ + log.info("查询订单详情:{}",id); + OrderVO orderVO = orderService.showDetails(id); + return Result.success(orderVO); + } + + @PutMapping("/confirm") + @ApiOperation("接单") + public Result confirm(@RequestBody OrdersConfirmDTO ordersConfirmDTO){ + log.info("接单:{}",ordersConfirmDTO); + orderService.confirm(ordersConfirmDTO); + return Result.success(); + } + + @PutMapping("/rejection") + @ApiOperation("拒单") + public Result reject(@RequestBody OrdersRejectionDTO ordersRejectionDTO){ + log.info("拒单:{}",ordersRejectionDTO); + orderService.reject(ordersRejectionDTO); + return Result.success(); + } + + @PutMapping("/cancel") + @ApiOperation("取消订单") + public Result cancel(@RequestBody OrdersCancelDTO ordersCancelDTO){ + log.info("取消订单:{}",ordersCancelDTO); + orderService.adminCancel(ordersCancelDTO); + return Result.success(); + } + + @PutMapping("/delivery/{id}") + @ApiOperation("派送订单") + public Result delivery(@PathVariable Long id){ + log.info("派送订单:{}",id); + orderService.delivery(id); + return Result.success(); + } + + @PutMapping("/complete/{id}") + @ApiOperation("完成订单") + public Result complete(@PathVariable Long id){ + log.info("完成订单:{}",id); + orderService.complete(id); + return Result.success(); + } + + + +} diff --git a/sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java b/sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java new file mode 100644 index 0000000..67a1481 --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java @@ -0,0 +1,118 @@ +package com.sky.controller.notify; + +import com.alibaba.druid.support.json.JSONUtils; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.sky.properties.WeChatProperties; +import com.sky.service.OrderService; +import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.entity.ContentType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; + +/** + * 支付回调相关接口 + */ +@RestController +@RequestMapping("/notify") +@Slf4j +public class PayNotifyController { + @Autowired + private OrderService orderService; + @Autowired + private WeChatProperties weChatProperties; + + /** + * 支付成功回调 + * + * @param request + */ + @RequestMapping("/paySuccess") + public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { + //读取数据 + String body = readData(request); + log.info("支付成功回调:{}", body); + + //数据解密 + String plainText = decryptData(body); + log.info("解密后的文本:{}", plainText); + + JSONObject jsonObject = JSON.parseObject(plainText); + String outTradeNo = jsonObject.getString("out_trade_no");//商户平台订单号 + String transactionId = jsonObject.getString("transaction_id");//微信支付交易号 + + log.info("商户平台订单号:{}", outTradeNo); + log.info("微信支付交易号:{}", transactionId); + + //业务处理,修改订单状态、来单提醒 + orderService.paySuccess(outTradeNo); + + //给微信响应 + responseToWeixin(response); + } + + /** + * 读取数据 + * + * @param request + * @return + * @throws Exception + */ + private String readData(HttpServletRequest request) throws Exception { + BufferedReader reader = request.getReader(); + StringBuilder result = new StringBuilder(); + String line = null; + while ((line = reader.readLine()) != null) { + if (result.length() > 0) { + result.append("\n"); + } + result.append(line); + } + return result.toString(); + } + + /** + * 数据解密 + * + * @param body + * @return + * @throws Exception + */ + private String decryptData(String body) throws Exception { + JSONObject resultObject = JSON.parseObject(body); + JSONObject resource = resultObject.getJSONObject("resource"); + String ciphertext = resource.getString("ciphertext"); + String nonce = resource.getString("nonce"); + String associatedData = resource.getString("associated_data"); + + AesUtil aesUtil = new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8)); + //密文解密 + String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), + nonce.getBytes(StandardCharsets.UTF_8), + ciphertext); + + return plainText; + } + + /** + * 给微信响应 + * @param response + */ + private void responseToWeixin(HttpServletResponse response) throws Exception{ + response.setStatus(200); + HashMap map = new HashMap<>(); + map.put("code", "SUCCESS"); + map.put("message", "SUCCESS"); + response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(JSONUtils.toJSONString(map).getBytes(StandardCharsets.UTF_8)); + response.flushBuffer(); + } +} diff --git a/sky-server/src/main/java/com/sky/controller/user/OrderController.java b/sky-server/src/main/java/com/sky/controller/user/OrderController.java new file mode 100644 index 0000000..f29ff81 --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/user/OrderController.java @@ -0,0 +1,96 @@ +package com.sky.controller.user; + +import com.sky.dto.OrdersPaymentDTO; +import com.sky.dto.OrdersSubmitDTO; +import com.sky.result.PageResult; +import com.sky.result.Result; +import com.sky.service.OrderService; +import com.sky.vo.OrderPaymentVO; +import com.sky.vo.OrderSubmitVO; +import com.sky.vo.OrderVO; +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.*; + + +@RestController("userOrderController") +@RequestMapping("/user/order") +@Api(tags = "用户端订单相关接口") +@Slf4j +public class OrderController { + + @Autowired + private OrderService orderService; + /* + * 用户下单 + * */ + @PostMapping("/submit") + @ApiOperation("用户下单") + public Result submit(@RequestBody OrdersSubmitDTO ordersSubmitDTO){ + log.info("用户下单,参数为:{}",ordersSubmitDTO); + OrderSubmitVO orderSubmitVO = orderService.submitOrder(ordersSubmitDTO); + return Result.success(orderSubmitVO); + } + + + /** + * 订单支付 + * + * @param ordersPaymentDTO + * @return + */ + @PutMapping("/payment") + @ApiOperation("订单支付") + public Result payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception { + log.info("订单支付:",ordersPaymentDTO); + OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO); + log.info("生成预支付交易单:{}", orderPaymentVO); + orderService.paySuccess(ordersPaymentDTO.getOrderNumber()); + return Result.success(orderPaymentVO); + } + + @GetMapping("/historyOrders") + @ApiOperation("历史订单查询") + public Result historyQueryPage(int page, int pageSize,Integer status){ + PageResult pageResult = orderService.historyQueryPage(page,pageSize,status); + return Result.success(pageResult); + } + + + @GetMapping("/orderDetail/{id}") + @ApiOperation("查询订单详情") + public Result details(@PathVariable Long id){ + log.info("查询订单详情:{}",id); + OrderVO orderVO = orderService.showDetails(id); + return Result.success(orderVO); + } + + @ApiOperation("取消订单") + @PutMapping("/cancel/{id}") + public Result cancel(@PathVariable Long id){ + log.info("取消订单:{}",id); + orderService.cancel(id); + return Result.success(); + } + + @ApiOperation("再来一单") + @PostMapping("/repetition/{id}") + public Result repetition(@PathVariable Long id){ + log.info("再来一单:{}",id); + orderService.repetiton(id); + return Result.success(); + } + + /* + * 客户催单 + * */ + @GetMapping("/reminder/{id}") + @ApiOperation("客户催单") + public Result reminder(@PathVariable("id") Long id){ + log.info("客户催单:{}",id); + orderService.reminder(id); + return Result.success(); + } +} diff --git a/sky-server/src/main/java/com/sky/mapper/AddressBookMapper.java b/sky-server/src/main/java/com/sky/mapper/AddressBookMapper.java new file mode 100644 index 0000000..7ea2d19 --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/AddressBookMapper.java @@ -0,0 +1,4 @@ +package com.sky.mapper; + +public interface AddressBookMapper { +} diff --git a/sky-server/src/main/java/com/sky/mapper/DishMapper.java b/sky-server/src/main/java/com/sky/mapper/DishMapper.java new file mode 100644 index 0000000..b73034e --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/DishMapper.java @@ -0,0 +1,4 @@ +package com.sky.mapper; + +public interface DishMapper { +} diff --git a/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java b/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java new file mode 100644 index 0000000..c510746 --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/OrderDetailMapper.java @@ -0,0 +1,22 @@ +package com.sky.mapper; + +import com.sky.entity.OrderDetail; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface OrderDetailMapper { + /* + * 批量插入订单明细数据 + * */ + void insertBatch(List orderDetailList); + + @Select("select * from order_detail where order_id = #{orderId}") + List getByOrderId(Long orderId); + + @Delete("delete from order_detail where order_id = #{orderId}") + void deleteBatchByOrderId(Long id); +} diff --git a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java new file mode 100644 index 0000000..6cbe268 --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java @@ -0,0 +1,67 @@ +package com.sky.mapper; + +import com.github.pagehelper.Page; +import com.sky.dto.GoodsSalesDTO; +import com.sky.dto.OrdersPageQueryDTO; +import com.sky.entity.Orders; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +@Mapper +public interface OrderMapper { + /* + * 插入订单数据 + * */ + void insert(Orders orders); + + + /** + * 根据订单号查询订单 + * @param orderNumber + */ + @Select("select * from orders where number = #{orderNumber}") + Orders getByNumber(String orderNumber); + + /** + * 修改订单信息 + * @param orders + */ + void update(Orders orders); + + Page pageQuery(OrdersPageQueryDTO ordersPageQueryDTO); + + @Select("select * from orders where id = #{id}") + Orders getById(Long id); + + @Delete("delete from orders where id = #{id}") + void deleteById(Long id); + + @Select("select count(id) from orders where status = #{status}") + Integer countStatus(Integer status); + + /* + * 根据订单状态和下单时间查询订单 + * */ + @Select("select * from orders where status = #{status} and order_time < #{orderTime}") + List getByStatusAndOrderTimeLT(Integer status, LocalDateTime orderTime); + + /* + * 根据动态条件统计营业额数据 + * */ + Double sumByMap(Map map); + + /* + * 根据动态条件统计订单数据 + * */ + Integer countByMap(Map map); + + /* + * 统计指定时间内的销量排名前10 + */ + List getSalesTop10(LocalDateTime begin,LocalDateTime end); +} diff --git a/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java b/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java new file mode 100644 index 0000000..e7634d2 --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/SetmealMapper.java @@ -0,0 +1,4 @@ +package com.sky.mapper; + +public interface SetmealMapper { +} diff --git a/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java b/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java new file mode 100644 index 0000000..72f11be --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/ShoppingCartMapper.java @@ -0,0 +1,4 @@ +package com.sky.mapper; + +public interface ShoppingCartMapper { +} diff --git a/sky-server/src/main/java/com/sky/mapper/UserMapper.java b/sky-server/src/main/java/com/sky/mapper/UserMapper.java new file mode 100644 index 0000000..d0e6174 --- /dev/null +++ b/sky-server/src/main/java/com/sky/mapper/UserMapper.java @@ -0,0 +1,4 @@ +package com.sky.mapper; + +public interface UserMapper { +} diff --git a/sky-server/src/main/java/com/sky/service/OrderService.java b/sky-server/src/main/java/com/sky/service/OrderService.java new file mode 100644 index 0000000..3b388eb --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/OrderService.java @@ -0,0 +1,57 @@ +package com.sky.service; + +import com.sky.dto.*; +import com.sky.result.PageResult; +import com.sky.vo.OrderPaymentVO; +import com.sky.vo.OrderStatisticsVO; +import com.sky.vo.OrderSubmitVO; +import com.sky.vo.OrderVO; + +public interface OrderService { + + /* + * 用户下单 + * */ + OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO); + + /** + * 订单支付 + * @param ordersPaymentDTO + * @return + */ + OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception; + + /** + * 支付成功,修改订单状态 + * @param outTradeNo + */ + void paySuccess(String outTradeNo); + + + PageResult historyQueryPage(int page, int pageSize, Integer status); + + OrderVO showDetails(Long id); + + void cancel(Long id); + + void repetiton(Long id); + + + PageResult searchOrder(OrdersPageQueryDTO ordersPageQueryDTO); + + + OrderStatisticsVO statistics(); + + + void confirm(OrdersConfirmDTO ordersConfirmDTO); + + void reject(OrdersRejectionDTO ordersRejectionDTO); + + void adminCancel(OrdersCancelDTO ordersCancelDTO); + + void delivery(Long id); + + void complete(Long id); + + void reminder(Long id); +} diff --git a/sky-server/src/main/java/com/sky/service/ReportService.java b/sky-server/src/main/java/com/sky/service/ReportService.java new file mode 100644 index 0000000..96a4436 --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/ReportService.java @@ -0,0 +1,32 @@ +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 { + + /* + * 统计指定时间内的营业额 + * */ + TurnoverReportVO getTurnoverStatistics(LocalDate begin,LocalDate end); + + /* + * 统计指定时间内的用户数据 + * */ + UserReportVO getUserStatistics(LocalDate begin, LocalDate end); + + + OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end); + + SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end); + + /* + * 导出运营数据报表 + * */ + void exportBusinessData(HttpServletResponse response); +} diff --git a/sky-server/src/main/java/com/sky/service/WorkspaceService.java b/sky-server/src/main/java/com/sky/service/WorkspaceService.java new file mode 100644 index 0000000..d5cd511 --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/WorkspaceService.java @@ -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(); + +} diff --git a/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..4bfa9c5 --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java @@ -0,0 +1,424 @@ +package com.sky.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.sky.constant.MessageConstant; +import com.sky.context.BaseContext; +import com.sky.dto.*; +import com.sky.entity.*; +import com.sky.exception.AddressBookBusinessException; +import com.sky.exception.OrderBusinessException; +import com.sky.exception.ShoppingCartBusinessException; +import com.sky.mapper.*; +import com.sky.result.PageResult; +import com.sky.service.OrderService; +import com.sky.utils.WeChatPayUtil; +import com.sky.vo.OrderPaymentVO; +import com.sky.vo.OrderStatisticsVO; +import com.sky.vo.OrderSubmitVO; +import com.sky.vo.OrderVO; +import com.sky.websocket.WebSocketServer; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.CollectionUtils; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class OrderServiceImpl implements OrderService { + + @Autowired + private OrderMapper orderMapper; + @Autowired + private OrderDetailMapper orderDetailMapper; + @Autowired + private AddressBookMapper addressBookMapper; + @Autowired + private ShoppingCartMapper shoppingCartMapper; + @Autowired + private WeChatPayUtil weChatPayUtil; + @Autowired + private UserMapper userMapper; + @Autowired + private WebSocketServer webSocketServer; + /* + * 用户下单 + * */ + @Transactional + @Override + public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) { + //1.处理各种业务异常(地址薄为空,购物车数据为空) + AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId()); + if(addressBook == null){ + //抛出业务异常 + throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL); + } + + //查询当前用户购物车数据 + Long userId = BaseContext.getCurrentId(); + ShoppingCart shoppingCart = new ShoppingCart(); + shoppingCart.setUserId(userId); + List shoppingCartList = shoppingCartMapper.list(shoppingCart); + if(shoppingCartList == null || shoppingCartList.size() == 0){ + //抛出业务异常 + throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL); + } + //2.向订单表插入一条数据 + Orders orders = new Orders(); + BeanUtils.copyProperties(ordersSubmitDTO,orders); + orders.setOrderTime(LocalDateTime.now()); + orders.setPayStatus(Orders.UN_PAID); + orders.setStatus(Orders.PENDING_PAYMENT); + orders.setNumber(String.valueOf(System.currentTimeMillis())); + orders.setPhone(addressBook.getPhone()); + orders.setConsignee(addressBook.getConsignee()); + orders.setUserId(userId); + orderMapper.insert(orders); + + List orderDetailList = new ArrayList<>(); + //3.向订单明细表插入n条数据 + for (ShoppingCart cart : shoppingCartList) { + OrderDetail orderDetail = new OrderDetail(); + BeanUtils.copyProperties(cart,orderDetail); + orderDetail.setOrderId(orders.getId());//设置当前订单明细的orderId + orderDetailList.add(orderDetail); + } + orderDetailMapper.insertBatch(orderDetailList); + //4.清空购物车数据 + shoppingCartMapper.deleteByUserId(userId); + //5.封装VO返回结果 + OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder() + .id(orders.getId()) + .orderTime(orders.getOrderTime()) + .orderNumber(orders.getNumber()) + .orderAmount(orders.getAmount()) + .build(); + return orderSubmitVO; + } + + /** + * 订单支付 + * + * @param ordersPaymentDTO + * @return + */ + public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception { + // 当前登录用户id + Long userId = BaseContext.getCurrentId(); + User user = userMapper.getById(userId); + + //调用微信支付接口,生成预支付交易单 + /* JSONObject jsonObject = weChatPayUtil.pay( + ordersPaymentDTO.getOrderNumber(), //商户订单号 + new BigDecimal(0.01), //支付金额,单位 元 + "苍穹外卖订单", //商品描述 + user.getOpenid() //微信用户的openid + );*/ + JSONObject jsonObject = new JSONObject(); + + if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) { + throw new OrderBusinessException("该订单已支付"); + } + + OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class); + vo.setPackageStr(jsonObject.getString("package")); + + return vo; + } + + /** + * 支付成功,修改订单状态 + * + * @param outTradeNo + */ + public void paySuccess(String outTradeNo) { + + // 根据订单号查询订单 + Orders ordersDB = orderMapper.getByNumber(outTradeNo); + + // 根据订单id更新订单的状态、支付方式、支付状态、结账时间 + Orders orders = Orders.builder() + .id(ordersDB.getId()) + .status(Orders.TO_BE_CONFIRMED) + .payStatus(Orders.PAID) + .checkoutTime(LocalDateTime.now()) + .build(); + + orderMapper.update(orders); + + //通过websocket向客户端浏览器推送消息 type orderId content + Map map = new HashMap<>(); + map.put("type",1);//1表示来单提醒 2表示客户催单 + map.put("orderId",ordersDB.getId()); + map.put("content","订单号:" + outTradeNo); + + String json = JSON.toJSONString(map); + webSocketServer.sendToAllClient(json); + } + + @Override + public PageResult historyQueryPage(int pageNum, int pageSize, Integer status) { + PageHelper.startPage(pageNum,pageSize); + + OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO(); + Long userId = BaseContext.getCurrentId(); + ordersPageQueryDTO.setUserId(userId); + ordersPageQueryDTO.setStatus(status); + + //分页查询条件 + Page page = orderMapper.pageQuery(ordersPageQueryDTO); + + List list = new ArrayList<>(); + if(page != null && page.getTotal() > 0){ + for (Orders orders : page) { + Long orderId = orders.getId(); + List orderDetails = orderDetailMapper.getByOrderId(orderId); + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders,orderVO); + orderVO.setOrderDetailList(orderDetails); + list.add(orderVO); + } + } + return new PageResult(page.getTotal(),list); + } + + @Override + public OrderVO showDetails(Long id) { + //根据id查询订单 + Orders orders = orderMapper.getById(id); + List orderDetails = orderDetailMapper.getByOrderId(orders.getId()); + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders,orderVO); + orderVO.setOrderDetailList(orderDetails); + return orderVO; + } + + @Transactional + @Override + public void cancel(Long id) { + Orders orders = orderMapper.getById(id); + if(orders == null){ + throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND); + } + //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 + /*业务规则: + - 待支付和待接单状态下,用户可直接取消订单 + - 商家已接单状态下,用户取消订单需电话沟通商家 + - 派送中状态下,用户取消订单需电话沟通商家 + - 如果在待接单状态下取消订单,需要给用户退款 + - 取消订单后需要将订单状态修改为“已取消” + */ + if(orders.getStatus() > 2){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + if(orders.getStatus() == Orders.TO_BE_CONFIRMED) { + //调用微信支付退款接口 + /* weChatPayUtil.refund( + orders.getNumber(), //商户订单号 + orders.getNumber(), //商户退款单号 + new BigDecimal(0.01),//退款金额,单位 元 + new BigDecimal(0.01));//原订单金额*/ + + //支付状态修改为 退款 + orders.setPayStatus(Orders.REFUND); + } + //更新订单状态,取消原因,取消时间 + orders.setStatus(Orders.CANCELLED); + orders.setRejectionReason("用户取消订单"); + orders.setCancelTime(LocalDateTime.now()); + orderMapper.update(orders); + } + + @Override + public void repetiton(Long id) { + Long userId = BaseContext.getCurrentId(); + List orderDetails = orderDetailMapper.getByOrderId(id); + // 将订单详情对象转换为购物车对象 + List shoppingCartList = orderDetails.stream().map(x -> { + ShoppingCart shoppingCart = new ShoppingCart(); + // 将原订单详情里面的菜品信息重新复制到购物车对象中 + BeanUtils.copyProperties(x, shoppingCart, "id"); + shoppingCart.setUserId(userId); + shoppingCart.setCreateTime(LocalDateTime.now()); + + return shoppingCart; + }).collect(Collectors.toList()); + + shoppingCartMapper.insertBatch(shoppingCartList); + } + + @Override + public PageResult searchOrder(OrdersPageQueryDTO ordersPageQueryDTO) { + PageHelper.startPage(ordersPageQueryDTO.getPage(),ordersPageQueryDTO.getPageSize()); + Page page = orderMapper.pageQuery(ordersPageQueryDTO); + //部分订单状态,需要额外返回订单菜品信息,将Orders转化为OrderVO + List orderVOList = getOrderVOList(page); + return new PageResult(page.getTotal(),orderVOList); + } + + @Override + public OrderStatisticsVO statistics() { + Integer toByConfirmed = orderMapper.countStatus(Orders.TO_BE_CONFIRMED); + Integer confirmed = orderMapper.countStatus(Orders.CONFIRMED); + Integer deliveryInProgress = orderMapper.countStatus(Orders.DELIVERY_IN_PROGRESS); + + OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO(); + orderStatisticsVO.setConfirmed(toByConfirmed); + orderStatisticsVO.setConfirmed(confirmed); + orderStatisticsVO.setDeliveryInProgress(deliveryInProgress); + return orderStatisticsVO; + } + + @Override + public void confirm(OrdersConfirmDTO ordersConfirmDTO) { + Orders orders = orderMapper.getById(ordersConfirmDTO.getId()); + orders.setStatus(Orders.CONFIRMED); + orderMapper.update(orders); + } + + @Override + public void reject(OrdersRejectionDTO ordersRejectionDTO) { + Orders orders = orderMapper.getById(ordersRejectionDTO.getId()); + //订单状态 1待付款 2待接单 3已接单 4派送中 5已完成 6已取消 + /*业务规则: + + - 商家拒单其实就是将订单状态修改为“已取消” + - 只有订单处于“待接单”状态时可以执行拒单操作 + - 商家拒单时需要指定拒单原因 + - 商家拒单时,如果用户已经完成了支付,需要为用户退款*/ + if(orders == null || orders.getStatus() != Orders.TO_BE_CONFIRMED){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + orders.setId(ordersRejectionDTO.getId()); + orders.setStatus(Orders.CANCELLED); + orders.setRejectionReason(ordersRejectionDTO.getRejectionReason()); + orders.setCancelTime(LocalDateTime.now()); + if(orders.getPayStatus() == Orders.PAID){ + //调用微信支付退款接口 + /* weChatPayUtil.refund( + orders.getNumber(), //商户订单号 + orders.getNumber(), //商户退款单号 + new BigDecimal(0.01),//退款金额,单位 元 + new BigDecimal(0.01));//原订单金额*/ + orders.setPayStatus(Orders.REFUND); + } + orderMapper.update(orders); + } + + @Override + public void adminCancel(OrdersCancelDTO ordersCancelDTO) { + /*业务规则: + + - 取消订单其实就是将订单状态修改为“已取消” + - 商家取消订单时需要指定取消原因 + - 商家取消订单时,如果用户已经完成了支付,需要为用户退款*/ + Orders orders = orderMapper.getById(ordersCancelDTO.getId()); + orders.setId(ordersCancelDTO.getId()); + orders.setStatus(Orders.CANCELLED); + orders.setRejectionReason(ordersCancelDTO.getCancelReason()); + orders.setCancelTime(LocalDateTime.now()); + if(orders.getPayStatus() == Orders.PAID){ + //调用微信支付退款接口 + /* weChatPayUtil.refund( + orders.getNumber(), //商户订单号 + orders.getNumber(), //商户退款单号 + new BigDecimal(0.01),//退款金额,单位 元 + new BigDecimal(0.01));//原订单金额*/ + orders.setPayStatus(Orders.REFUND); + } + orderMapper.update(orders); + } + + @Override + public void delivery(Long id) { +/* 业务规则: + + - 派送订单其实就是将订单状态修改为“派送中” + - 只有状态为“待派送”的订单可以执行派送订单操作*/ + Orders orders = orderMapper.getById(id); + if(orders == null || orders.getStatus() != Orders.CONFIRMED){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + orders.setId(id); + orders.setStatus(Orders.DELIVERY_IN_PROGRESS); + orderMapper.update(orders); + } + + @Override + public void complete(Long id) { + /* 业务规则: + + - 完成订单其实就是将订单状态修改为“已完成” + - 只有状态为“派送中”的订单可以执行订单完成操作*/ + Orders orders = orderMapper.getById(id); + if(orders == null || orders.getStatus() != Orders.DELIVERY_IN_PROGRESS){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + orders.setId(id); + orders.setStatus(Orders.COMPLETED); + orders.setDeliveryTime(LocalDateTime.now()); + orderMapper.update(orders); + } + + @Override + public void reminder(Long id) { + Orders orders = orderMapper.getById(id); + if(orders == null){ + throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR); + } + + Map map = new HashMap(); + map.put("type",2);//1表示来单提醒,2表示客户催单 + map.put("orderId",id); + map.put("content","订单号:" + orders.getNumber()); + String json = JSON.toJSONString(map); + //通过websocket向客户端浏览器推送消息 + webSocketServer.sendToAllClient(json); + } + private List getOrderVOList(Page page){ + // 需要返回订单菜品信息,自定义OrderVO响应结果 + List orderVOList = new ArrayList<>(); + List ordersList = page.getResult(); + if(!CollectionUtils.isEmpty(ordersList)){ + for (Orders orders : ordersList) { + OrderVO orderVO = new OrderVO(); + BeanUtils.copyProperties(orders,orderVO); + String orderDishes = getOrderDishesStr(orders); + + // 将订单菜品信息封装到orderVO中,并添加到orderVOList + orderVO.setOrderDishes(orderDishes); + orderVOList.add(orderVO); + } + } + return orderVOList; + } + + /* + * 根据订单id获取菜品信息字符串 + * */ + private String getOrderDishesStr(Orders orders){ + //查询订单菜品详细信息 + List orderDetailList = orderDetailMapper.getByOrderId(orders.getId()); + + // 将每一条订单菜品信息拼接为字符串(格式:宫保鸡丁*3;) + List orderDishList = orderDetailList.stream().map(x -> { + String orderDish = x.getName() + "*" + x.getNumber() + ";"; + return orderDish; + }).collect(Collectors.toList()); + + // 将该订单对应的所有菜品信息拼接在一起 + return String.join("", orderDishList); + } + +// TODO:校验收货地址是否超出配送范围 + +} diff --git a/sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java new file mode 100644 index 0000000..21fe53c --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/impl/ReportServiceImpl.java @@ -0,0 +1,247 @@ +package com.sky.service.impl; + +import com.sky.dto.GoodsSalesDTO; +import com.sky.entity.Orders; +import com.sky.mapper.OrderDetailMapper; +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.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 OrderDetailMapper orderDetailMapper; + @Autowired + private WorkspaceService workspaceService; + /* + * 统计指定日期内的营业额 + * */ + @Override + public TurnoverReportVO getTurnoverStatistics(LocalDate begin, LocalDate end) { + //当前集合用于存放从begin到end范围内的每天的日期 + List dateList = new ArrayList<>(); + dateList.add(begin); + while(!begin.equals(end)){ + //日期计算,计算指定日期的后一天对应的日期 + begin = begin.plusDays(1); + dateList.add(begin); + } + + //每天的营业额 + List turnoverList = new ArrayList<>(); + for (LocalDate date : dateList) { + //查询date日期对应的营业额:状态为“已完成”的订单金额合计 + LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN); + LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX); + Map map = new HashMap<>(); + map.put("begin",beginTime); + map.put("end",endTime); + map.put("status", Orders.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(); + } + + /* + * 统计指定日期内的用户数据 + * */ + @Override + public UserReportVO getUserStatistics(LocalDate begin, LocalDate end) { + //当前集合用于存放从begin到end范围内的每天的日期 + List dateList = new ArrayList<>(); + dateList.add(begin); + while(!begin.equals(end)){ + //日期计算,计算指定日期的后一天对应的日期 + begin = begin.plusDays(1); + dateList.add(begin); + } + + //存放每天的新增用户数量 + List newUserList = new ArrayList<>(); + //存放每天的总用户数量 + List totalUserList = new ArrayList<>(); + Integer totalUser = 0; + for (LocalDate date : dateList) { + LocalDateTime beginTime = LocalDateTime.of(date,LocalTime.MIN); + LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX); + Map map = new HashMap(); + map.put("begin",beginTime); + map.put("end",endTime); + Integer newUser = userMapper.countByMap(map); + newUserList.add(newUser); + totalUser += newUser; + totalUserList.add(totalUser); + } + + return UserReportVO + .builder().dateList(StringUtils.join(dateList,",")) + .newUserList(StringUtils.join(newUserList,",")) + .totalUserList(StringUtils.join(totalUserList,",")) + .build(); + + } + + @Override + public OrderReportVO getOrderStatistics(LocalDate begin, LocalDate end) { + List dateList = new ArrayList<>(); + dateList.add(begin); + while(!begin.equals(end)){ + begin = begin.plusDays(1); + dateList.add(begin); + } + + //总订单数 + List orderCountList = new ArrayList<>(); + //有效订单 + List validOrderCountList = new ArrayList<>(); + for (LocalDate date : dateList) { + LocalDateTime beginTime = LocalDateTime.of(date,LocalTime.MIN); + LocalDateTime endTime = LocalDateTime.of(date,LocalTime.MAX); + //关键一步 + Integer orderCount = getOrderCount(beginTime,endTime,null); + Integer validOrderCount = getOrderCount(beginTime,endTime,Orders.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(); + } + + @Override + public SalesTop10ReportVO getTop10(LocalDate begin, LocalDate end) { + + LocalDateTime beginTime = LocalDateTime.of(begin,LocalTime.MIN); + LocalDateTime endTime = LocalDateTime.of(end,LocalTime.MAX); + List salesTop10 = orderMapper.getSalesTop10(beginTime,endTime); + List names = salesTop10.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList()); + String nameList = StringUtils.join(names, ","); + List numbers = salesTop10.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList()); + String numberList = StringUtils.join(numbers, ","); + return SalesTop10ReportVO + .builder() + .nameList(nameList) + .numberList(numberList) + .build(); + } + + /* + * 导出运营数据报表 + * */ + @Override + 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/运营数据报表模板.xlsx"); + + try { + //基于模板文件创建一个新的excel文件 + XSSFWorkbook excel = new XSSFWorkbook(in); + + //获取表格文件的sheet页 + XSSFSheet sheet = excel.getSheet("Sheet1"); + + //填充数据 时间 + sheet.getRow(1).getCell(1).setCellValue("时间:" + dateBegin + "至" + dateEnd); + + XSSFRow row = sheet.getRow(3); + row.getCell(2).setCellValue(businessDataVO.getTurnover()); + row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate()); + row.getCell(6).setCellValue(businessDataVO.getNewUsers()); + + 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(); + } + + + } + + /* + * 根据条件统计订单数量 + * */ + 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); + } +} diff --git a/sky-server/src/main/java/com/sky/service/impl/WorkspaceServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/WorkspaceServiceImpl.java new file mode 100644 index 0000000..dbfeefe --- /dev/null +++ b/sky-server/src/main/java/com/sky/service/impl/WorkspaceServiceImpl.java @@ -0,0 +1,164 @@ +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(); + } + + + /** + * 查询订单管理数据 + * + * @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(); + } + + /** + * 查询菜品总览 + * + * @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(); + } +} diff --git a/sky-server/src/main/java/com/sky/websocket/WebSocketServer.java b/sky-server/src/main/java/com/sky/websocket/WebSocketServer.java new file mode 100644 index 0000000..c1087a9 --- /dev/null +++ b/sky-server/src/main/java/com/sky/websocket/WebSocketServer.java @@ -0,0 +1,72 @@ +package com.sky.websocket; + +import org.springframework.stereotype.Component; + +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * WebSocket服务 + */ +@Component +@ServerEndpoint("/ws/{sid}") +public class WebSocketServer { + + //存放会话对象 + private static Map sessionMap = new HashMap(); + + /** + * 连接建立成功调用的方法 + */ + @OnOpen + public void onOpen(Session session, @PathParam("sid") String sid) { + System.out.println("客户端:" + sid + "建立连接"); + sessionMap.put(sid, session); + } + + /** + * 收到客户端消息后调用的方法 + * + * @param message 客户端发送过来的消息 + */ + @OnMessage + public void onMessage(String message, @PathParam("sid") String sid) { + System.out.println("收到来自客户端:" + sid + "的信息:" + message); + } + + /** + * 连接关闭调用的方法 + * + * @param sid + */ + @OnClose + public void onClose(@PathParam("sid") String sid) { + System.out.println("连接断开:" + sid); + sessionMap.remove(sid); + } + + /** + * 群发 + * + * @param message + */ + public void sendToAllClient(String message) { + Collection sessions = sessionMap.values(); + for (Session session : sessions) { + try { + //服务器向客户端发送消息 + session.getBasicRemote().sendText(message); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + +} diff --git a/sky-server/src/main/resources/mapper/OrderDetailMapper.xml b/sky-server/src/main/resources/mapper/OrderDetailMapper.xml new file mode 100644 index 0000000..ff09f97 --- /dev/null +++ b/sky-server/src/main/resources/mapper/OrderDetailMapper.xml @@ -0,0 +1,14 @@ + + + + + + + insert into order_detail(name, image, order_id, dish_id, setmeal_id, dish_flavor, amount) + values + + (#{od.name},#{od.image},#{od.orderId},#{od.dishId},#{od.setmealId},#{od.dishFlavor},#{od.amount}) + + + + diff --git a/sky-server/src/main/resources/mapper/OrderMapper.xml b/sky-server/src/main/resources/mapper/OrderMapper.xml new file mode 100644 index 0000000..7ff570e --- /dev/null +++ b/sky-server/src/main/resources/mapper/OrderMapper.xml @@ -0,0 +1,118 @@ + + + + + + insert into orders(number, status, user_id, address_book_id, order_time, + checkout_time, pay_method, pay_status, amount, remark, + phone, address, user_name, consignee, cancel_reason, + rejection_reason, cancel_time, estimated_delivery_time, + delivery_status, delivery_time, pack_amount, + tableware_number, tableware_status) + values(#{number},#{status},#{userId},#{addressBookId},#{orderTime},#{checkoutTime}, + #{payMethod},#{payStatus},#{amount},#{remark},#{phone},#{address},#{userName}, + #{consignee},#{cancelReason},#{rejectionReason},#{cancelTime},#{estimatedDeliveryTime}, + #{deliveryStatus},#{deliveryTime},#{packAmount},#{tablewareNumber},#{tablewareStatus}) + + + + update orders + + + cancel_reason=#{cancelReason}, + + + rejection_reason=#{rejectionReason}, + + + cancel_time=#{cancelTime}, + + + pay_status=#{payStatus}, + + + pay_method=#{payMethod}, + + + checkout_time=#{checkoutTime}, + + + status = #{status}, + + + delivery_time = #{deliveryTime} + + + where id = #{id} + + + + + +