今日目標:
(1)掌握 Freemarker常用的指令與內建函數
(2)完成商品詳細頁的數據顯示
(3)完成商品詳細頁的動態顯示
(4)完成商品詳細頁讀取SKU信息的業務邏輯
(5)完成商品審覈調用功能
目錄
2、運行測試,執行http://localhost:9101/goods/genHtml.do?goodsId=149187842867981
1、商品詳細頁-數據顯示
準備工作:搭建工程(page-interface、page-service),並編寫相關配置和引入相關依賴
1.1 配置
(1)配置Freemarker的bean,在WEB-INF下創建ftl文件夾
<!-- 配置freemarker-bean -->
<bean id="freeMarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 模板文件位置 -->
<property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
<!-- 默認編碼 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
(2)配置存放商品詳細頁的位置,注意保證文件夾存在,還需要將樣式文件拷入該目錄
## 商品詳細頁存放位置
PAGE_DIR=D:\\item\\
1.2 服務層
(1)page-interface,編寫ItemPageService接口
package com.pinyougou.page.service;
/**
* 商品詳細頁靜態化
* Author xushuai
* Description
*/
public interface ItemPageService {
/**
* 生成商品詳細頁
*
* @param goodsId 商品id
* @return boolean
*/
boolean genItemPage(Long goodsId);
}
(2)page-service,編寫ItemPageServiceImpl實現
package com.pinyougou.page.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.mapper.TbGoodsDescMapper;
import com.pinyougou.mapper.TbGoodsMapper;
import com.pinyougou.page.service.ItemPageService;
import com.pinyougou.pojo.TbGoods;
import com.pinyougou.pojo.TbGoodsDesc;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
/**
* 商品詳情頁靜態化實現
* Author xushuai
* Description
*/
@Service
@Transactional
public class ItemPageServiceImpl implements ItemPageService {
@Autowired
private FreeMarkerConfigurer FreeMarkerConfigurer;
@Autowired
private TbGoodsMapper goodsMapper;
@Autowired
private TbGoodsDescMapper goodsDescMapper;
@Value("PAGE_DIR")
private String PAGE_DIR;
@Override
public boolean genItemPage(Long goodsId) {
try {
// 查詢商品基本信息和商品擴展信息
TbGoods tbGoods = goodsMapper.selectByPrimaryKey(goodsId);
TbGoodsDesc tbGoodsDesc = goodsDescMapper.selectByPrimaryKey(goodsId);
// 將查詢到的數據封裝到Map
Map<String, Object> data = new HashMap<>();
data.put("goods", tbGoods);
data.put("goodsDesc", tbGoodsDesc);
// 創建文件輸出流
Writer out = new FileWriter(PAGE_DIR + goodsId + ".html");
// 使用模板生成商品詳細頁
Configuration configuration = FreeMarkerConfigurer.getConfiguration();
Template template = configuration.getTemplate("item.ftl");
template.process(data, out);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
1.3 基本測試
(1)拷貝靜態原型的item.html作爲模板
(2)修改模板中的商品標題爲插值:${goods.goodsName}
(3)測試
1.4 替換模板基本信息爲插值
(1)將item.ftl中的頭部和尾部分別放入另外兩個模板中,在item.ftl中使用<#include>導入
(2)將商品基本信息使用插值替換到模板中
1.5 替換模板圖片列表
(1)因爲圖片列表爲json串,我們需要將json串轉換爲對象
<#-- 處理圖片列表Json串 -->
<#assign imageList = goodsDesc.itemImages?eval>
(2)遍歷生成的對象,展示圖片,注意限制圖片放大鏡的最大寬高
(3)效果
1.6 生成擴展屬性列表
(1)將擴展信息的json串轉換爲對象
<#-- 處理擴展屬性Json串 -->
<#if goodsDesc.customAttributeItems??>
<#assign attrList = goodsDesc.customAttributeItems?eval>
</#if>
(2)遍歷展示擴展信息
(3)效果
1.7 生成規格列表
(1)將規格列表信息的json串轉換爲對象
<#-- 處理規格列表Json串 -->
<#if goodsDesc.specificationItems??>
<#assign specList = goodsDesc.specificationItems?eval>
</#if>
(2)展示規格信息
(3)效果
1.8 生成商品類型麪包屑
(1)服務層實現(page-interface),修改ItemPageServiceImpl中的代碼,主要爲:查詢分類信息
package com.pinyougou.page.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.pinyougou.mapper.TbGoodsDescMapper;
import com.pinyougou.mapper.TbGoodsMapper;
import com.pinyougou.mapper.TbItemCatMapper;
import com.pinyougou.page.service.ItemPageService;
import com.pinyougou.pojo.TbGoods;
import com.pinyougou.pojo.TbGoodsDesc;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
/**
* 商品詳情頁靜態化實現
* Author xushuai
* Description
*/
@Service
@Transactional
public class ItemPageServiceImpl implements ItemPageService {
@Autowired
private FreeMarkerConfigurer FreeMarkerConfigurer;
@Autowired
private TbGoodsMapper goodsMapper;
@Autowired
private TbGoodsDescMapper goodsDescMapper;
@Autowired
private TbItemCatMapper itemCatMapper;
@Value("${PAGE_DIR}")
private String PAGE_DIR;
@Override
public boolean genItemPage(Long goodsId) {
try {
// 獲取數據
Map<String, Object> data = getDataMap(goodsId);
// 創建文件輸出流
Writer out = new FileWriter(PAGE_DIR + goodsId + ".html");
// 使用模板生成商品詳細頁
Configuration configuration = FreeMarkerConfigurer.getConfiguration();
Template template = configuration.getTemplate("item.ftl");
template.process(data, out);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 獲取模板需要的數據
*
* @param goodsId 商品ID
* @return java.util.Map<java.lang.String,java.lang.Object>
*/
private Map<String, Object> getDataMap(Long goodsId) {
Map<String, Object> data = new HashMap<>();
// 查詢商品基本信息和商品擴展信息
TbGoods tbGoods = goodsMapper.selectByPrimaryKey(goodsId);
TbGoodsDesc tbGoodsDesc = goodsDescMapper.selectByPrimaryKey(goodsId);
// 查詢商品分類信息
String category1 = itemCatMapper.selectByPrimaryKey(tbGoods.getCategory1Id()).getName();
String category2 = itemCatMapper.selectByPrimaryKey(tbGoods.getCategory2Id()).getName();
String category3 = itemCatMapper.selectByPrimaryKey(tbGoods.getCategory3Id()).getName();
// 將查詢到的數據封裝到Map
data.put("goods", tbGoods);
data.put("goodsDesc", tbGoodsDesc);
data.put("category1", category1);
data.put("category2", category2);
data.put("category3", category3);
return data;
}
}
(2)替換模板中的文本
(3)效果
2、商品詳細頁-前端邏輯
2.1 數量的加減
(1)拷貝相關的JS文件到存放商品詳情頁的目錄中
(2)在js目錄中新建controller文件夾,編寫itemController.js文件
app.controller('itemController', function ($scope) {
// 數量
$scope.num = 1;
// 增加數量
$scope.incrNum = function() {
$scope.num ++;
}
// 減少數量
$scope.decrNum = function() {
if($scope.num > 1) {
$scope.num --;
}
}
});
(2)修改模板,在模板中引入相關JS文件和基本指令
(3)數量輸入框綁定變量,+號和-號綁定單擊事件
2.2 規格選擇
(1)在itemController.js中新增方法
// 選中的規格數據
$scope.specificationItems = {};
// 點擊選中規格
$scope.selectSpec = function(name, value) {
// 設置給規格數據
$scope.specificationItems[name] = value;
}
// 判斷當前規格是否被選中
$scope.isSelected = function(name, value) {
if ($scope.specificationItems[name] == value) {
return true;
} else {
return false;
}
}
(2)模板中綁定變量和單擊事件
(3)效果
3、商品詳細頁-讀取SKU信息
3.1 服務層實現(page-service)
(1)修改ItemPageServiceImpl中的getDataMap方法,新增獲取SKU列表數據的邏輯
(2)在頁面中將獲取到的SKU列表數據,生成變量,以後訪問都通過訪問這個變量
<script>
var skuList = [
<#list itemList as item>
{
"id" : ${item.id?c},
"title" : "${item.title!''}",
"price" : ${item.price?c},
"spec" : ${item.spec}
},
</#list>
];
</script>
(3)測試效果
3.2 加載默認的SKU標題和價格
(1)在itemController.js中新增方法
// 當前選擇SKU信息
$scope.sku={};
// 加載默認的SKU信息
$scope.loadSku = function() {
// 將skuList中的默認SKU信息賦給當前選擇的SKU信息
$scope.sku = skuList[0];
}
(2)在模板標題和價格處,綁定變量
(3)默認選中默認的規格,修改loadSku方法
(4)效果
3.3 選擇規格加載對應的標題和價格
(1)在itemController.js中新增方法
// 判斷兩個對象是否內容相同
$scope.matchObject = function(object1, object2) {
for (var key in object1) {
// 校驗當前鍵的值是否一致
if (object1[key] != object2[key]) {
return false;
}
}
for (var key in object2) {
// 校驗當前鍵的值是否一致
if (object2[key] != object1[key]) {
return false;
}
}
// 內容相同
return true;
}
// 獲取當前選中的SKU
findSku = function() {
for (var i = 0; i < skuList.length; i++) {
if ($scope.matchObject($scope.specificationItems,skuList[i].spec)) {// 規格匹配
// 當前循環到的sku爲選中的sku
$scope.sku = skuList[i];
return ;
}
}
}
(2)在選擇規格時,改變標題和價格,即在selectSpec中調用findSku方法
(3)效果
3.4 預留加入購物車方法
(1)在itemController.js中新增方法
// 加入商品到購物車
$scope.addToCart = function() {
alert("SKU:" + $scope.sku.id + "加入購物車成功,購買數量爲:" + $scope.num);
}
(2)加入購物車按鈕,綁定事件
(3)效果
4、審覈商品生成商品詳細頁
4.1 控制層(manager-web)
(1)修改GoodsController中的updateStatus方法,新增邏輯
其他:與搜索模塊對接
1、配置Nginx
(1)修改生成靜態網頁的位置(page-service)
## 商品詳細頁存放位置
PAGE_DIR=E:\\temp\\freemarker\\
(2)將資源文件放入該文件夾中
(3)配置nginx.conf配置文件(windows版,測試用)
2、運行測試,執行http://localhost:9101/goods/genHtml.do?goodsId=149187842867981
3、對接
(1)修改圖片鏈接地址