商城订单管理
商品显示页
从商品的显示页中加入购物车或者下单。
跳转页面的请求地址(Get方式请求)
http://localhost:8080/tmall/product/{pid}
Request URL: http://localhost:8080/tmall/product/13
Request Method: GET
涉及到的控制器:ForeProductDetailsController
//转到前台天猫-产品详情页
@RequestMapping(value = "product/{pid}", method = RequestMethod.GET)
public String goToPage(HttpSession session, Map<String, Object> map,
@PathVariable("pid") String pid /*产品ID*/) {
logger.info("检查用户是否登录");
Object userId = checkUser(session);
if (userId != null) {
logger.info("获取用户信息");
User user = userService.get(Integer.parseInt(userId.toString()));
map.put("user", user);
}
logger.info("获取产品ID");
Integer product_id = Integer.parseInt(pid);
logger.info("获取产品信息");
Product product = productService.get(product_id);
if (product == null || product.getProduct_isEnabled() == 1) {
return "redirect:/404";
}
logger.info("获取产品子信息-分类信息");
product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
logger.info("获取产品子信息-预览图片信息");
List<ProductImage> singleProductImageList = productImageService.getList(product_id, (byte) 0, null);
product.setSingleProductImageList(singleProductImageList);
logger.info("获取产品子信息-详情图片信息");
List<ProductImage> detailsProductImageList = productImageService.getList(product_id, (byte) 1, null);
product.setDetailProductImageList(detailsProductImageList);
logger.info("获取产品子信息-产品属性值信息");
List<PropertyValue> propertyValueList = propertyValueService.getList(new PropertyValue().setPropertyValue_product(product), null);
logger.info("获取产品子信息-分类信息对应的属性列表");
List<Property> propertyList = propertyService.getList(new Property().setProperty_category(product.getProduct_category()), null);
logger.info("属性列表和属性值列表合并");
for (Property property : propertyList) {
for (PropertyValue propertyValue : propertyValueList) {
if (property.getProperty_id().equals(propertyValue.getPropertyValue_property().getProperty_id())) {
List<PropertyValue> property_value_item = new ArrayList<>(1);
property_value_item.add(propertyValue);
property.setPropertyValueList(property_value_item);
break;
}
}
}
logger.info("获取产品子信息-产品评论信息");
product.setReviewList(reviewService.getListByProductId(product_id, null));
if (product.getReviewList() != null) {
for (Review review : product.getReviewList()) {
review.setReview_user(userService.get(review.getReview_user().getUser_id()));
}
}
logger.info("获取猜你喜欢列表");
Integer category_id = product.getProduct_category().getCategory_id();
Integer total = productService.getTotal(new Product().setProduct_category(new Category().setCategory_id(category_id)), new Byte[]{0, 2});
logger.info("分类ID为{}的产品总数为{}条", category_id, total);
//生成随机数
int i = new Random().nextInt(total);
if (i + 2 >= total) {
i = total - 3;
}
if (i < 0) {
i = 0;
}
List<Product> loveProductList = productService.getList(new Product().setProduct_category(
new Category().setCategory_id(category_id)),
new Byte[]{0, 2},
null,
new PageUtil().setCount(3).setPageStart(i)
);
if (loveProductList != null) {
logger.info("获取产品列表的相应的一张预览图片");
for (Product loveProduct : loveProductList) {
loveProduct.setSingleProductImageList(productImageService.getList(loveProduct.getProduct_id(), (byte) 0, new PageUtil(0, 1)));
}
}
logger.info("获取分类列表");
List<Category> categoryList = categoryService.getList(null, new PageUtil(0, 3));
map.put("loveProductList", loveProductList);
map.put("categoryList", categoryList);
map.put("propertyList", propertyList);
map.put("product", product);
map.put("guessNumber", i);
map.put("pageUtil", new PageUtil(0, 10).setTotal(product.getProduct_review_count()));
logger.info("转到前台-产品详情页");
return "fore/productDetailsPage";
}
根据最后返回的地址,确定对应的页面位置:
fore/productDetailsPage
加入购物车的代码流程
<form method="get" class="context_buy_form">
<input class="context_buyNow" type="submit" value="立即购买"/>
</form>
JS绑定事件
点击添加购物车按钮之后向后台发送请求。
涉及部分
<dl class="context_info_member">
<dt>数量</dt>
<dd>
<input type="text" value="1" maxlength="8" title="请输入购买量" class="context_buymember">
<input type="hidden" id="stock" value="1000">
<span class="amount-btn">
<img src="${pageContext.request.contextPath}/res/images/fore/WebsiteImage/up.png"
class="amount_value_up">
<img src="${pageContext.request.contextPath}/res/images/fore/WebsiteImage/down.png"
class="amount_value-down">
</span>
<span class="amount_unit">件</span>
<em>库存1000件</em>
</dd>
</dl>
知识点一:isNaN函数
定义和用法
isNaN() 函数用于检查其参数是否是非数字值。
语法
isNaN(x)
参数 | 描述 |
---|---|
x | 必需。要检测的值。 |
返回值
如果 x 是特殊的非数字值 NaN(或者能被转换为这样的值),返回的值就是 true。如果 x 是其他值,则返回 false。
说明
isNaN() 函数可用于判断其参数是否是 NaN,该值表示一个非法的数字(比如被 0 除后得到的结果)。
如果把 NaN 与任何值(包括其自身)相比得到的结果均是 false,所以要判断某个值是否是 NaN,不能使用 == 或 === 运算符。正因为如此,isNaN() 函数是必需的。
提示和注释
提示:isNaN() 函数通常用于检测 parseFloat() 和 parseInt() 的结果,以判断它们表示的是否是合法的数字。当然也可以用 isNaN() 函数来检测算数错误,比如用 0 作除数的情况。
实例
检查数字是否非法:
<script> document.write(isNaN(123));
document.write(isNaN(-1.23));
document.write(isNaN(5-2));
document.write(isNaN(0));
document.write(isNaN("Hello"));
document.write(isNaN("2005/12/12")); </script>
输出:
false
false
false
false
true
true
创建购物车向后端发送请求
$.trim(str)的作用是去掉字符串首尾空格
$.trim(str)
返回:string;
在前端的过程中通过jquery进行校验,如果时非法数字重新进行刷新,正常数字会发送请求参数。
发送请求的方式为post方式,
发送的地址为:/orderItem/create/{产品id}
携带的参数:product_number:购买的数量
$(".context_buyCar_form").submit(function () {
if ('${sessionScope.userId}' === "") {
$(".loginModel").show();
$(".loginDiv").show();
return false;
}
var number = isNaN($.trim($(".context_buymember").val()));
if (number) {
location.reload();
} else {
$.ajax({
url: "${pageContext.request.contextPath}/orderItem/create/${requestScope.product.product_id}?product_number=" + $.trim($(".context_buymember").val()),
type: "POST",
data: {"product_number": number},
dataType: "json",
success: function (data) {
if (data.success) {
$(".msg").stop(true, true).animate({
opacity: 1
}, 550, function () {
$(".msg").animate({
opacity: 0
}, 1500);
});
} else {
if (data.url != null) {
location.href = "/tmall" + data.url; //里面的data.url为后端返回的
} else {
alert("加入购物车失败,请稍后再试!");
}
}
},
beforeSend: function () {
},
error: function () {
alert("加入购物车失败,请稍后再试!");
}
});
return false;
}
});
在请求后端的参数成功之后。弹出添加购物车成功的弹窗
用于创建自定义动画的函数。
返回值:jQuery animate(params, [duration], [easing], [callback])如果使用的是“hide”、“show”或“toggle”这样的字符串值,则会为该属性调用默认的动画形式。paramsOptions一组包
含作为动画属性和终值的样式属性和及其值的集合
完成成功之后的操作对应着,创建自定义提示的交互过程
后端的ForeOrderController控制器接收请求
涉及到的控制器:ForeOrderController(核心的订单处理控制器)
核心控制器中包含的方法
//创建订单项-购物车-ajax
@ResponseBody
@RequestMapping(value = "orderItem/create/{product_id}", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
public String createOrderItem(@PathVariable("product_id") Integer product_id,
@RequestParam(required = false, defaultValue = "1") Short product_number,
HttpSession session,
HttpServletRequest request) {
JSONObject object = new JSONObject();
logger.info("检查用户是否登录");
Object userId = checkUser(session);
if (userId == null) {
object.put("url", "/login");
object.put("success", false);
return object.toJSONString();
}
logger.info("通过产品ID获取产品信息:{}", product_id);
Product product = productService.get(product_id);
if (product == null) {
object.put("url", "/login");
object.put("success", false);
return object.toJSONString();
}
ProductOrderItem productOrderItem = new ProductOrderItem();
logger.info("检查用户的购物车项");
List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
for (ProductOrderItem orderItem : orderItemList) {
if (orderItem.getProductOrderItem_product().getProduct_id().equals(product_id)) {
logger.info("找到已有的产品,进行数量追加");
int number = orderItem.getProductOrderItem_number();
number += 1;
productOrderItem.setProductOrderItem_id(orderItem.getProductOrderItem_id());
productOrderItem.setProductOrderItem_number((short) number);
productOrderItem.setProductOrderItem_price(number * product.getProduct_sale_price());
boolean yn = productOrderItemService.update(productOrderItem);
if (yn) {
object.put("success", true);
} else {
object.put("success", false);
}
return object.toJSONString();
}
}
logger.info("封装订单项对象");
productOrderItem.setProductOrderItem_product(product);
productOrderItem.setProductOrderItem_number(product_number);
productOrderItem.setProductOrderItem_price(product.getProduct_sale_price() * product_number);
productOrderItem.setProductOrderItem_user(new User().setUser_id(Integer.valueOf(userId.toString())));
boolean yn = productOrderItemService.add(productOrderItem);
if (yn) {
object.put("success", true);
} else {
object.put("success", false);
}
return object.toJSONString();
}
在执行核心的方法之前首先检查,登录状态:调用Basecontroller
//检查用户是否登录
protected Object checkUser(HttpSession session){
Object o = session.getAttribute("userId");
if(o==null){
logger.info("用户未登录");
return null;
}
logger.info("用户已登录,用户ID:{}", o);
return o;
}
知识点二:@PathVariable 映射 URL 绑定的[占位符]
- 带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
- 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
知识点三:JSONObject 对象
用法实例
import org.json.JSONObject;
public class JSONObjectSample {
public static void main(String[] args) {
createJson();
}
private static void createJson() {
JSONObject obj = new JSONObject();
obj.put("name", "John");
obj.put("sex", "male");
obj.put("age", 22);
obj.put("is_student", true);
obj.put("hobbies", new String[] {"hiking", "swimming"});
//调用toString()方法可直接将其内容打印出来
System.out.println(obj.toString());
}
执行结果
{“hobbies”:[“hiking”,“swimming”],“sex”:“male”,“name”:“John”,“is_student”:true,“age”:22}
断点调试,查看返回的商品信息
根据id获取需要添加到购物车中的产品信息
返回商品信息之后在创建ProductOrderItem(产品订单项)
private Integer productOrder_id/*订单ID*/;
private String productOrder_code/*订单流水号*/;
private Address productOrder_address/*订单地址*/;
private String productOrder_detail_address/*订单详细地址*/;
private String productOrder_post/*订单邮政编码*/;
private String productOrder_receiver/*订单收货人名称*/;
private String productOrder_mobile/*订单收货人号码*/;
private Date productOrder_pay_date/*订单支付日期*/;
private Date productOrder_delivery_date/*订单发货日期*/;
private Date productOrder_confirm_date/*订单确认日期*/;
private Byte productOrder_status/*订单状态*/;
private User productOrder_user/*订单对应用户*/;
private List<ProductOrderItem> productOrderItemList/*订单项集合*/;
Integer.valueOf()和Integer.valueOf()这两个方法都是Integer的静态方法,都可以传入一个只包含整数的字符串类型,将其转换为整数。
List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()),
执行for循环语句,找到购物车中的原有项数目加number,没有则会跳出循环,来创建新订单
for (ProductOrderItem orderItem : orderItemList) {
if (orderItem.getProductOrderItem_product().getProduct_id().equals(product_id)) {
logger.info("找到已有的产品,进行数量追加");
int number = orderItem.getProductOrderItem_number();
number += 1;
productOrderItem.setProductOrderItem_id(orderItem.getProductOrderItem_id());
productOrderItem.setProductOrderItem_number((short) number);
productOrderItem.setProductOrderItem_price(number * product.getProduct_sale_price());
boolean yn = productOrderItemService.update(productOrderItem);
if (yn) {
object.put("success", true);
} else {
object.put("success", false);
}
return object.toJSONString();
}
}
如果匹配成功则会在for循环中修改订单的信息完成对应的修改操作。
调用update语句修改订单项,之后完成数据库更新
boolean yn = productOrderItemService.update(productOrderItem);
到这位置添加购物车订单的流程执行完毕
购物车显示页
请求地址:
Request URL: http://localhost:8080/tmall/cart
请求方式:get方式
请求方法说明://转到前台天猫-购物车页
返回地址:fore/productBuyCarPage(前端的购物车显示页面)
//转到前台天猫-购物车页
@RequestMapping(value = "cart", method = RequestMethod.GET)
public String goToCartPage(Map<String, Object> map, HttpSession session) {
logger.info("检查用户是否登录");
Object userId = checkUser(session);
User user;
if (userId != null) {
logger.info("获取用户信息");
user = userService.get(Integer.parseInt(userId.toString()));
map.put("user", user);
} else {
return "redirect:/login";
}
logger.info("获取用户购物车信息");
List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
Integer orderItemTotal = 0;
if (orderItemList.size() > 0) {
logger.info("获取用户购物车的商品总数");
orderItemTotal = productOrderItemService.getTotalByUserId(Integer.valueOf(userId.toString()));
logger.info("获取用户购物车内的商品信息");
for (ProductOrderItem orderItem : orderItemList) {
Integer product_id = orderItem.getProductOrderItem_product().getProduct_id();
Product product = productService.get(product_id);
product.setSingleProductImageList(productImageService.getList(product_id, (byte) 0, null));
product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
orderItem.setProductOrderItem_product(product);
}
}
map.put("orderItemList", orderItemList);
map.put("orderItemTotal", orderItemTotal);
logger.info("转到前台天猫-购物车页");
return "fore/productBuyCarPage";
}
ForeOrderController处理请求完成页面跳转
方法名:goToCartPage()
断点调试:走获取购物车信息的流程
之前要先获取用户的信息(从session中的userid中获取信息->查出user的信息)
通过调用业务逻辑层(和之前的复用)
List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
最后获取购物车中的商品总数和对应的信息,完成操作
orderItemTotal = productOrderItemService.getTotalByUserId(Integer.valueOf(userId.toString()));
if (orderItemList.size() > 0) {
logger.info("获取用户购物车的商品总数");
orderItemTotal = productOrderItemService.getTotalByUserId(Integer.valueOf(userId.toString()));
logger.info("获取用户购物车内的商品信息");
for (ProductOrderItem orderItem : orderItemList) {
Integer product_id = orderItem.getProductOrderItem_product().getProduct_id();
Product product = productService.get(product_id); //获取一条产品
product.setSingleProductImageList(productImageService.getList(product_id, (byte) 0, null));//获取对应的图片
product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
orderItem.setProductOrderItem_product(product);
}
}
map.put("orderItemList", orderItemList);
map.put("orderItemTotal", orderItemTotal);
logger.info("转到前台天猫-购物车页");
return "fore/productBuyCarPage";
//设置订单对应的产品
private Product productOrderItem_product/*订单项对应产品*/;
最后通过map集合进行封装,将携带的数据返回到前台的jsp页面中
map.put("orderItemList", orderItemList);
map.put("orderItemTotal", orderItemTotal);
logger.info("转到前台天猫-购物车页");
return "fore/productBuyCarPage";
在前台的页面进行map集合数据的遍历和渲染
${requestScope.orderItemTotal}
<div id="J_FilterBar">
<ul id="J_CartSwitch">
<li>
<a href="${pageContext.request.contextPath}/cart" class="J_MakePoint">
<em>全部商品</em>
<span class="number">${requestScope.orderItemTotal}</span>
</a>
</li>
</ul>
<div class="cart-sum">
<span class="pay-text">已选商品(不含运费)</span>
<strong class="price"><em id="J_SmallTotal"><span
class="total-symbol"> </span>0.00</em></strong>
<a id="J_SmallSubmit" class="submit-btn submit-btn-disabled">结 算</a>
</div>
<div class="wrap-line">
<div class="floater"></div>
</div>
</div>
数据表格渲染(c:foreach标签)
<c:forEach items="${requestScope.orderItemList}" var="orderItem">
<tr class="orderItem_category">
<td colspan="6"><span class="shop_logo"></span><span
class="category_shop">店铺:贤趣${orderItem.productOrderItem_product.product_category.category_name}旗舰店</span>
</td>
</tr>
<tr class="orderItem_info">
<td class="tbody_checkbox"><input type="checkbox" class="cbx_select"
id="cbx_orderItem_select_${orderItem.productOrderItem_id}"
name="orderItem_id"><label
for="cbx_orderItem_select_${orderItem.productOrderItem_id}"></label></td>
<td><img class="orderItem_product_image"
src="${pageContext.request.contextPath}/res/images/item/productSinglePicture/${orderItem.productOrderItem_product.singleProductImageList[0].productImage_src}"
style="width: 80px;height: 80px;"/><span class="orderItem_product_name"><a
href="${pageContext.request.contextPath}/product/${orderItem.productOrderItem_product.product_id}">${orderItem.productOrderItem_product.product_name}</a></span>
</td>
<td><span
class="orderItem_product_price">¥${orderItem.productOrderItem_price/orderItem.productOrderItem_number}</span>
</td>
<td>
<div class="item_amount">
<a href="javascript:void(0)" οnclick="up(this)"
class="J_Minus <c:if test="${orderItem.productOrderItem_number<=1}">no_minus</c:if>">-</a>
<input type="text" value="${orderItem.productOrderItem_number}"/>
<a href="javascript:void(0)" οnclick="down(this)" class="J_Plus">+</a>
</div>
</td>
<td>
<span class="orderItem_product_realPrice">¥${orderItem.productOrderItem_price}</span>
</td>
<td><a href="javascript:void(0)" οnclick="removeItem('${orderItem.productOrderItem_id}')"
class="remove_order">删除</a></td>
<td>
<input type="hidden" class="input_orderItem" name="${orderItem.productOrderItem_id}"/>
</td>
</tr>
</c:forEach>
购物车删除操作
请求路径:http://localhost:8080/tmall/orderItem/909
请求方式:delete方式
携带参数:订单编号
ForeOrderController控制器处理删除操作
//删除订单项-购物车-ajax
@ResponseBody
@RequestMapping(value = "orderItem/{orderItem_id}", method = RequestMethod.DELETE, produces = "application/json;charset=utf-8")
public String deleteOrderItem(@PathVariable("orderItem_id") Integer orderItem_id,
HttpSession session,
HttpServletRequest request) {
JSONObject object = new JSONObject();
logger.info("检查用户是否登录");
Object userId = checkUser(session);
if (userId == null) {
object.put("url", "/login");
object.put("success", false);
return object.toJSONString();
}
logger.info("检查用户的购物车项");
List<ProductOrderItem> orderItemList = productOrderItemService.getListByUserId(Integer.valueOf(userId.toString()), null);
boolean isMine = false;
for (ProductOrderItem orderItem : orderItemList) {
logger.info("找到匹配的购物车项");
if (orderItem.getProductOrderItem_id().equals(orderItem_id)) {
isMine = true;
break;
}
}
if (isMine) {
logger.info("删除订单项信息");
boolean yn = productOrderItemService.deleteList(new Integer[]{orderItem_id});
if (yn) {
object.put("success", true);
} else {
object.put("success", false);
}
} else {
object.put("success", false);
}
return object.toJSONString();
}
注意:批量删除操作还没有实现
购物车单个结算的操作
单个结算的购物地址:http://localhost:8080/tmall/orderItem
请求方式Put
说明:在提交订单之前完成先更新购物车中的信息
知识点四:JSONObject、MAP、对象、字符串互相转换
实体类(User类)、JSON对象、json字符串
JSONObject jsonObject = JSON.parseObject(user); // 转换为json对象
JSONObject jso = (JSONObject) JSON.toJSON(user); // 转换为json对象`
String personStr = JSONObject.toJSONString(user); // 转换为json字符串
String str = JSON.toJSONString(user); // 转换为json字符串`
User user = jsonObject.toJavaObject(User.class); // json对象转换为实体类
JSON.parseObject(“{“band”:“XX”,“price”:“888”}”, User.class) //String类型json转换为实体类`
2)、List、数组、Map与json代码转换
JSONObject itemJSONObj = JSONObject.parseObject(JSON.toJSONString(itemMap)); //将Map类型的itemInfo转换成json,再经JSONObject转换实现。
JSONObject itemJSONObj = JSONObject.parseObject(JSON.toJSONString(list)); // list转换
JSONArray jsonArray1 = JSONArray.parseObject(JSON.toJSONString(array)); // 数组转换为JSONObject
搞清楚JSONObject的操作步骤
JSONObject orderItemString = JSON.parseObject(orderItemMap);
Set<String> orderItemIDSet = orderItemString.keySet();
Integer. valueOf()方法的作用
Integer. valueOf()可以将基本类型int转换为包装类型Integer,或者将String转换成Integer,String如果为Null或“”都会报错
ForeOrderController控制器实现购物车更新
productOrderItemService.get(Integer.valueOf(key));
根据产品订单项的id获取数据库中的一条订单条目信息
说明改订单已经生成了不在属于购物车
Short number = Short.valueOf(orderItemString.getString(key));
if (number <= 0 || number > 500) {
logger.warn("订单项产品数量不合法!");
object.put("success", false);
return object.toJSONString();
}
//获取前台提供的订单数判断时候合法符合规定
在结算的时候先更新结算的状态
//更新购物车订单项数量-ajax
@ResponseBody
@RequestMapping(value = "orderItem", method = RequestMethod.PUT, produces = "application/json;charset=utf-8")
public String updateOrderItem(HttpSession session, Map<String, Object> map, HttpServletResponse response,
@RequestParam String orderItemMap) {
JSONObject object = new JSONObject();
logger.info("检查用户是否登录");
Object userId = checkUser(session);
if (userId == null) {
object.put("success", false);
return object.toJSONString();
}
JSONObject orderItemString = JSON.parseObject(orderItemMap);
Set<String> orderItemIDSet = orderItemString.keySet();
if (orderItemIDSet.size() > 0) {
logger.info("更新产品订单项数量");
for (String key : orderItemIDSet) {
ProductOrderItem productOrderItem = productOrderItemService.get(Integer.valueOf(key));
if (productOrderItem == null || !productOrderItem.getProductOrderItem_user().getUser_id().equals(userId)) {
logger.warn("订单项为空或用户状态不一致!");
object.put("success", false);
return object.toJSONString();
}
if (productOrderItem.getProductOrderItem_order() != null) {
logger.warn("用户订单项不属于购物车,回到购物车页");
return "redirect:/cart";
}
Short number = Short.valueOf(orderItemString.getString(key));
if (number <= 0 || number > 500) {
logger.warn("订单项产品数量不合法!");
object.put("success", false);
return object.toJSONString();
}
double price = productOrderItem.getProductOrderItem_price() / productOrderItem.getProductOrderItem_number();
Boolean yn = productOrderItemService.update(new ProductOrderItem().setProductOrderItem_id(Integer.valueOf(key)).setProductOrderItem_number(number).setProductOrderItem_price(number * price));
if (!yn) {
throw new RuntimeException();
}
}
Object[] orderItemIDArray = orderItemIDSet.toArray();
object.put("success", true);
object.put("orderItemIDArray", orderItemIDArray);
return object.toJSONString();
} else {
logger.warn("无订单项可以处理");
object.put("success", false);
return object.toJSONString();
}
}
购物车结算时前台向后台发送的请求
function create(obj) {
obj = $(obj);
if (!obj.hasClass("selected")) {
return true;
}
var orderItemMap = {};
var tr = $("input.cbx_select:checked").parents("tr.orderItem_info");
tr.each(function () {
var key = $(this).find(".input_orderItem").attr("name");
orderItemMap[key] = $(this).find(".item_amount").children("input").val();
});
$.ajax({
url: "/tmall/orderItem",
type: "PUT",
data: {
"orderItemMap": JSON.stringify(orderItemMap)
},
traditional: true,
success: function (data) {
if (data.success) {
location.href = "/tmall/order/create/byCart?order_item_list=" + data.orderItemIDArray;
return true;
} else {
alert("购物车商品结算异常,请稍候再试!");
location.href = "/tmall/cart";
}
},
beforeSend: function () {
},
error: function () {
alert("购物车商品结算异常,请稍候再试!");
location.href = "/tmall/cart";
}
});
我们可以通过 JSON.stringify() 把 JavaScript 对象转换为字符串。
JSON.stringify()
语法
JSON.stringify(value[, replacer [, space]])
JSON.stringify()
不是只有一个参数,它最多可以有三个参数,只是一般后面两个用不到,所以我们会忽略它们。
value
将要序列化成 一个 JSON
字符串的值。
replacer [可选]
如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON
字符串中;如果该参数为 null
或者未提供,则对象所有的属性都会被序列化。
space [可选]
指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为10。该值若小于1,则意味着没有空格;如果该参数为字符串(当字符串长度超过10个字母,取其前10个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。
“orderItemMap”: JSON.stringify(orderItemMap)
traditional: true,
这个属性可以让ajax传数组,或对象
修改购物车的状态完成之后发送请求
/tmall/order/create/byCart?order_item_list=" + data.orderItemIDArray;
说明创建多个订单(集合)
跳转到购物车建立订单页
//转到前台天猫-购物车订单建立页
@RequestMapping(value = "order/create/byCart", method = RequestMethod.GET)
public String goToOrderConfirmPageByCart(Map<String, Object> map,
HttpSession session, HttpServletRequest request,
@RequestParam(required = false) Integer[] order_item_list) throws UnsupportedEncodingException {
logger.info("检查用户是否登录");
Object userId = checkUser(session);
User user;
if (userId != null) {
logger.info("获取用户信息");
user = userService.get(Integer.parseInt(userId.toString()));
map.put("user", user);
} else {
return "redirect:/login";
}
if (order_item_list == null || order_item_list.length == 0) {
logger.warn("用户订单项数组不存在,回到购物车页");
return "redirect:/cart";
}
logger.info("通过订单项ID数组获取订单信息");
List<ProductOrderItem> orderItemList = new ArrayList<>(order_item_list.length);
for (Integer orderItem_id : order_item_list) {
orderItemList.add(productOrderItemService.get(orderItem_id));
}
logger.info("------检查订单项合法性------");
if (orderItemList.size() == 0) {
logger.warn("用户订单项获取失败,回到购物车页");
return "redirect:/cart";
}
for (ProductOrderItem orderItem : orderItemList) {
if(orderItem.getProductOrderItem_user().getUser_id().equals(userId)==false){
// if (orderItem.getProductOrderItem_user().getUser_id() != userId) {
logger.warn("用户订单项与用户不匹配,回到购物车页");
return "redirect:/cart";
}
if (orderItem.getProductOrderItem_order() != null) {
logger.warn("用户订单项不属于购物车,回到购物车页");
return "redirect:/cart";
}
}
logger.info("验证通过,获取订单项的产品信息");
double orderTotalPrice = 0.0;
for (ProductOrderItem orderItem : orderItemList) {
Product product = productService.get(orderItem.getProductOrderItem_product().getProduct_id());
product.setProduct_category(categoryService.get(product.getProduct_category().getCategory_id()));
product.setSingleProductImageList(productImageService.getList(product.getProduct_id(), (byte) 0, new PageUtil(0, 1)));
orderItem.setProductOrderItem_product(product);
orderTotalPrice += orderItem.getProductOrderItem_price();
}
String addressId = "110000";
String cityAddressId = "110100";
String districtAddressId = "110101";
String detailsAddress = null;
String order_post = null;
String order_receiver = null;
String order_phone = null;
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
switch (cookieName) {
case "addressId":
addressId = cookieValue;
break;
case "cityAddressId":
cityAddressId = cookieValue;
break;
case "districtAddressId":
districtAddressId = cookieValue;
break;
case "order_post":
order_post = URLDecoder.decode(cookieValue, "UTF-8");
break;
case "order_receiver":
order_receiver = URLDecoder.decode(cookieValue, "UTF-8");
break;
case "order_phone":
order_phone = URLDecoder.decode(cookieValue, "UTF-8");
break;
case "detailsAddress":
detailsAddress = URLDecoder.decode(cookieValue, "UTF-8");
break;
}
}
}
logger.info("获取省份信息");
List<Address> addressList = addressService.getRoot();
logger.info("获取addressId为{}的市级地址信息", addressId);
List<Address> cityAddress = addressService.getList(null, addressId);
logger.info("获取cityAddressId为{}的区级地址信息", cityAddressId);
List<Address> districtAddress = addressService.getList(null, cityAddressId);
map.put("orderItemList", orderItemList);
map.put("addressList", addressList);
map.put("cityList", cityAddress);
map.put("districtList", districtAddress);
map.put("orderTotalPrice", orderTotalPrice);
map.put("addressId", addressId);
map.put("cityAddressId", cityAddressId);
map.put("districtAddressId", districtAddressId);
map.put("order_post", order_post);
map.put("order_receiver", order_receiver);
map.put("order_phone", order_phone);
map.put("detailsAddress", detailsAddress);
logger.info("转到前台天猫-订单建立页");
return "fore/productBuyPage";
}
获取购物车中结算的信息用来创建订单
return "fore/productBuyPage";
根据控制器中的信息判端出前端的返回地址
//转到前台天猫-购物车订单建立页
@RequestMapping(value = "order/create/byCart", method = RequestMethod.GET)
public String goToOrderConfirmPageByCart(Map<String, Object> map,
HttpSession session, HttpServletRequest request,
@RequestParam(required = false) Integer[] order_item_list) throws UnsupportedEncodingException {
logger.info("检查用户是否登录");
return "fore/productBuyPage";