品優購項目記錄:day12

今日目標:

(1)掌握 Freemarker常用的指令與內建函數

(2)完成商品詳細頁的數據顯示

(3)完成商品詳細頁的動態顯示

(4)完成商品詳細頁讀取SKU信息的業務邏輯

(5)完成商品審覈調用功能

 

目錄

1、商品詳細頁-數據顯示

1.1 配置

1.2 服務層

1.3 基本測試

1.4 替換模板基本信息爲插值

1.5 替換模板圖片列表

1.6 生成擴展屬性列表

1.7 生成規格列表

1.8 生成商品類型麪包屑

2、商品詳細頁-前端邏輯

2.1 數量的加減

2.2 規格選擇

3、商品詳細頁-讀取SKU信息

3.1 服務層實現(page-service)

3.2 加載默認的SKU標題和價格

3.3 選擇規格加載對應的標題和價格

3.4 預留加入購物車方法

4、審覈商品生成商品詳細頁

4.1 控制層(manager-web)

其他:與搜索模塊對接

1、配置Nginx

2、運行測試,執行http://localhost:9101/goods/genHtml.do?goodsId=149187842867981

3、對接


 

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)修改圖片鏈接地址

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章