一、创建jl-order项目
订单为提供者,需定义公共接口,和实现类
new -> Moudule> maven 创建子项目
jl-order
继承、添加jl-common工具类依赖和跳过测试类打包的插件
将
jl-cart
的resources
复制到jl-order
修改配置文件application.yml 设置端口为
8095
修改dubbo配置: 将
application.name
改为provider-order
; 将protocol.port
改为20882
将
UserMapper.xml
改成cartMapper.xml
, 并添加OrderItemMapper.xml
OrderShippingMapper.xml
以及修改里面的映射路径
jl-order
的com.jl.mapper
包路径下创建OrderMapper
OrderItemMapper
OrderShippingMapper
接口,并继承对应的BaseMapper<pojo对象>
在
jl-common
中定义DubboOrderService
接口在
jl-cart
定义接口实现类DubboCartServiceImpl
创建SpringBootRun启动类 ,加上@MapperScan(“com.jl.mapper”)注解
在
jl-common
中添加Order
OrderItem
OrderShipping
pojo对象
1.1 pojo对象
1.1.1 Order
package com.jl.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
import java.util.List;
@TableName("tb_order")
@Data
@Accessors(chain=true)
public class Order extends BasePojo {
//一对一
@TableField(exist = false) //入库操作忽略该字段
private OrderShipping orderShipping;
//封装订单商品信息 一对多
@TableField(exist = false) //入库操作忽略该字段
private List<OrderItem> orderItems;
@TableId
private String orderId; //订单号:登录用户id+当前时间戳
private String payment;
private Integer paymentType;
private String postFee;
private Integer status; //状态:1、未付款2、已付款3、未发货4、已发货5、交易成功6、交易关闭
private Date paymentTime;
private Date consignTime;
private Date endTime;
private Date closeTime;
private String shippingName;
private String shippingCode;
private Long userId;
private String buyerMessage;
private String buyerNick;
private Integer buyerRate;
}
1.1.2 OrderItem
package com.jl.pojo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@TableName("tb_order_item")
@Data
@Accessors(chain=true)
public class OrderItem extends BasePojo{
@TableId
private String itemId;
@TableId
private String orderId;
private Integer num;
private String title;
private Long price;
private Long totalFee;
private String picPath;
}
1.1.3 OrderShipping
package com.jl.pojo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@TableName("tb_order_shipping")
@Data
@Accessors(chain=true)
public class OrderShipping extends BasePojo{
@TableId
private String orderId;
private String receiverName;
private String receiverPhone;
private String receiverMobile;
private String receiverState;
private String receiverCity;
private String receiverDistrict;
private String receiverAddress;
private String receiverZip;
}
二、订单业务
2.1 跳转订单确认
url 分析 :
http://www.jl.com/order/create.html
在
jl-web
中创建OrderController
,创建create方法
@Controller
@RequestMapping("/order")
public class OrderController {
@Reference(check = false)
private DubboCartService cartService;
/**
* 订单确认页,需要获取购物车记录.
* 通过userId.
* 页面获取数据:${carts}
* @return
*/
@RequestMapping("/create")
public String create(Model model) {
Long userId = UserThreadLocal.getUser().getId();
List<Cart> cartList = cartService.findCartListByUserId(userId);
model.addAttribute("carts", cartList);
return "order-cart";//执行视图解析器方法
}
}
2.2 订单新增
2.2.1 页面分析
页面url分析 :
http://www.jl.com/order/submit
页面js
/**
* 提交订单方法
*/
function submit_Order() {
$("#submit_message").hide();
jQuery.ajax( {
type : "POST",
dataType : "json",
url : "/order/submit",
data : $("#orderForm").serialize(),
cache : false,
success : function(result) {
if(result.status == 200){
location.href = "/order/success.html?id="+result.data;
}else{
$("#submit_message").html("订单提交失败,请稍后重试...").show();
}
},
error : function(error) {
$("#submit_message").html("亲爱的用户请不要频繁点击, 请稍后重试...").show();
}
});
}
2.2.2 编辑OrderController
实现订单提交
/**
* 实现订单提交
*/
@RequestMapping("/submit")
@ResponseBody
public SysResult insertOrder(Order order) {
Long userId = UserThreadLocal.getUser().getId();
order.setUserId(userId);
String orderId = orderService.insertOrder(order);
if (StringUtils.isEmpty(orderId)) {
return SysResult.fail();
}
return SysResult.success(orderId);
}
2.2.3 编辑OrderService
在
DubboOrderService
添加insertOrder
方法在
OrderServiceImpl
实现当入库成功之后,需要回传orderID
package com.jl.service;
@Service
public class OrderServiceImpl implements DubboOrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
@Autowired
private OrderShippingMapper orderShippingMapper;
@Transactional //事务控制
@Override
public String insertOrder(Order order) {
//订单号:登录用户id+当前时间戳
String orderId = "" + order.getUserId() + System.currentTimeMillis();
Date date = new Date();
//1.入库order对象
order.setOrderId(orderId).setStatus(1).setCreated(date).setUpdated(date);
orderMapper.insert(order);
System.out.println("订单入库成功!!!!");
//2.入库订单物流
OrderShipping shipping = order.getOrderShipping();
shipping.setOrderId(orderId).setCreated(date).setUpdated(date);
orderShippingMapper.insert(shipping);
System.out.println("订单物流入库成功!!!");
//sql: insert into tb_order_item(...) valus(....),(....),(....),(....)
//动态拼接sql
//3.实现订单商品入库
List<OrderItem> orderItems = order.getOrderItems();
for (OrderItem orderItem : orderItems) {
orderItem.setOrderId(orderId).setCreated(date).setUpdated(date);
orderItemMapper.insert(orderItem);
}
System.out.println("订单商品入库成功!!!!!");
return orderId;
}
}
2.3 订单查询
2.3.1 页面分析
页面url分析 :
http://www.jl.com/order/success
2.3.2 编辑OrderController
根据orderId 查询数据库记录
页面取值:${order.orderId}
@RequestMapping("/success")
public String findOrderById(String id, Model model) {
Order order = orderService.findOrderById(id);
model.addAttribute("order", order);
return "success";
}
2.3.3 编辑OrderService
在
DubboOrderService
添加findOrderById
方法在
OrderServiceImpl
实现查询3张表数据.实现数据封装
@Override
public Order findOrderById(String id) {
Order order = orderMapper.selectById(id);
OrderShipping shipping = orderShippingMapper.selectById(id);
QueryWrapper<OrderItem> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_id", id);
List<OrderItem> orderItems = orderItemMapper.selectList(queryWrapper);
return order.setOrderShipping(shipping).setOrderItems(orderItems);
}
三、Quartz定时任务
3.1 Quartz介绍
Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。
流程图:
Job:自定义任务
JobDetail: 封装Job的工具API
调度器: 控制记录所有的任务
触发器: 控制任务什么时候执行
执行流程:
- 自定义任务.并且封装为jobDetail对象.之后交给调度器管理
- 调度器负责任务的维护(实例化任务对象),并且管理触发器
- 为触发器设定执行的时间(周期),如果时间一到,则开启新的线程执行任务
3.2 Quartz整合项目
3.2.1 导入Quartz表达式生成器
运行
Main.java
可以自定义生成计划时间表达式
3.2.2 导入Quartz的jar包
<!--添加Quartz的支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
3.2.3 编辑定时任务配置类
在
jl-order
的com.jl.conf
下编辑OrderQuartzConfig
配置类
- 定义任务详情
- 定义触发器
package com.jl.conf;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.jl.quartz.OrderQuartz;
@Configuration
public class OrderQuartzConfig {
//定义任务详情
@Bean
public JobDetail orderjobDetail() {
//指定job的名称和持久化保存任务
return JobBuilder
.newJob(OrderQuartz.class) //1.自定义任务
.withIdentity("orderQuartz") //2.任务名称
.storeDurably()
.build();
}
//定义触发器
@Bean
public Trigger orderTrigger() {
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/1 * * * ?"); //1.执行周期
return TriggerBuilder
.newTrigger()
.forJob(orderjobDetail())
.withIdentity("orderQuartz") //2.任务
.withSchedule(scheduleBuilder).build();
}
}
3.2.4 编辑自定义任务
准备订单定时任务,在
jl-order
里的com.jl.quartz
包中编辑OrderQuartz
超时:当前时间 - 创建订单的时间> 30分钟;创建时间 < 当前时间-30分钟
业务:如果超时30分钟.则将状态由1改为6
sql:
update tb_order set status=6,updated=#{date} where status = 1 and created < #{timeOut}
package com.jl.quartz;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.jl.mapper.OrderMapper;
import com.jl.pojo.Order;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.Calendar;
import java.util.Date;
//准备订单定时任务
@Component
public class OrderQuartz extends QuartzJobBean {
@Autowired
private OrderMapper orderMapper;
@Override
@Transactional
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
//1.计算超时时间 日历工具API 用于计算时间
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, -30);
Date timeOut = calendar.getTime(); //获取超时时间
Order orderTemp = new Order();
orderTemp.setStatus(6).setUpdated(new Date());
UpdateWrapper<Order> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("status", 1).lt("created", timeOut);
orderMapper.update(orderTemp, updateWrapper);
System.out.println("定时任务操成功!!!!!");
}
}