SpringBoot电脑商城项目--创建订单+统计业务方法耗时

发布于:2025-06-23 ⋅ 阅读:(18) ⋅ 点赞:(0)

创建订单

1. 创建数据库表

        一共有两个表,一个是订单表,一个是订单商品表,两张表差不太多,order表是记录有这么一个订单,orderItem表可以用于订单列表的展示

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. 创建对应的实体类

  • 订单Order实体类
package com.cy.store.entity;

import lombok.Data;

import java.util.Date;

/** 订单数据的实体类 */
@Data
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;
}
  • 订单项OrderItem实体类 


/** 订单中的商品数据 */
@Data
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语句

  • 在订单表中新增数据
  • 在订单项表中新增数据

3.2 编写OrderMapper接口以及抽象方法

package com.cy.store.mapper;


import com.cy.store.entity.Order;
import com.cy.store.entity.OrderItem;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface OrderMapper {
    /** 插入订单数据 */
    Integer insertOrder(Order order);

    /** 插入订单项数据 */
    Integer insertOrderItem(OrderItem orderItem);

}

3.3 sql映射

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//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>

3.4 测试类进行对mapper接口的测试


@SpringBootTest
class OrderMapperTest {
    @Autowired
    private OrderMapper orderMapper;

    @Test
    void insertOrder() {
        Order order = new Order();
        order.setUid(1);
        order.setRecvName("张三");
        order.setRecvPhone("12345678901");
        order.setRecvProvince("广东省");
        order.setRecvCity("广州市");
        order.setRecvArea("海珠区");
        order.setRecvAddress("广州大学城");
        order.setStatus(0);
        orderMapper.insertOrder(order);
    }

    @Test
    void insertOrderItem() {
        OrderItem orderItem = new OrderItem();
        orderItem.setOid(1);
        orderItem.setPid(10000001);
        orderItem.setTitle("测试商品");
        orderItem.setImage("https://picsum.photos/200/300");
        orderItem.setNum(1);
        orderMapper.insertOrderItem(orderItem);

    }
}

4. 业务层

        准备工作:需要在收货地址表中获取收货地址的信息,封装到订单表和订单项表中

4.1 在AddressService接口中定义根据收货地址id获取收货地址数据

    /**
     * 根据收货地址id,查询收货地址详情
     * @param aid 收货地址id
     * @return 匹配的收货地址详情,如果没有匹配的数据,则返回null
     */
    Address findByAid(Integer aid,Integer uid);

4.2 在子类中实现抽象方法

    /**
     * 根据收货地址id查询收货地址数据
     * @param aid 收货地址id
     * @param uid 用户id
     * @return 匹配的收货地址数据,如果没有匹配的数据则返回null
     */
    @Override
    public Address findByAid(Integer aid, Integer uid) {
        Address address = addressMapper.findByAid(aid);
        if (address==null){
            throw new AddressNotFoundException("收货地址数据不存在");
        }
        if (!address.getUid().equals(uid)){
            throw new AccessDeniedException("非法数据访问");
        }
//        将不必要的数据都设为null
        address.setProvinceCode(null);
        address.setCityCode(null);
        address.setAreaCode(null);
        address.setCreatedTime( null);
        address.setModifiedTime(null);
        address.setModifiedUser( null);
        address.setCreatedUser( null);
        return address;
    }

 4.3 在OrderService中定义接口和抽象方法

package com.cy.store.service;

import com.cy.store.entity.Order;

public interface OrderService {
    /**
     * 创建订单
     * @param aid 收货地址id
     * @param uid 用户id
     * @param cids 购物车数据id
     * @param username 用户名
     * @return 订单id
     */
    public Order create(Integer aid, Integer[] cids, Integer uid, String username);
}

4.4 实现类实现接口重写抽象方法



@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    //需要调用业务层的getByAid方法
    @Autowired
    private AddressService addressService;

    //需要调用业务层的getVOByCids方法
    @Autowired
    private CartService cartService;

    //需要调用业务层的getByUid方法
    private UserService userService;

     @Override
    public Order create(Integer aid, Integer[] cids, Integer uid, String username) {

        //返回的列表中的对象都是即将下单的
        List<CartVO> list = cartService.findVOByCid(uid, cids);

        long totalPrice = 0L;
        for (CartVO cartVO : list) {
            totalPrice += cartVO.getRealPrice()*cartVO.getNum();

        }
//         获取用户的收获地址信息
        Address address = addressService.findByAid(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.setOrderTime(new Date());
        order.setStatus(0);
        order.setTotalPrice(totalPrice);

        //封装四个日志
        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 cartVO : list) {
            OrderItem orderItem = new OrderItem();

            /**
             * 此时获取的oid不为空,因为在配置文件里面开启了oid主
             * 键自增,所以上面的代码执行插入时就自动将oid赋值了
             */
            orderItem.setOid(order.getOid());

            orderItem.setPid(cartVO.getPid());
            orderItem.setTitle(cartVO.getTitle());
            orderItem.setImage(cartVO.getImage());
            orderItem.setPrice(cartVO.getRealPrice());
            orderItem.setNum(cartVO.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("插入数据时产生未知的异常");
            }
        }
        return order;
    }


}

4.5 进行测试


@SpringBootTest
class OrderServiceTest {
    @Autowired
    private OrderService orderService;

    @Test
    void create() {
        Order order = orderService.create(9, new Integer[]{4, 5, 6}, 5, "admin");
        System.out.println(order);
    }
}

5. 控制层

        在OrderController类中接收前端传过来的请求,调用接口完成实现请求

@RestController
@RequestMapping("/orders")
public class OrderController extends BaseController{
    @Autowired
    private OrderService orderService;

    @RequestMapping("/create")
    public JsonResult<Order> create(Integer aid, Integer[] cids, HttpSession session) {
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        Order data = orderService.create(aid, cids, uid, username);
        return new JsonResult<>(OK, data);
    }

}

6. 前端页面 

        在orderConfirm.html页面中点击“在线支付”按钮时,发送请求

  • $("#address-list").val() 获取 选中的地址id
  • location.search.substr(1) 拿到url拼接的参数cid
// 点击 在线支付 按钮 点击事件
			$("#btn-create-order").click(function() {
				//获取 选中的地址id
				var aid = $("#address-list").val();//12
				// 拿到url拼接的参数cid
				var cids = location.search.substr(1);//cids=4&cids=6&cids=8
				$.ajax({
					url: "/orders/create",
					data: "aid=" + aid + "&" + cids, // aid和cid进行拼接作为请求参数传递到后端,aid=12&cids=4&cids=6&cids=8
					type: "GET",
					dataType: "JSON",
					success: function(json) {
						if (json.state == 200) {
							alert("创建订单成功!")
							location.href = "payment.html";
						} else {
							alert("创建订单失败!" + json.message);
						}
					},
					error: function(xhr) {
						alert("创建订单数据时产生未知的异常" + xhr.status);
					}
				});
			});


网站公告

今日签到

点亮在社区的每一天
去签到