- 大多数搜索引擎应用都必须具有某种搜索功能,问题是搜索功能往往是巨大的资源消耗,并且它们会由于沉重的数据库加载而拖垮你的应用性能。
- 这就是为什么转移负载到一个外部的搜索服务器的主要原因,Apache Solr是一个流行的开源搜索服务器,它通过使用类似REST的HTTP API,确保你能从几乎任何编程语言来使用solr。
- Solr是一个开源搜索平台,用于构建搜索应用程序。 它建立在 Lucene (全文搜索引擎)之上。Solr是企业级的,快速的,高度可扩展的。
- 为了在CNET网络的公司网站上添加搜索功能,Yonik Seely于2004年创建了Solr。并在2006年1月,它成为Apache软件基金会下的一个开源项目。并于2016年发布最新版本Solr 6.0,支持并行SQL查询的执行。
- Solr可以和Hadoop一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,它是一种非关系数据存储和处理技术。
- 总之,Solr是一个可扩展的,可部署,搜索 / 存储引擎,优化搜索大量以文本为中心的数据。
获取 solr
注意:需要提前配置好linux下的java环境
- 上传压缩包至 linux,并解压到/usr/local/solr目录下(软件\solr\solr-7.2.1.tgz)
- 进入解压目录,进入bin目录,启动:
./solr start -force //root用户启动需要增加 -force
上述正常可直接跳转4,创建核心库
- 访问:Solr服务的默认服务端口是8983,此刻访问你的 http://IP:8983 , 应该可以看到Solr的控制面板了。
例如中级项目为:http://192.168.188.180:8983
访问 8983端口 连接失败,原因可能有两个:
(1)Solr 服务没有启动,启动即可,可以通过命令查看Solr的当前状态
cd /usr/local/solr/bin
./solr status
(2)把防火墙相关端口打开:
firewall-cmd --add-port=8983/tcp --permanent
firewall-cmd --reload
- 创建core:core是solr的特有概念,每个core是一个查询数据、索引等的集合体,你可以把它想象成一个独立数据库,我们创建一个新core:名字[collection1]
cd /usr/solr/bin
./solr create -c collection1 -force // -c 指定要创建的Core名称 root用户启动需要增加 -force
创建成功刷新页面显示:
IK Analyzer 是一个开源的,基于 java 语言开发的轻量级的中文分词工具包。从 2006年 12 月推出 1.0 版开始, IKAnalyzer 已经推出了 4 个大版本。最初,它是以开源项目Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立 Lucene 项目,同时提供了对 Lucene 的默认优化实现。在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。
步骤:
- 下载 IKAnalyzer for solr5 的源码包,然后使用Maven编译,得到一个文件IKAnalyzer-5.0.jar
- 上传ik jar包到/usr / local / solr / server / solr-webapp / webapp / WEB-INF / lib目录中
- 修改/usr / local / solr / server / solr / collection1 / conf / managed-schema,添加fieldType内容:
(注:先安装连接 Notepad++ 五、Notepad++)
然后,重启 solr
./solr restart -force
1、刷新网页测试分词:登录Solr管理控制台,选择collection1,点击Analyse 进入分词界面
选择分词类型 FileType : text_ik
在Field Value (Index) 输入要测试的中文语句,Field Value (Query) 输入要检索的关键词:
(建议到 Notepad++ 中操作)
域相当于数据库的表字段,用户存放数据,因此用户根据业务需要去定义相关的Field(域),一般来说,每一种对应着一种数据,用户对同一种数据进行相同的操作。
域的常用属性:
- name:指定域的名称
- type:指定域的类型
- indexed:是否索引
- stored:是否存储
- required:是否必须
- multiValued:是否多值
修改 /usr / local / solr / server / solr / collection1 / conf / managed-schema,设置业务系统 Field
删除多余的field,保留id,version,_text_这三个field
复制域的作用在于将某一个Field中的数据复制到另一个域中
当我们需要动态扩充字段时,就需要使用动态域。对于优乐选,规格的值是不确定的,所以我们需要使用动态域来实现。如:
配置:
保存,重启 solr !
虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?可以,Spring Data Solr就是为了方便Solr的开发所研制的一个框架,其底层是对SolrJ(官方API)的封装。
(1)创建maven jar 工程 spring-data-solr ,并且在pom.xml中引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.datagroupId>
<artifactId>spring-data-solrartifactId>
<version>1.5.5.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.2.4.RELEASEversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.7.0version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
plugins>
build>
(2)在src/main/resources下创建 spring / spring_solr.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:solr="http://www.springframework.org/schema/data/solr"
xsi:schemaLocation="http://www.springframework.org/schema/data/solr
http://www.springframework.org/schema/data/solr/spring-solr.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<solr:solr-server id="solrServer" url="http://192.168.188.180:8983/solr/collection1" />
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServer" />
bean>
beans>
创建 com.zql.pojo 包,将优乐选的TbItem实体类拷入本工程 ,属性使用@Field注解标识 。 如果属性与solr配置文件定义的域名称不一致,需要在注解中指定域名称。
package com.zql.pojo;
import org.apache.solr.client.solrj.beans.Field;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
public class TbItem implements Serializable {
private Long id;
@Field("item_title")
private String title;
private String sellPoint;
@Field("item_price")
private BigDecimal price;
private Integer stockCount;
private Integer num;
private String barcode;
@Field("item_image")
private String image;
private Long categoryid;
private String status;
private Date createTime;
@Field("item_updatetime")
private Date updateTime;
private String itemSn;
private BigDecimal costPirce;
private BigDecimal marketPrice;
private String isDefault;
@Field("item_goodsid")
private Long goodsId;
private String sellerId;
private String cartThumbnail;
@Field("item_category")
private String category;
@Field("item_brand")
private String brand;
private String spec;
@Field("item_seller")
private String seller;
private static final long serialVersionUID = 1L;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title == null ? null : title.trim();
}
public String getSellPoint() {
return sellPoint;
}
public void setSellPoint(String sellPoint) {
this.sellPoint = sellPoint == null ? null : sellPoint.trim();
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getStockCount() {
return stockCount;
}
public void setStockCount(Integer stockCount) {
this.stockCount = stockCount;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode == null ? null : barcode.trim();
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image == null ? null : image.trim();
}
public Long getCategoryid() {
return categoryid;
}
public void setCategoryid(Long categoryid) {
this.categoryid = categoryid;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status == null ? null : status.trim();
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getItemSn() {
return itemSn;
}
public void setItemSn(String itemSn) {
this.itemSn = itemSn == null ? null : itemSn.trim();
}
public BigDecimal getCostPirce() {
return costPirce;
}
public void setCostPirce(BigDecimal costPirce) {
this.costPirce = costPirce;
}
public BigDecimal getMarketPrice() {
return marketPrice;
}
public void setMarketPrice(BigDecimal marketPrice) {
this.marketPrice = marketPrice;
}
public String getIsDefault() {
return isDefault;
}
public void setIsDefault(String isDefault) {
this.isDefault = isDefault == null ? null : isDefault.trim();
}
public Long getGoodsId() {
return goodsId;
}
public void setGoodsId(Long goodsId) {
this.goodsId = goodsId;
}
public String getSellerId() {
return sellerId;
}
public void setSellerId(String sellerId) {
this.sellerId = sellerId == null ? null : sellerId.trim();
}
public String getCartThumbnail() {
return cartThumbnail;
}
public void setCartThumbnail(String cartThumbnail) {
this.cartThumbnail = cartThumbnail == null ? null : cartThumbnail.trim();
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category == null ? null : category.trim();
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand == null ? null : brand.trim();
}
public String getSpec() {
return spec;
}
public void setSpec(String spec) {
this.spec = spec == null ? null : spec.trim();
}
public String getSeller() {
return seller;
}
public void setSeller(String seller) {
this.seller = seller == null ? null : seller.trim();
}
}
测试:
创建测试类TestSolr.java
package com.zql;
import com.zql.pojo.TbItem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.math.BigDecimal;
/**
* @Author:Daniel
* @Version 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring_solr.xml")
public class TestSolr {
@Autowired
private SolrTemplate solrTemplate;
@Test
public void testAdd(){
TbItem item = new TbItem();
// 主键相同,即修改
item.setId(5L);
item.setBrand("大话");
item.setCategory("手抓");
item.setGoodsId(1L);
item.setSeller("专卖店");
item.setTitle("米Mate9");
item.setPrice(new BigDecimal(4500));
solrTemplate.saveBean(item);
solrTemplate.commit();
}
}
浏览器输入:http://192.168.188.180:8983/
运行结果如下:
去看看:访问solr控制台–找到对应core—查找
- q:查询关键字:必须的,如果查询所有使用*
- fq:(filter query)过虑查询:作用:在q查询符合结果中同时是fq查询符合的
如:过滤查询价格从1到20的记录,使用 item_price:[0 TO 4000]
也可以使用“*”表示无限,例如:
20以上:price:[20 TO ]
20以下:price:[ TO 20]
- sort:排序:格式:sort=+
[,+ ]… 。
示例:product_price desc 按照价格从高到低进行排序- product_price asc 按照价格从低到高进行排序
- start, rows:行的索引,从0开始,[start, rows]
- fl:指定返回那些字段内容:用逗号或空格分隔多个,不写默认返回全部配置的。
- df:指定一个默认搜索Field:一般默认
- wt:(writer type)指定输出格式:可以有xml, json, csv, python, php等格式
- hl:是否高亮:设置高亮Field,设置格式前缀和后缀。
package com.zql;
import com.zql.pojo.TbItem;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.Query;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* @Author:Daniel
* @Version 1.0
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring_solr.xml")
public class TestSolr {
@Autowired
private SolrTemplate solrTemplate;
@Test
public void testAdd(){
TbItem item = new TbItem();
// 主键相同,即修改
item.setId(5L);
item.setBrand("大话");
item.setCategory("手抓");
item.setGoodsId(1L);
item.setSeller("专卖店");
item.setTitle("米Mate9");
item.setPrice(new BigDecimal(4500));
solrTemplate.saveBean(item);
solrTemplate.commit();
}
//按主键查询
@Test
public void testFindOne(){
TbItem byId = solrTemplate.getById(5, TbItem.class);
System.out.println(byId.getBrand());
}
//按主键删除
@Test
public void deleteByKey(){
solrTemplate.deleteById("5");
solrTemplate.commit();
}
//首先循环插入100条测试数据分页查询
@Test
public void testAddList(){
List<TbItem> list=new ArrayList();
for(int i=1;i<101;i++){
TbItem item=new TbItem();
item.setId(Long.valueOf(i));
item.setBrand("华为");
item.setCategory("手机");
item.setGoodsId(1L);
item.setSeller("华为"+i+"号专卖店");
item.setTitle("华为Mate"+i);
item.setPrice(new BigDecimal(2000+i));
list.add(item);
}
solrTemplate.saveBeans(list);
solrTemplate.commit();
}
//分页查询测试
@Test
public void pageTestSolr(){
Query query = new SimpleQuery("*:*");
query.setOffset(10);// 开始索引(默认0)
query.setRows(20); // 每页记录数(默认10)
ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
System.out.println("总记录数:" + page.getTotalElements());
List<TbItem> list = page.getContent();
for (TbItem item : list) {
System.out.println(item.getTitle() + item.getPrice());
}
}
//条件查询
@Test
public void testPageQueryMutil(){
Query query = new SimpleQuery("*:*");
Criteria criteria = new Criteria("item_title").contains("2");
criteria = criteria.and("item_price").greaterThan(2020);
query.addCriteria(criteria);
Sort s = new Sort(Sort.Direction.DESC, "item_price");
query.addSort(s);
// query.setOffset(10); //开始索引(默认0)
// query.setRows(100); //每页记录数(默认10)
ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class);
System.out.println("总记录数:" + page.getTotalElements());
List<TbItem> list = page.getContent();
for (TbItem item : list) {
System.out.println(item.getTitle() + "," + item.getPrice());
}
}
//删除全部数据
@Test
public void testDeleteAll(){
SimpleQuery query = new SimpleQuery("*:*");
solrTemplate.delete(query);
solrTemplate.commit();
}
}
Criteria 用于对条件的封装:
运行分别如下:
案例源码
编写专门的导入程序,将商品数据导入到Solr系统中。上线前,或测试时手动数据导入,真正上线后,会实时自动同步。
(1)创建子模块 youlexuan_solr_util(jar)模块, 引入youlexuan_dao 以及spring 相关依赖
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
dependency>
<dependency>
<groupId>com.zqlgroupId>
<artifactId>youlexuan_daoartifactId>
<version>1.0version>
dependency>
dependencies>
(2)src/main/resources下创建 spring / applicationContext_solr.xml配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:solr="http://www.springframework.org/schema/data/solr"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/data/solr
http://www.springframework.org/schema/data/solr/spring-solr.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.zql.solrutil"/>
<solr:solr-server id="solrServer" url="http://192.168.188.180:8983/solr/collection1" />
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServer" />
bean>
beans>
(1)将solr入门 demo工程 中添加了@Field注解的实体类拷贝到youlexuan_pojo中
package com.zql.pojo;
import org.apache.solr.client.solrj.beans.Field;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
public class TbItem implements Serializable {
private Long id;
@Field("item_title")
private String title;
private String sellPoint;
@Field("item_price")
private BigDecimal price;
private Integer stockCount;
private Integer num;
private String barcode;
@Field("item_image")
private String image;
private Long categoryid;
private String status;
private Date createTime;
@Field("item_updatetime")
private Date updateTime;
private String itemSn;
private BigDecimal costPirce;
private BigDecimal marketPrice;
private String isDefault;
@Field("item_goodsid")
private Long goodsId;
private String sellerId;
private String cartThumbnail;
@Field("item_category")
private String category;
@Field("item_brand")
private String brand;
private String spec;
@Field("item_seller")
private String seller;
private static final long serialVersionUID = 1L;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title == null ? null : title.trim();
}
public String getSellPoint() {
return sellPoint;
}
public void setSellPoint(String sellPoint) {
this.sellPoint = sellPoint == null ? null : sellPoint.trim();
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public Integer getStockCount() {
return stockCount;
}
public void setStockCount(Integer stockCount) {
this.stockCount = stockCount;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode == null ? null : barcode.trim();
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image == null ? null : image.trim();
}
public Long getCategoryid() {
return categoryid;
}
public void setCategoryid(Long categoryid) {
this.categoryid = categoryid;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status == null ? null : status.trim();
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public String getItemSn() {
return itemSn;
}
public void setItemSn(String itemSn) {
this.itemSn = itemSn == null ? null : itemSn.trim();
}
public BigDecimal getCostPirce() {
return costPirce;
}
public void setCostPirce(BigDecimal costPirce) {
this.costPirce = costPirce;
}
public BigDecimal getMarketPrice() {
return marketPrice;
}
public void setMarketPrice(BigDecimal marketPrice) {
this.marketPrice = marketPrice;
}
public String getIsDefault() {
return isDefault;
}
public void setIsDefault(String isDefault) {
this.isDefault = isDefault == null ? null : isDefault.trim();
}
public Long getGoodsId() {
return goodsId;
}
public void setGoodsId(Long goodsId) {
this.goodsId = goodsId;
}
public String getSellerId() {
return sellerId;
}
public void setSellerId(String sellerId) {
this.sellerId = sellerId == null ? null : sellerId.trim();
}
public String getCartThumbnail() {
return cartThumbnail;
}
public void setCartThumbnail(String cartThumbnail) {
this.cartThumbnail = cartThumbnail == null ? null : cartThumbnail.trim();
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category == null ? null : category.trim();
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand == null ? null : brand.trim();
}
public String getSpec() {
return spec;
}
public void setSpec(String spec) {
this.spec = spec == null ? null : spec.trim();
}
public String getSeller() {
return seller;
}
public void setSeller(String seller) {
this.seller = seller == null ? null : seller.trim();
}
}
(2)在youlexuan_pojo中引入依赖
<dependencies>
<dependency>
<groupId>org.springframework.datagroupId>
<artifactId>spring-data-solrartifactId>
<version>1.5.5.RELEASEversion>
dependency>
dependencies>
创建com.zql.solrutil 包,创建类SolrUtil,实现商品数据的查询(已审核商品)
package com.zql.solrutil;
import com.zql.mapper.TbItemMapper;
import com.zql.pojo.TbItem;
import com.zql.pojo.TbItemExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Author:Daniel
* @Version 1.0
*/
@Component
public class SolrUtil {
@Autowired
private TbItemMapper itemMapper;
@Autowired
private SolrTemplate solrTemplate;
public void importItemData(){
TbItemExample example = new TbItemExample();
TbItemExample.Criteria criteria = example.createCriteria();
criteria.andStatusEqualTo("1");
List<TbItem> itemList = itemMapper.selectByExample(example);
System.out.println("商品列表");
for (TbItem tbItem : itemList) {
System.out.println(tbItem.getTitle()+"\t"+tbItem.getPrice());
}
solrTemplate.saveBeans(itemList);
solrTemplate.commit();
System.out.println("导入成功");
}
//删除
public void delete(){
SimpleQuery query = new SimpleQuery("*:*");
solrTemplate.delete(query);
solrTemplate.commit();
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext_*.xml");
SolrUtil solrUtil = (SolrUtil) context.getBean("solrUtil");
//solrUtil.delete();
solrUtil.importItemData();
}
}
浏览器效果:http://192.168.188.180:8983
修改工程 youlexuan_pojo 里面的TbItem.java ,添加属性(还要getter setter方法)
@Dynamic
@Field("item_spec_*") //Notepad++加入得那一条动态域
private Map<String,String> specMap;
public Map<String, String> getSpecMap() {
return specMap;
}
public void setSpecMap(Map<String, String> specMap) {
this.specMap = specMap;
}
修改youlexuan_solr_util 的 SolrUtil.java ,先引入fastJSON依赖
引入中文转化依赖
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
<dependency>
<groupId>com.github.promeggroupId>
<artifactId>tinypinyinartifactId>
<version>2.0.3version>
dependency>
注意:
- solr 5.x后,安装方式从 tomcat 中独立出来,且键不支持中文了。因此,itme_spec_网络 的动态属性,会保存为itme_spec___ 形式的下划线。
- 解决方案:将中文转为拼音。
SolrUtil.java 完整代码:
package com.zql.solrutil;
import com.alibaba.fastjson.JSON;
import com.github.promeg.pinyinhelper.Pinyin;
import com.zql.mapper.TbItemMapper;
import com.zql.pojo.TbItem;
import com.zql.pojo.TbItemExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author:Daniel
* @Version 1.0
*/
@Component
public class SolrUtil {
@Autowired
private TbItemMapper itemMapper;
@Autowired
private SolrTemplate solrTemplate;
public void importItemData(){
TbItemExample example = new TbItemExample();
TbItemExample.Criteria criteria = example.createCriteria();
criteria.andStatusEqualTo("1");
List<TbItem> itemList = itemMapper.selectByExample(example);
System.out.println("商品列表");
//遍历全部通过审核商品列表数据
for (TbItem tbItem : itemList) {
System.out.println(tbItem.getTitle()+"\t"+tbItem.getPrice());
//读取规格数据,字符串,转换成json对象
Map<String,String> specMap = JSON.parseObject(tbItem.getSpec(), Map.class);
/**① solr显示:两个_ _
* "item_spec___":"联通3G",
* "item_spec_____":"16G",
*/
//创建一个新map集合存储拼音
Map<String, String> pinyinMap = new HashMap<>();
//遍历map,替换key从汉字变为拼音
for (String key : specMap.keySet()) {
pinyinMap.put(Pinyin.toPinyin(key,"").toLowerCase(),specMap.get(key));
/**
* ② solr显示: 大写字母,转小写使用:toLowerCase()
* "item_spec_WANGLUO":"联通3G",
* "item_spec_JISHENNEICUN":"16G",
*
* 变为小写如下
* "item_spec_jishenneicun":"16G",
* "item_spec_wangluo":"联通3G",
*/
}
tbItem.setSpecMap(pinyinMap);
}
//保存集合数据到solr
solrTemplate.saveBeans(itemList);
solrTemplate.commit();
System.out.println("导入成功");
}
//删除
public void delete(){
SimpleQuery query = new SimpleQuery("*:*");
solrTemplate.delete(query);
solrTemplate.commit();
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext_*.xml");
SolrUtil solrUtil = (SolrUtil) context.getBean("solrUtil");
// solrUtil.delete();
solrUtil.importItemData();
}
}
显示一:
显示二:
最终优化:
打开搜索页面,在搜索框输入要搜索的关键字,点击搜索按钮即可进行搜索,展示搜索结果
(1)创建youlexuan_search_interface模块(搜索服务接口),依赖youlexuan_pojo
<dependencies>
<dependency>
<groupId>com.zqlgroupId>
<artifactId>youlexuan_pojoartifactId>
<version>1.0version>
dependency>
dependencies>
(2)创建com.zql.search.service包,创建业务接口 ItemSearchService
package com.zql.search.service;
import java.util.Map;
/**
* @Author:Daniel
* @Version 1.0
* 搜索
*/
public interface ItemSearchService {
public Map<String,Object> search(Map searchMap);
}
(1)创建war工程youlexuan_search_service,pom参考其它服务工程,如youlexuan_content_service:
- 去掉对dao的依赖,查询走solr索引库
- 引入youlexuan_search_interface依赖
- tomcat端口9003
<packaging>warpackaging>
<properties>
<webVersion>3.0webVersion>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jmsartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
<dependency>
<groupId>javassistgroupId>
<artifactId>javassistartifactId>
dependency>
<dependency>
<groupId>commons-codecgroupId>
<artifactId>commons-codecartifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.zqlgroupId>
<artifactId>youlexuan_commonartifactId>
<version>1.0version>
dependency>
<dependency>
<groupId>com.zqlgroupId>
<artifactId>youlexuan_search_interfaceartifactId>
<version>1.0version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<configuration>
<path>/path>
<port>9003port>
configuration>
plugin>
plugins>
build>
(2)添加web.xml ,参考其它服务工程,如youlexuan_content_service
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath*:spring/applicationContext_*.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
web-app>
(3)在src/main/resources下配置文件,参见其它服务工程,如 youlexuan_content_service:
- 对事务控制的 service.xml 可以删除
- dubbo端口20883,应用名,包名,然后在youlexuan_search_service下面创建包
com.zql.search.service.impl
applicationContext_service.xml
<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">
<dubbo:protocol name="dubbo" port="20883">dubbo:protocol>
<dubbo:application name="youlexuan_search_service"/>
<dubbo:registry address="zookeeper://192.168.188.180:2181"/>
<dubbo:annotation package="com.zql.search.service.impl" />
beans>
(4)在src/main/resources下,复制youlexuan-solr-util 的 applicationContext_solr.xml 并且删掉扫描包
applicationContext_solr.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:solr="http://www.springframework.org/schema/data/solr"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/data/solr
http://www.springframework.org/schema/data/solr/spring-solr.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<solr:solr-server id="solrServer" url="http://192.168.188.180:8983/solr/collection1" />
<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
<constructor-arg ref="solrServer" />
bean>
beans>
(5)在包下创建并编写服务实现类 ItemSearchServiceImpl.java
package com.zql.search.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.zql.pojo.TbItem;
import com.zql.search.service.ItemSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.Criteria;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.data.solr.core.query.result.ScoredPage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author:Daniel
* @Version 1.0
*/
@Service(timeout = 3000)
public class ItemSearchServiceImpl implements ItemSearchService {
@Autowired
private SolrTemplate solrTemplate;
@Override
public Map<String, Object> search(Map searchMap) {
Map<String, Object> map = new HashMap<>();
SimpleQuery query = new SimpleQuery();
// is:基于分词后的结果 和 传入的参数匹配
Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keyWords"));
// 添加查询条件
query.addCriteria(criteria);
ScoredPage<TbItem> tbItems = solrTemplate.queryForPage(query, TbItem.class);
List<TbItem> itemList = tbItems.getContent();
long total = tbItems.getTotalElements();
map.put("rows",itemList);
map.put("total",total);
return map;
}
}
(1)创建子工程 youlexuan_search_web 的 war工程
pom依赖参见其它web模块,如:youlexuan_portal_web
- 依赖 youlexuan_search_interface
- tomcat 端口 9104
<packaging>warpackaging>
<properties>
<webVersion>3.0webVersion>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-aspectsartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jmsartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-supportartifactId>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>dubboartifactId>
dependency>
<dependency>
<groupId>org.apache.zookeepergroupId>
<artifactId>zookeeperartifactId>
dependency>
<dependency>
<groupId>org.apache.curatorgroupId>
<artifactId>curator-recipesartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
<dependency>
<groupId>javassistgroupId>
<artifactId>javassistartifactId>
dependency>
<dependency>
<groupId>commons-codecgroupId>
<artifactId>commons-codecartifactId>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.zqlgroupId>
<artifactId>youlexuan_search_interfaceartifactId>
<version>1.0version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<configuration>
<path>/path>
<port>9104port>
configuration>
plugin>
plugins>
build>
(2)添加web.xml,参见其它web工程,如:youlexuan_portal_web
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>springmvcservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring/springmvc.xmlparam-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>springmvcservlet-name>
<url-pattern>*.dourl-pattern>
servlet-mapping>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:spring/spring*.xmlparam-value>
context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
listener-class>
listener>
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
(3)添加配置文件,参见其它web工程,如:youlexuan_portal_web
spring_mvc.xml修改:应用名,包名
<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:mvc="http://www.springframework.org/schema/mvc"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<context:component-scan base-package="com.zql"/>
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json"/>
<property name="features">
<array>
<value>WriteMapNullValuevalue>
<value>WriteDateUseDateFormatvalue>
array>
property>
bean>
mvc:message-converters>
mvc:annotation-driven>
<dubbo:application name="youlexuan_search_web" />
<dubbo:registry address="zookeeper://192.168.188.180:2181"/>
<dubbo:annotation package="com.zql" />
beans>
(4)创建包com.zql.search.controller 编写控制器类 ItemSearchController.java
package com.zql.search.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.zql.search.service.ItemSearchService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* @Author:Daniel
* @Version 1.0
*/
@RestController
@RequestMapping("/itemSearch")
public class ItemSearchController {
@Reference
private ItemSearchService itemSearchService;
//@Reference是注入的分布式中的远程服务对象,需要dubbo的配置;
// @Resource和@Autowired是注入本地spring容器中的对象
@RequestMapping("/search")
public Map<String, Object> search(@RequestBody Map searchMap){
return itemSearchService.search(searchMap);
}
}
测试后端可参见postman工具 八、postman的使用
http://localhost:9104/itemSearch/search.do
{'keyWords':'手机'}
将 资源 \ 静态原型 \ 网站前台,所需资源拷贝至youlexuan_search_web \ webapp 下面
拷贝base.js到js文件夹,并在js文件夹下建立service、controller目录
youlexuan_search_web工程创建 searchService.js
app.service('searchService',function ($http) {
this.search = function (searchMap) {
return $http.post("itemSearch/search.do",searchMap);
}
});
youlexuan_search_web 工程 searchController.js
app.controller('searchController',function ($scope,$controller,searchService) {
$controller('baseController',{$scope:$scope});//继承
$scope.search=function () {
searchService.search($scope.searchMap).success(function (response) {
$scope.resultMap = response; //搜索返回的结果
})
}
});
youlexuan_search_web工程search.html
引入js、指定控制器
前台测试显示查看
测试:
- 安装youlexuan_search_interface
- 启动youlexuan_search_service
- 启动youlexuan_search_web
测试:http://localhost:9104/search.html
附完整 search.html
DOCTYPE html>
DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<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-list.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/service/searchService.js">script>
<script type="text/javascript" src="js/controller/baseController.js">script>
<script type="text/javascript" src="js/controller/searchController.js">script>
<style type="text/css" >
.hot-list .list-wrap {
box-sizing:border-box;
padding-left:20px;
}
style>
head>
<body ng-app="youlexuan" ng-controller="searchController">
<div id="nav-bottom">
<div class="nav-top">
<div class="top">
<div class="py-container">
<div class="shortcut">
<ul class="fl">
<li class="f-item">优乐选欢迎您!li>
<li class="f-item">请
<a href="login.html" target="_blank">登录a> <span><a href="register.html" target="_blank">免费注册a>span>li>
ul>
<ul class="fr">
<li class="f-item">我的订单li>
<li class="f-item space">li>
<li class="f-item">
<a href="home.html" target="_blank">我的优乐选a>
li>
<li class="f-item space">li>
<li class="f-item">优乐选会员li>
<li class="f-item space">li>
<li class="f-item">企业采购li>
<li class="f-item space">li>
<li class="f-item">关注优乐选li>
<li class="f-item space">li>
<li class="f-item" id="service">
<span>客户服务span>
<ul class="service">
<li>
<a href="cooperation.html" target="_blank">合作招商a>
li>
<li>
<a href="shoplogin.html" target="_blank">商家后台a>
li>
<li>
<a href="cooperation.html" target="_blank">合作招商a>
li>
<li>
<a href="#">商家后台a>
li>
ul>
li>
<li class="f-item space">li>
<li class="f-item">网站导航li>
ul>
div>
div>
div>
<div class="header">
<div class="py-container">
<div class="yui3-g Logo">
<div class="yui3-u Left logoArea">
<a class="logo-bd" title="优乐选" href="JD-index.html" target="_blank">a>
div>
<div class="yui3-u Center searchArea">
<div class="search">
<form action="" class="sui-form form-inline">
<div class="input-append">
<input type="text" id="autocomplete" ng-model="searchMap.keyWords" type="text" class="input-error input-xxlarge" />
<button class="sui-btn btn-xlarge btn-danger" ng-click="search()" type="button">搜索button>
div>
form>
div>
<div class="hotwords">
<ul>
<li class="f-item">优乐选首发li>
<li class="f-item">亿元优惠li>
<li class="f-item">9.9元团购li>
<li class="f-item">每满99减30li>
<li class="f-item">亿元优惠li>
<li class="f-item">9.9元团购li>
<li class="f-item">办公用品li>
ul>
div>
div>
<div class="yui3-u Right shopArea">
<div class="fr shopcar">
<div class="show-shopcar" id="shopcar">
<span class="car">span>
<a class="sui-btn btn-default btn-xlarge" href="cart.html" target="_blank">
<span>我的购物车span>
<i class="shopnum">0i>
a>
<div class="clearfix shopcarlist" id="shopcarlist" style="display:none">
<p>"啊哦,你的购物车还没有商品哦!"p>
<p>"啊哦,你的购物车还没有商品哦!"p>
div>
div>
div>
div>
div>
<div class="yui3-g NavList">
<div class="yui3-u Left all-sort">
<h4>全部商品分类h4>
div>
<div class="yui3-u Center navArea">
<ul class="nav">
<li class="f-item">服装城li>
<li class="f-item">美妆馆li>
<li class="f-item">品优超市li>
<li class="f-item">全球购li>
<li class="f-item">闪购li>
<li class="f-item">团购li>
<li class="f-item">有趣li>
<li class="f-item">
<a href="seckill-index.html" target="_blank">秒杀a>
li>
ul>
div>
<div class="yui3-u Right">div>
div>
div>
div>
div>
div>
<div class="main">
<div class="py-container">
<div class="bread">
<ul class="fl sui-breadcrumb">
<li>
<a href="#">全部结果 {{resultMap.total}}a>
li>
<li class="active"> 智能手机li>
ul>
<ul class="tags-choose">
<li class="tag">全网通<i class="sui-icon icon-tb-close">i>li>
<li class="tag">63G<i class="sui-icon icon-tb-close">i>li>
ul>
<form class="fl sui-form form-dark">
<div class="input-control control-right">
<input type="text" />
<i class="sui-icon icon-touch-magnifier">i>
div>
form>
<div class="clearfix">div>
div>
<div class="clearfix selector">
<div class="type-wrap">
<div class="fl key">商品分类div>
<div class="fl value">
<a href="#">手机a> <a href="#">电视a>
div>
<div class="fl ext">div>
div>
<div class="type-wrap logo">
<div class="fl key brand">品牌div>
<div class="value logos">
<ul class="logo-list">
<li><img src="img/_/phone01.png" />li>
<li><img src="img/_/phone02.png" />li>
<li><img src="img/_/phone03.png" />li>
<li><img src="img/_/phone04.png" />li>
<li><img src="img/_/phone05.png" />li>
<li><img src="img/_/phone06.png" />li>
<li><img src="img/_/phone07.png" />li>
<li><img src="img/_/phone08.png" />li>
<li><img src="img/_/phone09.png" />li>
<li><img src="img/_/phone10.png" />li>
<li><img src="img/_/phone11.png" />li>
<li><img src="img/_/phone12.png" />li>
<li><img src="img/_/phone13.png" />li>
<li><img src="img/_/phone14.png" />li>
<li><img src="img/_/phone05.png" />li>
<li><img src="img/_/phone06.png" />li>
<li><img src="img/_/phone07.png" />li>
<li><img src="img/_/phone02.png" />li>
ul>
div>
<div class="ext">
<a href="javascript:void(0);" class="sui-btn">多选a>
<a href="javascript:void(0);">更多a>
div>
div>
<div class="type-wrap">
<div class="fl key">网络制式div>
<div class="fl value">
<ul class="type-list">
<li>
<a>GSM(移动/联通2G)a>
li>
<li>
<a>电信2Ga>
li>
<li>
<a>电信3Ga>
li>
<li>
<a>移动3Ga>
li>
<li>
<a>联通3Ga>
li>
<li>
<a>联通4Ga>
li>
<li>
<a>电信3Ga>
li>
<li>
<a>移动3Ga>
li>
<li>
<a>联通3Ga>
li>
<li>
<a>联通4Ga>
li>
ul>
div>
<div class="fl ext">div>
div>
<div class="type-wrap">
<div class="fl key">显示屏尺寸div>
<div class="fl value">
<ul class="type-list">
<li>
<a>4.0-4.9英寸a>
li>
<li>
<a>4.0-4.9英寸a>
li>
ul>
div>
<div class="fl ext">div>
div>
<div class="type-wrap">
<div class="fl key">摄像头像素div>
<div class="fl value">
<ul class="type-list">
<li>
<a>1200万以上a>
li>
<li>
<a>800-1199万a>
li>
<li>
<a>1200-1599万a>
li>
<li>
<a>1600万以上a>
li>
<li>
<a>无摄像头a>
li>
ul>
div>
<div class="fl ext">div>
div>
<div class="type-wrap">
<div class="fl key">价格div>
<div class="fl value">
<ul class="type-list">
<li>
<a>0-500元a>
li>
<li>
<a>500-1000元a>
li>
<li>
<a>1000-1500元a>
li>
<li>
<a>1500-2000元a>
li>
<li>
<a>2000-3000元 a>
li>
<li>
<a>3000元以上a>
li>
ul>
div>
<div class="fl ext">
div>
div>
<div class="type-wrap">
<div class="fl key">更多筛选项div>
<div class="fl value">
<ul class="type-list">
<li>
<a>特点a>
li>
<li>
<a>系统a>
li>
<li>
<a>手机内存 a>
li>
<li>
<a>单卡双卡a>
li>
<li>
<a>其他a>
li>
ul>
div>
<div class="fl ext">
div>
div>
div>
<div class="details">
<div class="sui-navbar">
<div class="navbar-inner filter">
<ul class="sui-nav">
<li class="active">
<a href="#">综合a>
li>
<li>
<a href="#">销量a>
li>
<li>
<a href="#">新品a>
li>
<li>
<a href="#">评价a>
li>
<li>
<a href="#">价格a>
li>
ul>
div>
div>
<div class="goods-list">
<ul class="yui3-g">
<li class="yui3-u-1-5" ng-repeat="item in resultMap.rows">
<div class="list-wrap">
<div class="p-img">
<a href="item.html" target="_blank"><img src="{{item.image}}" />a>
div>
<div class="price">
<strong>
<em>¥em>
<i>{{item.price}}i>
strong>
div>
<div class="attr">
<em>{{item.title}}em>
div>
<div class="cu">
<em>em>
div>
<div class="commit">
<i class="command">已有2000人评价i>
div>
<div class="operate">
<a href="success-cart.html" target="_blank" class="sui-btn btn-bordered btn-danger">加入购物车a>
<a href="javascript:void(0);" class="sui-btn btn-bordered">对比a>
<a href="javascript:void(0);" class="sui-btn btn-bordered">关注a>
div>
div>
li>
ul>
div>
<div class="fr page">
<div class="sui-pagination pagination-large">
<ul>
<li class="prev disabled">
<a href="#">«上一页a>
li>
<li class="active">
<a href="#">1a>
li>
<li>
<a href="#">2a>
li>
<li>
<a href="#">3a>
li>
<li>
<a href="#">4a>
li>
<li>
<a href="#">5a>
li>
<li class="dotted"><span>...span>li>
<li class="next">
<a href="#">下一页»a>
li>
ul>
<div><span>共10页 span><span>
到第
<input type="text" class="page-num">
页 <button class="page-confirm" onclick="alert(1)">确定button>span>div>
div>
div>
div>
<div class="clearfix hot-sale">
<h4 class="title">热卖商品h4>
<div class="hot-list">
<ul class="yui3-g">
<li class="yui3-u-1-4">
<div class="list-wrap">
<div class="p-img">
<img src="img/xg/h02.png" />
div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)em>
div>
<div class="price">
<strong>
<em>¥em>
<i>4088.00i>
strong>
div>
<div class="commit">
<i class="command">已有700人评价i>
div>
div>
li>
<li class="yui3-u-1-4">
<div class="list-wrap">
<div class="p-img">
<img src="img/xg/h05.png" />
div>
<div class="attr">
<em>金属A面,360°翻转,APP下单省300!em>
div>
<div class="price">
<strong>
<em>¥em>
<i>4088.00i>
strong>
div>
<div class="commit">
<i class="command">已有700人评价i>
div>
div>
li>
<li class="yui3-u-1-4">
<div class="list-wrap">
<div class="p-img">
<img src="img/xg/h04.png" />
div>
<div class="attr">
<em>256SSD商务大咖,完爆职场,APP下单立减200em>
div>
<div class="price">
<strong>
<em>¥em>
<i>4068.00i>
strong>
div>
<div class="commit">
<i class="command">已有20人评价i>
div>
div>
li>
<li class="yui3-u-1-4">
<div class="list-wrap">
<div class="p-img">
<img src="img/xg/h03.png" />
div>
<div class="attr">
<em>Apple苹果iPhone 6s (A1699)em>
div>
<div class="price">
<strong>
<em>¥em>
<i>4088.00i>
strong>
div>
<div class="commit">
<i class="command">已有700人评价i>
div>
div>
li>
ul>
div>
div>
div>
div>
<div class="clearfix footer">
<div class="py-container">
<div class="footlink">
<div class="Mod-service">
<ul class="Mod-Service-list">
<li class="grid-service-item intro intro1">
<i class="serivce-item fl">i>
<div class="service-text">
<h4>正品保障h4>
<p>正品保障,提供发票p>
div>
li>
<li class="grid-service-item intro intro2">
<i class="serivce-item fl">i>
<div class="service-text">
<h4>正品保障h4>
<p>正品保障,提供发票p>
div>
li>
<li class="grid-service-item intro intro3">
<i class="serivce-item fl">i>
<div class="service-text">
<h4>正品保障h4>
<p>正品保障,提供发票p>
div>
li>
<li class="grid-service-item intro intro4">
<i class="serivce-item fl">i>
<div class="service-text">
<h4>正品保障h4>
<p>正品保障,提供发票p>
div>
li>
<li class="grid-service-item intro intro5">
<i class="serivce-item fl">i>
<div class="service-text">
<h4>正品保障h4>
<p>正品保障,提供发票p>
div>
li>
ul>
div>
<div class="clearfix Mod-list">
<div class="yui3-g">
<div class="yui3-u-1-6">
<h4>购物指南h4>
<ul class="unstyled">
<li>购物流程li>
<li>会员介绍li>
<li>生活旅行/团购li>
<li>常见问题li>
<li>购物指南li>
ul>
div>
<div class="yui3-u-1-6">
<h4>配送方式h4>
<ul class="unstyled">
<li>上门自提li>
<li>211限时达li>
<li>配送服务查询li>
<li>配送费收取标准li>
<li>海外配送li>
ul>
div>
<div class="yui3-u-1-6">
<h4>支付方式h4>
<ul class="unstyled">
<li>货到付款li>
<li>在线支付li>
<li>分期付款li>
<li>邮局汇款li>
<li>公司转账li>
ul>
div>
<div class="yui3-u-1-6">
<h4>售后服务h4>
<ul class="unstyled">
<li>售后政策li>
<li>价格保护li>
<li>退款说明li>
<li>返修/退换货li>
<li>取消订单li>
ul>
div>
<div class="yui3-u-1-6">
<h4>特色服务h4>
<ul class="unstyled">
<li>夺宝岛li>
<li>DIY装机li>
<li>延保服务li>
<li>优乐选E卡li>
<li>优乐选通信li>
ul>
div>
<div class="yui3-u-1-6">
<h4>帮助中心h4>
<img src="img/xg/erweima.jpg">
div>
div>
div>
<div class="Mod-copyright">
<ul class="helpLink">
<li>关于我们<span class="space">span>li>
<li>联系我们<span class="space">span>li>
<li>关于我们<span class="space">span>li>
<li>商家入驻<span class="space">span>li>
<li>营销中心<span class="space">span>li>
<li>友情链接<span class="space">span>li>
<li>关于我们<span class="space">span>li>
<li>营销中心<span class="space">span>li>
<li>友情链接<span class="space">span>li>
<li>关于我们li>
ul>
<p>地址:北京市朝阳区五方桥基地 邮编:100096 电话:400-650-7353 传真:010-88888100p>
<p>京ICP备10218183号-88 京公网安备11010802020723号p>
div>
div>
div>
div>
<div class="J-global-toolbar">
<div class="toolbar-wrap J-wrap">
<div class="toolbar">
<div class="toolbar-panels J-panel">
<div style="visibility: hidden;" class="J-content toolbar-panel tbar-panel-cart toolbar-animate-out">
<h3 class="tbar-panel-header J-panel-header">
<a href="" class="title"><i>i><em class="title">购物车em>a>
<span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('cart');" >span>
h3>
<div class="tbar-panel-main">
<div class="tbar-panel-content J-panel-content">
<div id="J-cart-tips" class="tbar-tipbox hide">
<div class="tip-inner">
<span class="tip-text">还没有登录,登录后商品将被保存span>
<a href="#none" class="tip-btn J-login">登录a>
div>
div>
<div id="J-cart-render">
<div id="cart-list" class="tbar-cart-list">
div>
div>
div>
div>
<div id="cart-footer" class="tbar-panel-footer J-panel-footer">
<div class="tbar-checkout">
<div class="jtc-number"> <strong class="J-count" id="cart-number">0strong>件商品 div>
<div class="jtc-sum"> 共计:<strong class="J-total" id="cart-sum">¥0strong> div>
<a class="jtc-btn J-btn" href="#none" target="_blank">去购物车结算a>
div>
div>
div>
<div style="visibility: hidden;" data-name="follow" class="J-content toolbar-panel tbar-panel-follow">
<h3 class="tbar-panel-header J-panel-header">
<a href="#" target="_blank" class="title"> <i>i> <em class="title">我的关注em> a>
<span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('follow');">span>
h3>
<div class="tbar-panel-main">
<div class="tbar-panel-content J-panel-content">
<div class="tbar-tipbox2">
<div class="tip-inner"> <i class="i-loading">i> div>
div>
div>
div>
<div class="tbar-panel-footer J-panel-footer">div>
div>
<div style="visibility: hidden;" class="J-content toolbar-panel tbar-panel-history toolbar-animate-in">
<h3 class="tbar-panel-header J-panel-header">
<a href="#" target="_blank" class="title"> <i>i> <em class="title">我的足迹em> a>
<span class="close-panel J-close" onclick="cartPanelView.tbar_panel_close('history');">span>
h3>
<div class="tbar-panel-main">
<div class="tbar-panel-content J-panel-content">
<div class="jt-history-wrap">
<ul>
ul>
<a href="#" class="history-bottom-more" target="_blank">查看更多足迹商品 >>a>
div>
div>
div>
<div class="tbar-panel-footer J-panel-footer">div>
div>
div>
<div class="toolbar-header">div>
<div class="toolbar-tabs J-tab">
<div onclick="cartPanelView.tabItemClick('cart')" class="toolbar-tab tbar-tab-cart" data="购物车" tag="cart">
<i class="tab-ico">i>
<em class="tab-text">em>
<span class="tab-sub J-count " id="tab-sub-cart-count">0span>
div>
<div onclick="cartPanelView.tabItemClick('follow')" class="toolbar-tab tbar-tab-follow" data="我的关注" tag="follow">
<i class="tab-ico">i>
<em class="tab-text">em>
<span class="tab-sub J-count hide">0span>
div>
<div onclick="cartPanelView.tabItemClick('history')" class="toolbar-tab tbar-tab-history" data="我的足迹" tag="history">
<i class="tab-ico">i>
<em class="tab-text">em>
<span class="tab-sub J-count hide">0span>
div>
div>
<div class="toolbar-footer">
<div class="toolbar-tab tbar-tab-top">
<a href="#"> <i class="tab-ico ">i> <em class="footer-tab-text">顶部em> a>
div>
<div class="toolbar-tab tbar-tab-feedback">
<a href="#" target="_blank"> <i class="tab-ico">i> <em class="footer-tab-text ">反馈em> a>
div>
div>
<div class="toolbar-mini">div>
div>
<div id="J-toolbar-load-hook">div>
div>
div>
<script type="text/template" id="tbar-cart-item-template">
<div class="tbar-cart-item">
<div class="jtc-item-promo">
<em class="promo-tag promo-mz">满赠<i class="arrow"></i></em>
<div class="promo-text">已购满600元,您可领赠品</div>
</div>
<div class="jtc-item-goods">
<span class="p-img"><a href="#" target="_blank"><img src="{2}" alt="{1}" height="50" width="50" /></a></span>
<div class="p-name">
<a href="#">{1}</a>
</div>
<div class="p-price"><strong>¥{3}</strong>×{4} </div>
<a href="#none" class="p-del J-del">删除</a>
</div>
</div>
script>
<script type="text/javascript" src="js/plugins/jquery/jquery.min.js">script>
<script type="text/javascript">
$(function() {
$("#service").hover(function() {
$(".service").show();
}, function() {
$(".service").hide();
});
$("#shopcar").hover(function() {
$("#shopcarlist").show();
}, function() {
$("#shopcarlist").hide();
});
})
script>
<script type="text/javascript" src="js/model/cartModel.js">script>
<script type="text/javascript" src="js/czFunction.js">script>
<script type="text/javascript" src="js/plugins/jquery.easing/jquery.easing.min.js">script>
<script type="text/javascript" src="js/plugins/sui/sui.min.js">script>
<script type="text/javascript" src="js/widget/cartPanelView.js">script>
body>
html>
当前 youlexuan 所有完整代码