目录
- 苍穹外卖day09-10
- 一:springtask
- 二:订单状态定时处理
- 三:websocket
- 四:来单提醒
- 五:客户催单
- 总结
苍穹外卖day09-10
首先第九天是实战日,要完成以下内容的开发:
用户端历史订单模块:
- 查询历史订单
- 查询订单详情
- 取消订单
- 再来一单
商家端订单管理模块:
- 订单搜索
- 各个状态的订单数量统计
- 查询订单详情
- 接单
- 拒单
- 取消订单
- 派送订单
- 完成订单
这里面基本上是增删改查,而且资料里有答案;我就不过多赘述了
直接进入第十天:
一:springtask
可以去网站生成cron表达式Cron - 在线Cron表达式生成器
自定义任务类:在项目中再建一个软件包,然后定义一个类,类上要加上compont注解将类交给容器管理,然后定义一个方法。里面完成定时任务的逻辑,方法上要加上@Scheduled注解,里面指定cron表达式;
@Component
@Slf4j
public class Mytask {
@Scheduled(cron = "0/5 * * * * ?")
public void task(){
log.info("定时任务已触发:{}",new Date());
}
}
二:订单状态定时处理
1:超时未支付:
@Scheduled(cron = "0 0/1 * * * ?")
public void PENDING_PAYMENTtask(){
log.info("定时任务已触发:{}",new Date());
LocalDateTime localDateTime = LocalDateTime.now().plusMinutes(-15);
List<Orders>orders= orderMapper.select(Long.valueOf(Orders.PENDING_PAYMENT),localDateTime);
for (Orders order : orders) {
order.setStatus(Orders.CANCELLED);
order.setCancelReason("超时未支付");
order.setCancelTime(LocalDateTime.now());
orderMapper.update(order);
}
}
我们每分钟去检查有没有超时的,具体的超时时间就是:下单时间超过15分钟,也就是当前时间-下单时间》15分钟:
我们sql是这么写的:
@Select("select * from orders where status=#{status} and order_time<#{orderTime}") List<Orders> select(Long status, LocalDateTime orderTime);
所以我们要传入的是当前时间减去谁5分钟,而localDateTime有方法可以直接减去,那么我们获取到了超时订单,就要遍历然后修改状态让超时订单取消,取消的话另外还要给取消原因和取消时间赋值;最后调用update修改就行了
2:派送中处理:
@Scheduled(cron = "0 0 1 * * ?")
public void DELIVERY_IN_PROGRESStask(){
LocalDateTime localDateTime = LocalDateTime.now().plusHours(-1);
List<Orders> orders = orderMapper.select(Long.valueOf(Orders.DELIVERY_IN_PROGRESS), localDateTime);
for (Orders order : orders) {
order.setStatus(Orders.COMPLETED);
orderMapper.update(order);
}
我们每天的凌晨一点去检查有没有派送中的订单,这里我们还是用我们定义的那个mapper方法:查询的状态是配送中,并且下单时间是昨天,也就是当前时间减一小时;然后遍历集合修改状态就行了;
三:websocket
不同于http,http只能由客户端主动发送消息,不能由服务器发送,被称为请求响应;而websocket是双向传输,只要建立链接只会,双方可以互发消息;
具体步骤:1:导入websocket依赖坐标:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
然后要导入服务端组件:
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {
//存放会话对象
private static Map<String, Session> 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<Session> sessions = sessionMap.values();
for (Session session : sessions) {
try {
//服务器向客户端发送消息
session.getBasicRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
@Component
@ServerEndpoint(“/ws/{sid}”)要有这两个注解,ServerEndpoint里是指定了建立连接的地址
还要导入一个配置类,用于注册websocket的组件
/**
* WebSocket配置类,用于注册WebSocket的Bean
*/
@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
四:来单提醒
这里我们直接再用户支付成功后想管理端的前端发送消息,我们约定的消息是json格式的包含上述内容:
Map map=new HashMap<>();
map.put("type",1);
map.put("orderId",orders.getId());
map.put("content","订单号"+outTradeNo);
String jsonString = JSON.toJSONString(map);
webSocketServer.sendToAllClient(jsonString);
这里就是将我们要传入给前端的值存放在map中,然后将map转换为json格式;
五:客户催单
这里我们单独设置一个接口,因为是用户在点击催单后发送的请求,所以我们要单独设置接口:
controller:
@GetMapping("/reminder/{id}")
public Result reminder(@PathVariable Long id){
Orders orders= orderService.reminder(id);
return Result.success();
}
因为我们需要订单号所有我们还要去调用service
service:
@Override
public Orders reminder(Long id) {
Orders orders = orderMapper.selectById(id);
Map map=new HashMap<>();
map.put("type",2);
map.put("orderId",id);
map.put("content","订单号"+orders.getNumber());
String jsonString = JSON.toJSONString(map);
webSocketServer.sendToAllClient(jsonString);
return orders;
}
这里就是先查询信息,然后放入map中,再将map转成一个json字符串,然后再通过ws发送给前端;
总结
“orderId”,id);
map.put(“content”,“订单号”+orders.getNumber());
String jsonString = JSON.toJSONString(map);
webSocketServer.sendToAllClient(jsonString);
return orders;
}
> 这里就是先查询信息,然后放入map中,再将map转成一个json字符串,然后再通过ws发送给前端;
# 总结
今天学习了springtask的简单使用,用springtask来定义定时任务,然后学习了websocket的双向传输,了解了通过ws由服务器端向前端发送数据;完成了来单提醒,催单的功能;