72. 显示确认订单信息页
显示“确认订单信息”页面中,需要显示2种数据:当前用户的所有收货地址列表;用户在前序页面中选择的购物车中的商品。
首先,完成“显示当前用户的所有收货地址的列表”,在此前开发“收货地址”相关功能时,已经可以通过/addresses/
这个URL获取收货地址列表!则直接在orderConfirm.html
中通过$.ajax()
获取数据并显示即可!
接下来,应该“显示用户在前序页面中选择的购物车中的商品的列表”,对应的查询功能的SQL语句大致是:
select * from t_cart left join t_product on t_cart.pid=t_product.id where cid in (?,?,?)
所以,需要在CartMapper.java
接口中添加:
List<CartVO> findByCids(Integer[] cids);
在CartMapper.xml
中配置以上抽象方法的映射:
<select id="findByCids" resultType="xx.xx.xx.CartVO">
SELECT
cid, uid,
pid, t_cart.num,
t_cart.price, t_product.price AS realPrice,
title, image
FROM
t_cart
LEFT JOIN
t_product
ON
t_cart.pid=t_product.id
WHERE
cid IN
<foreach collection="array"
item="cid" seperator=","
open="(" close=")">
#{cid}
</foreach>
ORDER BY
t_cart.created_time DESC
</select>
完成持久层后,接下来,需要在ICartService
业务层接口中添加抽象方法,以对外提供数据访问功能:
List<CartVO> getByCids(Integer[] cids, Integer uid);
然后,在实现类中,先私有化编写持久层的方法:
private List<CartVO> findByCids(Integer[] cids) {
return cartMapper.findByCids(cids);
}
并重写接口中的抽象方法:
public List<CartVO> getByCids(Integer[] cids, Integer uid) {
if (cids == null) {
return new ArrayList<>();
}
List<CartVO> result = findByCids(cids);
Iterator<CartVO> it = result.iterator();
while(it.hasNext()) {
CartVO cartVO = it.next();
if (cartVO.getUid() != uid) {
it.remove();
}
}
return result;
}
测试完成后,需要在控制器层提供接口:
@GetMapping("get_by_cids")
public JsonResult<List<CartVO>> getByCids(
Integer[] cids, HttpSession session) {
// 从session中获取uid
Integer uid = getUidFromSession(session);
// 调用业务层对象的方法执行任务
List<CartVO> data = cartService.getByCids(cids, uid);
// 响应成功
return new JsonResult<>(SUCCESS, data);
}
然后,打开浏览器,可以通过http://localhost:8080/carts/get_by_cids?cids=14&cids=15&cids=16
进行单元测试。
测试完成后,需要在orderConfirm.html
中发出对这个URL的请求,以获取数据,并显示。
73. 创建订单-创建数据表
创建“订单表”:
CREATE TABLE t_order (
oid INT AUTO_INCREMENT COMMENT '订单id',
uid INT COMMENT '用户id',
recv_name VARCHAR(50) COMMENT '收货人receiver姓名',
recv_phone VARCHAR(20) COMMENT '收货人电话',
recv_province VARCHAR(50) COMMENT '收货地址所在省',
recv_city VARCHAR(50) COMMENT '收货地址所在市',
recv_area VARCHAR(50) COMMENT '收货地址所在区',
recv_address VARCHAR(100) COMMENT '详细收货地址',
total_price BIGINT COMMENT '总价',
status INT COMMENT '状态:0-未支付,1-已支付,2-已取消',
order_time DATETIME COMMENT '下单时间',
pay_time DATETIME COMMENT '支付时间',
created_user VARCHAR(50) COMMENT '创建人',
created_time DATETIME COMMENT '创建时间',
modified_user VARCHAR(50) COMMENT '最后修改人',
modified_time DATETIME COMMENT '最后修改时间',
PRIMARY KEY (oid)
) DEFAULT CHARSET=UTF8;
创建“订单商品表”:
CREATE TABLE t_order_item (
id INT AUTO_INCREMENT COMMENT 'id',
oid INT COMMENT '归属的订单id',
pid INT COMMENT '商品id',
title VARCHAR(100) COMMENT '商品标题',
image VARCHAR(500) COMMENT '商品图片',
price BIGINT COMMENT '商品单价',
num INT COMMENT '购买数量',
created_user VARCHAR(50) COMMENT '创建人',
created_time DATETIME COMMENT '创建时间',
modified_user VARCHAR(50) COMMENT '最后修改人',
modified_time DATETIME COMMENT '最后修改时间',
PRIMARY KEY (id)
) DEFAULT CHARSET=UTF8;
73. 创建订单-创建实体类
订单实体类:
/**
* 订单数据的实体类
*/
public class Order extends BaseEntity {
private static final long serialVersionUID = -3216224344757796927L;
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;
// ...
}
订单商品实体类:
/**
* 订单商品数据的实体类
*/
public class OrderItem extends BaseEntity {
private static final long serialVersionUID = -8879247924788259070L;
private Integer id;
private Integer oid;
private Integer pid;
private String title;
private String image;
private Long price;
private Integer num;
// ...
}
74. 创建订单-持久层
接口与抽象方法:
/**
* 处理订单和订单商品数据的持久层接口
*/
public interface OrderMapper {
/**
* 插入订单数据
* @param order 订单数据
* @return 受影响的行数
*/
Integer insertOrder(Order order);
/**
* 插入订单商品数据
* @param orderItem 订单商品数据
* @return 受影响的行数
*/
Integer insertOrderItem(OrderItem orderItem);
}
映射:
<mapper namespace="cn.tedu.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>
测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderMapperTests {
@Autowired
OrderMapper mapper;
@Test
public void insertOrder() {
Order order = new