第一篇文章鏈接:模仿天貓實(shí)戰(zhàn)【SSM版】——項(xiàng)目起步
第二篇文章鏈接:模仿天貓實(shí)戰(zhàn)【SSM版】——后臺(tái)開發(fā)總結(jié):項(xiàng)目從4-27號(hào)開始寫,到今天5-7號(hào)才算真正的完工,有許多粗糙的地方,但總算完成了,比想象中的開發(fā)周期要久的多,并且大部分的時(shí)間都花在了前端頁(yè)面的編寫上...僅以此文來(lái)總結(jié)一下
項(xiàng)目總結(jié)
功能一覽表
大致理了一下功能列表,應(yīng)該是齊全的,其中推薦鏈接暫時(shí)不支持修改。
項(xiàng)目頁(yè)面一覽表
- 后端頁(yè)面: 后臺(tái)所需要用到的頁(yè)面,從名字很好區(qū)分功能,其中 index.jsp 只有一行代碼用于跳轉(zhuǎn)
- 公共頁(yè)面: 都是前端頁(yè)面,從對(duì)天貓頁(yè)面的分析提取出一些復(fù)用比較高的頁(yè)面用于動(dòng)態(tài)的包含在其他前端頁(yè)面中。
- 前臺(tái)頁(yè)面:前臺(tái)相較于后臺(tái)頁(yè)面 CSS 更加復(fù)雜,交互也更多,我把每一個(gè)頁(yè)面的需要用到的 css 和 js 代碼均保留在了當(dāng)前 JSP 頁(yè)面中,方便瀏覽學(xué)習(xí)。
項(xiàng)目主要邏輯類
- 控制器(Controller): 用于控制頁(yè)面的邏輯, 提取出一個(gè) PageController 來(lái)專門控制頁(yè)面的跳轉(zhuǎn),F(xiàn)oreController 用于前臺(tái)所有的邏輯操作
- 攔截器(Interceptor): LoginInteceptor 用于對(duì)登錄進(jìn)行判斷,因?yàn)橛幸恍╉?yè)面需要登錄之后才能訪問的,例如:購(gòu)物車;OtherInterceptor 用于向頁(yè)面中添加一些其他的數(shù)據(jù),例如:購(gòu)物車數(shù)量。
- 業(yè)務(wù)層(Service層): 業(yè)務(wù)處理層,其中封裝了 Dao 層,用于完成主要的邏輯處理。
不需要登錄就能訪問的頁(yè)面(以下為攔截器中的代碼片段):
- 其中包括:主頁(yè)、搜索結(jié)果頁(yè)、產(chǎn)品展示頁(yè)、登錄頁(yè)、注冊(cè)頁(yè)。
- 還包括一些其他的路徑用于處理邏輯,test 為開發(fā)過(guò)程中用于測(cè)試的頁(yè)面
前臺(tái)總結(jié)
前臺(tái)花費(fèi)了大部分的時(shí)間,不僅僅是繁雜的樣式和頁(yè)面需要自己去編寫,業(yè)務(wù)邏輯也比后臺(tái)要復(fù)雜一些,因?yàn)槭悄7拢源蟛糠值?CSS 我都是參照著天貓官網(wǎng)寫的(利用FireFox來(lái)查看元素和元素樣式):
另外一部分是參照了how2j.cn上模仿的前端教程:戳這里
首頁(yè)
簡(jiǎn)要的首頁(yè)大概就是這樣,請(qǐng)別在意輪播下面的【女裝/內(nèi)衣】中的產(chǎn)品,因?yàn)樵?月份的時(shí)候,第一個(gè)分類的名字還叫【女裝 /男裝 /內(nèi)衣】(好像是這個(gè)),后來(lái)項(xiàng)目寫著寫著突然改了...
觀察大部分的頁(yè)面,其實(shí)都是包含了其中的三個(gè)部分:
即頂部導(dǎo)航欄、一個(gè)搜索框、還有底部,我們可以單獨(dú)把他們寫成一個(gè) jsp ,并動(dòng)態(tài)的包含在我們的頁(yè)面中
- 首頁(yè)分類欄
因?yàn)橐婚_始,我以為分類欄中保存的是一些直接的產(chǎn)品,但是分析前端的時(shí)候發(fā)現(xiàn)它們只是一些 hot-word 熱詞,所以為了和天貓的首頁(yè)保持一致,我直接把分類欄寫死了寫成了一個(gè)單獨(dú)的 JSP 文件并包含進(jìn)了主頁(yè):
我還自己寫了一個(gè)小程序,用來(lái)將這些 hor-word 轉(zhuǎn)換成對(duì)應(yīng)的 html 代碼,不然這手寫 2000 行可能真的夠嗆...
產(chǎn)品搜索頁(yè)
并且支持按照【綜合(銷量*評(píng)價(jià))】、【人氣(評(píng)論量)】、【銷量】、【價(jià)格】來(lái)排序產(chǎn)品,使用 Java 8 的新特性來(lái)完成該功能:
產(chǎn)品展示頁(yè)
所有的產(chǎn)品展示圖片均是來(lái)自how2j.com上的一張圖,前面有鏈接,表示有參照這個(gè)教程來(lái)做。
購(gòu)買頁(yè)
在產(chǎn)品頁(yè)中點(diǎn)擊立即購(gòu)買,或者在購(gòu)物車點(diǎn)擊結(jié)算都會(huì)跳轉(zhuǎn)到該頁(yè)面,創(chuàng)建訂單。
付款頁(yè)面
無(wú)恥的黏了一張自己的收款二維碼...
付款成功頁(yè)
當(dāng)點(diǎn)擊確認(rèn)支付按鈕之后,就會(huì)跳轉(zhuǎn)到該頁(yè)面來(lái)。
購(gòu)物車頁(yè)
該頁(yè)面支持刪除訂單和對(duì)訂單項(xiàng)進(jìn)行相關(guān)的操作,點(diǎn)擊結(jié)算頁(yè)面跳轉(zhuǎn)到購(gòu)買頁(yè)。
我的訂單頁(yè)
該頁(yè)面用于對(duì)訂單的管理,可以查看和操作訂單。
評(píng)價(jià)頁(yè)
當(dāng)完成購(gòu)買,即經(jīng)過(guò)購(gòu)買→支付→發(fā)貨→確認(rèn)收貨的流程之后,即可對(duì)產(chǎn)品進(jìn)行評(píng)論,評(píng)論完成后能看到其他用戶的評(píng)價(jià)信息:
注冊(cè)頁(yè)
用戶注冊(cè)頁(yè),在前端判斷兩次密碼是否相同,并提交給后臺(tái)判斷用戶名是否唯一。
登錄頁(yè)
因?yàn)榉直媛实膯栴}有一點(diǎn) BUG,不過(guò)不影響體驗(yàn),登錄之后頂部導(dǎo)航欄出現(xiàn)用戶信息:
后臺(tái)總結(jié)
前臺(tái)因?yàn)橛鞋F(xiàn)成的原型可以參照和模仿,后臺(tái)需要自己去設(shè)計(jì)和實(shí)現(xiàn)界面,所以我直接找了一個(gè)模板代碼,很方便也很快的完成了開發(fā),在我的第二篇文章:模仿天貓實(shí)戰(zhàn)【SSM版】——后臺(tái)開發(fā) 有介紹。
分類管理
其中的分頁(yè)和搜索功能是我找來(lái)的模板中用 js 代碼來(lái)實(shí)現(xiàn)的,分類管理中不僅提供了更改分類名稱的功能,還能管理分類下的產(chǎn)品和屬性。
產(chǎn)品管理頁(yè)
產(chǎn)品圖片管理頁(yè)
產(chǎn)品的圖片是默認(rèn)放置在 img/product/產(chǎn)品的id號(hào)/
目錄下的,并且默認(rèn)的五張圖片分別為:1.jpg、2.jpg.....5.jpg,用于默認(rèn)顯示的圖片均為 1.jpg
屬性值管理頁(yè)
產(chǎn)品屬性值管理頁(yè),能增加的屬性值只能為當(dāng)前分類下?lián)碛械膶傩浴?/p>
用戶管理
提供一個(gè)修改密碼的功能,給申訴修改密碼的用戶留一條后路。
訂單管理頁(yè)
等待發(fā)貨的訂單有一個(gè)發(fā)貨按鈕,用于發(fā)貨。
上面有一些產(chǎn)品管理的按鈕亂入了..直接拷貝的之前的圖片,左側(cè)欄中的產(chǎn)品管理按鈕是刪除了的...
推薦鏈接管理
暫時(shí)不提供修改功能。
項(xiàng)目中遇到的一些問題
輪播失效
Bootstrap 的引入要在 JQuery 之后,不然不能正常使用...
為什么不在 PropertyValue 表中增加 property_name 字段?
在產(chǎn)品詳情頁(yè)明顯感覺到顯示產(chǎn)品的屬性的時(shí)候,特別不方便。
PropertyValue
新增一個(gè) Property 屬性,來(lái)完成產(chǎn)品頁(yè)的傳遞
后臺(tái)屬性值管理邏輯有點(diǎn)問題
之前的代碼:
<c:forEach items="${propertyValues}" var="pv">
<tr>
<td>
<c:forEach items="${properties}" var="p">
<c:if test="${p.id==pv.property_id}">${p.name}</c:if>
</c:forEach>
</td>
<td>${pv.value}</td>
<td><a href="editPropertyValue?id=${pv.id}"><span
class="glyphicon glyphicon-edit"></span></a></td>
<td>
<a href="deletePropertyValue?id=${pv.id}&category_id=${product.category_id}"><span
class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</c:forEach>
非常糟糕,邏輯就是錯(cuò)的。
利用上面為 PropertyValue 添加的 Property 來(lái)完成功能:
- 下面的 select 標(biāo)簽也是錯(cuò)的
生成出來(lái)的代碼是這樣的:
我想要綁定一個(gè)隱藏的 input ,看來(lái)這樣寫是不行的,搜索了一下,可以通過(guò)為 <select>
標(biāo)簽寫 onchange
屬性來(lái)完成:
使用 Java 8 的新特性來(lái)排序
使用了 Java 8 的 Lambda 表達(dá)式來(lái)完成前端的排序工作:
注冊(cè)頁(yè)
天貓的注冊(cè)搞得很高大上的樣子,淘寶也弄成了一樣的,不是很好模仿出效果:
所以照著改了一改,弄成了這個(gè)樣子:
在前端通過(guò) JS 來(lái)判斷完成確認(rèn)密碼的功能,然后這是注冊(cè)成功的頁(yè)面:
發(fā)現(xiàn) OrderItem 少設(shè)計(jì)了一個(gè)字段
這是最初設(shè)計(jì)的數(shù)據(jù)庫(kù)表與表之間的關(guān)系:
當(dāng)我按照流程一步一步完成著項(xiàng)目,在完成立即購(gòu)買這個(gè)功能時(shí),我需要按照user_id來(lái)返回訂單項(xiàng)時(shí),不容易實(shí)現(xiàn),我們需要為 OrderItem 增加一個(gè)字段(user_id):
CREATE TABLE `order_item` (
`id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '唯一索引id',
`product_id` INT(11) NOT NULL COMMENT '對(duì)應(yīng)產(chǎn)品id',
`order_id` INT(11) NOT NULL COMMENT '對(duì)應(yīng)訂單id',
`user_id` INT(11) NOT NULL COMMENT '對(duì)應(yīng)用戶id',
`number` INT(11) NULL DEFAULT NULL COMMENT '對(duì)應(yīng)產(chǎn)品購(gòu)買的數(shù)量',
INDEX `fk_order_item_product` (`product_id`),
INDEX `fk_order_item_order` (`order_id`),
INDEX `fk_order_item_user` (`user_id`),
PRIMARY KEY (`id`),
CONSTRAINT `fk_order_item_order` FOREIGN KEY (`order_id`) REFERENCES `order_` (`id`),
CONSTRAINT `fk_order_item_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`),
CONSTRAINT `fk_order_item_product` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`)
)COLLATE='utf8_general_ci' ENGINE=InnoDB;
然后運(yùn)行 TestMybatisGenerator 來(lái)重新生成相關(guān)的文件.
更改 OrderItem 表中的 order_id 字段默認(rèn)為空
order_id 是用于判斷當(dāng)前的 OrderItem 是否存在于購(gòu)物車中的依據(jù),最開始我們將這個(gè)字段設(shè)計(jì)為不能為空,那么就只能在購(gòu)物車中存在,當(dāng)我們不需要經(jīng)過(guò)購(gòu)物車而要直接購(gòu)買的時(shí)候,就不能得到滿足...
修復(fù)購(gòu)物車邏輯問題
之前給 cart.jsp 頁(yè)面的 List<OrderItem> 僅僅是通過(guò) listByUserId 方法來(lái)獲取,但其實(shí)真正的購(gòu)物車是那些 order_id 為空的,所以我在 OrderItemService 中新增了一個(gè)方法:listForCart 來(lái)返回那些真正屬于購(gòu)物車的訂單項(xiàng):
@Override
public List<OrderItem> listForCart(Integer user_id) {
OrderItemExample example = new OrderItemExample();
example.or().andUser_idEqualTo(user_id).andOrder_idIsNull();
List<OrderItem> result = orderItemMapper.selectByExample(example);
setProduct(result);
return result;
}
Github
完成之后的項(xiàng)目直接上傳 Github,代碼可能有些亂,可讀性不是很高,但結(jié)構(gòu)還是清晰的,還是值得參考:傳送門
后期再對(duì)代碼進(jìn)行維護(hù)吧...菜鳥學(xué)習(xí)代碼,勿噴....
關(guān)于 sql 語(yǔ)句
這里給一個(gè)連接提供建表語(yǔ)句以及一些數(shù)據(jù):傳送門
歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明出處!
簡(jiǎn)書ID:@我沒有三顆心臟
github:wmyskxz
歡迎關(guān)注公眾微信號(hào):wmyskxz_javaweb
分享自己的Java Web學(xué)習(xí)之路以及各種Java學(xué)習(xí)資料