Spring Task實現定時處理訂單狀態
作用:不需要輸入提示信號,便可定時自動執行程序
使用步驟
1、啟動類上加上注解(@EnableScheduling)開啟定時任務調度
2、專門創建一個包來管理執行定時任務的類,該類需要交給IOC容器管理
3、通過注解@Scheduled() + Cron表達式來指定執行時間(通過6|7個域 (秒 分 時 [日] 月 [周] 年),周和日只存在其一)
場景
訂單下單后一直沒有支付;派送完成后用戶沒有點擊已收貨;
示例
@Scheduled(cron = "0 * * * * ? ") //每分鐘觸發一次public void processTimeoutOrder(){log.info("定時處理超時訂單:{}", LocalDateTime.now()); ?LocalDateTime time = LocalDateTime.now().plusMinutes(-15); ?List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time); ?if(ordersList != null && ordersList.size() > 0){for (Orders orders : ordersList) {orders.setStatus(Orders.CANCELLED);orders.setCancelReason("訂單超時,自動取消");orders.setCancelTime(LocalDateTime.now());orderMapper.update(orders);}}} ?
WebSocket 實現來單提醒
作用:基于TCP的網絡協議,僅需一次握手,便可實現瀏覽器和服務器雙向通信
場景:實時通信類、有交換類的游戲或功能
使用流程:
1、導入maven
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>
2、創建配置類來配置 WebSocket
/*** WebSocket配置類,用于注冊WebSocket的Bean*/ @Configuration public class WebSocketConfiguration { ?@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();} ? }
3、封裝一個Socket服務來處理客戶端發送的消息
@Component @ServerEndpoint("/ws/{sid}") public class WebSocketServer { ?//存放會話對象private static Map<String, Session> sessionMap = new HashMap();/*** 連接建立成功調用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客戶端:" + sid + "建立連接");sessionMap.put(sid, session);}/*** 收到客戶端消息后調用的方法* @param message 客戶端發送過來的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到來自客戶端:" + sid + "的信息:" + message);}/*** 連接關閉調用的方法* @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("連接斷開:" + sid);sessionMap.remove(sid);}/*** 群發* @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服務器向客戶端發送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}} } ?
4、使用
? @Component public class WebSocketTask {@Autowiredprivate WebSocketServer webSocketServer;/*** 通過WebSocket每隔5秒向客戶端發送消息*/@Scheduled(cron = "0/5 * * * * ?")public void sendMessageToClient() {webSocketServer.sendToAllClient("這是來自服務端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));} }
營業額統計
ServiceImpl
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 = 5Map 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();}
Mapper.xml
<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>
訂單統計和用戶統計功能實現也一樣基本為增刪改查,不過返回數據的類型之前不同