电商订单的操作

Posted liuyi13535496566

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商订单的操作相关的知识,希望对你有一定的参考价值。

1 结算页面不进行任何业务层处理,购物车数据转订单详情

结算页面提交订单时,只能提交一次(防止表单重复提交)

防止表单重复提交具体步骤:

点击购物车结算按钮时→ 后台生成TradeCode交易码分别放在订单页面和redis缓存各一份

点击提交订单时→会将订单页面的交易码跟缓存里面的进行比对,如果为true,则重定向到支付页面,并删除redis缓存里的TradeCode交易码,如果用户回退,因为redis缓存的交易码已经用过并删除了,所以比对失败,跳到失败页面,达到防止表单重复提交的效果


代码如下:

 点击购物车结算跳到订单页面

@LoginRequired
@RequestMapping("toTrade")
public String toTrade(HttpServletRequest request, ModelMap map){

String memberId = (String)request.getAttribute("memberId");
String nickname = (String)request.getAttribute("nickname");

// 查询购物车数据
List<OmsCartItem> omsCartItems = cartService.getCartList(memberId);

// 转化成订单数据
List<OmsOrderItem> omsOrderItems = new ArrayList<>();
for (OmsCartItem omsCartItem : omsCartItems) {
OmsOrderItem omsOrderItem = new OmsOrderItem();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String orderSn = "gmall"+sdf.format(date)+System.currentTimeMillis();
omsOrderItem.setOrderSn(orderSn);
omsOrderItem.setProductCategoryId(omsCartItem.getProductCategoryId());
omsOrderItem.setProductId(omsCartItem.getProductId());
......
omsOrderItems.add(omsOrderItem);
}
map.put("orderDetailList",omsOrderItems);
List<UmsMemberReceiveAddress> umsMemberReceiveAddresses = userService.getAddressListByMemberId(memberId);
map.put("userAddressList",umsMemberReceiveAddresses);
// 防止表单重复提交
String tradeCode = orderService.genTradeCode(memberId);
map.put("tradeCode",tradeCode);
return "trade";
}

查询购物车数据

@Override
public List<OmsCartItem> getCartList(String memberId) {
List<OmsCartItem> cartItems = new ArrayList<>();
Jedis jedis = redisUtil.getJedis();
List<String> hvals = jedis.hvals("user:" + memberId + ":cart");
if(hvals!=null&&hvals.size()>0){
for (String hval : hvals) {
OmsCartItem omsCartItem = JSON.parseObject(hval,OmsCartItem.class);
cartItems.add(omsCartItem);
}
}
jedis.close();
return cartItems;
}

查询用户地址
@Override
public List<UmsMemberReceiveAddress> getAddressListByMemberId(String memberId) {
UmsMemberReceiveAddress umsMemberReceiveAddress = new UmsMemberReceiveAddress();
umsMemberReceiveAddress.setMemberId(memberId);
List<UmsMemberReceiveAddress> umsMemberReceiveAddresses = umsMemberReceiveAddressMapper.select(umsMemberReceiveAddress);

return umsMemberReceiveAddresses;
}

获取交易码
@Override
public String genTradeCode(String memberId) {
Jedis jedis = null;
jedis = redisUtil.getJedis();
String tradeCode = UUID.randomUUID().toString();
jedis.setex("user:" + memberId + ":tradeCode", 60 * 15,tradeCode );
jedis.close();
return tradeCode;
}



@LoginRequired
@RequestMapping("submitOrder")
public String submitOrder(HttpServletRequest request, ModelMap map, String deliveryAddressId, String tradeCode){
// 获取用户信息
String memberId = (String)request.getAttribute("memberId");
String nickname = (String)request.getAttribute("nickname");
  //比对订单页面的交易码和redis缓存里面的交易码是否一样
boolean b = orderService.checkTradeCode(tradeCode,memberId);

if(b){

// 用户收获信息
UmsMemberReceiveAddress umsMemberReceiveAddress = userService.getAddressById(deliveryAddressId);

// 根据用户获取购物车数据
List<OmsCartItem> cartList = cartService.getCartList(memberId);
// 根据购物车数据生成订单数据
OmsOrder omsOrder = new OmsOrder();
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String orderSn = "gmall"+sdf.format(date)+System.currentTimeMillis();
omsOrder.setOrderSn(orderSn);
omsOrder.setPayAmount(getTotalAmount(cartList));
omsOrder.setStatus("0");
omsOrder.setCreateTime(new Date());
     ......
List<OmsOrderItem> omsOrderItems = new ArrayList<OmsOrderItem>();
List<String> cartIds = new ArrayList<>();
for (OmsCartItem omsCartItem : cartList) {
OmsOrderItem omsOrderItem = new OmsOrderItem();
omsOrderItem.setProductSkuCode(omsCartItem.getProductSkuCode());
omsOrderItem.setProductPrice(omsCartItem.getPrice());
omsOrderItem.setOrderSn(orderSn);
       ......
omsOrderItems.add(omsOrderItem);
cartIds.add(omsCartItem.getId());
}
omsOrder.setOmsOrderItems(omsOrderItems);

// 将订单数据保存到数据库
orderService.addOrder(omsOrder);

// 删除购物车数据
// cartService.delCarts(cartIds);

System.out.println("获取用户信息");
System.out.println("根据用户获取购物车数据");
System.out.println("根据购物车数据生成订单数据");
System.out.println("将订单数据保存到数据库");
System.out.println("删除购物车数据");
System.out.println("重定向到支付页面");
}else{
return "tradeFail";
}

return "pay";// 重定向到支付页面
}


比对订单页面的交易码和redis缓存里面的交易码是否一样
@Override
public boolean checkTradeCode(String tradeCode,String memberId) {
boolean b = false;

Jedis jedis = null;
jedis = redisUtil.getJedis();
// String tradeCodeFromCache = jedis.get("user:" + memberId + ":tradeCode");
// if(StringUtils.isNotBlank(tradeCodeFromCache)&&tradeCodeFromCache.equals(tradeCode)){
// b = true;
// jedis.del("user:" + memberId + ":tradeCode");
// }
     //并发问题推荐用这种
String script = "if redis.call(‘get‘, KEYS[1]) == ARGV[1] then return redis.call(‘del‘, KEYS[1]) else return 0 end";
Long eval = (Long) jedis.eval(script, Collections.singletonList("user:" + memberId + ":tradeCode"),
Collections.singletonList(tradeCode));
if(new BigDecimal(eval).compareTo(new BigDecimal("0"))!=0){
b = true;
}
jedis.close();
return b;
}

用户地址信息
@Override
public UmsMemberReceiveAddress getAddressById(String deliveryAddress) {

UmsMemberReceiveAddress umsMemberReceiveAddress = new UmsMemberReceiveAddress();
umsMemberReceiveAddress.setId(deliveryAddress);
UmsMemberReceiveAddress umsMemberReceiveAddress1 = umsMemberReceiveAddressMapper.selectOne(umsMemberReceiveAddress);
return umsMemberReceiveAddress1;
}
}


将订单信息保存到数据库
@Override
public void addOrder(OmsOrder omsOrder) {
omsOrderMapper.insertSelective(omsOrder);
String orderId = omsOrder.getId();
List<OmsOrderItem> omsOrderItems = omsOrder.getOmsOrderItems();
for (OmsOrderItem omsOrderItem : omsOrderItems) {
omsOrderItem.setOrderId(orderId);
omsOrderItemMapper.insertSelective(omsOrderItem);
}
}

以上就完成啦!









 

以上是关于电商订单的操作的主要内容,如果未能解决你的问题,请参考以下文章

架构设计 | 基于电商交易流程,图解TCC事务分段提交

基于rabbitMQ 消息延时队列方案 模拟电商超时未支付订单处理场景

Vue3电商项目实战-结算&支付 305-结算-收货地址-添加06-结算-收货地址-修改07-结算-提交订单

基于JAVA springboot+mybatis 电商书城平台系统设计和实现

电商后台系统-订单系统-订单状态的梳理(跨境电商)

电商产品之订单拆分规则与流程