[TOC]
## 步驟 1 : 先運行,看到效果,再學習
先將完整的 tmall_ssm 項目(向老師要相關資料),配置運行起來,確認可用之后,再學習做了哪些步驟以達到這樣的效果。
## 步驟 2 : 模仿和排錯
在確保可運行項目能夠正確無誤地運行之后,再嚴格照著教程的步驟,對代碼模仿一遍。
模仿過程難免代碼有出入,導致無法得到期望的運行結果,此時此刻通過比較**正確答案** ( 可運行項目 ) 和自己的代碼,來定位問題所在。
采用這種方式,**學習有效果,排錯有效率**,可以較為明顯地提升學習速度,跨過學習路上的各個檻。
## 步驟 3 : 界面效果
在產品頁面點擊加入購物車的,除了得到像**立即購買運行效果**中在OrderItem表里插入一條數據外,把界面上的**加入購物車**按鈕變成灰色并且不可點擊。

## 步驟 4 : 在產品頁點擊加入購物車
如果未登錄,那么點擊加入購物車會彈出**模態登錄窗口**,關于這個功能的詳細介紹在**模態登錄**,在此不做贅述。
登錄之后,點擊加入購物車,會使用Ajax異步訪問地址
`http://127.0.0.1:8080/tmall_ssm/foreaddCart?pid=264&num=4`
并帶上了產品id 264和購買數量4

## 步驟 5 : ForeController.addCart
上一步訪問地址/foreaddCart導致ForeController.addCart()方法被調用
addCart()方法和立即購買中的 步驟做的事情是一樣的,區別在于返回不一樣
1. 獲取參數pid
2. 獲取參數num
3. 根據pid獲取產品對象p
4. 從session中獲取用戶對象user
接下來就是新增訂單項OrderItem, 新增訂單項要考慮兩個情況
a. 如果已經存在這個產品對應的OrderItem,并且還沒有生成訂單,即還在購物車中。 那么就應該在對應的OrderItem基礎上,調整數量
a.1 基于用戶對象user,查詢沒有生成訂單的訂單項集合
a.2 遍歷這個集合
a.3 如果產品是一樣的話,就進行數量追加
a.4 獲取這個訂單項的 id
b. 如果不存在對應的OrderItem,那么就新增一個訂單項OrderItem
b.1 生成新的訂單項
b.2 設置數量,用戶和產品
b.3 插入到數據庫
b.4 獲取這個訂單項的 id
與**ForeController.buyone()** 客戶端跳轉到**結算頁面**不同的是, 最后返回字符串"success",表示添加成功
~~~
package com.dodoke.tmall.controller;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.HtmlUtils;
import com.dodoke.tmall.comparator.ProductAllComparator;
import com.dodoke.tmall.comparator.ProductDateComparator;
import com.dodoke.tmall.comparator.ProductPriceComparator;
import com.dodoke.tmall.comparator.ProductReviewComparator;
import com.dodoke.tmall.comparator.ProductSaleCountComparator;
import com.dodoke.tmall.pojo.Category;
import com.dodoke.tmall.pojo.OrderItem;
import com.dodoke.tmall.pojo.Product;
import com.dodoke.tmall.pojo.ProductImage;
import com.dodoke.tmall.pojo.PropertyValue;
import com.dodoke.tmall.pojo.Review;
import com.dodoke.tmall.pojo.User;
import com.dodoke.tmall.service.CategoryService;
import com.dodoke.tmall.service.OrderItemService;
import com.dodoke.tmall.service.OrderService;
import com.dodoke.tmall.service.ProductImageService;
import com.dodoke.tmall.service.ProductService;
import com.dodoke.tmall.service.PropertyValueService;
import com.dodoke.tmall.service.ReviewService;
import com.dodoke.tmall.service.UserService;
import com.github.pagehelper.PageHelper;
@Controller
@RequestMapping("")
public class ForeController {
@Autowired
CategoryService categoryService;
@Autowired
ProductService productService;
@Autowired
UserService userService;
@Autowired
ProductImageService productImageService;
@Autowired
PropertyValueService propertyValueService;
@Autowired
OrderService orderService;
@Autowired
OrderItemService orderItemService;
@Autowired
ReviewService reviewService;
@RequestMapping("forehome")
public String home(Model model) {
List<Category> cs = categoryService.list();
productService.fill(cs);
productService.fillByRow(cs);
model.addAttribute("cs", cs);
return "fore/home";
}
@RequestMapping("foreregister")
public String register(Model model, User user) {
String name = user.getName();
// 把賬號里的特殊符號進行轉義
name = HtmlUtils.htmlEscape(name);
user.setName(name);
boolean exist = userService.isExist(name);
if (exist) {
String m = "用戶名已經被使用,不能使用";
model.addAttribute("msg", m);
model.addAttribute("user", null);
return "fore/register";
}
userService.add(user);
return "redirect:registerSuccessPage";
}
@RequestMapping("forelogin")
public String login(@RequestParam("name") String name, @RequestParam("password") String password, Model model,
HttpSession session) {
name = HtmlUtils.htmlEscape(name);
User user = userService.get(name, password);
if (null == user) {
model.addAttribute("msg", "賬號密碼錯誤");
return "fore/login";
}
session.setAttribute("user", user);
return "redirect:forehome";
}
@RequestMapping("forelogout")
public String logout(HttpSession session) {
session.removeAttribute("user");
return "redirect:forehome";
}
@RequestMapping("foreproduct")
public String product(int pid, Model model) {
Product p = productService.get(pid);
// 根據對象p,獲取這個產品對應的單個圖片集合
List<ProductImage> productSingleImages = productImageService.list(p.getId(), ProductImageService.type_single);
// 根據對象p,獲取這個產品對應的詳情圖片集合
List<ProductImage> productDetailImages = productImageService.list(p.getId(), ProductImageService.type_detail);
p.setProductSingleImages(productSingleImages);
p.setProductDetailImages(productDetailImages);
// 獲取產品的所有屬性值
List<PropertyValue> pvs = propertyValueService.list(p.getId());
// 獲取產品對應的所有的評價
List<Review> reviews = reviewService.list(p.getId());
// 設置產品的銷量和評價數量
productService.setSaleAndReviewNumber(p);
model.addAttribute("reviews", reviews);
model.addAttribute("p", p);
model.addAttribute("pvs", pvs);
return "fore/product";
}
@RequestMapping("forecheckLogin")
@ResponseBody
public String checkLogin(HttpSession session) {
User user = (User) session.getAttribute("user");
if (null != user) {
return "success";
}
return "fail";
}
@RequestMapping("foreloginAjax")
@ResponseBody
public String loginAjax(@RequestParam("name") String name, @RequestParam("password") String password,
HttpSession session) {
name = HtmlUtils.htmlEscape(name);
User user = userService.get(name, password);
if (null == user) {
return "fail";
}
session.setAttribute("user", user);
return "success";
}
@RequestMapping("forecategory")
public String category(int cid, String sort, Model model) {
Category c = categoryService.get(cid);
productService.fill(c);
productService.setSaleAndReviewNumber(c.getProducts());
if (null != sort) {
switch (sort) {
case "review":
Collections.sort(c.getProducts(), new ProductReviewComparator());
break;
case "date":
Collections.sort(c.getProducts(), new ProductDateComparator());
break;
case "saleCount":
Collections.sort(c.getProducts(), new ProductSaleCountComparator());
break;
case "price":
Collections.sort(c.getProducts(), new ProductPriceComparator());
break;
case "all":
Collections.sort(c.getProducts(), new ProductAllComparator());
break;
}
}
model.addAttribute("c", c);
return "fore/category";
}
@RequestMapping("foresearch")
public String search(String keyword, Model model) {
PageHelper.offsetPage(0, 20);
List<Product> ps = productService.search(keyword);
productService.setSaleAndReviewNumber(ps);
model.addAttribute("ps", ps);
return "fore/searchResult";
}
@RequestMapping("forebuyone")
public String buyone(int pid, int num, HttpSession session) {
Product p = productService.get(pid);
int oiid = 0;
User user = (User) session.getAttribute("user");
boolean found = false;
List<OrderItem> ois = orderItemService.listByUser(user.getId());
for (OrderItem oi : ois) {
if (oi.getProduct().getId().intValue() == p.getId().intValue()) {
oi.setNumber(oi.getNumber() + num);
orderItemService.update(oi);
found = true;
oiid = oi.getId();
break;
}
}
if (!found) {
OrderItem oi = new OrderItem();
oi.setUserId(user.getId());
oi.setNumber(num);
oi.setProductId(pid);
orderItemService.add(oi);
oiid = oi.getId();
}
return "redirect:forebuy?oiid=" + oiid;
}
@RequestMapping("forebuy")
public String buy(Model model, String[] oiid, HttpSession session) {
List<OrderItem> ois = new ArrayList<>();
float total = 0;
for (String strid : oiid) {
int id = Integer.parseInt(strid);
OrderItem oi = orderItemService.get(id);
total += oi.getProduct().getPromotePrice() * oi.getNumber();
ois.add(oi);
}
session.setAttribute("ois", ois);
model.addAttribute("total", total);
return "fore/buy";
}
@RequestMapping("foreaddCart")
@ResponseBody
public String addCart(int pid, int num, Model model,HttpSession session) {
Product p = productService.get(pid);
User user =(User) session.getAttribute("user");
boolean found = false;
List<OrderItem> ois = orderItemService.listByUser(user.getId());
for (OrderItem oi : ois) {
if(oi.getProduct().getId().intValue()==p.getId().intValue()){
oi.setNumber(oi.getNumber()+num);
orderItemService.update(oi);
found = true;
break;
}
}
if(!found){
OrderItem oi = new OrderItem();
oi.setUserId(user.getId());
oi.setNumber(num);
oi.setProductId(pid);
orderItemService.add(oi);
}
return "success";
}
}
~~~
- 項目簡介
- 功能一覽
- 前臺
- 后臺
- 開發流程
- 需求分析-展示
- 首頁
- 產品頁
- 分類頁
- 搜索結果頁
- 購物車查看頁
- 結算頁
- 確認支付頁
- 支付成功頁
- 我的訂單頁
- 確認收貨頁
- 確認收貨成功頁
- 評價頁
- 需求分析-交互
- 分類頁排序
- 立即購買
- 加入購物車
- 調整訂單項數量
- 刪除訂單項
- 生成訂單
- 訂單頁功能
- 確認付款
- 確認收貨
- 提交評價信息
- 登錄
- 注冊
- 退出
- 搜索
- 前臺需求列表
- 需求分析后臺
- 分類管理
- 屬性管理
- 產品管理
- 產品圖片管理
- 產品屬性設置
- 用戶管理
- 訂單管理
- 后臺需求列表
- 表結構設計
- 數據建模
- 表與表之間的關系
- 后臺-分類管理
- 可運行的項目
- 靜態資源
- JSP包含關系
- 查詢
- 分頁
- 增加
- 刪除
- 編輯
- 修改
- 做一遍
- 重構
- 分頁方式
- 分類逆向工程
- 所有逆向工程
- 后臺其他頁面
- 屬性管理實現
- 產品管理實現
- 產品圖片管理實現
- 產品屬性值設置
- 用戶管理實現
- 訂單管理實現
- 前端
- 前臺-首頁
- 可運行的項目
- 靜態資源
- ForeController
- home方法
- home.jsp
- homePage.jsp
- 前臺-無需登錄
- 注冊
- 登錄
- 退出
- 產品頁
- 模態登錄
- 分類頁
- 搜索
- 前臺-需要登錄
- 購物流程
- 立即購買
- 結算頁面
- 加入購物車
- 查看購物車頁面
- 登錄狀態攔截器
- 其他攔截器
- 購物車頁面操作
- 訂單狀態圖
- 生成訂單
- 我的訂單頁
- 我的訂單頁操作
- 評價產品
- 總結