SpingBoot的项目实战--模拟电商【4.订单及订单详情的生成】
2024-01-07 18:58:14
🥳🥳Welcome Huihui's Code World ! !🥳🥳
接下来看看由辉辉所写的关于SpringBoot电商项目的相关操作吧?
目录
🥳🥳Welcome Huihui's Code World ! !🥳🥳
?一.功能需求
①订单的显示
②订单的结算【订单项新增,订单新增】
③订单生成之后,需要将购物车中的信息清除掉
二.代码编写
1.订单的显示
前端
这里的js是点击去结算按钮,跳转到订单的显示界面
js
/****************************订单结算*******************************/ $(".count").click(function(){ let ids=[] $(".th").each((i,el)=>{ //子复选框--选中状态 let flag =$(el).find('input[type=checkbox]').prop('checked') //如果元素被选择了 if(flag){ let id=$(el).find('.mynum').attr('data-gid') ids.push(id) } }) //如果没有选择商品,则不做操作 if(ids.length===0)return //如果选择了商品则跳转页面 //跳转页面需要将选中的商品的id带过去 ids=ids.join(",") location.href='/cart/toOrder?ids='+ids })
然后在界面上遍历集合,显示出来元素即可
html
<!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</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"> <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"> <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}/shopCar/queryShopCar" class="fr">返回购物车</a></h3> <#assign total=0> <#list cart as c> <#assign total=total+c.xj()> <ul class="clearfix"> <li class="fl"> <img src="${(c.goodsImg)!}" style="height: 100px; width: 100px;"> </li> <li class="fl"> <p>${(c.goodsName)!}</p> <p>数量:${(c.num)!}</p> </li> <li class="fr">¥${(c.xj())!}</li> </ul> </#list> </div> <!--------tips----------------> <div class="tips"> <p><span class="fl">商品金额:</span><span class="fr">¥${total}</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">¥${total}</span></p> </div> <!--<input type="button" name="" value="去支付"> --> <a href="javascript:void(0);" class="pay" data-ids="${RequestParameters['ids']}">去支付</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/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>
后端
其中在订单页面显示的就是当前用户所勾选的商品,那么就是需要拿到用户勾选的商品的id集合到数据库中查询对应购物车信息即可
service
package com.wh.easyshop.service; import com.wh.easyshop.model.User; import com.wh.easyshop.vo.CartVo; import java.util.List; public interface IRedisService { /** * 拿到当前用户购物车中的指定商品 * @param user * @param ids * @return */ List<CartVo> loadCart(User user,String ids); }
package com.wh.easyshop.service; import com.wh.easyshop.model.User; import com.wh.easyshop.util.Constants; import com.wh.easyshop.vo.CartVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @Service public class RedisServiceImpl implements IRedisService { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 拿到对应的商品 * @param user * @param ids * @return */ @Override public List<CartVo> loadCart(User user, String ids) { //获取操Redi中hash类型数据对象--通过其将购物车存入到缓存中 HashOperations<String, String , CartVo> rediscart = redisTemplate.opsForHash(); //大键【hash的键】 String hashKey=Constants.REDIS_CART_PREFIX + user.getId(); List<String> myids = Arrays.asList(ids.split(",")); return rediscart.multiGet(hashKey, myids); } }
controller
其中还是先去redis中拿到对应的商品id的集合
再通过 id去数据库中拿到对应的商品信息
? ? ? ?package com.wh.easyshop.controller; import com.wh.easyshop.model.Goods; import com.wh.easyshop.model.User; import com.wh.easyshop.resp.JsonResponseBody; import com.wh.easyshop.service.IGoodsService; import com.wh.easyshop.service.IRedisService; import com.wh.easyshop.util.CookieUtils; import com.wh.easyshop.vo.CartVo; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import javax.jws.WebParam; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** * <p> * 购物车 前端控制器 * </p> * * @author wh * @since 2024-1-2 */ @Controller @RequestMapping("/cart") public class CartController { @Autowired IRedisService redisService; @Autowired IGoodsService goodsService; @RequestMapping("/toOrder") public String order (User user,String ids, Model model) { List<CartVo> usercart = redisService.loadCart(user,ids);//使用参数解析器 //拿出所有的购物车中的商id--集合 List<Long> usercartids = usercart.stream().map(CartVo::getGid).collect(Collectors.toList()); //根据这个id集合查询所有对应的商品 List<Goods> goods = goodsService.listByIds(usercartids); //遍历集合 赋值给对应的对象 for (Goods g : goods) { //找到对应id相同的元素 CartVo vo = usercart.stream() .filter(v -> Objects.equals(v.getGid(), g.getGid())) .findFirst() .get(); //将商品g的属性赋值给vo【这样vo中的属性就有数据了】 BeanUtils.copyProperties(g,vo); } model.addAttribute("cart",usercart); return "order"; } }
效果预览
2.订单结算
这里无论你是否支付成功,都需要先将订单以及订单详情生成【怕用户点击支付支付之后却又取消支付了,如果没有在点击支付的时候就是生成订单,那么用户取消支付后,就无法找到这个订单的信息了】
关于表信息,在这篇博文中
前端
js
这里面需要传递到后端的数据【收货人,手机号...】,都是在页面上面获取,这里因为没有设计那张表了,所以就直接采取这种方式了
首先是需要拿到我们选中的框
当我选中这个框的时候,发现上面会出现一个on的class属性【选中的元素即是这样】,所以就拿到当前有on属性的框
再通过这个框去拿取框中的元素
然后将这些从页面上拿到的属性,封装成一个对象,传递到后端
/****************************去支付*******************************/ $(".pay").click(function(){ //拿到当前所选择的个人信息框【选中的框会有一个on】 let mydiv=$(".addres").find(".on"); //收货人 let person=mydiv.find(".tit .fl").text(); //地址 let address=mydiv.find(".addCon p:first-child").text(); //手机号 let telephone=mydiv.find(".addCon p:last-child").text(); //支付方式 let pay=$(".way .on ").attr("value"); //快递 let mail=$(".dis .on ").text(); //商品的id let ids= $(this).attr("data-ids"); let order={ person, address, telephone, pay, mail, ids } $.post('/order/addOrder',order,resp=>{ if(resp.code===200){ alert("订单生成成功") } },'json') })
html
<!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</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"> <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"> <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}/shopCar/queryShopCar" class="fr">返回购物车</a></h3> <#assign total=0> <#list cart as c> <#assign total=total+c.xj()> <ul class="clearfix"> <li class="fl"> <img src="${(c.goodsImg)!}" style="height: 100px; width: 100px;"> </li> <li class="fl"> <p>${(c.goodsName)!}</p> <p>数量:${(c.num)!}</p> </li> <li class="fr">¥${(c.xj())!}</li> </ul> </#list> </div> <!--------tips----------------> <div class="tips"> <p><span class="fl">商品金额:</span><span class="fr">¥${total}</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">¥${total}</span></p> </div> <!--<input type="button" name="" value="去支付"> --> <a href="javascript:void(0);" class="pay" data-ids="${RequestParameters['ids']}">去支付</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/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>
后端
service
这里跟显示订单详情是一样的,要拿到当前用户所选取的商品id再去数据库中查询商品信息,后面的生成订单详情以及生成订单的方法都是mybatis-plus自带的接口
package com.wh.easyshop.service; import com.wh.easyshop.model.User; import com.wh.easyshop.vo.CartVo; import java.util.List; public interface IRedisService { /** * 拿到当前用户购物车中的指定商品 * @param user * @param ids * @return */ List<CartVo> loadCart(User user,String ids); }
package com.wh.easyshop.service; import com.wh.easyshop.model.User; import com.wh.easyshop.util.Constants; import com.wh.easyshop.vo.CartVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @Service public class RedisServiceImpl implements IRedisService { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 拿到对应的商品 * @param user * @param ids * @return */ @Override public List<CartVo> loadCart(User user, String ids) { //获取操Redi中hash类型数据对象--通过其将购物车存入到缓存中 HashOperations<String, String , CartVo> rediscart = redisTemplate.opsForHash(); //大键【hash的键】 String hashKey=Constants.REDIS_CART_PREFIX + user.getId(); List<String> myids = Arrays.asList(ids.split(",")); return rediscart.multiGet(hashKey, myids); } }
controller
其中都有详细的代码注释,在这就不过多的去阐述了
package com.wh.easyshop.controller; import com.github.yitter.idgen.YitIdHelper; import com.wh.easyshop.model.Goods; import com.wh.easyshop.model.Order; import com.wh.easyshop.model.OrderItem; import com.wh.easyshop.model.User; import com.wh.easyshop.resp.JsonResponseBody; import com.wh.easyshop.service.IGoodsService; import com.wh.easyshop.service.IOrderItemService; import com.wh.easyshop.service.IOrderService; import com.wh.easyshop.service.IRedisService; import com.wh.easyshop.vo.CartVo; import com.wh.easyshop.vo.OrderVo; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * <p> * 订单信息表 前端控制器 * </p> * * @author wh * @since 2023-12-27 */ @RestController @RequestMapping("/order") public class OrderController { @Autowired IRedisService redisService; @Autowired IGoodsService goodsService; @Autowired IOrderItemService iOrderItemService; @Autowired IOrderService iOrderService; @RequestMapping("/addOrder") public JsonResponseBody<?> order (User user, OrderVo orderVo) { //拿到其中的商品id String ids = orderVo.getIds(); //拿到购物车中指定的商品【数量和id】 List<CartVo> cartVos = redisService.loadCart(user, ids); List<Long> ds = cartVos.stream().map(CartVo::getGid).collect(Collectors.toList()); //拿到数据库中的内容【名字,价格】 List<Goods> goods = goodsService.listByIds(ds); //遍历集合 赋值给对应的对象 for (Goods g : goods) { //找到对应id相同的元素 CartVo vo = cartVos.stream() .filter(v -> Objects.equals(v.getGid(), g.getGid())) .findFirst() .get(); //将商品g的属性赋值给vo【这样vo中的属性就有数据了】 BeanUtils.copyProperties(g,vo); } //订单中的总价 BigDecimal total =new BigDecimal(0); //生成订单详情 //需要订单id【雪花id生成】 long oid = YitIdHelper.nextId(); //使用集合将需要加进去的订单详情装起来【使用批处理一次性处理掉】 List<OrderItem> orderItemList=new ArrayList<>(); for (CartVo cartVo : cartVos) { //订单详情 OrderItem orderItem = new OrderItem(); //将vo类的属性赋值给orderitem【共有的属性赋值】 BeanUtils.copyProperties(cartVo,orderItem); //还有一个数量的值没有赋成功【因为两个实体中的这个属性名字不一样】 orderItem.setQuantity(cartVo.getNum()); //设置订单详情的id orderItem.setOoid(YitIdHelper.nextId()); //设置订单id orderItem.setOid(oid); //将订单详情加入到订单详情的集合中 orderItemList.add(orderItem); //计算总价 total=total.add(cartVo.xj()); } //将生成的额订单详情加入到数据库中 iOrderItemService.saveBatch(orderItemList,5); //生成订单 Order order = new Order(); //将其中的ordervo的属性赋值给order BeanUtils.copyProperties(orderVo,order); //总价 order.setTotal(total); //用户id order.setUserId(user.getId()); //订单生成时间 order.setCreateDate(new Date()); //订单状态【0 未支付】 order.setStatus(0); //将生成的订单加入到数据库 iOrderService.save(order); //订单生成成功之后需要将购物车中的信息删除 String ids1 = orderVo.getIds(); List<String> delids = Arrays.asList(ids1.split(",")); redisService.delCart(delids,user); return JsonResponseBody.success(); } }
3.清除购物车信息
代码
package com.wh.easyshop.service; import com.wh.easyshop.model.User; import com.wh.easyshop.vo.CartVo; import java.util.List; public interface IRedisService { /** * 删除购物车 * @param ids * @param user */ void delCart(List<String> ids, User user); }
package com.wh.easyshop.service; import com.wh.easyshop.model.User; import com.wh.easyshop.util.Constants; import com.wh.easyshop.vo.CartVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @Service public class RedisServiceImpl implements IRedisService { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 删除购物车 * @param ids * @param user */ @Override public void delCart(List<String> ids, User user) { //获取操Redi中hash类型数据对象--通过其将购物车存入到缓存中 HashOperations<String, String , CartVo> rediscart = redisTemplate.opsForHash(); //大键【hash的键】 String hashKey=Constants.REDIS_CART_PREFIX + user.getId(); for (String id : ids) { rediscart.delete(hashKey, id); } } }
效果预览
好啦,今天的分享就到这了,希望能够帮到你呢!😊😊??
文章来源:https://blog.csdn.net/m0_74315688/article/details/135368643
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!