【电商项目实战】实现订单超时支付取消
2024-01-03 19:37:47
🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《电商项目实战》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖
前言
大家对电商购物应该都比较熟悉了,我们应该注意到,在下单之后,通常会有一个倒计时,如果超过支付时间,订单就会被自动取消。这个功能说难也不难,说简单但也足以难倒一大片人,今天我就为大家提供一种思路。
一、订单显示
我们在购物车页面点击结算的时候肯定还是没有直接让我们交钱的,是跳转一个订单确认页面,确认订单信息无误,选择收货地址支付方式等才会生成订单。
订单详情页面
<!DOCTYPE html>
<html>
<head lang="en">
<#include "common/head.html">
<link rel="stylesheet" type="text/css" href="css/public.css"/>
<link rel="stylesheet" type="text/css" href="css/proList.css" />
<link rel="stylesheet" type="text/css" href="css/mygxin.css" />
</head>
<body>
<!----------------------------------------order------------------>
<div class="head ding">
<div class="wrapper clearfix">
<div class="clearfix" id="top">
<h1 class="fl"><a href="${ctx}/"><img src="img/logo.png"/></a></h1>
<div class="fr clearfix" id="top1">
<form action="#" method="get" class="fl">
<input type="text" placeholder="搜索" />
<input type="button" />
</form>
</div>
</div>
</div>
</div>
<!-----------------site------------------->
<div class="order cart mt">
<div class="site">
<p class="wrapper clearfix">
<span class="fl">订单确认</span>
<img class="top" src="img/temp/cartTop02.png">
</p>
</div>
<!-----------------orderCon------------------->
<div class="orderCon wrapper clearfix">
<div class="orderL fl">
<!--------h3---------------->
<h3>收件信息<a href="#" class="fr">新增地址</a></h3>
<!--------addres---------------->
<div class="addres clearfix">
<div class="addre fl on">
<div class="tit clearfix">
<p class="fl">张三1
<span class="default">[默认地址]</span>
</p>
<p class="fr">
<a href="#">删除</a>
<span>|</span>
<a href="#" class="edit">编辑</a>
</p>
</div>
<div class="addCon">
<p>河北省 唐山市 路北区 大学生公寓村</p>
<p>15732570937</p>
</div>
</div>
<div class="addre fl">
<div class="tit clearfix">
<p class="fl">张三2
</p>
<p class="fr">
<a href="#" class="setDefault">设为默认</a>
<span>|</span>
<a href="#">删除</a>
<span>|</span>
<a href="#" class="edit">编辑</a>
</p>
</div>
<div class="addCon">
<p>河北省 唐山市 路北区 大学生公寓村</p>
<p>15732570937</p>
</div>
</div>
<div class="addre fl">
<div class="tit clearfix">
<p class="fl">张三3
</p>
<p class="fr">
<a href="#" class="setDefault">设为默认</a>
<span>|</span>
<a href="#">删除</a>
<span>|</span>
<a href="#" class="edit">编辑</a>
</p>
</div>
<div class="addCon">
<p>河北省 唐山市 路北区 大学生公寓村</p>
<p>15732570937</p>
</div>
</div>
</div>
<h3>支付方式</h3>
<!--------way---------------->
<div class="way clearfix">
<img class="on" value="0" src="img/temp/way01.jpg">
<img value="1" src="img/temp/way02.jpg">
<img value="2" src="img/temp/way03.jpg">
<img value="3" src="img/temp/way04.jpg">
</div>
<h3>选择快递</h3>
<!--------dis---------------->
<div class="dis clearfix">
<span class="on">顺风快递</span>
<span>百世汇通</span>
<span>圆通快递</span>
<span>中通快递</span>
</div>
</div>
<div class="orderR fr">
<div class="msg">
<h3>订单内容<a href="${ctx}/cart/getCart" class="fr">返回购物车</a></h3>
<#--定义商品总价-->
<#assign sumnum=0>
<#--遍历商品信息-->
<#if item??>
<#list item as g>
<ul class="clearfix">
<li class="fl">
<img src="${g.goodsImg}" style="width: 100px;height: 100px">
</li>
<li class="fl">
<p>${g.goodsTitle}</p>
<p>${g.goodsName}</p>
<p>数量:${g.num}</p>
<#assign xiaoji=g.num*g.goodsPrice>
</li>
<li class="fr">¥${g.goodsPrice}</li>
</ul>
<#assign sumnum=sumnum+xiaoji>
</#list>
</#if>
</div>
<!--------tips---------------->
<div class="tips">
<p><span class="fl">商品金额:</span><span class="fr">¥${sumnum}</span></p>
<p><span class="fl">优惠金额:</span><span class="fr">¥0.00</span></p>
<p><span class="fl">运费:</span><span class="fr">免运费</span></p>
</div>
<!--------tips count---------------->
<div class="count tips">
<p><span class="fl">合计:</span><span class="fr">¥${sumnum}</span></p>
</div>
<!--<input type="button" name="" value="去支付"> -->
<a href="javascript:void(0);" class="pay">去支付</a>
</div>
</div>
</div>
<!--编辑弹框-->
<!--遮罩-->
<div class="mask"></div>
<div class="adddz editAddre">
<form action="#" method="get">
<input type="text" placeholder="姓名" class="on" />
<input type="text" placeholder="手机号" />
<div class="city">
<select name="">
<option value="省份/自治区">省份/自治区</option>
</select>
<select>
<option value="城市/地区">城市/地区</option>
</select>
<select>
<option value="区/县">区/县</option>
</select>
<select>
<option value="配送区域">配送区域</option>
</select>
</div>
<textarea name="" rows="" cols="" placeholder="详细地址"></textarea>
<input type="text" placeholder="邮政编码" />
<div class="bc">
<input type="button" value="保存" />
<input type="button" value="取消" />
</div>
</form>
</div>
<!--返回顶部-->
<input type="hidden" id="gids" value="${RequestParameters['gids']!}"/>
<#include "common/footer.html">
<script src="js/others/order.js" type="text/javascript" charset="utf-8"></script>
<script src="js/public.js" type="text/javascript" charset="utf-8"></script>
<script src="js/pro.js" type="text/javascript" charset="utf-8"></script>
<script src="js/user.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
?
1.前端代码?
首先我们为结算按钮设置点击事件
$(".count").click(function (){
//拿到所有选中的商品id
let ids=[];
$(".th input[type='checkbox']:checked").each(function(j){
//获取单条数据上面的gid属性
let gid=$(this).attr('data-gid');
ids.push(gid)
})
ids=ids.join(",")
//将商品数据发送到后端
location.href="/cart/getOrder?ids="+ids;
})
?
2.后端代码?
?拿到选中需要结算的商品后需要先去Redis中将对应的商品拿出来
// 查询用户结算的购物车商品
List<GoodsVo> loadCart(User user,List<String> ids);
@Override
public List<GoodsVo> loadCart(User user, List<String> ids) {
HashOperations<String,String,GoodsVo> operations=redisTemplate.opsForHash();
String bigKey=Constants.REDIS_CART_PREFIX + user.getId();
//根据用户Id查询结算的购物车商品
List<GoodsVo> goodsVos = operations.multiGet(bigKey, ids);
return goodsVos;
}
这里拿出来的商品只有商品id和数量所以还需要拿到数据库做比较
@RequestMapping("/getOrder")
public String getOrder(User user, String ids, Model model) {
//根据用户查询结算购物车商品
List<String> ds = (List<String>) Arrays.asList(ids.split(","));
List<GoodsVo> item = redisService.loadCart(user,ds);
//根据商品Id查询对应商品
List<Integer> gds = item.stream().map(GoodsVo::getGid).collect(Collectors.toList());
if (gds.size() > 0) {
List<Goods> goods = goodsService.listByIds(gds);
// 进行遍历筛选合适的数据
for (Goods g : goods) {
//找到对应属性的商品
for (GoodsVo gv : item) {
if (g.getGid() == gv.getGid()) {
BeanUtils.copyProperties(g, gv);
}
}
}
}
model.addAttribute("item", item);
return "order";
}
3.数据显示?
最后在前端显示相应的数据即可
//订单详情页面部分代码
<#--定义商品总价-->
<#assign sumnum=0>
<#--遍历商品信息-->
<#if item??>
<#list item as g>
<ul class="clearfix">
<li class="fl">
<img src="${g.goodsImg}" style="width: 100px;height: 100px">
</li>
<li class="fl">
<p>${g.goodsTitle}</p>
<p>${g.goodsName}</p>
<p>数量:${g.num}</p>
<#assign xiaoji=g.num*g.goodsPrice>
</li>
<li class="fr">¥${g.goodsPrice}</li>
</ul>
<#assign sumnum=sumnum+xiaoji>
</#list>
</#if>
</div>
<!--------tips---------------->
<div class="tips">
<p><span class="fl">商品金额:</span><span class="fr">¥${sumnum}</span></p>
<p><span class="fl">优惠金额:</span><span class="fr">¥0.00</span></p>
<p><span class="fl">运费:</span><span class="fr">免运费</span></p>
</div>
<!--------tips count---------------->
<div class="count tips">
<p><span class="fl">合计:</span><span class="fr">¥${sumnum}</span></p>
</div>
效果展示:?
这里其他的东西除了商品以外都是定死的,包括收件信息(感兴趣的可以自行优化)?
?
?二、生成订单
1.表设计
生成订单前,我们先看一下订单表和订单详情表有什么表字段好去拿什么值。
t_orde(订单表
t_order_item(订单详情表
?
?2.前端取值
我们可以先对页面元素进行判断,拿取我们需要的元素
?这里我为选中的收件信息、支付方式、快递都添加了一个"on"样式,我们只需要根据标签层层抓取即可。
//生成订单
$(".pay").click(function (){
let el=$(".addres").find(".on")
let person= el.find(".tit .fl").text()
let address= el.find(".addCon p:first-child").text()
let telephone= el.find(".addCon p:last-child").text()
let pay=$(".way .on").attr('value')
let mail=$(".dis .on").text()
let ids=$(this).attr('data-ids')
let order={
person,address,telephone,pay,mail,ids
}
console.log(order)
})
?打印结果没有问题,那么我们就可以向后端发起请求了
?我们把后面的请求写完
//生成订单
$(".pay").click(function (){
let el=$(".addres").find(".on")
let person= el.find(".tit .fl").text()
let address= el.find(".addCon p:first-child").text()
let telephone= el.find(".addCon p:last-child").text()
let pay=$(".way .on").attr('value')
let mail=$(".dis .on").text()
let ids=$(this).attr('data-ids')
let order={
person,address,telephone,pay,mail,ids
}
// console.log(order)
$.post('order/addOrder',order,resp=>{
if(resp.code===200){alert("新增订单成功")}
},'json')
})
?
2.后端处理
首先需要一个接收前端参数的Vo类
@Data
public class OrderVo extends Order implements Serializable {
private String ids;
}
?随后就可以开始编写我们的controller层代码
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private IRedisService redisService;
@Autowired
private IGoodsService goodsService;
@Autowired
private IOrderItemService orderItemService;
@Autowired
private IOrderService orderService;
@RequestMapping("/addOrder")
public JsonResponseBody<?> addOrder(User user, OrderVo vo) {
//从Redis将数据查询出来
String ids = vo.getIds();
List<String> ds = Arrays.asList(ids.split(","));
List<GoodsVo> item = redisService.loadCart(user, ds);
//根据商品id到数据库查询商品详情
//根据商品Id查询对应商品
List<Integer> gds = item.stream().map(GoodsVo::getGid).collect(Collectors.toList());
if (gds.size() > 0) {
List<Goods> goods = goodsService.listByIds(gds);
// 进行遍历筛选合适的数据
for (Goods g : goods) {
//找到对应属性的商品
for (GoodsVo gv : item) {
if (g.getGid() == gv.getGid()) {
BeanUtils.copyProperties(g, gv);
}
}
}
}
BigDecimal sumPrice= BigDecimal.valueOf(0);//保存商品总价
long oid = YitIdHelper.nextId();//订单id
//新增订单详情
//订单项集合
List<OrderItem> orderItems=new ArrayList<>();
for (GoodsVo it : item) {
//生成订单项
OrderItem orderItem=new OrderItem();
BeanUtils.copyProperties(it,orderItem);
orderItem.setQuantity(it.getNum());
orderItem.setOoid(YitIdHelper.nextId());
orderItem.setGid(Long.valueOf(it.getGid()+""));
orderItem.setOid(oid);
//将订单项加入集合中
orderItems.add(orderItem);
BigDecimal sum= BigDecimal.valueOf(it.getNum()*Double.parseDouble((it.getGoodsPrice()+"")));//保存商品小计
sumPrice.add(sum);
}
//为了反正sql过长可选择批量
orderItemService.saveBatch(orderItems,5);
//新增订单
Order order=new Order();
BeanUtils.copyProperties(vo,order);
order.setTotal(sumPrice);
order.setUserId(user.getId());
order.setStatus(0);
order.setOid(oid);
order.setCreateDate(new Date());
orderService.save(order);
//删除购物车信息
redisService.deleteCart(user,ds);
return JsonResponseBody.success();
}
}
?将我们需要的参数一个一个注入进去即可下面实践一下
?
?
到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖
文章来源:https://blog.csdn.net/weixin_74318097/article/details/135362932
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!