【SpringBoot】电脑商城-12-订单功能

创建订单

1 订单-创建数据表

1.使用use命令先选中store数据库。

USE store;

2.在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 订单-创建实体类

1.在com.cy.store.entity包下创建Order实体类。

package com.cy.store.entity;
import java.io.Serializable;
import java.util.Date;/** 订单数据的实体类 */
public class Order extends BaseEntity implements Serializable {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;// Generate: Getter and Setter、Generate hashCode() and equals()、toString()
}    

2.在com.cy.store.entity包下创建OrderItem实体类。

package com.cy.store.entity;
import java.io.Serializable;/** 订单中的商品数据 */
public class OrderItem extends BaseEntity implements Serializable {private Integer id;private Integer oid;private Integer pid;private String title;private String image;private Long price;private Integer num;// Generate: Getter and Setter、Generate hashCode() and equals()、toString()
}    

3 订单-持久层

3.1 规划需要执行的SQL语句

1.插入订单数据的SQL语句大致是。

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 (#对应字段的值列表
)

2.插入订单商品数据的SQL语句大致是。

INSERT INTO t_order_item ( oid, pid, title, image, price, num, created_user, created_time, modified_user, modified_time 
)
VALUES ( #对应字段的值列表
)
3.2 接口与抽象方法

在com.cy.store.mapper包下创建OrderMapper接口并在接口中添加抽象方法。

package com.cy.store.mapper;
import com.cy.store.entity.Order;
import com.cy.store.entity.OrderItem;/** 处理订单及订单商品数据的持久层接口 */
public interface OrderMapper {/*** 插入订单数据* @param order 订单数据* @return 受影响的行数*/Integer insertOrder(Order order);/*** 插入订单商品数据* @param orderItem 订单商品数据* @return 受影响的行数*/Integer insertOrderItem(OrderItem orderItem);
}
3.3 配置SQL映射

1.在main\resources\mapper文件夹下创建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"><!-- 插入订单数据:Integer insertOrder(Order order) --><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><!-- 插入订单商品数据:Integer insertOrderItem(OrderItem orderItem) --><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.在com.cy.store.mapper包下创建OrderMapperTests测试类,并添加测试方法。

package com.cy.store.mapper;
import com.cy.store.entity.Order;
import com.cy.store.entity.OrderItem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderMapperTests {@Autowiredprivate OrderMapper orderMapper;@Testpublic void insertOrder() {Order order = new Order();order.setUid(31);order.setRecvName("小王");Integer rows = orderMapper.insertOrder(order);System.out.println("rows=" + rows);}@Testpublic void insertOrderItem() {OrderItem orderItem = new OrderItem();orderItem.setOid(1);orderItem.setPid(2);orderItem.setTitle("高档铅笔");Integer rows = orderMapper.insertOrderItem(orderItem);System.out.println("rows=" + rows);}
}

4 订单-业务层

4.1 规划异常

说明:无异常。

4.2 接口与抽象方法

1.由于处理过程中还需要涉及收货地址数据的处理,所以需要先在IAddressService接口中添加getByAid()方法。

/*** 根据收货地址数据的id,查询收货地址详情* @param aid 收货地址id* @param uid 归属的用户id* @return 匹配的收货地址详情*/
Address getByAid(Integer aid, Integer uid);

2.在AddressServiceImpl类中实现接口中的getByAid()抽象方法。

@Override
public Address getByAid(Integer aid, Integer uid) {// 根据收货地址数据id,查询收货地址详情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.在com.cy.store.service包下创建IOrderService业务层接口并添加抽象方法。

package com.cy.store.service;
import com.cy.store.entity.Order;/** 处理订单和订单数据的业务层接口 */
public interface IOrderService {/*** 创建订单* @param aid 收货地址的id* @param cids 即将购买的商品数据在购物车表中的id* @param uid 当前登录的用户的id* @param username 当前登录的用户名* @return 成功创建的订单数据*/Order create(Integer aid, Integer[] cids, Integer uid, String username);
}
4.3 实现抽象方法

1.在com.cy.store.service.impl包下创建OrderServiceImpl业务层实现类并实现IOrderService接口;在类定义之前添加@Service注解,在类中添加OrderMapper订单持久层对象、IAddressService处理收货地址对象、ICartService购物车数据对象,并都添加@Autowired注解进行修饰。

package com.cy.store.service.impl;
import com.cy.store.entity.Address;
import com.cy.store.entity.Order;
import com.cy.store.entity.OrderItem;
import com.cy.store.mapper.OrderMapper;
import com.cy.store.service.IAddressService;
import com.cy.store.service.ICartService;
import com.cy.store.service.IOrderService;
import com.cy.store.service.ex.InsertException;
import com.cy.store.vo.CartVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;/** 处理订单和订单数据的业务层实现类 */
@Service
public class OrderServiceImpl implements IOrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate IAddressService addressService;@Autowiredprivate ICartService cartService;// ...
}

2.在OrderServiceImpl类中重写父接口中的create()抽象方法。

@Transactional
@Override
public Order create(Integer aid, Integer[] cids, Integer uid, String username) {// 创建当前时间对象// 根据cids查询所勾选的购物车列表中的数据// 计算这些商品的总价// 创建订单数据对象// 补全数据:uid// 查询收货地址数据// 补全数据:收货地址相关的6项// 补全数据:totalPrice// 补全数据:status// 补全数据:下单时间// 补全数据:日志// 插入订单数据// 遍历carts,循环插入订单商品数据// 创建订单商品数据// 补全数据:oid(order.getOid())// 补全数据:pid, title, image, price, num// 补全数据:4项日志// 插入订单商品数据// 返回
}

3.OrderServiceImpl类中的create()方法具体逻辑代码实现见下。

@Transactional
@Override
public Order create(Integer aid, Integer[] cids, Integer uid, String username) {// 创建当前时间对象Date now = new Date();// 根据cids查询所勾选的购物车列表中的数据List<CartVO> carts = cartService.getVOByCids(uid, cids);// 计算这些商品的总价long totalPrice = 0;for (CartVO cart : carts) {totalPrice += cart.getRealPrice() * cart.getNum();}// 创建订单数据对象Order order = new Order();// 补全数据:uidorder.setUid(uid);// 查询收货地址数据Address address = addressService.getByAid(aid, uid);// 补全数据:收货地址相关的6项order.setRecvName(address.getName());order.setRecvPhone(address.getPhone());order.setRecvProvince(address.getProvinceName());order.setRecvCity(address.getCityName());order.setRecvArea(address.getAreaName());order.setRecvAddress(address.getAddress());// 补全数据:totalPriceorder.setTotalPrice(totalPrice);// 补全数据:statusorder.setStatus(0);// 补全数据:下单时间order.setOrderTime(now);// 补全数据:日志order.setCreatedUser(username);order.setCreatedTime(now);order.setModifiedUser(username);order.setModifiedTime(now);// 插入订单数据Integer rows1 = orderMapper.insertOrder(order);if (rows1 != 1) {throw new InsertException("插入订单数据时出现未知错误,请联系系统管理员");}// 遍历carts,循环插入订单商品数据for (CartVO cart : carts) {// 创建订单商品数据OrderItem item = new OrderItem();// 补全数据:setOid(order.getOid())item.setOid(order.getOid());// 补全数据:pid, title, image, price, numitem.setPid(cart.getPid());item.setTitle(cart.getTitle());item.setImage(cart.getImage());item.setPrice(cart.getRealPrice());item.setNum(cart.getNum());// 补全数据:4项日志item.setCreatedUser(username);item.setCreatedTime(now);item.setModifiedUser(username);item.setModifiedTime(now);// 插入订单商品数据Integer rows2 = orderMapper.insertOrderItem(item);if (rows2 != 1) {throw new InsertException("插入订单商品数据时出现未知错误,请联系系统管理员");}}// 返回return order;
}

4.在com.cy.store.service测试包下创建OrderServiceTests测试类,并添加create()方法进行功能测试。

package com.cy.store.service;
import com.cy.store.entity.Order;
import com.cy.store.service.ex.ServiceException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderServiceTests {@Autowiredprivate IOrderService orderService;@Testpublic void create() {try {Integer aid = 21;Integer[] cids = {4, 5, 6,7};Integer uid = 31;String username = "订单管理员";Order order = orderService.create(aid, cids, uid, username);System.out.println(order);} catch (ServiceException e) {System.out.println(e.getClass().getSimpleName());System.out.println(e.getMessage());}}
}

5 订单-控制器层

5.1 处理异常

说明:无异常。

5.2 设计请求

设计用户提交的请求,并设计响应的方式。

请求路径:/orders/create
请求参数:Integer aid, Integer[] cids, HttpSession session
请求类型:POST
响应结果:JsonResult<Order>
5.3 处理请求

1.在com.cy.store.controller包下创建OrderController类,并继承自BaseController类;并在类前添加@RequestMapping(“orders”)注解和@RestController注解;在类中声明IOrderService业务对象,然后添加@Autowired注解修饰;最后在类中添加处理请求的方法。

package com.cy.store.controller;
import com.cy.store.entity.Order;
import com.cy.store.service.IOrderService;
import com.cy.store.util.JsonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;@RestController
@RequestMapping("orders")
public class OrderController extends BaseController {@Autowiredprivate IOrderService orderService;@RequestMapping("create")public JsonResult<Order> create(Integer aid, Integer[] cids, HttpSession session) {// 从Session中取出uid和usernameInteger uid = getUidFromSession(session);String username = getUsernameFromSession(session);// 调用业务对象执行业务Order data = orderService.create(aid, cids, uid, username);// 返回成功与数据return new JsonResult<Order>(OK, data);}
}

2.完成后启动项目,先登录再访问http://localhost:8080/orders/create?aid=21&cids=4&cids=5&cids=6&cids=7进行测试。
在这里插入图片描述

6 订单-前端页面

1.在orderConfirm.xml页面中的body标签内的script标签内添加“在线支付”按钮的点击时间。

$("#btn-create-order").click(function() {$.ajax({url: "/orders/create",data: $("#form-create-order").serialize(),type: "POST",dataType: "JSON",success: function(json) {if (json.state == 200) {alert("创建订单成功!");console.log(json.data);} else {alert("创建订单失败!" + json.message);}},error: function(xhr) {alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);location.href = "login.html";}});
});

2.完成后启动项目,先登录再访问http://localhost:8080/web/cart.html页面,勾选购车中的商品,再点击“结算”按钮,最后在订单确认页中点击“在线支付”按钮进行功能的测试。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/418631.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mac 上 YYDS 的自动切换输入法工具:好用到原地炸裂式起飞

有一种幸福的状态就是 任何时刻你都可以全力以赴 被打断、被终止也没有遗憾 因为你对结果没有那么期待 而且已经用尽全力了 当你深刻认识到你所做的事情 是多么好的时候 自然会产生一种想要分享出去 的心情 如今社会大部分工作都被电脑化了&#xff0c;在很多方面我们的…

第140天:内网安全-横向移动局域网ARP欺骗DNS劫持钓鱼中间人单双向

目录 案例一&#xff1a;局域网&工作组-ARP原理-断网限制-单向 案例二&#xff1a;局域网&工作组-ARP欺骗-劫持数据-双向 案例三&#xff1a;局域网&工作组-DNS 劫持-钓鱼渗透-双向 案例一&#xff1a;局域网&工作组-ARP原理-断网限制-单向 原理&#xff1…

数据库MySQL基础

目录 一、数据库的介绍 1.数据库概述 &#xff08;1&#xff09;数据的存储方式 &#xff08;2&#xff09;数据库 2.常见数据库排行榜 二、数据库的安装与卸载 1.数据库的安装 2.数据库的卸载 三、数据库服务的启动与登录 1.Windows 服务方式启动 &#xff08;1&…

Java反序列化漏洞-TemplatesImpl利用链分析

文章目录 一、前言二、正文1. 寻找利用链2. 构造POC2.1 生成字节码2.2 加载字节码1&#xff09;getTransletInstance2&#xff09;defineTransletClasses 2.3 创建实例 3. 完整POC 三、参考文章 一、前言 java.lang.ClassLoader#defineClass defineClass可以加载字节码&…

相机常见名词详解

本文主要参考超人视觉课程做的笔记&#xff0c;有讲解不太懂的&#xff0c;又做了详细的解释 1、物距&#xff1a;物体到镜片的距离&#xff1b; 2、像距&#xff1a;像到镜片的距离&#xff1b; 3、焦距&#xff1a;镜片到焦点的距离&#xff1b; (1)二倍焦距以外&#xff…

AF路由模式组网部署

实验拓扑 防火墙基本配置 接口配置 eth1 eth2 eth3 路由配置 地址转换配置 放通策略 1. 出口申请了主电信、备联通两条外网线路&#xff08;均为 50M 带宽&#xff09;。 2. 内网有 web 服务器linux 172.16.3.100运行 http 服务&#xff0c;内外网用户通过 出口路由器…

用PG Back Web轻松进行PostgreSQL备份

什么是 PG Back Web &#xff1f; PG Back Web &#x1f418; 使用用户友好的 Web 界面轻松进行 PostgreSQL 备份&#xff01;&#x1f310;&#x1f4be;。PG Back Web 不仅仅是另一个备份工具。借助 PG Back Web&#xff0c;用户可以通过受 PGP 加密保护的直观 Web 界面轻松安…

【redis】数据量庞大时的应对策略

文章目录 为什么数据量多了主机会崩分布式系统应用数据分离架构应用服务集群架构负载均衡器数据库读写分离 引入缓存冷热分离架构 分库分表微服务是什么代价优势 为什么数据量多了主机会崩 一台主机的硬件资源是有上限的&#xff0c;包括但不限于一下几种&#xff1a; CPU内存…

【Postgresql】地理空间数据的存储与查询,查询效率优化策略,数据类型与查询速度的影响

注&#xff1a;使用postgresql数据库会用到PostGIS 扩展。 一、安装PostGIS 扩展 在 PostgreSQL 中遇到错误 “type geography does not exist” 通常意味着你的 PostgreSQL 数据库还没有安装 PostGIS 扩展&#xff0c;或者 PostGIS 扩展没有被正确地安装在你的数据库中。geo…

我司使用了两年的高效日志打印工具,非常牛逼!

为了更方便地排查问题&#xff0c;电商交易系统的日志中需要记录用户id和订单id等字段。然而&#xff0c;每次打印日志都需要手动设置用户id&#xff0c;这一过程非常繁琐&#xff0c;需要想个办法优化下。 log.warn("user:{}, orderId:{} 订单提单成功",userId, or…

linux服务器之top命令详解

top&#xff1a;系统资源管理器 top命令类似于windows的任务管理器&#xff0c;可以查看内存、cpu、进程等信息(动态查看系统资源信息)在linux系统中常用top命令查看资源性能分析工具 一、参数释义&#xff1a; 第一行 系统时间和平均负载 top&#xff1a;名称22:12:46&#…

Spring Boot 部署方案!打包 + Shell 脚本详解

本篇和大家分享的是springboot打包并结合shell脚本命令部署&#xff0c;重点在分享一个shell程序启动工具&#xff0c;希望能便利工作&#xff1b; profiles指定不同环境的配置 maven-assembly-plugin打发布压缩包 分享shenniu_publish.sh程序启动工具 linux上使用shenniu_p…

一文梳理RAG(检索增强生成)的现状与挑战

一 RAG简介 大模型相较于过去的语言模型具备更加强大的能力&#xff0c;但在实际应用中&#xff0c;例如在准确性、知识更新速度和答案透明度方面&#xff0c;仍存在不少问题&#xff0c;比如典型的幻觉现象。因此&#xff0c;检索增强生成 (Retrieval-Augmented Generation, …

哪种超声波清洗机效果好?较好的超声波眼镜清洗机品牌推荐

作为一名拥有20年戴镜经验的眼镜爱好者&#xff0c;我深深体会到眼镜清洁的挑战&#xff1a;微小缝隙里的污垢难以触及&#xff0c;频繁的脏污让我苦于找不到清洁时机&#xff0c;而用力不当的擦拭方法更是可能对眼镜特别是镜片造成伤害&#xff0c;这确实让人感到苦恼&#xf…

Java专栏介绍

专栏导读 在当今这个技术飞速发展的时代&#xff0c;Java作为一门成熟且广泛应用的编程语言&#xff0c;一直是软件开发领域的中坚力量。本“Java技术”专栏旨在帮助读者深入理解Java编程语言的精髓&#xff0c;掌握其核心概念与高级特性&#xff0c;并通过实战案例提升编程技…

字符编码转换

文章目录 1. 背景2. 解决方案3. 编码转换实现3.1 shell实现3.2 python实现3.3 开源工具实现 4. 常见中文字符编码介绍4.1 字符编码解决什么问题4.2 常见的中文字符编码4.3 常见中文字符编码关系4.4 unicide字符集与utf-8 1. 背景 在团队合作开发中&#xff0c;经常发现组员的代…

Redis安装步骤——离线安装与在线安装详解

Linux环境下Redis的离线安装与在线安装详细步骤 环境信息一、离线安装1、安装环境2、下载redis安装包3、上传到服务器并解压4、编译redis5、安装redis6、配置redis&#xff08;基础配置&#xff09;7、启动redis8、本机访问redis9、远程访问redis 二、在线安装1、更新yum源2、安…

k8s 高级调度

搞懂Kubernetes调度 K8S调度器Kube-schduler的主要作用是将新创建的Pod调度到集群中的合适节点上运行。kube-scheduler的调度算法非常灵活&#xff0c;可以根据不同的需求进行自定义配置&#xff0c;比如资源限制、亲和性和反亲和性等。 kube-scheduler的工作原理如下&#x…

基于SpringBoot+Vue+MySQL的宿舍维修管理系统

系统展示 前台界面 管理员界面 维修员界面 学生界面 系统背景 在当今高校后勤管理的日益精细化与智能化背景下&#xff0c;宿舍维修管理系统作为提升校园生活品质、优化资源配置的关键环节&#xff0c;其重要性日益凸显。随着学生规模的扩大及住宿条件的不断提升&#xff0c;宿…

Qt/C++ 个人开源项目#串口助手(源码与发布链接)

一、项目概述 该串口助手工具基于Qt/C开发&#xff0c;专为简化串口通信调试与开发而设计&#xff0c;适合新手快速上手。工具具有直观的用户界面和丰富的功能&#xff0c;旨在帮助用户与串口设备建立可靠通信&#xff0c;便于调试、数据传输和分析。 二、主要功能 波特率&a…