当前位置: 首页 > news >正文

【基于SprintBoot+Mybatis+Mysql】电脑商城项目之显示勾选的购物车数据和创建订单

🧸安清h:个人主页 

   🎥个人专栏:【Spring篇】【计算机网络】【Mybatis篇】

🚦作者简介:一个有趣爱睡觉的intp,期待和更多人分享自己所学知识的真诚大学生。


目录

🚀1.显示勾选的购物车数据-持久层

✨1.1规划SQL语句

✨1.2设计接口和抽象方法

✨1.3配置SQL映射

🚀2.显示勾选的购物车数据-业务层

✨2.2设计接口和抽象方法

✨2.3完成抽象方法的设计 

🚀3.显示勾选的购物车数据-控制层

✨3.1设计请求

✨3.2处理请求

🚀4.1显示勾选的购物车数据-前端页面

🚀4.2购物车页面显示收货地址列表-前端页面

🎯1.创建订单-数据表

🎯2.创建订单-实体类

🎯3.创建订单-持久层

✨3.1规划SQL语句

✨3.2设计接口和抽象方法

✨3.3配置SQL映射

🎯4.创建订单-业务层

🎯5.创建订单-控制层

✨5.1设计请求

✨5.2处理请求

🎯6.创建订单-前端页面


🚀1.显示勾选的购物车数据-持久层

✨1.1规划SQL语句

1.用户在购物车列表中通过随即勾选相关的商品,在点击“结算”按钮后跳转到结算页面,在这个页面中需要展示用户在上个页面所勾选的购物车对应的数据。列表的展示,展示的内容还是来自于购物车表。两个页面需要将用户勾选的cid传递给下一个页面。

当前只要cid的值能够达到in里面的任意一个值,都属于满足整体的where条件。用户在前端所传递过来的这个?的值,在后台可以用一个集合来接收到,然后层层传递给mapper,mapper用一个集合来代替就行了,只要cid属于集合中任意一个数就符合条件了。

selectcid,uid,pid,t_cart.price,t_cart.num,title,t_product.price as realPrice,image
from t_cart
left join t_product on t_cart.pid = t_product.id
where cid in (?,?,?)
order by t_cart.created_time desc

✨1.2设计接口和抽象方法

List<CartVO> findVOByCid(Integer[] cids);

✨1.3配置SQL映射

    <select id="findVOByCid" resultType="com.cy.store.Vo.CartVO">selectcid,uid,pid,t_cart.price,t_cart.num,title,t_product.price as realPrice,imagefrom t_cartleft join t_product on t_cart.pid = t_product.idwhere cid in (<foreach collection="array" item="cid" separator=",">   --把每个cid拿到,中间用,分隔#{cid}</foreach>)order by t_cart.created_time desc</select>

进行单元测试

    @Testpublic void findVOByCids() {Integer[] cids = {1,2,3,9};System.out.println(cartMapper.findVOByCid(cids));}

🚀2.显示勾选的购物车数据-业务层

2.1查询语句,无异常规划。

✨2.2设计接口和抽象方法

List<CartVO> getVOByCid(Integer uid, Integer[] cids);

✨2.3完成抽象方法的设计 

@Overridepublic List<CartVO> getVOByCid(Integer uid,Integer[] cids) {List<CartVO> list = cartMapper.findVOByCid(cids);Iterator<CartVO> it = list.iterator();while (it.hasNext()) {CartVO cartVO = it.next();if (!cartVO.getUid().equals(uid)) { //表示当前的数据不属于当前的用户//从集合中移除这个元素list.remove(cartVO);}}return list;}

🚀3.显示勾选的购物车数据-控制层

✨3.1设计请求

请求路径:/carts/list

请求方式:POST

请求数据:Integer[] cids ,HttpSession session

响应结果:JsonResult<List<CartVO>>

✨3.2处理请求

    @RequestMapping("list")public JsonResult<List<CartVO>> getVOByCid(Integer[] cids, HttpSession session) {List<CartVO> data = cartService.getVOByCid(getuidFromSession(session), cids);return new JsonResult<>(OK, data);}

🚀4.1显示勾选的购物车数据-前端页面

1.把type属性改成submit,让其自动提交。

<input type="submit" value="  结  算  " class="btn btn-primary btn-lg link-account" />

2.orderConfirm.html页面中添加自动加载从上个页面中传递过来的cids数据,再去请求ajax,再在ajax中进行填充到当前的某个区域。

3.注释掉以下代码:

<script src="../js/orderConfirm.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">$(document).ready(function() {showCartList();});function showCartList() {$("#cart-list").empty();$.ajax({url: "/carts/list",type: "GET",data: location.search.substr(1),  //截问号后的第一个参数dataType: "JSON",success: function(json) {if (json.state == 200) {let list = json.data;let allCount = 0;let allPrice = 0;for (let i = 0; i < list.length; i++) {let tr = '<tr>\n' +'<td><img src="..#{image}collect.png" class="img-responsive" /></td>\n' +'<td>#{title}</td>\n' +'<td>¥<span>#{price}</span></td>\n' +'<td>#{num}</td>\n' +'<td><span>#{totalPrice}</span></td>\n' +'</tr>';tr = tr.replace("#{image}",list[i].image);tr = tr.replace("#{title}",list[i].title);tr = tr.replace("#{price}",list[i].realPrice);tr = tr.replace("#{num}",list[i].num);tr = tr.replace("#{totalPrice}",list[i].realPrice*list[i].num);$("#cart-list").append(tr);allCount += list[i].num;allPrice += list[i].realPrice*list[i].num;}$("#all-count").html(allCount);$("#all-price").html(allPrice);}},error: function (xhr) {alert("结算时发生未知的异常"+xhr.status);}});}
</script>

🚀4.2购物车页面显示收货地址列表-前端页面

1.收货地址存放在一个select下拉列表中,将查询到的当前登录用户的收货地址动态的加载到这个下拉列表中.从数据库的角度是一个select查询语句。已经编写了根据用户的uid来查询当前用户的收货地址数据。

2.orderConfirm.html页面中,收货地址数据的展示需要自动进行加载,需要将方法的逻辑放在ready函数中。

	$(document).ready(function() {showCartList();showAddressList();});
function showCartList() {$("#address-list").empty();$.ajax({url: "/addresses/",type: "GET",dataType: "JSON",success: function(json) {if (json.state == 200) {let list = json.data;for (let i = 0; i < list.length; i++) {var opt = '<option value="#{aid}">#{name}&nbsp;&nbsp;&nbsp;#{tag}&nbsp;&nbsp;&nbsp;#{provinceName}#{cityName}#{areaName}#{address}&nbsp;&nbsp;&nbsp;#{tel}</option>';opt = opt.replace("#{aid}",list[i].aid);opt = opt.replace("#{name}",list[i].name);opt = opt.replace("#{tag}",list[i].tag);opt = opt.replace("#{provinceName}",list[i].provinceName);opt = opt.replace("#{cityName}",list[i].cityName);opt = opt.replace("#{areaName}",list[i].areaName);opt = opt.replace("#{address}",list[i].address);opt = opt.replace("#{tel}",list[i].tel);$("#address-list").append(opt);}}},error: function (xhr) {alert("结算时发生未知的异常"+xhr.status);}});}

🎯1.创建订单-数据表

在数据库store中创建数据表t_order和t_order_item。

CREATE TABLE t_order (oid INT AUTO_INCREMENT COMMENT '订单id',uid INT NOT NULL COMMENT '用户id',recv_name VARCHAR(20) NOT NULL COMMENT '收货人姓名',recv_phone VARCHAR(20) COMMENT '收货人电话',recv_province VARCHAR(15) COMMENT '收货人所在省',recv_city VARCHAR(15) COMMENT '收货人所在市',recv_area VARCHAR(15) COMMENT '收货人所在区',recv_address VARCHAR(50) COMMENT '收货详细地址',total_price BIGINT COMMENT '总价',status INT COMMENT '状态:0-未支付,1-已支付,2-已取消,3-已关闭,4-已完成',order_time DATETIME COMMENT '下单时间',pay_time DATETIME COMMENT '支付时间',created_user VARCHAR(20) COMMENT '创建人',created_time DATETIME COMMENT '创建时间',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改时间',PRIMARY KEY (oid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;CREATE TABLE t_order_item (id INT AUTO_INCREMENT COMMENT '订单中的商品记录的id',oid INT NOT NULL COMMENT '所归属的订单的id',pid INT NOT NULL COMMENT '商品的id',title VARCHAR(100) NOT NULL COMMENT '商品标题',image VARCHAR(500) COMMENT '商品图片',price BIGINT COMMENT '商品价格',num INT COMMENT '购买数量',created_user VARCHAR(20) COMMENT '创建人',created_time DATETIME COMMENT '创建时间',modified_user VARCHAR(20) COMMENT '修改人',modified_time DATETIME COMMENT '修改时间',PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

🎯2.创建订单-实体类

在com.cy.store.entity包下创建Order类并使其继承基类。

public class Order extends BaseEntity {private Integer oid;private Integer uid;private String recvName;private String recvPhone;private String recvProvince;private String recvCity;private String recvArea;private String recvAddress;private Long totalPrice;private Integer status;private Date orderTime;private Date payTime;
。。。。。。
}    

在com.cy.store.entity包下创建OrderItem类并使其继承基类。 

public class OrderItem extends BaseEntity {private Integer id;private Integer oid;private Integer pid;private String title;private String image;private Long price;private Integer num;
......
} 

🎯3.创建订单-持久层

✨3.1规划SQL语句

1.将数据插入到订单表中。

insert into t_order (oid除外所有的字段) values (字段值)

2.将数据插入订单项表中。

insert into t_order_item (id除外所有的字段) values (字段值)

✨3.2设计接口和抽象方法

创建一个OrderMapper接口,接口中添加以上两个SQL对象的抽象方法。

public interface OrderMapper {/*** 插入订单数据* @param order 订单数据* @return 受影响的行数*/Integer insertOrder(Order order);/*** 插入订单项的数据* @param orderItem 订单项数据* @return 受影响的行数*/Integer insertOrderItem(OrderItem orderItem);
}

✨3.3配置SQL映射

1.创建OrderMapper.xml文件。 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.store.mapper.OrderMapper"><insert id="insertOrder" useGeneratedKeys="true" keyProperty="oid">insert into t_order (uid, recv_name, recv_phone, recv_province, recv_city, recv_area, recv_address,total_price,status, order_time, pay_time, created_user, created_time, modified_user,modified_time) values (#{uid}, #{recvName}, #{recvPhone}, #{recvProvince}, #{recvCity}, #{recvArea},#{recvAddress}, #{totalPrice}, #{status}, #{orderTime}, #{payTime}, #{createdUser},#{createdTime}, #{modifiedUser}, #{modifiedTime})</insert><insert id="insertOrderItem" useGeneratedKeys="true" keyProperty="id">insert into t_order_item (oid, pid, title, image, price, num, created_user,created_time, modified_user, modified_time) values (#{oid}, #{pid}, #{title}, #{image}, #{price}, #{num}, #{createdUser},#{createdTime}, #{modifiedUser}, #{modifiedTime})</insert>
</mapper>

2.单元测试。

   @Testpublic void insertOrder(){Order order = new Order();order.setUid(6);order.setRecvName("子敬");order.setRecvPhone("384570219");orderMapper.insertOrder(order);}@Testpublic void insertOrderItem(){OrderItem orderItem = new OrderItem();orderItem.setOid(1);orderItem.setPid(10000002);orderItem.setTitle("广博(GuangBo)皮面日程本子 计划记事本效率手册米色FB60322");orderMapper.insertOrderItem(orderItem);}

🎯4.创建订单-业务层

1.在IAddressService接口中定义根据收货地址的id获取收货地址的数据。

Address getByAid(Integer aid);

 2.实现方法。

@Overridepublic Address getByAid(Integer aid,Integer uid) {Address address  =addressMapper.findByAid(aid);if(address == null){throw new AddressNotFoundException("收货地址数据不存在");}if(address.getUid().equals(uid)){throw new AccessDeniedException("非法数据访问");}address.setProvinceCode(null);address.setCityCode(null);address.setAreaCode(null);address.setCreatedUser(null);address.setCreatedTime(null);address.setModifiedUser(null);address.setModifiedTime(null);return address;}

3.在service包下创建IOrderService接口添加抽象方法用于创建订单。

public interface IOrderService {Address create(Integer aid,Integer uid,String username,Integer[] cids);
}

4.创建实现类OrderServiceImpl。

    @Autowiredprivate OrderMapper orderMapper;@Autowiredprivate IAddressService addressService;@Autowiredprivate ICartService cartService;@Overridepublic Order create(Integer aid, Integer uid, String username, Integer[] cids) {//即将要下单的列表List<CartVO> list = cartService.getVOByCid(uid,cids);//计算商品的总价Long totaolPrice = 0L;Address address = addressService.getByAid(aid, uid);Order order = new Order();order.setUid(uid);//收货地址数据order.setRecvName(address.getName());order.setRecvPhone(address.getPhone());order.setRecvProvince(address.getProvinceName());order.setRecvCity(address.getCityName());order.setRecvArea(address.getAreaName());order.setRecvAddress(address.getAddress());//支付,总价,时间order.setStatus(0);order.setTotalPrice(totaolPrice);order.setOrderTime(new Date());//日志order.setCreatedUser(username);order.setCreatedTime(new Date());order.setModifiedUser(username);order.setModifiedTime(new Date());Integer rows = orderMapper.insertOrder(order);if(rows != 1){throw new InsertException("插入时异常");}//创建订单详细项的数据for(CartVO c : list){//创建一个订单项数据对象OrderItem orderItem = new OrderItem();orderItem.setOid(order.getOid());orderItem.setPid(c.getPid());orderItem.setTitle(c.getTitle());orderItem.setImage(c.getImage());orderItem.setPrice(c.getPrice());orderItem.setNum(c.getNum());//日志字段orderItem.setCreatedUser(username);orderItem.setCreatedTime(new Date());orderItem.setModifiedUser(username);orderItem.setModifiedTime(new Date());//插入数据操作rows = orderMapper.insertOrderItem(orderItem);if(rows != 1){throw new InsertException("插入时异常");}orderMapper.insertOrderItem(orderItem);}return order;}

5.创建测试方法并完成测试。

@SpringBootTest
public class OrderServiceTests {@Autowiredprivate IOrderService orderService;@Testpublic void create(){Integer[] cids = {3,4};Order order = orderService.create(12,6,"小明",cids);System.out.println(order);}}

🎯5.创建订单-控制层

✨5.1设计请求

 请求路径:/orders/create/

请求参数:Integer aid,Integer[] cids,HttpSession session

请求类型:POST

响应结果:JsonResult<Order>

✨5.2处理请求

创建一个OrderController类,并编写处理请求方法。

@RequestMapping("/orders/")
@RestController
public class OrderController extends BaseController{@Autowiredprivate IOrderService orderService;@RequestMapping("create")public JsonResult<Order> create(Integer aid, Integer[] cids, HttpSession session){Order data = orderService.create(aid,getuidFromSession(session),getUsernameFromSession(session),cids);return new JsonResult<>(OK,data);}
}

🎯6.创建订单-前端页面

在订单确定页面中添加发送请求的处理方法。

	$("#btn-create-order").click(function() {let aid = $("#address-list").val();let cids = location.search.substr(1);$.ajax({url: "/orders/create",type: "GET",data: "aid="+aid + "&" + cids,dataType: "JSON",success: function(json) {if (json.state == 200) {location.href = "payment.html";alert("订单创建成功");console.log(json.data) //调试} else {alert("创建订单失败" + json.message);}},error: function(xhr) {alert("创建订单数据时产生未知的异常" + xhr.status);}});});

感谢各位的陪伴,最后一篇也更完啦🎉🎉🎉

相关文章:

  • spark和Hadoop之间的对比和联系
  • 【C++】特殊类的设计、单例模式以及Cpp类型转换
  • 明远智睿2351开发板四核1.4G Linux处理器:驱动创新的引擎
  • 实现鼠标拖拽图片效果
  • 搜索引擎的高级语法
  • 【Spring】单例模式的创建方式(Bean解析)
  • 并发设计模式实战系列(3):工作队列
  • 【后端】构建简洁的音频转写系统:基于火山引擎ASR实现
  • C# 实现TCP/IP通信协议——Message结构设计
  • 变更管理 Change Management
  • 基于 Electron、Vue3 和 TypeScript 的辅助创作工具全链路开发方案:涵盖画布系统到数据持久化的完整实现
  • 【前端记事】关于electron的入门使用
  • Spring Boot 启动生命周期详解
  • 通俗的理解TCP的三次握手四次挥手
  • 高级java每日一道面试题-2025年4月21日-基础篇[反射篇]-如何使用反射获取一个类的所有方法?
  • Pikachu靶场-RCE漏洞
  • 三网通电玩城平台系统结构与源码工程详解(三):控制台与银商权限模块设计
  • Linux虚拟机中 编译Linux源码 记录
  • spark和Hadoop之间的对比与联系
  • wps批量修改字体
  • 天启年间故宫“三殿”重修与晚明财政
  • 十二届上海市委第六轮巡视全面进驻,巡视组联系方式公布
  • 两部门调度部署“五一”假期安全防范工作,要求抓好旅游安全
  • 城市更新·简报│中央财政支持城市更新,倾斜超大特大城市
  • 结婚这件事,年轻人到底怎么想的?
  • 国泰海通合并后首份业绩报告出炉:一季度净利润增逾391%