地址簿
数据库表设计
就是基本增删改查,与前面的类似。
用户下单
用户点餐业务流程:
购物车-订单提交-订单支付-下单成功
展示购物车数据,不需要提交到后端
数据库设计:两个表【订单表orders,订单明细表order_detail】
DTO:
VO:
controller:
@RestController("UserOrderController")//作为Bean名称,避免与admin端名称重复
@RequestMapping("/user/order")
@Api(tags = "B端用户订单接口")
public class OrderController {
@Autowired
private OrderService orderService;
@PostMapping("/submit")
@ApiOperation("用户下单")
public Result<OrderSubmitVO> submit(@RequestBody OrdersSubmitDTO submitDTO){
return Result.success(orderService.submit(submitDTO));//传入DTO返回VO
}
service :
@Transactional/
/设计几多个数据表,需要保证数据一致性,需要事务注解–保证原子性,全成功或全失败
@Transactional//事务注解 -方法执行完提交才插入
@Override
public OrderSubmitVO submit(OrdersSubmitDTO submitDTO) {
//处理各种业务异常检查(地址是否为空,购物车是否为空)
AddressBook addressBook = addressBookMapper.getById(submitDTO.getAddressBookId());
if (addressBook == null) {
throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
}
//检查当前用户的购物车是否为空
Long userId = BaseContext.getCurrentId();//当前用户ID
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.setUserId(userId);
List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
if (list == null || list.size() == 0) {
throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
}
//1.增加一条订单信息
Orders orders = new Orders();
BeanUtils.copyProperties(submitDTO, 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);//用户ID
orderMapper.insert(orders);
//2.增加多条订单详情
List<OrderDetail> orderDetailList = new ArrayList<>();//整个批量插入
for (ShoppingCart cart : list) {//遍历购物车里的数据
OrderDetail orderDetail = new OrderDetail();//订单单明细
BeanUtils.copyProperties(cart, orderDetail);
orderDetail.setOrderId(orders.getId());//设置当前订单明细关联的订单id
orderDetailList.add(orderDetail);
}
orderDetailMapper.insertBatch(orderDetailList);
//3.删除用户购物车
shoppingCartMapper.deleteByUserId(userId);
//4.封装VO对象并返回
OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
.id(orders.getId())
.orderNumber(orders.getNumber())
.orderTime(orders.getOrderTime())
.orderAmount(orders.getAmount())
.build();
return orderSubmitVO;
}
增加1订单
mapper:
void insert(Orders orders);
xml:出入后返回订单主键值
<insert id="insert" parameterType="Orders" useGeneratedKeys="true" keyProperty="id">
insert into orders (number, status, user_id, address_book_id, order_time, checkout_time, pay_status, pay_method,amount, remark, phone, address, consignee, estimated_delivery_time, delivery_status,pack_amount, tableware_number, tableware_status)
values (#{number}, #{status}, #{userId}, #{addressBookId}, #{orderTime}, #{checkoutTime}, #{payMethod},
#{payStatus}, #{amount}, #{remark}, #{phone}, #{address}, #{consignee}, #{estimatedDeliveryTime},
#{deliveryStatus}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus})
</insert>
批量增加订单详情:
void insertBatch(List<OrderDetail> orderDetailList);
<insert id="insertBatch">
insert into order_detail (name, image, order_id, dish_id, setmeal_id, dish_flavor, number, amount)
values
<foreach collection="orderDetailList" item="od" separator=",">
(#{od.name},#{od.image},#{od.orderId} ,#{od.dishId},#{od.setmealId},#{od.dishFlavor},#{od.number},#{od.amount})
</foreach>
</insert>
订单支付(*流程)
微信支付介绍
JSAPI下单:商户调用该接口在后台生成预支付交易单,返回表示,
微信支付准备工作
两个问题:
1.调用过程如何保证数据安全?
获取微信支付平台整证书、商户私钥文件
从微信商户平台得到两个文件
2.微信后台如何调用到商户系统?
当前商务系统的ip就是本地电脑ip这个局域网的IP,微信后跳调用不到,应该用公网IP。
获取临时域名:
cpolar.exe内网穿透生成一个临时域名。
略。
从用户发起支付订单开始看:
@PutMapping("/payment")
@ApiOperation("订单支付")
public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
//订单支付
OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
//生成预交易订单
return Result.success(orderPaymentVO);
}
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
);
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;
}