电商订单的操作
Posted liuyi13535496566
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了电商订单的操作相关的知识,希望对你有一定的参考价值。
1 结算页面不进行任何业务层处理,购物车数据转订单详情
2 结算页面提交订单时,只能提交一次(防止表单重复提交)
防止表单重复提交具体步骤:
点击购物车结算按钮时→ 后台生成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);
}
}
以上就完成啦!
以上是关于电商订单的操作的主要内容,如果未能解决你的问题,请参考以下文章
基于rabbitMQ 消息延时队列方案 模拟电商超时未支付订单处理场景
Vue3电商项目实战-结算&支付 305-结算-收货地址-添加06-结算-收货地址-修改07-结算-提交订单