品优购项目笔记(八)
创建商品详情页面
商品上架流程(改进):
添加了商品详情页面
一、添加配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--<context:component-scan base-package="com.pinyougou.page.service.impl"/>-->
<dubbo:protocol name="dubbo" port="20885"></dubbo:protocol>
<dubbo:application name="pinyougou-page-service"/>
<dubbo:registry address="zookeeper://192.168.200.128:2181"/>
<dubbo:annotation package="cn.itcast.core.service" />
<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>
</beans>
二、创建页面模板
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
<title>产品详情页</title>
<link rel="icon" href="assets/img/favicon.ico">
<link rel="stylesheet" type="text/css" href="css/webbase.css" />
<link rel="stylesheet" type="text/css" href="css/pages-item.css" />
<link rel="stylesheet" type="text/css" href="css/pages-zoom.css" />
<link rel="stylesheet" type="text/css" href="css/widget-cartPanelView.css" />
<script type="text/javascript" src="plugins/angularjs/angular.min.js"> </script>
<script type="text/javascript" src="js/base.js"> </script>
<script type="text/javascript" src="js/controller/itemController.js"> </script>
<script>
var skuList=[
<#list itemList as item>
{
id:${item.id?c},
title:'${item.title}',
price:${item.price?c},
spec:${item.spec}
} ,
</#list>
];
</script>
</head>
<body ng-app="pinyougou" ng-controller="itemController" ng-init="num=1;loadSku()">
<!--页面顶部 开始-->
<#include "head.ftl">
<#--图片列表-->
<#assign imageList=goodsDesc.itemImages?eval>
<#--扩展属性-->
<#assign customAttributeList=goodsDesc.customAttributeItems?eval>
<#--规格-->
<#assign specificationList=goodsDesc.specificationItems?eval>
<!--页面顶部 结束-->
<div class="py-container">
<div id="item">
<div class="crumb-wrap">
<ul class="sui-breadcrumb">
<!--
<li>
<a href="#">${itemCat1}</a>
</li>
<li>
<a href="#">${itemCat2}</a>
</li>
<li>
<a href="#">${itemCat3}</a>
</li>
-->
</ul>
</div>
<!--product-info-->
<div class="product-info">
<div class="fl preview-wrap">
<!--放大镜效果-->
<div class="zoom">
<!--默认第一个预览-->
<div id="preview" class="spec-preview">
<span class="jqzoom">
<#if (imageList?size>0)>
<img jqimg="${imageList[0].url}" src="${imageList[0].url}" width="400px" height="400px" />
</#if>
</span>
</div>
<!--下方的缩略图-->
<div class="spec-scroll">
<a class="prev"><</a>
<!--左右按钮-->
<div class="items">
<ul>
<#list imageList as item>
<li><img src="${item.url}" bimg="${item.url}" onmousemove="preview(this)" /></li>
</#list>
</ul>
</div>
<a class="next">></a>
</div>
</div>
</div>
<div class="fr itemInfo-wrap">
<div class="sku-name">
<h4>{{sku.title}}</h4>
</div>
<div class="news"><span>${goods.caption} </span></div>
<div class="summary">
<div class="summary-wrap">
<div class="fl title">
<i>价 格</i>
</div>
<div class="fl price">
<i>¥</i>
<em>{{sku.price}}</em>
<span>降价通知</span>
</div>
<div class="fr remark">
<i>累计评价</i><em>612188</em>
</div>
</div>
<div class="summary-wrap">
<div class="fl title">
<i>促 销</i>
</div>
<div class="fl fix-width">
<i class="red-bg">加价购</i>
<em class="t-gray">满999.00另加20.00元,或满1999.00另加30.00元,或满2999.00另加40.00元,即可在购物车换
购热销商品</em>
</div>
</div>
</div>
<div class="support">
<div class="summary-wrap">
<div class="fl title">
<i>支 持</i>
</div>
<div class="fl fix-width">
<em class="t-gray">以旧换新,闲置手机回收 4G套餐超值抢 礼品购</em>
</div>
</div>
<div class="summary-wrap">
<div class="fl title">
<i>配 送 至</i>
</div>
<div class="fl fix-width">
<em class="t-gray">满999.00另加20.00元,或满1999.00另加30.00元,或满2999.00另加40.00元,即可在购物车换购热销商品</em>
</div>
</div>
</div>
<div class="clearfix choose">
<div id="specification" class="summary-wrap clearfix">
<#list specificationList as spec>
<dl>
<dt>
<div class="fl title">
<i>${spec.attributeName}</i>
</div>
</dt>
<#list spec.attributeValue as item>
<dd><a href="javascript:;"
class="{{isSelected('${spec.attributeName}','${item}')?'selected':''}}"
ng-click="selectSpecification('${spec.attributeName}','${item}')">${item}
<span title="点击取消选择"> </span>
</a></dd>
</#list>
</dl>
</#list>
</div>
<div class="summary-wrap">
<div class="fl title">
<div class="control-group">
<div class="controls">
<input autocomplete="off" ng-model="num" type="text" value="1" minnum="1" class="itxt" />
<a href="javascript:void(0)" class="increment plus" ng-click="addNum(1)">+</a>
<a href="javascript:void(0)" class="increment mins" ng-click="addNum(-1)">-</a>
</div>
</div>
</div>
<div class="fl">
<ul class="btn-choose unstyled">
<li>
<a class="sui-btn btn-danger addshopcar" ng-click="addToCart()">加入购物车</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!--product-detail-->
<div class="clearfix product-detail">
<div class="fl aside">
<ul class="sui-nav nav-tabs tab-wraped">
<li class="active">
<a href="#index" data-toggle="tab">
<span>相关分类</span>
</a>
</li>
<li>
<a href="#profile" data-toggle="tab">
<span>推荐品牌</span>
</a>
</li>
</ul>
<div class="tab-content tab-wraped">
<div id="index" class="tab-pane active">
<ul class="part-list unstyled">
<li>手机</li>
<li>手机壳</li>
<li>内存卡</li>
<li>Iphone配件</li>
<li>贴膜</li>
<li>手机耳机</li>
<li>移动电源</li>
<li>平板电脑</li>
</ul>
<ul class="goods-list unstyled">
<li>
<div class="list-wrap">
<div class="p-img">
<img src="img/_/part01.png" />
</div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>6088.00</i>
</strong>
</div>
<div class="operate">
<a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
</div>
</div>
</li>
<li>
<div class="list-wrap">
<div class="p-img">
<img src="img/_/part02.png" />
</div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>6088.00</i>
</strong>
</div>
<div class="operate">
<a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
</div>
</div>
</li>
<li>
<div class="list-wrap">
<div class="p-img">
<img src="img/_/part03.png" />
</div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>6088.00</i>
</strong>
</div>
<div class="operate">
<a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
</div>
</div>
<div class="list-wrap">
<div class="p-img">
<img src="img/_/part02.png" />
</div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>6088.00</i>
</strong>
</div>
<div class="operate">
<a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
</div>
</div>
<div class="list-wrap">
<div class="p-img">
<img src="img/_/part03.png" />
</div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>6088.00</i>
</strong>
</div>
<div class="operate">
<a href="javascript:void(0);" class="sui-btn btn-bordered">加入购物车</a>
</div>
</div>
</li>
</ul>
</div>
<div id="profile" class="tab-pane">
<p>推荐品牌</p>
</div>
</div>
</div>
<div class="fr detail">
<div class="clearfix fitting">
<h4 class="kt">选择搭配</h4>
<div class="good-suits">
<div class="fl master">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/l-m01.png" />
</div>
<em>¥5299</em>
<i>+</i>
</div>
</div>
<div class="fl suits">
<ul class="suit-list">
<li class="">
<div id="">
<img src="img/_/dp01.png" />
</div>
<i>Feless费勒斯VR</i>
<label data-toggle="checkbox" class="checkbox-pretty">
<input type="checkbox"><span>39</span>
</label>
</li>
<li class="">
<div id=""><img src="img/_/dp02.png" /> </div>
<i>Feless费勒斯VR</i>
<label data-toggle="checkbox" class="checkbox-pretty">
<input type="checkbox"><span>50</span>
</label>
</li>
<li class="">
<div id=""><img src="img/_/dp03.png" /></div>
<i>Feless费勒斯VR</i>
<label data-toggle="checkbox" class="checkbox-pretty">
<input type="checkbox"><span>59</span>
</label>
</li>
<li class="">
<div id=""><img src="img/_/dp04.png" /></div>
<i>Feless费勒斯VR</i>
<label data-toggle="checkbox" class="checkbox-pretty">
<input type="checkbox"><span>99</span>
</label>
</li>
</ul>
</div>
<div class="fr result">
<div class="num">已选购0件商品</div>
<div class="price-tit"><strong>套餐价</strong></div>
<div class="price">¥5299</div>
<button class="sui-btn btn-danger addshopcar">加入购物车</button>
</div>
</div>
</div>
<div class="tab-main intro">
<ul class="sui-nav nav-tabs tab-wraped">
<li class="active">
<a href="#one" data-toggle="tab">
<span>商品介绍</span>
</a>
</li>
<li>
<a href="#two" data-toggle="tab">
<span>规格与包装</span>
</a>
</li>
<li>
<a href="#three" data-toggle="tab">
<span>售后保障</span>
</a>
</li>
<li>
<a href="#four" data-toggle="tab">
<span>商品评价</span>
</a>
</li>
<li>
<a href="#five" data-toggle="tab">
<span>手机社区</span>
</a>
</li>
</ul>
<div class="clearfix"></div>
<div class="tab-content tab-wraped">
<div id="one" class="tab-pane active">
<ul class="goods-intro unstyled">
<#list customAttributeList as item>
<#if item.value??>
<li>${item.text}:${item.value}</li>
</#if>
</#list>
</ul>
<div class="intro-detail">
${goodsDesc.introduction}
</div>
</div>
<div id="two" class="tab-pane">
<p>${goodsDesc.packageList}</p>
</div>
<div id="three" class="tab-pane">
<p>${goodsDesc.saleService}</p>
</div>
<div id="four" class="tab-pane">
<p>商品评价</p>
</div>
<div id="five" class="tab-pane">
<p>手机社区</p>
</div>
</div>
</div>
</div>
</div>
<!--like-->
<div class="clearfix"></div>
<div class="like">
<h4 class="kt">猜你喜欢</h4>
<div class="like-list">
<ul class="yui3-g">
<li class="yui3-u-1-6">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/itemlike01.png" />
</div>
<div class="attr">
<em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>3699.00</i>
</strong>
</div>
<div class="commit">
<i class="command">已有6人评价</i>
</div>
</div>
</li>
<li class="yui3-u-1-6">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/itemlike02.png" />
</div>
<div class="attr">
<em>Apple苹果iPhone 6s/6s Plus 16G 64G 128G</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>4388.00</i>
</strong>
</div>
<div class="commit">
<i class="command">已有700人评价</i>
</div>
</div>
</li>
<li class="yui3-u-1-6">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/itemlike03.png" />
</div>
<div class="attr">
<em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>4088.00</i>
</strong>
</div>
<div class="commit">
<i class="command">已有700人评价</i>
</div>
</div>
</li>
<li class="yui3-u-1-6">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/itemlike04.png" />
</div>
<div class="attr">
<em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>4088.00</i>
</strong>
</div>
<div class="commit">
<i class="command">已有700人评价</i>
</div>
</div>
</li>
<li class="yui3-u-1-6">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/itemlike05.png" />
</div>
<div class="attr">
<em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>4088.00</i>
</strong>
</div>
<div class="commit">
<i class="command">已有700人评价</i>
</div>
</div>
</li>
<li class="yui3-u-1-6">
<div class="list-wrap">
<div class="p-img">
<img src="img/_/itemlike06.png" />
</div>
<div class="attr">
<em>DELL戴尔Ins 15MR-7528SS 15英寸 银色 笔记本</em>
</div>
<div class="price">
<strong>
<em>¥</em>
<i>4088.00</i>
</strong>
</div>
<div class="commit">
<i class="command">已有700人评价</i>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<!-- 底部栏位 -->
<!--页面底部 开始 -->
<#include "foot.ftl">
<!--页面底部 结束 -->
</body>
</html>
三、创建服务,用于生成商品详情的静态页面
package cn.itcast.core.service;
import cn.itcast.core.dao.good.GoodsDao;
import cn.itcast.core.dao.good.GoodsDescDao;
import cn.itcast.core.dao.item.ItemCatDao;
import cn.itcast.core.dao.item.ItemDao;
import cn.itcast.core.pojo.good.Goods;
import cn.itcast.core.pojo.good.GoodsDesc;
import cn.itcast.core.pojo.item.Item;
import cn.itcast.core.pojo.item.ItemCat;
import cn.itcast.core.pojo.item.ItemQuery;
import com.alibaba.dubbo.config.annotation.Service;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ServletConfigAware;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class CmsServiceImpl implements CmsService, ServletContextAware {
@Autowired
private GoodsDao goodsDao;
@Autowired
private GoodsDescDao goodsDescDao;
@Autowired
private ItemDao itemDao;
@Autowired
private ItemCatDao itemCatDao;
@Autowired
private FreeMarkerConfigurer freemarkerConfig;
private ServletContext servletContext;
@Override
public void createGoodsInfoPage(Long goodsId, Map<String, Object> map) throws Exception {
//1.创建模板初始化对象
Configuration conf = freemarkerConfig.getConfiguration();
//2.创建模板对象
Template template = conf.getTemplate("item.ftl");
//3.输出流
String path = goodsId + ".html";
String realPath = servletContext.getRealPath(path);
Writer out = new OutputStreamWriter(new FileOutputStream(new File(realPath)),"utf-8");
//4.生成页面
template.process(map,out);
//5.关闭流
out.close();
}
/**
* 获取商品数据
* @param goodsId
* @return
*/
@Override
public Map<String, Object> getGoodsInfo(Long goodsId) {
//1.获取商品数据
Goods goods = goodsDao.selectByPrimaryKey(goodsId);
//2.获取商品详情数据
GoodsDesc goodsDesc = goodsDescDao.selectByPrimaryKey(goodsId);
//3.获取库存数据
ItemQuery itemQuery = new ItemQuery();
ItemQuery.Criteria criteria = itemQuery.createCriteria();
criteria.andGoodsIdEqualTo(goodsId);
List<Item> itemList = itemDao.selectByExample(itemQuery);
//4.获取分类数据
ItemCat itemCat1 = itemCatDao.selectByPrimaryKey(goods.getCategory1Id());
ItemCat itemCat2 = itemCatDao.selectByPrimaryKey(goods.getCategory2Id());
ItemCat itemCat3 = itemCatDao.selectByPrimaryKey(goods.getCategory3Id());
//5.组装数据
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("goods",goods);
resultMap.put("goodsDesc",goodsDesc);
resultMap.put("itemList",itemList);
resultMap.put("itemCat1",itemCat1);
resultMap.put("itemCat2",itemCat2);
resultMap.put("itemCat3",itemCat3);
return resultMap;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
}
四、当商品审核通过时,进行商品详情页面的创建
/**
* 修改审核状态
* @param ids
* @param status
* @return
*/
@RequestMapping("/updateStatus")
public Result updateStatus(Long[] ids, String status){
try {
if (ids!=null){
for (Long id : ids) {
//更新商品状态
goodsService.updateStatus(id,status);
//当审核通过时
if ("1".equals(status)){
//1、将库存数据存储到索引库中
solrManagerService.importItemDataToSolr(id);
//2、创建商品详情页面
Map<String, Object> goodsInfo = cmsService.getGoodsInfo(id);
cmsService.createGoodsInfoPage(id,goodsInfo);
}
}
}
return new Result(true,"状态修改成功!");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"状态修改失败!");
}
}
五、生成商品详情页面