JavaWeb - 小米商城 :创建订单
1.功能描述
接上篇 JavaWeb - 小米商城:商品添加到购物车 本篇博客将分析和实现小米商城通过购物车提 交。如以下H5页面所示:
购物车界面
通过购物界面点击生成订单按钮,依据购物车数据创建订单信息
订单预览界面
订单创建成功, 显示订单预览界面, 在预览界面可以显示和添加收货地址
支付提示界面:
当点击提交订单, 此时将订单数据存储到数据表
支付宝支付:
一般的开发中使用的是沙箱做模拟支付
我的订单列表:
支付成功可以通过点击我的订单查看订单列表
订单详情界面
通过点击订单列表中订单详情按钮打开该
2.提交功能分析
2.1 功能逻辑抽象
商品购物车成功点击生成订单时, 先判断一行是否登录, 如果用户没有登录, 则需要用户先完成登录, 获取到用户对象 , 然后从session中取得购物车数据, 根据购物车数据创建订单对象和订单详情List集合数据
商品购物车是面向数据库中的tb_cart表, 订单面向的是tb_order表和订单详情表tb_orderdetail, 在订单预览页面添加数据到对应的表, 在开发时基于三层架构体系购物车建立对应的CartServlet类, CartService接口和实现类, CartDao接口和实现类, 订单建立对应的OrderServlet类, OrderService接口和实现类, OrderDao接口和实现类, 订单建立对应的OrderDetailServlet类, OrderDetailService接口和实现类, OrderDetaDao接口和实现类
提示: 还需要创建辅助的vo类
OdersView : oid,uid,orderTime,userName,telphon,address,totalMoney,ostate
GoodOdersDeailVo : pid,pimg,pname,star,pubdate,price,num,money
3.代码实现
3.1前端
3.1.1修改购物车中添加收货地址a链接地址
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PxDcWEq9-1652785135869)(修改跳转连接.png)]
3.1.2修改order.html代码
<script type="text/javascript">
$(function () {
$("#btn_add").click(function () {
location.href = "order.do?action=generateOrder&aid=" + $("#address").val();
})
})
$(document).ready(function () {
//获取购物车的session数据显示到页面
$.get("cart.do?action=showCart", "", function (result) {
if (result.flag === true) {
var sum = 0;//计算总金额变量
var index = 1;
for (var i in result.data) {
var tbhtm ='<tr>' +
'<td>' + index + '</td>' +
'<td>' + result.data[i].goodsName + '</td>' +
'<td>¥ ' + result.data[i].price + '</td>' +
'<td>' + result.data[i].quantity + '</td>' +
'<td>¥ ' + result.data[i].subtotal + '</td>' +
'</tr>';
index++;
sum += result.data[i].subtotal;
$("#cartBody").append(tbhtm);
}
//显示总计
$("#total").html("<b>¥ " + sum + "</b>");
}
});
//获取地址列表的数据显示到页面
$.get("address.do?action=showAddress", "", function (result) {
var addStr = '';
var address = '<tr>' +
'<td colspan="5">' +
'<h5>收货地址</h5>' +
'<select id="address" style="width:60%" class="form-control">';
if (result.flag === true) {
for (var i in result.data) {
address += '<option value="' + result.data[i].id + '">' +
result.data[i].name + ' ' + result.data[i].phone + ' ' +
result.data[i].detail + '</option>';
}
} else {
addStr = '<a href="self_info.html">添加收货地址</a>';
}
address += '</select>' + addStr + '</td>' + '</tr>';
$("#addressFoot").append(address);
});
});
</script>
<script type="text/javascript" src="js/includeHeader.js"></script>
</head>
<body style="background-color:#f5f5f5">
<div id="headtop">
</div>
<div class="container" style="background-color: white;">
<div class="row" style="margin-left: 40px">
<h3>订单预览<small>温馨提示:请添加你要邮递到的地址</small></h3>
</div>
<div class="row" style="margin-top: 40px;">
<div class="col-md-10 col-md-offset-1">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>序号</th>
<th>商品名称</th>
<th>价格</th>
<th>数量</th>
<th>小计</th>
</tr>
</thead>
<tbody id="cartBody">
</tbody>
<tfoot id="addressFoot">
</tfoot>
</table>
</div>
</div>
<hr>
<div class="row">
<div style="margin-left: 40px;">
<h4>商品金额总计:<span id="total" class="text-danger"></span></h4>
</div>
</div>
<div class="row pull-right" style="margin-right: 40px;">
<div style="margin-bottom: 20px;">
<button id="btn_add" class="btn btn-danger btn-lg" type="button">提交订单</button>
</div>
</div>
</div>
3.2后端
3.2.1AddressServlet
在AddressServlet类中根据购物车信息创建订单数据
@WebServlet("/address.do")
public class AddressServlet extends BaseServlet{
private ResultData resultData = new ResultData();
/**
* 显示收货地址
* @param req
* @param resp
* @return
*/
public String showAddress(HttpServletRequest req, HttpServletResponse resp){
HttpSession session = req.getSession();
User user = (User) req.getSession().getAttribute(Constants.LOGINUSER);
System.err.println(user);
if (user == null) {
resultData.setFlag(false);
return Constants.REDIRECT + "/login.html";
}else {
AddressServiceImpl addressService=new AddressServiceImpl();
List<Address> addressList= addressService.queryAddressByUid(user.getId());
System.err.println(addressList);
if (addressList!=null){
resultData.setFlag(true);
resultData.setData(addressList);
}else {
resultData.setFlag(false);
}
}
String json = JSON.toJSONString(resultData);
System.err.println("id:" + json);
//在响应中声明返回的是json格式字符
resp.setContentType("application/json;charset=utf-8");
return json;
}
}
3.2.2 AddressService
/**
* 收货地址业务层
*/
public class AddressServiceImpl implements IAddressService {
private IAddressDao addressDao = null;
public AddressServiceImpl() {
addressDao = new AddressDaoImpl();
}
//.....
@Override
public List<Address> queryAddressByUid( int uid) {
return addressDao.queryAddressByUid(uid);
}
}
3.2.3 AddressDao
public class AddressDaoImpl implements IAddressDao {
//......
@Override
public List<Address> queryBySql(String sql, Object... parms) {
List<Address> addressList = null;
QueryRunner qrun = new QueryRunner(DBUtils.getDataSource());
try {
addressList = qrun.query(sql, parms, new BeanListHandler<>(Address.class));
} catch (SQLException e) {
e.printStackTrace();
}
return addressList;
}
@Override
public List<Address> queryAddressByUid(int uid) {
String sql="select * from tb_address where uid=?";
return queryBySql(sql,uid);
}
}
3.2.4 OrderServlet
在OrderServlet类中根据购物车信息创建订单数据
@WebServlet("/order.do")
public class OrderServlet extends BaseServlet {
private ResultData resultData = new ResultData();
/**
* 生成订单
*/
public String generateOrder(HttpServletRequest req, HttpServletResponse resp) {
boolean flag = false;//状态变量
String aidStr = req.getParameter("aid");
int aid = 0;
if (aidStr != null) {
try {
aid = Integer.parseInt(aidStr);
} catch (Exception e) {
return Constants.REDIRECT + "/self_info.html";
}
}
HttpSession session = req.getSession();
User user = (User) req.getSession().getAttribute(Constants.LOGINUSER);
Order order = new Order();//订单对象声明在if外
if (user == null) {
return Constants.REDIRECT + "/login.html";
} else {
Map<String, CartItem> cartItemMap = (Map<String, CartItem>) req.getSession().getAttribute(Constants.CART);
if (cartItemMap != null) {
//一个订单 对应多条 订单详情数据 === 购物车
String oid = RandomUtils.createOrderId();
order.setId(oid);
List<Cart> cartList = new ArrayList<>();
List<OrderDetail> orderDetailList = new ArrayList<>();
double totalMoney = 0.0;
for (String goodId : cartItemMap.keySet()) {
CartItem cartItem = cartItemMap.get(goodId);
//将订单项添加到Cart
int pid = Integer.parseInt(cartItem.getGoodsId());
Cart cart = new Cart(0, pid, cartItem.getQuantity(), cartItem.getSubtotal());
cartList.add(cart);
//将订单项添加到OrderDetail
OrderDetail orderDetail = new OrderDetail(0, oid, pid, cartItem.getQuantity(), cartItem.getSubtotal());
orderDetailList.add(orderDetail);
totalMoney += cartItem.getSubtotal();
}
order.setUid(user.getId());
order.setStatus(0);
order.setTime(RandomUtils.getNowTime());
order.setMoney(totalMoney);
//这些信息先放入到session
OrderServiceImpl orderService = new OrderServiceImpl();
flag = orderService.saveOrder(order, cartList, orderDetailList);
}
}
if (flag) {
//清空购物车
session.removeAttribute(Constants.CART);
return Constants.REDIRECT + "/orderSuccess.html?oid=" + order.getId() + "&money=" + order.getMoney();
} else {
return Constants.REDIRECT + "/error.html?msg=订单创建失败!";
}
}
/**
* 显示订单信息
*/
public String getOrderInfo(HttpServletRequest req, HttpServletResponse resp) {
HttpSession session = req.getSession();
resultData.setFlag(true);
Object order = session.getAttribute(Constants.ORDER);
if (order == null) {
resultData.setFlag(false);
}
resultData.setData(order);
String json = JSON.toJSONString(resultData);
System.out.println("id" + json);
//在响应中声明返回的是json格式字符
resp.setContentType("application/json;charset=utf-8");
return json;
}
}
3.2.5 编写OrderServiceImpl代码
订单创建涉及到多张数据表,必须做事务控制:
public class OrderServiceImpl implements IOrderService {
private IOrderDao orderDao = null;
private ICartDao cartDao = null;
private IOrderDetailDao orderDetailDao = null;
public OrderServiceImpl() {
orderDao = new OrderDaoImpl();
cartDao = new CartDaoImpl();
orderDetailDao = new OrderDetailDaoImpl();
}
//....
@Override
public boolean saveOrder(Order order, List<Cart> cartList, List<OrderDetail> orderDetailList) {
boolean isSuccess = false;//默认是失败状态
try {
DBUtils.beginTransaction();//开启事务
} catch (Exception e) {
e.printStackTrace();
}
int n1 = orderDao.addData(order);
if (n1 >= 1) {
int n2 = cartDao.addCartList(cartList);
if (n2 == cartList.size()) {
int n3 = orderDetailDao.addOrderDetailList(orderDetailList);
if (n3 == orderDetailList.size()) {
isSuccess = true;
DBUtils.commit();
}
}
}
if (isSuccess == false) {
DBUtils.rollback();
}
return isSuccess;
}
}
3.2.6 编写OrderDaoImpl码
public class OrderDaoImpl implements IOrderDao {
private QueryRunner queryRunner = null;
public OrderDaoImpl() {
queryRunner = new QueryRunner();
}
@Override
public int addData(Order order) {
int n = 0;
String sql = "insert into tb_order(id,uid,money,status,time,aid) values(?,?,?,?,?,?)";
try {
n = queryRunner.update(DBUtils.getConn(), sql, order.getId(), order.getUid(),
order.getMoney(), order.getStatus(), order.getTime(), order.getAid());
} catch (SQLException e) {
e.printStackTrace();
}
return n;
}
//.....
@Override
public List<Order> queryBySql(String sql, Object... parms) {
List<Order> orderList = null;
QueryRunner qrun = new QueryRunner(DBUtils.getDataSource());
try {
orderList = qrun.query(sql, parms, new BeanListHandler<>(Order.class));
} catch (SQLException e) {
e.printStackTrace();
}
return orderList;
}
}
3.2.7 编写CartDaoImpl代码
public class CartDaoImpl implements ICartDao {
private QueryRunner queryRunner = null;
public CartDaoImpl() {
queryRunner = new QueryRunner();
}
//....
@Override
public int addCartList(List<Cart> cartList) {
int n = 0;
String sql = "insert into tb_cart(pid,num,money) values(?,?,?)";
Object[][] parms = new Object[cartList.size()][3];
for (int i = 0; i < cartList.size(); i++) {
Cart cart = cartList.get(i);
parms[i] = new Object[]{cart.getPid(), cart.getNum(), cart.getMoney()};
}
try {
int[] nums = queryRunner.batch(DBUtils.getConn(), sql, parms);
for (int num : nums) {
n += num;
}
}catch (Exception e){
e.printStackTrace();
}
return n;
}
}