├── .gitignore ├── Screenshots ├── jddata.png ├── jconsole-1.png ├── jconsole-2.png ├── search-1.png ├── search-2.png ├── search-3.png ├── search-4.png ├── search-5.png └── solrdataimport.png ├── src ├── main │ ├── webapp │ │ ├── images │ │ │ ├── solr.png │ │ │ ├── top.png │ │ │ └── nopicture.png │ │ ├── css │ │ │ ├── pager.css │ │ │ └── 360buyimg.css │ │ ├── js │ │ │ ├── top.js │ │ │ └── jquery.pager.js │ │ └── WEB-INF │ │ │ ├── web.xml │ │ │ ├── mvc-dispatcher-servlet.xml │ │ │ └── pages │ │ │ ├── search.jsp │ │ │ └── jd.jsp │ ├── resources │ │ ├── chromedriver.exe │ │ ├── jdbc.properties │ │ ├── log4j.properties │ │ ├── sql.sql │ │ └── applicationContext.xml │ └── java │ │ └── net │ │ └── aimeizi │ │ ├── dao │ │ ├── CcdiNewsDao.java │ │ ├── JDProductDao.java │ │ └── impl │ │ │ ├── CcdiNewsDaoImpl.java │ │ │ └── JDProductDaoImpl.java │ │ ├── service │ │ ├── JDProductService.java │ │ ├── CcdiNewsService.java │ │ └── impl │ │ │ ├── JDProductServiceImpl.java │ │ │ └── CcdiNewsServiceImpl.java │ │ ├── webmagic │ │ ├── JdbcPipeline.java │ │ ├── JDPipeline.java │ │ ├── JDProductProcessor.java │ │ └── CcdiPageProcessor.java │ │ ├── domain │ │ ├── News.java │ │ └── Product.java │ │ └── controller │ │ ├── CcdiNewsController.java │ │ └── JDProductController.java └── test │ └── java │ └── net │ └── aimeizi │ └── service │ └── impl │ └── NewsServiceImplTest.java ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /*.iml 3 | /target 4 | -------------------------------------------------------------------------------- /Screenshots/jddata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/jddata.png -------------------------------------------------------------------------------- /Screenshots/jconsole-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/jconsole-1.png -------------------------------------------------------------------------------- /Screenshots/jconsole-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/jconsole-2.png -------------------------------------------------------------------------------- /Screenshots/search-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/search-1.png -------------------------------------------------------------------------------- /Screenshots/search-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/search-2.png -------------------------------------------------------------------------------- /Screenshots/search-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/search-3.png -------------------------------------------------------------------------------- /Screenshots/search-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/search-4.png -------------------------------------------------------------------------------- /Screenshots/search-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/search-5.png -------------------------------------------------------------------------------- /Screenshots/solrdataimport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/Screenshots/solrdataimport.png -------------------------------------------------------------------------------- /src/main/webapp/images/solr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/src/main/webapp/images/solr.png -------------------------------------------------------------------------------- /src/main/webapp/images/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/src/main/webapp/images/top.png -------------------------------------------------------------------------------- /src/main/resources/chromedriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/src/main/resources/chromedriver.exe -------------------------------------------------------------------------------- /src/main/webapp/images/nopicture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/v5tech/solrj-example/HEAD/src/main/webapp/images/nopicture.png -------------------------------------------------------------------------------- /src/main/resources/jdbc.properties: -------------------------------------------------------------------------------- 1 | jdbc.driverClassName=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/solr 3 | jdbc.username=root 4 | jdbc.password=root -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/dao/CcdiNewsDao.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.dao; 2 | 3 | import net.aimeizi.domain.News; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by Administrator on 2015/10/8. 9 | */ 10 | public interface CcdiNewsDao { 11 | void save(News news); 12 | 13 | List findAll(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/dao/JDProductDao.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.dao; 2 | 3 | import net.aimeizi.domain.Product; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by Administrator on 2015/10/8. 9 | */ 10 | public interface JDProductDao { 11 | void save(Product product); 12 | 13 | List findAll(); 14 | } -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/service/JDProductService.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.service; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by Administrator on 2015/10/14. 7 | */ 8 | public interface JDProductService { 9 | Map query(String queryString, String sort, int start, int pageSize) throws Exception; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | 2 | # Root logger option 3 | log4j.rootLogger=ERROR, stdout 4 | 5 | # Direct log messages to stdout 6 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 7 | log4j.appender.stdout.Target=System.out 8 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 9 | log4j.appender.stdout.layout.ConversionPattern=%r %-5p %c{1}:%L - %m%n 10 | 11 | # NodeChecker gets too chatty during test phase 12 | # log4j.category.io.searchbox.client.config.discovery.NodeChecker=FATAL -------------------------------------------------------------------------------- /src/main/webapp/css/pager.css: -------------------------------------------------------------------------------- 1 | #pageNav{padding-left:500px;} 2 | #pageNav ul.pages { 3 | display:block; 4 | border:none; 5 | text-transform:uppercase; 6 | font-size:12px; 7 | margin:10px 0 50px; 8 | padding:0; 9 | } 10 | #pageNav ul.pages li { 11 | list-style:none; 12 | float:left; 13 | border:1px solid #9AAFE5; 14 | text-decoration:none; 15 | margin:0 5px 0 0; 16 | padding:5px; 17 | } 18 | #pageNav ul.pages li:hover { 19 | border:1px solid #003f7e; 20 | } 21 | #pageNav ul.pages li.pgEmpty { 22 | 23 | } 24 | #pageNav ul.pages li.pgCurrent { 25 | border:none; 26 | /*border:1px solid #003f7e;*/ 27 | color:#000; 28 | font-weight:700; 29 | /*background-color:#eee;*/ 30 | background: none repeat scroll 0 0 #2E6AB1; 31 | border: 1px solid #2E6AB1; 32 | color: #FFFFFF; 33 | font-weight: bold; 34 | } -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/service/CcdiNewsService.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.service; 2 | 3 | import net.aimeizi.domain.News; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * Created by Administrator on 2015/10/8. 10 | */ 11 | public interface CcdiNewsService { 12 | void indexdb(); 13 | 14 | void addNews(News news) throws Exception; 15 | 16 | void addNews(List news) throws Exception; 17 | 18 | void addNewsBySolrInputDocument(News news) throws Exception; 19 | 20 | void addNewsBySolrInputDocument(List news) throws Exception; 21 | 22 | void updateNews(News news) throws Exception; 23 | 24 | void updateNews(List news) throws Exception; 25 | 26 | void deleteNews(String id) throws Exception; 27 | 28 | void deleteNews(List ids) throws Exception; 29 | 30 | void deleteNewsByQuery(String queryString) throws Exception; 31 | 32 | Map query(String queryString, int start, int pageSize) throws Exception; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/webapp/js/top.js: -------------------------------------------------------------------------------- 1 | function goTop(acceleration, time) 2 | { 3 | acceleration = acceleration || 0.1; 4 | time = time || 16; 5 | 6 | var x1 = 0; 7 | var y1 = 0; 8 | var x2 = 0; 9 | var y2 = 0; 10 | var x3 = 0; 11 | var y3 = 0; 12 | 13 | if (document.documentElement) 14 | { 15 | x1 = document.documentElement.scrollLeft || 0; 16 | y1 = document.documentElement.scrollTop || 0; 17 | } 18 | if (document.body) 19 | { 20 | x2 = document.body.scrollLeft || 0; 21 | y2 = document.body.scrollTop || 0; 22 | } 23 | var x3 = window.scrollX || 0; 24 | var y3 = window.scrollY || 0; 25 | 26 | var x = Math.max(x1, Math.max(x2, x3)); 27 | var y = Math.max(y1, Math.max(y2, y3)); 28 | 29 | var speed = 1 + acceleration; 30 | window.scrollTo(Math.floor(x / speed), Math.floor(y / speed)); 31 | 32 | if(x > 0 || y > 0) 33 | { 34 | var invokeFunction = "goTop(" + acceleration + ", " + time + ")"; 35 | window.setTimeout(invokeFunction, time); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/resources/sql.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE IF NOT EXISTS `solr` DEFAULT CHARACTER SET utf8; 2 | 3 | USE `solr`; 4 | 5 | DROP TABLE IF EXISTS `news`; 6 | 7 | CREATE TABLE `news` ( 8 | `id` int(11) NOT NULL AUTO_INCREMENT, 9 | `title` varchar(100) DEFAULT NULL, 10 | `content` mediumtext, 11 | `url` varchar(100) DEFAULT NULL, 12 | `source` varchar(50) DEFAULT NULL, 13 | `pubdate` varchar(50) DEFAULT NULL, 14 | `create` datetime DEFAULT NULL, 15 | `update` datetime DEFAULT NULL, 16 | PRIMARY KEY (`id`) 17 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 18 | 19 | 20 | 21 | DROP TABLE IF EXISTS `product`; 22 | 23 | CREATE TABLE `product` ( 24 | `id` int(11) NOT NULL AUTO_INCREMENT, 25 | `name` varchar(100) DEFAULT NULL, 26 | `pic` varchar(100) DEFAULT NULL, 27 | `price` double DEFAULT NULL, 28 | `comment` bigint(20) DEFAULT NULL, 29 | `url` varchar(150) DEFAULT NULL, 30 | `category` varchar(100) DEFAULT NULL, 31 | `create` datetime DEFAULT NULL, 32 | `update` datetime DEFAULT NULL, 33 | PRIMARY KEY (`id`) 34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # solrj-example 2 | 3 | solrj+webmagic+selenium示例 4 | 5 | 使用webmagic和selenium-java爬取京东商品信息并入库MySQL。采用solr dataimport创建索引,采用solrj检索商品信息。 6 | 7 | # solr单机模式 8 | 9 | https://coding.net/u/aimeizi/p/solr/git 10 | 11 | 基于solr4.10.4集成IKAnalyzer、mmseg4j、ansj中文分词及Dataimport功能 12 | 13 | # solr集群模式 14 | 15 | https://coding.net/u/aimeizi/p/SolrCloud/git 16 | 17 | solr集群模式。基于solr4.10.4集成IKAnalyzer、mmseg4j、ansj中文分词及Dataimport等功能 18 | 19 | # 运行 20 | 21 | JDProductProcessor 是JD商品采集的入口,main方法直接运行。 22 | 23 | CcdiPageProcessor 是纪检委网站采集的入口,main方法直接运行。 24 | 25 | 启动solr服务,运行爬虫采集程序,启动搜索服务,完成搜索。 26 | 27 | # Screenshots 28 | 29 | webmagic jmx监控 30 | ![](Screenshots/jconsole-1.png) 31 | 32 | webmagic jmx监控查看总抓取页数 33 | ![](Screenshots/jconsole-2.png) 34 | 35 | webmagic爬取JD商品数据入库数据 36 | ![](Screenshots/jddata.png) 37 | 38 | solrdataimport数据导入 39 | ![](Screenshots/solrdataimport.png) 40 | 41 | solr搜索 查询`所有商品`按`评论降序`排列,以`表格`的方式展现 42 | ![](Screenshots/search-1.png) 43 | 44 | solr搜索 查询`名称`为`手机`的商品按`价格降序`排列,以`表格`的方式展现 45 | ![](Screenshots/search-2.png) 46 | 47 | solr搜索 查询`名称`为`手机`且过滤`产品类别为手机`的商品信息按`价格降序`,以`列表`的方式展现 48 | ![](Screenshots/search-3.png) 49 | 50 | solr搜索 查询名称为`洗衣机`且过滤`产品类别为洗衣机`的商品信息按`价格降序`,以`表格`的方式展现 51 | ![](Screenshots/search-4.png) 52 | 53 | solr搜索 查询名称为`iPhone`的商品信息按`价格降序`,以`表格`的方式展现 54 | ![](Screenshots/search-5.png) 55 | 56 | # 参考文档 57 | 58 | http://webmagic.io/docs/zh/ -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | elasticsearch-jest-example 7 | 8 | contextConfigLocation 9 | 10 | classpath*:applicationContext.xml 11 | /WEB-INF/mvc-dispatcher-servlet.xml 12 | 13 | 14 | 15 | 16 | org.springframework.web.context.ContextLoaderListener 17 | 18 | 19 | CharacterEncodingFilter 20 | org.springframework.web.filter.CharacterEncodingFilter 21 | 22 | encoding 23 | UTF-8 24 | 25 | 26 | 27 | CharacterEncodingFilter 28 | /* 29 | 30 | 31 | 32 | mvc-dispatcher 33 | org.springframework.web.servlet.DispatcherServlet 34 | 35 | contextConfigLocation 36 | /WEB-INF/mvc-dispatcher-servlet.xml 37 | 38 | 1 39 | 40 | 41 | 42 | mvc-dispatcher 43 | / 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/webmagic/JdbcPipeline.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.webmagic; 2 | 3 | import net.aimeizi.dao.CcdiNewsDao; 4 | import net.aimeizi.domain.News; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Component; 8 | import us.codecraft.webmagic.ResultItems; 9 | import us.codecraft.webmagic.Task; 10 | import us.codecraft.webmagic.pipeline.Pipeline; 11 | 12 | import java.util.Date; 13 | import java.util.Map; 14 | 15 | /** 16 | * Created by Administrator on 2015/10/8. 17 | */ 18 | @Component("jdbcPipeline") 19 | public class JdbcPipeline implements Pipeline { 20 | @Autowired 21 | CcdiNewsDao newsDao; 22 | 23 | public void process(ResultItems resultItems, Task task) { 24 | Map items = resultItems.getAll(); 25 | if (resultItems != null && resultItems.getAll().size() > 0) { 26 | News news = new News(); 27 | news.setTitle((String) items.get("title")); 28 | news.setContent(replaceHTML((String) items.get("content"))); 29 | news.setUrl((String) items.get("url")); 30 | String source = (String) items.get("source"); 31 | if (StringUtils.isNotEmpty(source)) { 32 | source = source.replace("来源:", ""); 33 | } 34 | news.setSource(source); 35 | String pubdate = (String) items.get("pubdate"); 36 | if (StringUtils.isNotEmpty(pubdate)) { 37 | pubdate = pubdate.replace("发布时间:", ""); 38 | } 39 | news.setPubdate(pubdate); 40 | news.setCreate(new Date()); 41 | news.setUpdate(new Date()); 42 | newsDao.save(news); 43 | } 44 | } 45 | 46 | /** 47 | * html字符过滤 48 | * 49 | * @param str 50 | * @return 51 | */ 52 | public static String replaceHTML(String str) { 53 | return str != null ? str.replaceAll("\\<.*?>", "").replaceAll(" ", "") : ""; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/resources/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 39 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/domain/News.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.domain; 2 | 3 | import org.apache.solr.client.solrj.beans.Field; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * Created by Administrator on 2015/10/8. 9 | */ 10 | public class News { 11 | 12 | @Field("id") 13 | private String id; 14 | @Field("title") 15 | private String title; 16 | @Field("content") 17 | private String content; 18 | @Field("source") 19 | private String source; 20 | @Field("pubdate") 21 | private String pubdate; 22 | @Field("url") 23 | private String url; 24 | @Field("create") 25 | private Date create; 26 | @Field("update") 27 | private Date update; 28 | 29 | public String getId() { 30 | return id; 31 | } 32 | 33 | public void setId(String id) { 34 | this.id = id; 35 | } 36 | 37 | public String getTitle() { 38 | return title; 39 | } 40 | 41 | public void setTitle(String title) { 42 | this.title = title; 43 | } 44 | 45 | public String getContent() { 46 | return content; 47 | } 48 | 49 | public void setContent(String content) { 50 | this.content = content; 51 | } 52 | 53 | public String getSource() { 54 | return source; 55 | } 56 | 57 | public void setSource(String source) { 58 | this.source = source; 59 | } 60 | 61 | public String getPubdate() { 62 | return pubdate; 63 | } 64 | 65 | public void setPubdate(String pubdate) { 66 | this.pubdate = pubdate; 67 | } 68 | 69 | public String getUrl() { 70 | return url; 71 | } 72 | 73 | public void setUrl(String url) { 74 | this.url = url; 75 | } 76 | 77 | public Date getCreate() { 78 | return create; 79 | } 80 | 81 | public void setCreate(Date create) { 82 | this.create = create; 83 | } 84 | 85 | public Date getUpdate() { 86 | return update; 87 | } 88 | 89 | public void setUpdate(Date update) { 90 | this.update = update; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/webmagic/JDPipeline.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.webmagic; 2 | 3 | import net.aimeizi.dao.JDProductDao; 4 | import net.aimeizi.domain.Product; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | import us.codecraft.webmagic.ResultItems; 8 | import us.codecraft.webmagic.Task; 9 | import us.codecraft.webmagic.pipeline.Pipeline; 10 | 11 | import java.util.Date; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | /** 16 | * Created by Administrator on 2015/10/12. 17 | */ 18 | @Component("jdPipeline") 19 | public class JDPipeline implements Pipeline { 20 | 21 | @Autowired 22 | JDProductDao productDao; 23 | 24 | public void process(ResultItems resultItems, Task task) { 25 | Map items = resultItems.getAll(); 26 | if (resultItems != null && resultItems.getAll().size() > 0) { 27 | List names = (List) items.get("names"); 28 | List prices = (List) items.get("prices"); 29 | List comments = (List) items.get("comments"); 30 | List links = (List) items.get("links"); 31 | List pics = (List) items.get("pics"); 32 | String category = (String) items.get("category"); 33 | for (int i = 0; i < names.size(); i++) { 34 | Product p = new Product(); 35 | p.setName(names.get(i)); 36 | p.setPic(pics.get(i)); 37 | try{ 38 | double price = Double.parseDouble(prices.get(i)); 39 | p.setPrice(price); 40 | }catch (Exception e){ 41 | } 42 | try{ 43 | long comment = Long.parseLong(comments.get(i)); 44 | p.setComment(comment); 45 | }catch (Exception e){ 46 | } 47 | p.setUrl(links.get(i)); 48 | p.setCategory(category); 49 | p.setCreate(new Date()); 50 | p.setUpdate(new Date()); 51 | productDao.save(p); 52 | } 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/domain/Product.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.domain; 2 | 3 | import org.apache.solr.client.solrj.beans.Field; 4 | 5 | import java.util.Date; 6 | 7 | /** 8 | * Created by Administrator on 2015/10/10. 9 | */ 10 | public class Product { 11 | 12 | @Field 13 | private String id; 14 | @Field 15 | private String name; 16 | @Field 17 | private String pic; 18 | @Field 19 | private double price; 20 | @Field 21 | private long comment; 22 | @Field 23 | private String url; 24 | @Field 25 | private Date create; 26 | @Field 27 | private Date update; 28 | 29 | @Field 30 | private String category; 31 | 32 | public String getId() { 33 | return id; 34 | } 35 | 36 | public void setId(String id) { 37 | this.id = id; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public void setName(String name) { 45 | this.name = name; 46 | } 47 | 48 | public String getPic() { 49 | return pic; 50 | } 51 | 52 | public void setPic(String pic) { 53 | this.pic = pic; 54 | } 55 | 56 | public double getPrice() { 57 | return price; 58 | } 59 | 60 | public void setPrice(double price) { 61 | this.price = price; 62 | } 63 | 64 | public long getComment() { 65 | return comment; 66 | } 67 | 68 | public void setComment(long comment) { 69 | this.comment = comment; 70 | } 71 | 72 | public String getUrl() { 73 | return url; 74 | } 75 | 76 | public void setUrl(String url) { 77 | this.url = url; 78 | } 79 | 80 | public String getCategory() { 81 | return category; 82 | } 83 | 84 | public void setCategory(String category) { 85 | this.category = category; 86 | } 87 | 88 | public Date getCreate() { 89 | return create; 90 | } 91 | 92 | public void setCreate(Date create) { 93 | this.create = create; 94 | } 95 | 96 | public Date getUpdate() { 97 | return update; 98 | } 99 | 100 | public void setUpdate(Date update) { 101 | this.update = update; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/dao/impl/CcdiNewsDaoImpl.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.dao.impl; 2 | 3 | import net.aimeizi.dao.CcdiNewsDao; 4 | import net.aimeizi.domain.News; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.jdbc.core.JdbcTemplate; 7 | import org.springframework.jdbc.core.PreparedStatementSetter; 8 | import org.springframework.jdbc.core.RowMapper; 9 | import org.springframework.stereotype.Repository; 10 | 11 | import javax.sql.DataSource; 12 | import java.sql.PreparedStatement; 13 | import java.sql.ResultSet; 14 | import java.sql.SQLException; 15 | import java.sql.Timestamp; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by Administrator on 2015/10/8. 20 | */ 21 | @Repository 22 | public class CcdiNewsDaoImpl implements CcdiNewsDao { 23 | 24 | private JdbcTemplate jdbcTemplate; 25 | 26 | @Autowired 27 | public void setDataSource(DataSource dataSource) { 28 | this.jdbcTemplate = new JdbcTemplate(dataSource); 29 | } 30 | 31 | @Override 32 | public List findAll() { 33 | return jdbcTemplate.query("select * from news", new RowMapper() { 34 | @Override 35 | public News mapRow(ResultSet rs, int rowNum) throws SQLException { 36 | News news = new News(); 37 | news.setId(rs.getString("id")); 38 | news.setTitle(rs.getString("title")); 39 | news.setContent(rs.getString("content")); 40 | news.setUrl(rs.getString("url")); 41 | news.setSource(rs.getString("source")); 42 | news.setPubdate(rs.getString("pubdate")); 43 | news.setCreate(rs.getDate("create")); 44 | news.setUpdate(rs.getDate("update")); 45 | return news; 46 | } 47 | }); 48 | } 49 | 50 | public void save(final News news) { 51 | String sql = "INSERT INTO news (title,content,url,source,pubdate,`create`,`update`) VALUES (?,?,?,?,?,?,?)"; 52 | jdbcTemplate.update(sql, new PreparedStatementSetter() { 53 | public void setValues(PreparedStatement ps) throws SQLException { 54 | ps.setString(1, news.getTitle()); 55 | ps.setString(2, news.getContent()); 56 | ps.setString(3, news.getUrl()); 57 | ps.setString(4, news.getSource()); 58 | ps.setString(5, news.getPubdate()); 59 | ps.setTimestamp(6, new Timestamp(news.getCreate().getTime())); 60 | ps.setTimestamp(7, new Timestamp(news.getUpdate().getTime())); 61 | } 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/controller/CcdiNewsController.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.controller; 2 | 3 | import net.aimeizi.domain.News; 4 | import net.aimeizi.service.CcdiNewsService; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.servlet.ModelAndView; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | @Controller 18 | @RequestMapping(value = "/news") 19 | public class CcdiNewsController { 20 | 21 | @Autowired 22 | private CcdiNewsService newsService; 23 | 24 | @RequestMapping(method = RequestMethod.GET) 25 | public String tosearch() { 26 | return "search"; 27 | } 28 | 29 | @RequestMapping(value = "/search", method = RequestMethod.POST) 30 | public ModelAndView search(HttpServletRequest request, HttpServletResponse response) { 31 | ModelAndView modelAndView = new ModelAndView(); 32 | modelAndView.setViewName("search"); 33 | String queryString = request.getParameter("queryString"); 34 | String pageNumber = request.getParameter("pageNumber"); 35 | String pageSize = request.getParameter("pageSize"); 36 | if (StringUtils.isEmpty(queryString)) { 37 | return modelAndView; 38 | } 39 | try { 40 | if (StringUtils.isEmpty(pageNumber) || StringUtils.isEmpty(pageSize)) { 41 | pageNumber = String.valueOf("1"); 42 | pageSize = String.valueOf("10"); 43 | } 44 | Map maps = newsService.query(queryString, Integer.parseInt(pageNumber), Integer.parseInt(pageSize)); 45 | modelAndView.addObject("queryString", queryString); 46 | modelAndView.addObject("results", (List) maps.get("results")); 47 | long count = (Long) maps.get("totals"); 48 | modelAndView.addObject("count", count); 49 | modelAndView.addObject("qtime", maps.get("qtime")); 50 | modelAndView.addObject("pageNumber", pageNumber); 51 | modelAndView.addObject("pageSize", pageSize); 52 | modelAndView.addObject("totalPages", count % Integer.parseInt(pageSize) == 0 ? count / Integer.parseInt(pageSize) : count / Integer.parseInt(pageSize) + 1); 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | } 56 | return modelAndView; 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/controller/JDProductController.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.controller; 2 | 3 | import net.aimeizi.domain.Product; 4 | import net.aimeizi.service.JDProductService; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RequestMethod; 10 | import org.springframework.web.servlet.ModelAndView; 11 | 12 | import javax.servlet.http.HttpServletRequest; 13 | import javax.servlet.http.HttpServletResponse; 14 | import java.util.List; 15 | import java.util.Map; 16 | 17 | /** 18 | * 京东商品搜索 19 | * Created by Administrator on 2015/10/14. 20 | */ 21 | @Controller 22 | public class JDProductController { 23 | 24 | @Autowired 25 | JDProductService productService; 26 | 27 | @RequestMapping(value = "/", method = RequestMethod.GET) 28 | public String tosearch() { 29 | return "jd"; 30 | } 31 | 32 | @RequestMapping(value = "/search", method = RequestMethod.POST) 33 | public ModelAndView search(HttpServletRequest request, HttpServletResponse response) { 34 | ModelAndView modelAndView = new ModelAndView(); 35 | modelAndView.setViewName("jd"); 36 | String queryString = request.getParameter("queryString"); 37 | // 若什么都不输入,则表示搜索全部商品 38 | queryString = StringUtils.isEmpty(queryString) ? "*" : queryString; 39 | String sort = request.getParameter("sort"); 40 | String pageNumber = request.getParameter("pageNumber"); 41 | String pageSize = request.getParameter("pageSize"); 42 | if (StringUtils.isEmpty(queryString)) { 43 | return modelAndView; 44 | } 45 | try { 46 | if (StringUtils.isEmpty(pageNumber) || StringUtils.isEmpty(pageSize)) { 47 | pageNumber = String.valueOf("1"); 48 | pageSize = String.valueOf("60"); 49 | } 50 | Map maps = productService.query(queryString, sort, Integer.parseInt(pageNumber), Integer.parseInt(pageSize)); 51 | modelAndView.addObject("queryString", queryString); 52 | modelAndView.addObject("sort", sort); 53 | modelAndView.addObject("results", (List) maps.get("results")); 54 | long count = (Long) maps.get("totals"); 55 | modelAndView.addObject("count", count); 56 | modelAndView.addObject("qtime", maps.get("qtime")); 57 | modelAndView.addObject("pageNumber", pageNumber); 58 | modelAndView.addObject("pageSize", pageSize); 59 | modelAndView.addObject("totalPages", count % Integer.parseInt(pageSize) == 0 ? count / Integer.parseInt(pageSize) : count / Integer.parseInt(pageSize) + 1); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | return modelAndView; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/test/java/net/aimeizi/service/impl/NewsServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.service.impl; 2 | 3 | import net.aimeizi.domain.News; 4 | import net.aimeizi.service.CcdiNewsService; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.test.context.ContextConfiguration; 9 | import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; 10 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 11 | 12 | import java.util.Calendar; 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | /** 17 | * Created by Administrator on 2015/10/9. 18 | * solr查询语法参考 19 | * https://wiki.apache.org/solr/SolrQuerySyntax 20 | * http://www.solrtutorial.com/solr-query-syntax.html 21 | * http://www.lucenetutorial.com/lucene-query-syntax.html 22 | * https://lucene.apache.org/core/4_10_4/queryparser/org/apache/lucene/queryparser/classic/package-summary.html 23 | */ 24 | @RunWith(SpringJUnit4ClassRunner.class) 25 | @ContextConfiguration("classpath:applicationContext.xml") 26 | public class NewsServiceImplTest extends AbstractJUnit4SpringContextTests { 27 | 28 | @Autowired 29 | CcdiNewsService newsService; 30 | 31 | /** 32 | * 测试创建索引 33 | */ 34 | @Test 35 | public void indexdb() { 36 | long start = Calendar.getInstance().getTimeInMillis(); 37 | newsService.indexdb(); 38 | long end = Calendar.getInstance().getTimeInMillis(); 39 | long times = (end - start) / 1000; 40 | System.out.println("索引创建完毕.本次创建索引共耗时:" + times + "秒"); 41 | } 42 | 43 | 44 | /** 45 | * 测试查询 46 | */ 47 | @Test 48 | public void query() throws Exception { 49 | String queryString = "王岐山"; // term查询 50 | // queryString = "title:王岐山"; // field查询 51 | // queryString = "title:(王岐山 AND 四川)"; 52 | // queryString = "title:\"王岐山\" AND title:\"四川\""; 53 | // queryString = "title:(王?山 AND 四川)"; 54 | // queryString = "title:(王岐山 OR 四川)"; 55 | // queryString = "title:(王?山 OR 四川)"; 56 | // queryString = "title:王岐山 -title:四川"; 57 | Map maps = newsService.query(queryString, 1, 50); 58 | if (!maps.isEmpty()) { 59 | System.out.println("本次查询共耗时:" + maps.get("qtime") + "秒"); 60 | System.out.println("查询关键字"+queryString+"共查询到:" + maps.get("totals") + "条记录"); 61 | List newsList = (List) maps.get("results"); 62 | for (int i = 0; i < newsList.size(); i++) { 63 | System.out.println("id:" + newsList.get(i).getId()); 64 | System.out.println("title:" + newsList.get(i).getTitle()); 65 | System.out.println("content:" + newsList.get(i).getContent()); 66 | System.out.println("source:" + newsList.get(i).getSource()); 67 | System.out.println("url:" + newsList.get(i).getUrl()); 68 | System.out.println("pubdate:" + newsList.get(i).getPubdate()); 69 | System.out.println("--------------------------------------------------------------------------------------"); 70 | } 71 | } 72 | } 73 | 74 | 75 | /** 76 | * 清空索引 77 | * 78 | * @throws Exception 79 | */ 80 | @Test 81 | public void destroy() throws Exception { 82 | newsService.deleteNewsByQuery("*:*"); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/dao/impl/JDProductDaoImpl.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.dao.impl; 2 | 3 | import net.aimeizi.dao.JDProductDao; 4 | import net.aimeizi.domain.Product; 5 | import org.apache.commons.io.FileUtils; 6 | import org.apache.commons.io.FilenameUtils; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.jdbc.core.JdbcTemplate; 10 | import org.springframework.jdbc.core.PreparedStatementSetter; 11 | import org.springframework.jdbc.core.RowMapper; 12 | import org.springframework.stereotype.Repository; 13 | 14 | import javax.sql.DataSource; 15 | import java.io.File; 16 | import java.net.URL; 17 | import java.sql.PreparedStatement; 18 | import java.sql.ResultSet; 19 | import java.sql.SQLException; 20 | import java.sql.Timestamp; 21 | import java.util.List; 22 | 23 | /** 24 | * Created by Administrator on 2015/10/8. 25 | */ 26 | @Repository 27 | public class JDProductDaoImpl implements JDProductDao { 28 | 29 | private JdbcTemplate jdbcTemplate; 30 | 31 | @Autowired 32 | public void setDataSource(DataSource dataSource) { 33 | this.jdbcTemplate = new JdbcTemplate(dataSource); 34 | } 35 | 36 | @Override 37 | public List findAll() { 38 | return jdbcTemplate.query("select * from news", new RowMapper() { 39 | @Override 40 | public Product mapRow(ResultSet rs, int rowNum) throws SQLException { 41 | Product product = new Product(); 42 | product.setId(rs.getString("id")); 43 | product.setName(rs.getString("name")); 44 | product.setPic(rs.getString("pic")); 45 | product.setPrice(rs.getDouble("price")); 46 | product.setComment(rs.getLong("comment")); 47 | product.setUrl(rs.getString("url")); 48 | product.setCategory(rs.getString("category")); 49 | product.setCreate(rs.getDate("create")); 50 | product.setUpdate(rs.getDate("update")); 51 | return product; 52 | } 53 | }); 54 | } 55 | 56 | public void save(final Product product) { 57 | 58 | String sql = "INSERT INTO product (`name`,pic,price,comment,url,category,`create`,`update`) VALUES (?,?,?,?,?,?,?,?)"; 59 | jdbcTemplate.update(sql, new PreparedStatementSetter() { 60 | public void setValues(PreparedStatement ps) throws SQLException { 61 | // 获取src/main/webapp/images 绝对路径 62 | String filepath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "main" + File.separator + "webapp" + File.separator + "images"; 63 | String pic = product.getPic(); 64 | if (StringUtils.isNotEmpty(pic)) { 65 | String filename = FilenameUtils.getName(pic); 66 | try { 67 | File file = new File(filepath, filename); 68 | FileUtils.copyURLToFile(new URL("http:" + pic), file); //将文件写入到磁盘中 69 | pic = "images/" + filename; 70 | } catch (Exception e) { 71 | 72 | } 73 | } 74 | ps.setString(1, product.getName()); 75 | ps.setString(2, pic); 76 | ps.setDouble(3, product.getPrice()); 77 | ps.setLong(4, product.getComment()); 78 | ps.setString(5, product.getUrl()); 79 | ps.setString(6, product.getCategory()); 80 | ps.setTimestamp(7, new Timestamp(product.getCreate().getTime())); 81 | ps.setTimestamp(8, new Timestamp(product.getUpdate().getTime())); 82 | } 83 | }); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | net.aimeizi 5 | solrj-example 6 | war 7 | 1.0 8 | solrj-example 9 | http://maven.apache.org 10 | 11 | 12 | javax.servlet 13 | javax.servlet-api 14 | 3.1.0 15 | provided 16 | 17 | 18 | javax.servlet 19 | jstl 20 | 1.2 21 | 22 | 23 | 24 | us.codecraft 25 | webmagic-core 26 | 0.5.2 27 | 28 | 29 | us.codecraft 30 | webmagic-extension 31 | 0.5.2 32 | 33 | 34 | us.codecraft 35 | webmagic-selenium 36 | 0.5.2 37 | 38 | 39 | org.seleniumhq.selenium 40 | selenium-java 41 | 2.33.0 42 | 43 | 44 | 45 | org.apache.solr 46 | solr-solrj 47 | 4.10.4 48 | 49 | 50 | 51 | org.springframework 52 | spring-jdbc 53 | 4.2.1.RELEASE 54 | 55 | 56 | org.springframework 57 | spring-context-support 58 | 4.2.1.RELEASE 59 | 60 | 61 | mysql 62 | mysql-connector-java 63 | 5.1.31 64 | 65 | 66 | 67 | org.springframework 68 | spring-webmvc 69 | 4.2.1.RELEASE 70 | 71 | 72 | 73 | org.springframework 74 | spring-test 75 | 4.2.1.RELEASE 76 | 77 | 78 | junit 79 | junit 80 | 4.12 81 | 82 | 83 | 84 | 85 | solrj-example 86 | 87 | 88 | maven-compiler-plugin 89 | 2.5.1 90 | true 91 | 92 | 1.7 93 | 1.7 94 | 95 | 96 | 97 | org.apache.tomcat.maven 98 | tomcat7-maven-plugin 99 | 2.2 100 | 101 | 8888 102 | / 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/main/webapp/js/jquery.pager.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery pager plugin 3 | * Version 1.0 (12/22/2008) 4 | * @requires jQuery v1.2.6 or later 5 | * 6 | * Example at: http://jonpauldavies.github.com/JQuery/Pager/PagerDemo.html 7 | * 8 | * Copyright (c) 2008-2009 Jon Paul Davies 9 | * Dual licensed under the MIT and GPL licenses: 10 | * http://www.opensource.org/licenses/mit-license.php 11 | * http://www.gnu.org/licenses/gpl.html 12 | * 13 | * Read the related blog post and contact the author at http://www.j-dee.com/2008/12/22/jquery-pager-plugin/ 14 | * 15 | * This version is far from perfect and doesn't manage it's own state, therefore contributions are more than welcome! 16 | * 17 | * Usage: .pager({ pagenumber: 1, pagecount: 15, buttonClickCallback: PagerClickTest }); 18 | * 19 | * Where pagenumber is the visible page number 20 | * pagecount is the total number of pages to display 21 | * buttonClickCallback is the method to fire when a pager button is clicked. 22 | * 23 | * buttonClickCallback signiture is PagerClickTest = function(pageclickednumber) 24 | * Where pageclickednumber is the number of the page clicked in the control. 25 | * 26 | * The included Pager.CSS file is a dependancy but can obviously tweaked to your wishes 27 | * Tested in IE6 IE7 Firefox & Safari. Any browser strangeness, please report. 28 | */ 29 | (function($) { 30 | 31 | $.fn.pager = function(options) { 32 | 33 | var opts = $.extend({}, $.fn.pager.defaults, options); 34 | 35 | return this.each(function() { 36 | 37 | // empty out the destination element and then render out the pager with the supplied options 38 | $(this).empty().append(renderpager(parseInt(options.pagenumber), parseInt(options.pagecount), options.buttonClickCallback)); 39 | 40 | // specify correct cursor activity 41 | $('.pages li').mouseover(function() { document.body.style.cursor = "pointer"; }).mouseout(function() { document.body.style.cursor = "auto"; }); 42 | }); 43 | }; 44 | 45 | // render and return the pager with the supplied options 46 | function renderpager(pagenumber, pagecount, buttonClickCallback) { 47 | 48 | // setup $pager to hold render 49 | var $pager = $('
    '); 50 | 51 | // add in the previous and next buttons 52 | $pager.append(renderButton('首页', pagenumber, pagecount, buttonClickCallback)).append(renderButton('上一页', pagenumber, pagecount, buttonClickCallback)); 53 | 54 | // pager currently only handles 10 viewable pages ( could be easily parameterized, maybe in next version ) so handle edge cases 55 | var startPoint = 1; 56 | var endPoint = 9; 57 | 58 | if (pagenumber > 4) { 59 | startPoint = pagenumber - 4; 60 | endPoint = pagenumber + 4; 61 | } 62 | 63 | if (endPoint > pagecount) { 64 | startPoint = pagecount - 8; 65 | endPoint = pagecount; 66 | } 67 | 68 | if (startPoint < 1) { 69 | startPoint = 1; 70 | } 71 | 72 | // loop thru visible pages and render buttons 73 | for (var page = startPoint; page <= endPoint; page++) { 74 | 75 | var currentButton = $('
  • ' + (page) + '
  • '); 76 | 77 | page == pagenumber ? currentButton.addClass('pgCurrent') : currentButton.click(function() { buttonClickCallback(this.firstChild.data); }); 78 | currentButton.appendTo($pager); 79 | } 80 | 81 | // render in the next and last buttons before returning the whole rendered control back. 82 | $pager.append(renderButton('下一页', pagenumber, pagecount, buttonClickCallback)).append(renderButton('末页', pagenumber, pagecount, buttonClickCallback)); 83 | 84 | return $pager; 85 | } 86 | 87 | // renders and returns a 'specialized' button, ie 'next', 'previous' etc. rather than a page number button 88 | function renderButton(buttonLabel, pagenumber, pagecount, buttonClickCallback) { 89 | 90 | var $Button = $('
  • ' + buttonLabel + '
  • '); 91 | 92 | var destPage = 1; 93 | 94 | // work out destination page for required button type 95 | switch (buttonLabel) { 96 | case "首页": 97 | destPage = 1; 98 | break; 99 | case "上一页": 100 | destPage = pagenumber - 1; 101 | break; 102 | case "下一页": 103 | destPage = pagenumber + 1; 104 | break; 105 | case "末页": 106 | destPage = pagecount; 107 | break; 108 | } 109 | 110 | // disable and 'grey' out buttons if not needed. 111 | if (buttonLabel == "首页" || buttonLabel == "上一页") { 112 | pagenumber <= 1 ? $Button.addClass('pgEmpty') : $Button.click(function() { buttonClickCallback(destPage); }); 113 | } 114 | else { 115 | pagenumber >= pagecount ? $Button.addClass('pgEmpty') : $Button.click(function() { buttonClickCallback(destPage); }); 116 | } 117 | 118 | return $Button; 119 | } 120 | 121 | // pager defaults. hardly worth bothering with in this case but used as placeholder for expansion in the next version 122 | $.fn.pager.defaults = { 123 | pagenumber: 1, 124 | pagecount: 1 125 | }; 126 | 127 | })(jQuery); 128 | 129 | 130 | 131 | 132 | 133 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/service/impl/JDProductServiceImpl.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.service.impl; 2 | 3 | import net.aimeizi.domain.Product; 4 | import net.aimeizi.service.JDProductService; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.apache.solr.client.solrj.SolrQuery; 7 | import org.apache.solr.client.solrj.SolrServer; 8 | import org.apache.solr.client.solrj.beans.DocumentObjectBinder; 9 | import org.apache.solr.client.solrj.response.QueryResponse; 10 | import org.apache.solr.common.SolrDocument; 11 | import org.apache.solr.common.SolrDocumentList; 12 | import org.apache.solr.common.SolrInputDocument; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.stereotype.Service; 15 | 16 | import java.util.*; 17 | 18 | /** 19 | * Created by Administrator on 2015/10/14. 20 | */ 21 | @Service 22 | public class JDProductServiceImpl implements JDProductService { 23 | 24 | @Autowired 25 | SolrServer solrServer; 26 | 27 | public void setSolrServer(SolrServer solrServer) { 28 | this.solrServer = solrServer; 29 | } 30 | 31 | @Override 32 | public Map query(String queryString, String sort, int start, int pageSize) throws Exception { 33 | Map maps = new HashMap(); 34 | List productList = new ArrayList<>(); 35 | SolrQuery solrQuery = new SolrQuery(); 36 | solrQuery.setQuery("name:" + queryString); // *name:queryString*按名称查询 37 | start = (start - 1) * pageSize; 38 | solrQuery.setStart(start); //设置起始位置 39 | solrQuery.setRows(pageSize); // 设置页大小 40 | solrQuery.setHighlight(true); //启用高亮 41 | solrQuery.addHighlightField("name"); //设置高亮字段 42 | solrQuery.addHighlightField("category"); //设置高亮字段 43 | solrQuery.setHighlightFragsize(200); // 设置高亮内容大小 44 | solrQuery.setHighlightSimplePre(""); //设置高亮前缀 45 | solrQuery.setHighlightSimplePost(""); //设置高亮后缀 46 | sort = StringUtils.isNotEmpty(sort) ? sort : "score"; 47 | solrQuery.addSort(sort, SolrQuery.ORDER.desc); //设置排序 按score降序排序 48 | QueryResponse queryResponse = solrServer.query(solrQuery); 49 | int qtime = queryResponse.getQTime();//查询花费时间 50 | SolrDocumentList solrDocumentList = queryResponse.getResults();// 获取查询结果集 51 | // 获取高亮内容 第一个Map的键是文档的ID,第二个Map的键是高亮显示的字段名 52 | Map>> highlightingMaps = queryResponse.getHighlighting(); 53 | long totals = solrDocumentList.getNumFound();// 查询到的总记录数 54 | if (!solrDocumentList.isEmpty()) { 55 | Iterator it = solrDocumentList.iterator(); 56 | while (it.hasNext()) { 57 | SolrDocument solrDocument = it.next(); 58 | // 获取文档id 59 | String id = solrDocument.getFieldValue("id").toString(); 60 | // 处理高亮 61 | Map> highlightFieldMap = highlightingMaps.get(id); 62 | if (!highlightFieldMap.isEmpty()) { 63 | List highlightName = highlightFieldMap.get("name"); 64 | List highlightCategory = highlightFieldMap.get("category"); 65 | if (highlightName != null && !highlightName.isEmpty()) { 66 | String name = highlightName.get(0); 67 | // 将文档结果集中的name设置为高亮后的name 68 | solrDocument.setField("name", name); 69 | } 70 | if (highlightCategory != null && !highlightCategory.isEmpty()) { 71 | String category = highlightCategory.get(0); 72 | // 将文档结果集中的category设置为高亮后的category 73 | solrDocument.setField("category", category); 74 | } 75 | } 76 | // 调用solrDocument转java bean 77 | Product product = doc2bean(solrDocument); 78 | String picture = product.getPic(); 79 | // 处理图片地址为空或图片地址无效 80 | if (StringUtils.isEmpty(picture) || "done".equals(picture)) { 81 | product.setPic("images/nopicture.png"); 82 | } 83 | productList.add(product); 84 | } 85 | } 86 | maps.put("qtime", qtime); 87 | maps.put("totals", totals); 88 | maps.put("results", productList); 89 | return maps; 90 | } 91 | 92 | /** 93 | * solrDocument与java bean转换 94 | * 95 | * @param solrDocument 96 | * @return 97 | */ 98 | private Product doc2bean(SolrDocument solrDocument) { 99 | DocumentObjectBinder binder = new DocumentObjectBinder(); 100 | Product product = binder.getBean(Product.class, solrDocument); 101 | return product; 102 | } 103 | 104 | /** 105 | * solrDocument与java bean 集合转换 106 | * 107 | * @param solrDocumentList 108 | * @return 109 | */ 110 | private List doc2beans(SolrDocumentList solrDocumentList) { 111 | DocumentObjectBinder binder = new DocumentObjectBinder(); 112 | List productList = binder.getBeans(Product.class, solrDocumentList); 113 | return productList; 114 | } 115 | 116 | /** 117 | * bean与SolrInputDocument转换 118 | * 119 | * @param product 120 | * @return 121 | */ 122 | private SolrInputDocument bean2doc(Product product) { 123 | DocumentObjectBinder binder = new DocumentObjectBinder(); 124 | SolrInputDocument solrInputDocument = binder.toSolrInputDocument(product); 125 | return solrInputDocument; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/webmagic/JDProductProcessor.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.webmagic; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.support.ClassPathXmlApplicationContext; 6 | import us.codecraft.webmagic.Page; 7 | import us.codecraft.webmagic.Site; 8 | import us.codecraft.webmagic.Spider; 9 | import us.codecraft.webmagic.downloader.selenium.SeleniumDownloader; 10 | import us.codecraft.webmagic.monitor.SpiderMonitor; 11 | import us.codecraft.webmagic.processor.PageProcessor; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * Created by Administrator on 2015/10/12. 18 | * JD商品抓取 19 | */ 20 | public class JDProductProcessor implements PageProcessor { 21 | 22 | private Site site = Site.me() 23 | .setRetryTimes(3) 24 | .setSleepTime(1000) 25 | .setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"); 26 | 27 | // 未改版之前 28 | // private static final String URL_LIST = "http://list\\.jd\\.com/.*\\.html"; 29 | 30 | // 改版之后 31 | private static final String URL_LIST = "http://list\\.jd\\.com/list\\.html\\?cat=.*"; 32 | 33 | @Override 34 | public void process(Page page) { 35 | // 所有商品分类入口 36 | if (page.getUrl().regex("http://www\\.jd\\.com/allSort\\.aspx").match()) { 37 | List links = page.getHtml().links().regex(URL_LIST).all();// 获取商品分类链接匹配URL_LIST的链接信息 38 | // 添加商品分类页面所匹配到的所有商品信息到请求中 39 | page.addTargetRequests(links); 40 | } else { //处理商品列表页 41 | List names = page.getHtml().xpath("//li[@class='gl-item']/div[@class='gl-i-wrap j-sku-item']/div[@class='p-name']/a/em/text()").all(); 42 | List prices = page.getHtml().xpath("//li[@class='gl-item']/div[@class='gl-i-wrap j-sku-item']/div[@class='p-price']/strong[@class='J_price']/i/text()").all(); 43 | List comments = page.getHtml().xpath("//li[@class='gl-item']/div[@class='gl-i-wrap j-sku-item']/div[@class='p-commit']/strong/a/text()").all(); 44 | List links = page.getHtml().xpath("//li[@class='gl-item']/div[@class='gl-i-wrap j-sku-item']/div[@class='p-img']/a/@href").all(); 45 | List top3Pic = page.getHtml().xpath("//li[@class='gl-item']/div[@class='gl-i-wrap j-sku-item']/div[@class='p-img']/a/img/@src").all(); //获取页面初始化的前三张图片地址 46 | List lazyPic = page.getHtml().xpath("//li[@class='gl-item']/div[@class='gl-i-wrap j-sku-item']/div[@class='p-img']/a/img/@data-lazy-img").all(); // 获取懒加载的图片地址 47 | List pics = new ArrayList<>(); 48 | pics.addAll(top3Pic.subList(0, 3)); //获取前三张图片 49 | pics.addAll(lazyPic.subList(3, lazyPic.size())); //获取除前三张之外的图片 50 | String category = page.getHtml().xpath("//div[@id='J_selector']/div[@class='s-title']/h3/b/text()").get(); 51 | if ("".equals(category)) { 52 | category = page.getHtml().xpath("//div[@id='J_selector']/div[@class='s-title']/h3/em/text()").get(); 53 | } 54 | page.putField("names", names); 55 | page.putField("prices", prices); 56 | page.putField("comments", comments); 57 | page.putField("links", links); 58 | page.putField("pics", pics); 59 | page.putField("category", category); 60 | 61 | // 获取当前页url 62 | String url = page.getUrl().get(); 63 | if (url.endsWith(".html")) {// 若请求url是以.html结尾则表示是从商品分类页面中抽取到的商品url,即为该商品分类下的首页,以下代码获取该商品分类下的总页数,构建商品分页。并将分页信息添加到爬虫列表 64 | // 获取总页数 65 | String pages = page.getHtml().xpath("//div[@id='J_filter']/div[@class='f-line top']/div[@id='J_topPage']/span[@class='fp-text']/i/text()").get(); 66 | if (StringUtils.isNotEmpty(pages)) { 67 | int pageCount = Integer.parseInt(pages); 68 | // 将分页信息添加到爬虫列表 69 | for (int i = 2; i <= pageCount; i++) { //这里需要排除第一页,默认第一次打开的页面即为第一页,因此从第2页开始,下标为2 70 | String link = buildUrl(url, i); 71 | page.addTargetRequest(link); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | public Site getSite() { 79 | return site; 80 | } 81 | 82 | public static void main(String[] args) throws Exception { 83 | 84 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); 85 | JDPipeline jdPipeline = (JDPipeline) applicationContext.getBean("jdPipeline"); 86 | 87 | String chromeDriverPath = JDProductProcessor.class.getClassLoader().getResource("chromedriver.exe").getFile(); 88 | 89 | Spider jdSpider = Spider.create(new JDProductProcessor()) 90 | .addUrl("http://www.jd.com/allSort.aspx")// JD全部分类 91 | .addPipeline(jdPipeline) 92 | .setDownloader(new SeleniumDownloader(chromeDriverPath)) 93 | .thread(5); 94 | // 注册爬虫监控 95 | SpiderMonitor.instance().register(jdSpider); 96 | jdSpider.run(); 97 | } 98 | 99 | /** 100 | * 构建商品分页url 101 | * 102 | * @param str 103 | * @return 104 | */ 105 | private static String buildUrl(String str, int pageNumber) { 106 | String link = "http://list.jd.com/list.html?cat="; 107 | str = str.replace("http://list.jd.com/", "").replace(".html", ""); 108 | if (str.contains("-")) { 109 | str = str.replace("-", ","); 110 | link = link + str + "&page=" + pageNumber; 111 | } 112 | return link; 113 | } 114 | 115 | } 116 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/pages/search.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %> 2 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 4 | 5 | 6 | 7 | 8 | solrj example 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 42 | 43 | 44 |
    45 | 54 | 82 |
    83 |
    84 |
    85 | 86 |

    没有要查询的内容

    87 |
    88 | 89 |
    90 |

    ${news.title}

    91 | ${news.content} 92 |

    ${news.source} ${news.pubdate}

    93 |
    94 |
    95 | 97 |
    98 |
    99 |
    100 |
    101 |

    solrj example

    102 |
    103 |
    104 | 105 |
    106 | 回到顶部 107 |
    108 | 109 | 110 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/pages/jd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %> 2 | <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> 3 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 4 | 5 | 6 | 7 | 8 | 9 | Solr之JD商品搜索 10 | 11 | 12 | 13 | 14 | 16 | 25 | 26 | 27 |
    28 | 29 | 30 |
    31 | 32 |
    33 |
    34 |
    35 |
    36 | 37 | 38 | 39 | 41 | 42 |
    43 |
    44 |
    45 | 46 |
    47 | 查询关键字${queryString},共搜索到${count}条记录,每页显示${pageSize}条,共${totalPages}页,总耗时${qtime}毫秒 48 |
    49 |
    50 | 51 |
    52 |
    53 |
    54 |
    55 | 56 |
    57 |
    58 |
    59 |
    60 |
    61 | curr">评论数 63 | curr">价格 65 |
    66 |
    67 | ${pageNumber}/${totalPages} 68 |
    69 |
    70 | 列表 72 | 网格 74 |
    75 | 76 |
    77 |
    78 |
    79 |
    80 | 110 |
    111 | 113 |
    114 |
    115 | 116 |
    117 |
    118 |
    119 | 120 |
    122 | 123 | 回到顶部 124 | 125 |
    126 | 127 | 128 | 129 | 159 | 160 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/webmagic/CcdiPageProcessor.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.webmagic; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.support.ClassPathXmlApplicationContext; 6 | import us.codecraft.webmagic.Page; 7 | import us.codecraft.webmagic.Site; 8 | import us.codecraft.webmagic.Spider; 9 | import us.codecraft.webmagic.monitor.SpiderMonitor; 10 | import us.codecraft.webmagic.processor.PageProcessor; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by Administrator on 2015/10/8. 17 | * 爬取纪检委网站信息 18 | */ 19 | public class CcdiPageProcessor implements PageProcessor { 20 | 21 | private Site site = Site.me() 22 | .setRetryTimes(3) 23 | .setSleepTime(1000) 24 | .setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"); 25 | 26 | private static final String URL_LIST = "http://www\\.ccdi\\.gov\\.cn/.+/index[_0-9]*\\.html"; 27 | private static final String URL_POST = "http://www\\.ccdi\\.gov\\.cn/.+/\\d+/.*\\.html"; 28 | 29 | public void process(Page page) { 30 | List urllist = new ArrayList(); 31 | String urls; 32 | // 要闻url 33 | for (int i = 1; i < 50; i++) { 34 | urls = "http://www.ccdi.gov.cn/yw/index_" + i + ".html"; 35 | urllist.add(urls); 36 | } 37 | // 高层声音url 38 | for (int i = 1; i < 15; i++) { 39 | urls = "http://www.ccdi.gov.cn/ldhd/gcsy/index_" + i + ".html"; 40 | urllist.add(urls); 41 | } 42 | // 委部领导url 43 | for (int i = 1; i < 7; i++) { 44 | urls = "http://www.ccdi.gov.cn/ldhd/wbld/index_" + i + ".html"; 45 | urllist.add(urls); 46 | } 47 | // 头条url 48 | for (int i = 1; i < 50; i++) { 49 | urls = "http://www.ccdi.gov.cn/xwtt/index_" + i + ".html"; 50 | urllist.add(urls); 51 | } 52 | // 法规释义url 53 | for (int i = 1; i < 9; i++) { 54 | urls = "http://www.ccdi.gov.cn/djfg/fgsy/index_" + i + ".html"; 55 | urllist.add(urls); 56 | } 57 | // 业务顾问url 58 | for (int i = 1; i < 9; i++) { 59 | urls = "http://www.ccdi.gov.cn/djfg/ywgw/index_" + i + ".html"; 60 | urllist.add(urls); 61 | } 62 | // 党风政风url 63 | for (int i = 1; i < 42; i++) { 64 | urls = "http://www.ccdi.gov.cn/gzdt/dfzf/index_" + i + ".html"; 65 | urllist.add(urls); 66 | } 67 | // 巡视工作url 68 | for (int i = 1; i < 25; i++) { 69 | urls = "http://www.ccdi.gov.cn/gzdt/xsgz/index_" + i + ".html"; 70 | urllist.add(urls); 71 | } 72 | // 国际合作url 73 | for (int i = 1; i < 2; i++) { 74 | urls = "http://www.ccdi.gov.cn/gzdt/gjhz/index_" + i + ".html"; 75 | urllist.add(urls); 76 | } 77 | // 信访举报url 78 | for (int i = 1; i < 20; i++) { 79 | urls = "http://www.ccdi.gov.cn/gzdt/xfjb/index_" + i + ".html"; 80 | urllist.add(urls); 81 | } 82 | // 纪律审查url 83 | for (int i = 1; i < 65; i++) { 84 | urls = "http://www.ccdi.gov.cn/gzdt/jlsc/index_" + i + ".html"; 85 | urllist.add(urls); 86 | } 87 | // 宣传工作url 88 | for (int i = 1; i < 24; i++) { 89 | urls = "http://www.ccdi.gov.cn/gzdt/xcgz/index_" + i + ".html"; 90 | urllist.add(urls); 91 | } 92 | // 组织人事url 93 | for (int i = 1; i < 15; i++) { 94 | urls = "http://www.ccdi.gov.cn/gzdt/zzrs/index_" + i + ".html"; 95 | urllist.add(urls); 96 | } 97 | // 基层风采url 98 | for (int i = 1; i < 13; i++) { 99 | urls = "http://www.ccdi.gov.cn/gzdt/jcfc/index_" + i + ".html"; 100 | urllist.add(urls); 101 | } 102 | 103 | // 宣传教育-勤廉楷模url 104 | for (int i = 1; i < 22; i++) { 105 | urls = "http://www.ccdi.gov.cn/xcjy/qlkm/index_" + i + ".html"; 106 | urllist.add(urls); 107 | } 108 | 109 | // 宣传教育-以案警示url 110 | for (int i = 1; i < 11; i++) { 111 | urls = "http://www.ccdi.gov.cn/xcjy/yajs/index_" + i + ".html"; 112 | urllist.add(urls); 113 | } 114 | 115 | // 宣传教育-清风文苑url 116 | for (int i = 1; i < 31; i++) { 117 | urls = "http://www.ccdi.gov.cn/xcjy/qfwy/index_" + i + ".html"; 118 | urllist.add(urls); 119 | } 120 | 121 | // 宣传教育-廉史镜鉴url 122 | for (int i = 1; i < 24; i++) { 123 | urls = "http://www.ccdi.gov.cn/xcjy/lsjj/index_" + i + ".html"; 124 | urllist.add(urls); 125 | } 126 | 127 | // 宣传教育-海外观察url 128 | for (int i = 1; i < 13; i++) { 129 | urls = "http://www.ccdi.gov.cn/xcjy/hwgc/index_" + i + ".html"; 130 | urllist.add(urls); 131 | } 132 | 133 | // 判断是否是列表页 134 | if (page.getUrl().regex(URL_LIST).match()) { 135 | page.addTargetRequests(page.getHtml().xpath("//div[@class='other_center pub_center']/ul[@class='list_news_dl fixed']").links().regex(URL_POST).all()); 136 | page.addTargetRequests(urllist); 137 | } else {// 抽取内容详情页 138 | String title = page.getHtml().xpath("//div[@class='Article_61']/h2[@class='tit']/text()").get(); 139 | String content = page.getHtml().xpath("//div[@class='content']/div[@class='TRS_Editor']/div[@class='TRS_Editor']").get(); 140 | String pubdate = page.getHtml().xpath("//h3[@class='daty']/div[@class='daty_con']/em[@class='e e2']/text()").get(); 141 | if (StringUtils.isNotEmpty(pubdate)) { 142 | pubdate = pubdate.replace("发布时间:", ""); 143 | } 144 | String source = page.getHtml().xpath("//h3[@class='daty']/div[@class='daty_con']/em[@class='e e1']/text()").get(); 145 | if (StringUtils.isNotEmpty(source)) { 146 | source = source.replace("来源:", ""); 147 | } 148 | page.putField("title", title); 149 | page.putField("content", replaceHTML(content)); 150 | page.putField("pubdate", pubdate); 151 | page.putField("source", source); 152 | page.putField("url", page.getUrl().get()); 153 | } 154 | } 155 | 156 | public Site getSite() { 157 | return site; 158 | } 159 | 160 | public static void main(String[] args) throws Exception { 161 | 162 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); 163 | JdbcPipeline jdbcPipeline = (JdbcPipeline) applicationContext.getBean("jdbcPipeline"); 164 | 165 | Spider spider = Spider.create(new CcdiPageProcessor()) 166 | .addUrl("http://www.ccdi.gov.cn/yw/index.html")// 要闻 167 | .addUrl("http://www.ccdi.gov.cn/ldhd/gcsy/index.html")// 领导活动-高层声音 168 | .addUrl("http://www.ccdi.gov.cn/ldhd/wbld/index.html")// 领导活动-委部领导 169 | .addUrl("http://www.ccdi.gov.cn/xwtt/index.html") // 头条 170 | .addUrl("http://www.ccdi.gov.cn/djfg/fgsy/index.html")// 法规释义 171 | .addUrl("http://www.ccdi.gov.cn/djfg/ywgw/index.html")// 业务顾问 172 | .addUrl("http://www.ccdi.gov.cn/gzdt/dfzf/index.html")// 工作动态-党风政风 173 | .addUrl("http://www.ccdi.gov.cn/xsgz/index.html") // 工作动态-巡视工作 174 | .addUrl("http://www.ccdi.gov.cn/gzdt/gjhz/index.html")// 工作动态-国际合作 175 | .addUrl("http://www.ccdi.gov.cn/gzdt/xfjb/index.html")// 工作动态-信访举报 176 | .addUrl("http://www.ccdi.gov.cn/jlsc/index.html") // 工作动态-纪律审查 177 | .addUrl("http://www.ccdi.gov.cn/gzdt/xcgz/index.html")// 工作动态-宣传工作 178 | .addUrl("http://www.ccdi.gov.cn/gzdt/zzrs/index.html")// 工作动态-组织人事 179 | .addUrl("http://www.ccdi.gov.cn/gzdt/jcfc/index.html")// 工作动态-基层风采 180 | .addUrl("http://www.ccdi.gov.cn/xcjy/qlkm/index.html")// 宣传教育-勤廉楷模 181 | .addUrl("http://www.ccdi.gov.cn/xcjy/yajs/index.html")// 宣传教育-以案警示 182 | .addUrl("http://www.ccdi.gov.cn/xcjy/qfwy/index.html")// 宣传教育-清风文苑 183 | .addUrl("http://www.ccdi.gov.cn/xcjy/lsjj/index.html")// 宣传教育-廉史镜鉴 184 | .addUrl("http://www.ccdi.gov.cn/xcjy/hwgc/index.html")// 宣传教育-海外观察 185 | .addPipeline(jdbcPipeline) 186 | .thread(5); 187 | // 注册爬虫监控 188 | SpiderMonitor.instance().register(spider); 189 | spider.run(); 190 | } 191 | 192 | /** 193 | * html字符过滤 194 | * 195 | * @param str 196 | * @return 197 | */ 198 | public static String replaceHTML(String str) { 199 | return str != null ? str.replaceAll("\\<.*?>", "").replaceAll(" ", "") : ""; 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /src/main/java/net/aimeizi/service/impl/CcdiNewsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package net.aimeizi.service.impl; 2 | 3 | import net.aimeizi.dao.CcdiNewsDao; 4 | import net.aimeizi.domain.News; 5 | import net.aimeizi.service.CcdiNewsService; 6 | import org.apache.solr.client.solrj.SolrQuery; 7 | import org.apache.solr.client.solrj.SolrServer; 8 | import org.apache.solr.client.solrj.beans.DocumentObjectBinder; 9 | import org.apache.solr.client.solrj.impl.CloudSolrServer; 10 | import org.apache.solr.client.solrj.impl.HttpSolrServer; 11 | import org.apache.solr.client.solrj.response.QueryResponse; 12 | import org.apache.solr.common.SolrDocument; 13 | import org.apache.solr.common.SolrDocumentList; 14 | import org.apache.solr.common.SolrInputDocument; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.stereotype.Service; 17 | 18 | import java.util.*; 19 | 20 | /** 21 | * Created by Administrator on 2015/10/8. 22 | * http://wiki.apache.org/solr/Solrj 23 | */ 24 | @Service 25 | public class CcdiNewsServiceImpl implements CcdiNewsService { 26 | 27 | @Autowired 28 | private CcdiNewsDao newsDao; 29 | 30 | @Autowired 31 | SolrServer solrServer; 32 | 33 | public void setSolrServer(SolrServer solrServer) { 34 | this.solrServer = solrServer; 35 | } 36 | 37 | /** 38 | * 使用代码的方式创建HttpSolrServer 39 | * 40 | * @return 41 | */ 42 | public SolrServer createSolrServer() { 43 | String url = "http://127.0.0.1:8080/solr/"; 44 | HttpSolrServer solrServer = new HttpSolrServer(url); 45 | solrServer.setMaxRetries(1); 46 | solrServer.setConnectionTimeout(5000); 47 | solrServer.setSoTimeout(1000); 48 | solrServer.setDefaultMaxConnectionsPerHost(100); 49 | solrServer.setMaxTotalConnections(100); 50 | solrServer.setFollowRedirects(false); 51 | solrServer.setAllowCompression(true); 52 | return solrServer; 53 | } 54 | 55 | 56 | /** 57 | * 使用代码的方式创建CloudSolrServer 58 | * 59 | * @return 60 | */ 61 | public SolrServer createCloudSolrServer() { 62 | CloudSolrServer cloudSolrServer = new CloudSolrServer("127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183"); 63 | cloudSolrServer.setDefaultCollection("mycollection_shard1_replica1");//设置默认的Collection 64 | cloudSolrServer.setZkClientTimeout(12000); 65 | cloudSolrServer.setZkConnectTimeout(12000); 66 | return cloudSolrServer; 67 | } 68 | 69 | /** 70 | * 索引数据库 71 | */ 72 | @Override 73 | public void indexdb() { 74 | List newsList = newsDao.findAll(); 75 | try { 76 | addNews(newsList); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | /** 83 | * 索引bean 84 | * 85 | * @param news 86 | * @throws Exception 87 | */ 88 | public void addNews(News news) throws Exception { 89 | solrServer.addBean(news); 90 | solrServer.optimize(); 91 | solrServer.commit(); 92 | } 93 | 94 | 95 | /** 96 | * 批量索引bean 97 | * 98 | * @param news 99 | * @throws Exception 100 | */ 101 | public void addNews(List news) throws Exception { 102 | solrServer.addBeans(news); 103 | solrServer.optimize(); 104 | solrServer.commit(); 105 | } 106 | 107 | 108 | /** 109 | * 使用SolrInputDocument方式添加索引 110 | * 111 | * @param news 112 | * @throws Exception 113 | */ 114 | public void addNewsBySolrInputDocument(News news) throws Exception { 115 | SolrInputDocument solrInputDocument = new SolrInputDocument(); 116 | solrInputDocument.addField("id", news.getId()); 117 | solrInputDocument.addField("title", news.getTitle()); 118 | solrInputDocument.addField("content", news.getContent()); 119 | solrInputDocument.addField("source", news.getSource()); 120 | solrInputDocument.addField("pubdate", news.getPubdate()); 121 | solrInputDocument.addField("url", news.getUrl()); 122 | solrInputDocument.addField("create", news.getCreate()); 123 | solrInputDocument.addField("update", news.getUpdate()); 124 | solrServer.add(solrInputDocument); 125 | solrServer.optimize(); 126 | solrServer.commit(); 127 | } 128 | 129 | 130 | /** 131 | * 使用SolrInputDocument方式批量添加索引 132 | * 133 | * @param news 134 | * @throws Exception 135 | */ 136 | public void addNewsBySolrInputDocument(List news) throws Exception { 137 | List solrInputDocuments = new ArrayList<>(); 138 | for (int i = 0; i < news.size(); i++) { 139 | SolrInputDocument solrInputDocument = new SolrInputDocument(); 140 | solrInputDocument.addField("id", news.get(i).getId()); 141 | solrInputDocument.addField("title", news.get(i).getTitle()); 142 | solrInputDocument.addField("content", news.get(i).getContent()); 143 | solrInputDocument.addField("source", news.get(i).getSource()); 144 | solrInputDocument.addField("pubdate", news.get(i).getPubdate()); 145 | solrInputDocument.addField("url", news.get(i).getUrl()); 146 | solrInputDocument.addField("create", news.get(i).getCreate()); 147 | solrInputDocument.addField("update", news.get(i).getUpdate()); 148 | solrInputDocuments.add(solrInputDocument); 149 | } 150 | solrServer.add(solrInputDocuments); 151 | solrServer.optimize(); 152 | solrServer.commit(); 153 | } 154 | 155 | 156 | /** 157 | * 根据id修改索引 158 | * 159 | * @param news 160 | * @throws Exception 161 | */ 162 | public void updateNews(News news) throws Exception { 163 | solrServer.deleteById(String.valueOf(news.getId())); 164 | solrServer.addBean(news); 165 | solrServer.optimize(); 166 | solrServer.commit(); 167 | } 168 | 169 | /** 170 | * 批量修改索引 171 | * 172 | * @param news 173 | * @throws Exception 174 | */ 175 | public void updateNews(List news) throws Exception { 176 | List ids = Collections.emptyList(); 177 | for (int i = 0; i < news.size(); i++) { 178 | ids.add(news.get(i).getId()); 179 | } 180 | //批量删除索引 181 | solrServer.deleteById(ids); 182 | // 添加索引 183 | solrServer.addBeans(news); 184 | solrServer.optimize(); 185 | solrServer.commit(); 186 | } 187 | 188 | 189 | /** 190 | * 根据id删除索引 191 | * 192 | * @param id 193 | * @throws Exception 194 | */ 195 | public void deleteNews(String id) throws Exception { 196 | solrServer.deleteById(id); 197 | solrServer.optimize(); 198 | solrServer.commit(); 199 | } 200 | 201 | /** 202 | * 根据ids批量删除索引 203 | * 204 | * @param ids 205 | * @throws Exception 206 | */ 207 | public void deleteNews(List ids) throws Exception { 208 | solrServer.deleteById(ids); 209 | solrServer.optimize(); 210 | solrServer.commit(); 211 | } 212 | 213 | /** 214 | * 根据queryString删除索引 215 | * 216 | * @param queryString 217 | * @throws Exception 218 | */ 219 | public void deleteNewsByQuery(String queryString) throws Exception { 220 | solrServer.deleteByQuery(queryString); 221 | solrServer.optimize(); 222 | solrServer.commit(); 223 | } 224 | 225 | /** 226 | * 根据queryString分页检索 227 | * 228 | * @param queryString 229 | * @param start 230 | * @param pageSize 231 | * @return 232 | * @throws Exception 233 | */ 234 | public Map query(String queryString, int start, int pageSize) throws Exception { 235 | Map maps = new HashMap(); 236 | List newsList = new ArrayList<>(); 237 | SolrQuery solrQuery = new SolrQuery(); 238 | solrQuery.setQuery(queryString); // *:*全部查询 239 | start = (start - 1) * pageSize; 240 | solrQuery.setStart(start); //设置起始位置 241 | solrQuery.setRows(pageSize); // 设置页大小 242 | solrQuery.setHighlight(true); //启用高亮 243 | solrQuery.addHighlightField("title"); //设置高亮字段 244 | solrQuery.addHighlightField("content"); //设置高亮字段 245 | solrQuery.setHighlightFragsize(200); // 设置高亮内容大小 246 | solrQuery.setHighlightSimplePre(""); //设置高亮前缀 247 | solrQuery.setHighlightSimplePost(""); //设置高亮后缀 248 | solrQuery.addSort("score", SolrQuery.ORDER.desc); //设置排序 按score降序排序 249 | QueryResponse queryResponse = solrServer.query(solrQuery); 250 | int qtime = queryResponse.getQTime();//查询花费时间 251 | SolrDocumentList solrDocumentList = queryResponse.getResults();// 获取查询结果集 252 | // 获取高亮内容 第一个Map的键是文档的ID,第二个Map的键是高亮显示的字段名 253 | Map>> highlightingMaps = queryResponse.getHighlighting(); 254 | long totals = solrDocumentList.getNumFound();// 查询到的总记录数 255 | if (!solrDocumentList.isEmpty()) { 256 | Iterator it = solrDocumentList.iterator(); 257 | while (it.hasNext()) { 258 | SolrDocument solrDocument = it.next(); 259 | // 获取文档id 260 | String id = solrDocument.getFieldValue("id").toString(); 261 | // 处理高亮 262 | Map> highlightFieldMap = highlightingMaps.get(id); 263 | if (!highlightFieldMap.isEmpty()) { 264 | List highlightTitle = highlightFieldMap.get("title"); 265 | List highlightContent = highlightFieldMap.get("content"); 266 | if (highlightTitle != null && !highlightTitle.isEmpty()) { 267 | String title = highlightTitle.get(0); 268 | // 将文档结果集中的title设置为高亮后的title 269 | solrDocument.setField("title", title); 270 | } 271 | if (highlightContent != null && !highlightContent.isEmpty()) { 272 | String content = highlightContent.get(0); 273 | // 将文档结果集中的content设置为高亮后的content 274 | solrDocument.setField("content", content); 275 | } 276 | } 277 | // 调用solrDocument转java bean 278 | News news = doc2bean(solrDocument); 279 | newsList.add(news); 280 | } 281 | } 282 | maps.put("qtime", qtime); 283 | maps.put("totals", totals); 284 | maps.put("results", newsList); 285 | return maps; 286 | } 287 | 288 | /** 289 | * solrDocument与java bean转换 290 | * 291 | * @param solrDocument 292 | * @return 293 | */ 294 | private News doc2bean(SolrDocument solrDocument) { 295 | DocumentObjectBinder binder = new DocumentObjectBinder(); 296 | News news = binder.getBean(News.class, solrDocument); 297 | return news; 298 | } 299 | 300 | /** 301 | * solrDocument与java bean 集合转换 302 | * 303 | * @param solrDocumentList 304 | * @return 305 | */ 306 | private List doc2beans(SolrDocumentList solrDocumentList) { 307 | DocumentObjectBinder binder = new DocumentObjectBinder(); 308 | List newsList = binder.getBeans(News.class, solrDocumentList); 309 | return newsList; 310 | } 311 | 312 | /** 313 | * bean与SolrInputDocument转换 314 | * 315 | * @param news 316 | * @return 317 | */ 318 | private SolrInputDocument bean2doc(News news) { 319 | DocumentObjectBinder binder = new DocumentObjectBinder(); 320 | SolrInputDocument solrInputDocument = binder.toSolrInputDocument(news); 321 | return solrInputDocument; 322 | } 323 | 324 | } -------------------------------------------------------------------------------- /src/main/webapp/css/360buyimg.css: -------------------------------------------------------------------------------- 1 | /* jdf-1.0.0/ ui-base.css Date:2015-09-25 09:37:09 */ 2 | a,address,b,big,blockquote,body,center,cite,code,dd,del,div,dl,dt,em,fieldset,font,form,h1,h2,h3,h4,h5,h6,html,i,iframe,img,ins,label,legend,li,ol,p,pre,small,span,strong,u,ul,var { 3 | margin: 0; 4 | padding: 0 5 | } 6 | 7 | article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary { 8 | display: block 9 | } 10 | 11 | hr { 12 | -moz-box-sizing: content-box; 13 | box-sizing: content-box; 14 | height: 0 15 | } 16 | 17 | button,html input[type=button],input[type=submit] { 18 | -webkit-apperance: button; 19 | cursor: pointer 20 | } 21 | 22 | button[disabled],html input[disabled] { 23 | cursor: default 24 | } 25 | 26 | ol,ul { 27 | list-style: none 28 | } 29 | 30 | img { 31 | border: 0; 32 | vertical-align: middle 33 | } 34 | 35 | em,i,u { 36 | font-style: normal 37 | } 38 | 39 | .fl { 40 | float: left 41 | } 42 | 43 | .fr { 44 | float: right 45 | } 46 | 47 | .al { 48 | text-align: left 49 | } 50 | 51 | .ac { 52 | text-align: center 53 | } 54 | 55 | .ar { 56 | text-align: right 57 | } 58 | 59 | .hide { 60 | display: none 61 | } 62 | 63 | .clear,.clr { 64 | display: block; 65 | overflow: hidden; 66 | clear: both; 67 | height: 0; 68 | line-height: 0; 69 | font-size: 0 70 | } 71 | 72 | .clearfix:after { 73 | content: "."; 74 | display: block; 75 | height: 0; 76 | clear: both; 77 | visibility: hidden 78 | } 79 | 80 | .clearfix { 81 | *zoom: 1 82 | } 83 | 84 | .dorpdown { 85 | position: relative 86 | } 87 | 88 | .dorpdown-layer { 89 | display: none; 90 | position: absolute 91 | } 92 | 93 | .dorpdown:hover .dorpdown-layer,.hover .dorpdown-layer { 94 | display: block 95 | } 96 | 97 | .cw-icon { 98 | position: relative; 99 | cursor: default; 100 | zoom: 1 101 | } 102 | 103 | .cw-icon .i,.cw-icon i { 104 | display: block; 105 | position: absolute; 106 | overflow: hidden 107 | } 108 | 109 | .w { 110 | width: 990px; 111 | margin: 0 auto 112 | } 113 | 114 | .root61 .w { 115 | width: 1210px 116 | } 117 | 118 | body { 119 | font: 12px/150% Arial,Verdana,"\5b8b\4f53"; 120 | color: #666; 121 | background: #fff 122 | } 123 | 124 | a { 125 | color: #666; 126 | text-decoration: none 127 | } 128 | 129 | a:hover { 130 | color: #C81623 131 | } 132 | 133 | .m,.mb,.mc,.mt,.p-detail,.p-img,.p-market,.p-name,.p-price,.sm,.smb,.smc,.smt { 134 | overflow: hidden 135 | } 136 | 137 | .img-error { 138 | background: url(http://misc.360buyimg.com/lib/skin/e/i/error-jd.gif) no-repeat 50% 50% 139 | } 140 | /* jdf-1.0.0/ shortcut.css Date:2015-09-15 18:39:09 */ 141 | @charset "UTF-8"; 142 | 143 | #shortcut-2014 { 144 | width: 100%; 145 | height: 30px; 146 | line-height: 30px; 147 | background: #F1F1F1 148 | } 149 | 150 | #shortcut-2014 .w { 151 | background: #F1F1F1 152 | } 153 | 154 | #shortcut-2014 li { 155 | float: left; 156 | height: 30px; 157 | padding: 0 2px 158 | } 159 | 160 | #shortcut-2014 li#ttbar-navs { 161 | padding: 0 1px 0 2px 162 | } 163 | 164 | #shortcut-2014 li#ttbar-navs.hover,#shortcut-2014 li#ttbar-navs:hover { 165 | padding: 0 0 0 1px 166 | } 167 | 168 | #shortcut-2014 li.dorpdown { 169 | z-index: 13 170 | } 171 | 172 | #shortcut-2014 li.dorpdown:hover { 173 | padding: 0 1px 174 | } 175 | 176 | #shortcut-2014 li.dorpdown:hover .dt { 177 | background: #fff; 178 | border: solid #ddd; 179 | border-width: 0 1px 180 | } 181 | 182 | #shortcut-2014 li.hover { 183 | padding: 0 1px 184 | } 185 | 186 | #shortcut-2014 li.hover .dt { 187 | background: #fff; 188 | border: solid #ddd; 189 | border-width: 0 1px 190 | } 191 | 192 | #shortcut-2014 li.spacer { 193 | width: 1px; 194 | height: 12px; 195 | margin-top: 9px; 196 | padding: 0; 197 | background: #ddd; 198 | overflow: hidden 199 | } 200 | 201 | #shortcut-2014 .dt { 202 | float: left; 203 | padding: 0 8px 204 | } 205 | 206 | #shortcut-2014 .dd { 207 | line-height: 24px 208 | } 209 | 210 | #shortcut-2014 .loading { 211 | display: block; 212 | height: 50px; 213 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/loading.gif) no-repeat center center 214 | } 215 | 216 | #shortcut-2014 .dorpdown-layer { 217 | top: 30px; 218 | background: #fff; 219 | border: 1px solid #ddd; 220 | *left: 1px 221 | } 222 | 223 | #shortcut-2014 .ci-right { 224 | top: 12px; 225 | right: 8px; 226 | height: 7px; 227 | overflow: hidden; 228 | font: 400 15px/15px consolas; 229 | color: #6A6A6A; 230 | transition: transform .1s ease-in 0s; 231 | -webkit-transition: -webkit-transform .1s ease-in 0s 232 | } 233 | 234 | #shortcut-2014 .ci-right s { 235 | position: relative; 236 | top: -7px; 237 | text-decoration: none 238 | } 239 | 240 | #shortcut-2014 li:hover .ci-right { 241 | transform: rotate(180deg); 242 | -webkit-transform: rotate(180deg) 243 | } 244 | 245 | #shortcut-2014 .dd-spacer { 246 | position: absolute; 247 | top: -7px; 248 | height: 10px; 249 | background: #fff; 250 | overflow: hidden 251 | } 252 | 253 | #shortcut-2014 .style-red { 254 | color: #C81623 255 | } 256 | 257 | #shortcut-2014 #ttbar-home { 258 | padding-left: 20px; 259 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/jd2015img.png) no-repeat 0 -136px 260 | } 261 | 262 | #shortcut-2014 #ttbar-mycity { 263 | padding-left: 0 264 | } 265 | 266 | #shortcut-2014 #ttbar-mycity .dt { 267 | padding: 0 25px 0 10px 268 | } 269 | 270 | #shortcut-2014 #ttbar-mycity:hover .dt { 271 | padding: 0 24px 0 9px 272 | } 273 | 274 | #shortcut-2014 #ttbar-mycity .dd { 275 | width: 301px; 276 | padding: 10px 0 10px 10px 277 | } 278 | 279 | #shortcut-2014 #ttbar-mycity .dorpdown-layer { 280 | *left: 0 281 | } 282 | 283 | #shortcut-2014 #ttbar-mycity .item { 284 | float: left; 285 | width: 60px; 286 | padding: 2px 0 287 | } 288 | 289 | #shortcut-2014 #ttbar-mycity .item a { 290 | float: left; 291 | padding: 0 8px 292 | } 293 | 294 | #shortcut-2014 #ttbar-mycity .item a:hover { 295 | background: #F4F4F4 296 | } 297 | 298 | #shortcut-2014 #ttbar-mycity .item a.selected { 299 | background: #C81623; 300 | color: #fff 301 | } 302 | 303 | #shortcut-2014 #ttbar-mycity .dd-spacer { 304 | left: 0; 305 | width: 93px; 306 | _width: 95px 307 | } 308 | 309 | #shortcut-2014 #ttbar-mycity .dd-spacer-extend { 310 | width: 105px; 311 | _width: 107px 312 | } 313 | 314 | #shortcut-2014 #ttbar-login { 315 | margin-right: 10px 316 | } 317 | 318 | #shortcut-2014 #ttbar-login .link-login { 319 | font-family: "verdana,宋体" 320 | } 321 | 322 | #shortcut-2014 #ttbar-apps .dt { 323 | padding-left: 25px; 324 | padding-right: 25px 325 | } 326 | 327 | #shortcut-2014 #ttbar-apps .dt .ci-left { 328 | top: 5px; 329 | left: 7px; 330 | width: 15px; 331 | height: 20px; 332 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/jd2015img.png) 0 0 no-repeat 333 | } 334 | 335 | #shortcut-2014 #ttbar-apps .dd { 336 | width: 250px 337 | } 338 | 339 | #shortcut-2014 #ttbar-apps .dd a { 340 | display: block; 341 | position: absolute; 342 | width: 56px; 343 | height: 44px; 344 | overflow: hidden; 345 | text-indent: -500px 346 | } 347 | 348 | #shortcut-2014 #ttbar-apps .dd .link { 349 | width: 100px; 350 | height: 20px; 351 | overflow: hidden 352 | } 353 | 354 | #shortcut-2014 #ttbar-apps .dd .link1,#shortcut-2014 #ttbar-apps .dd .link2,#shortcut-2014 #ttbar-apps .dd .link3 { 355 | left: 92px; 356 | top: 6px; 357 | background-position: 0 -44px 358 | } 359 | 360 | #shortcut-2014 #ttbar-apps .dd .link2 { 361 | top: 26px 362 | } 363 | 364 | #shortcut-2014 #ttbar-apps .dd .link3 { 365 | top: 104px; 366 | background-position: -1px -66px 367 | } 368 | 369 | #shortcut-2014 #ttbar-apps .dd .jdapp-ipad,#shortcut-2014 #ttbar-apps .dd .wyapp-ipad { 370 | width: 45px 371 | } 372 | 373 | #shortcut-2014 #ttbar-apps .dd-inner { 374 | position: relative; 375 | width: 250px; 376 | height: 195px; 377 | overflow: hidden 378 | } 379 | 380 | #shortcut-2014 #ttbar-apps .jdapp-ios,#shortcut-2014 #ttbar-apps .wyapp-ios { 381 | top: 46px; 382 | left: 92px 383 | } 384 | 385 | #shortcut-2014 #ttbar-apps .jdapp-ios:hover,#shortcut-2014 #ttbar-apps .wyapp-ios:hover { 386 | background-position: 3px -1px 387 | } 388 | 389 | #shortcut-2014 #ttbar-apps .jdapp-android,#shortcut-2014 #ttbar-apps .wyapp-android { 390 | top: 46px; 391 | left: 147px 392 | } 393 | 394 | #shortcut-2014 #ttbar-apps .jdapp-android:hover,#shortcut-2014 #ttbar-apps .wyapp-android:hover { 395 | background-position: -52px -1px 396 | } 397 | 398 | #shortcut-2014 #ttbar-apps .jdapp-ipad,#shortcut-2014 #ttbar-apps .wyapp-ipad { 399 | width: 45px; 400 | top: 46px; 401 | left: 202px 402 | } 403 | 404 | #shortcut-2014 #ttbar-apps .jdapp-ipad:hover,#shortcut-2014 #ttbar-apps .wyapp-ipad:hover { 405 | background-position: -107px -1px 406 | } 407 | 408 | #shortcut-2014 #ttbar-apps .wyapp-android,#shortcut-2014 #ttbar-apps .wyapp-ios,#shortcut-2014 #ttbar-apps .wyapp-ipad { 409 | top: 143px 410 | } 411 | 412 | #shortcut-2014 #ttbar-apps .dd-spacer { 413 | left: 0; 414 | width: 98px 415 | } 416 | 417 | #shortcut-2014 #ttbar-apps.hover .dt .ci-left { 418 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/jd2015img.png) 0 -25px no-repeat 419 | } 420 | 421 | #shortcut-2014 #ttbar-atte .dt,#shortcut-2014 #ttbar-serv .dt { 422 | width: 49px; 423 | padding-right: 25px 424 | } 425 | 426 | #shortcut-2014 #ttbar-atte .dd,#shortcut-2014 #ttbar-serv .dd { 427 | width: 82px; 428 | padding-bottom: 8px 429 | } 430 | 431 | #shortcut-2014 #ttbar-atte .item,#shortcut-2014 #ttbar-serv .item { 432 | padding-left: 15px 433 | } 434 | 435 | #shortcut-2014 #ttbar-atte .dd-spacer,#shortcut-2014 #ttbar-serv .dd-spacer { 436 | left: 0; 437 | width: 82px 438 | } 439 | 440 | #shortcut-2014 #ttbar-navs .dt { 441 | width: 49px; 442 | padding-right: 25px 443 | } 444 | 445 | #shortcut-2014 #ttbar-navs .dd { 446 | right: 0; 447 | width: 988px; 448 | padding: 20px 0 16px; 449 | *left: auto; 450 | _right: -1px 451 | } 452 | 453 | #shortcut-2014 #ttbar-navs dl { 454 | float: left; 455 | width: 201px; 456 | padding-left: 20px; 457 | border-left: 1px solid #ddd 458 | } 459 | 460 | #shortcut-2014 #ttbar-navs dl.fore1 { 461 | border-left: none; 462 | width: 301px 463 | } 464 | 465 | #shortcut-2014 #ttbar-navs dt { 466 | font-size: 14px; 467 | font-weight: 700; 468 | margin-bottom: 6px 469 | } 470 | 471 | #shortcut-2014 #ttbar-navs .item { 472 | float: left; 473 | width: 100px 474 | } 475 | 476 | #shortcut-2014 #ttbar-navs .dd-spacer { 477 | right: 0; 478 | width: 82px 479 | } 480 | 481 | #shortcut-2014 .hover .dorpdown-layer { 482 | -webkit-transition: all 600ms cubic-bezier(0.23,1,.32,1) 483 | } 484 | 485 | .root61 #shortcut-2014 #ttbar-navs .dd { 486 | width: 1210px 487 | } 488 | 489 | .root61 #shortcut-2014 #ttbar-navs .fore2 { 490 | display: block 491 | } 492 | 493 | .root61 #shortcut-2014 #ttbar-navs dl { 494 | width: 259px 495 | } 496 | 497 | .root61 #shortcut-2014 #ttbar-navs dl.fore1 { 498 | width: 347px 499 | } 500 | 501 | .root61 #shortcut-2014 #ttbar-navs .item { 502 | width: 86px 503 | } 504 | /* jdf-1.0.0/ global-header.css Date:2015-09-15 18:39:12 */ 505 | @charset "UTF-8"; 506 | 507 | #logo-2014 { 508 | position: relative; 509 | z-index: 12; 510 | float: left; 511 | width: 362px; 512 | height: 60px; 513 | padding: 20px 0 514 | } 515 | 516 | #logo-2014 .logo { 517 | display: block; 518 | width: 270px; 519 | height: 60px; 520 | background: url(http://misc.360buyimg.com/lib/img/e/logo-201305.png) no-repeat 0 0; 521 | text-indent: -20000px 522 | } 523 | 524 | #logo-2014 .extra { 525 | position: absolute; 526 | top: 15px; 527 | left: 168px; 528 | width: 180px; 529 | height: 70px; 530 | padding-left: 10px; 531 | background: #fff 532 | } 533 | 534 | #channel { 535 | float: left; 536 | margin-right: 10px; 537 | cursor: default; 538 | font: 400 20px/70px "microsoft yahei"; 539 | color: #333 540 | } 541 | 542 | #categorys-mini-main { 543 | display: none; 544 | border: 1px solid #ccc; 545 | position: absolute; 546 | width: 152px; 547 | padding: 13px; 548 | margin-top: -1px; 549 | background: #fff; 550 | overflow: hidden 551 | } 552 | 553 | #categorys-mini-main h3 { 554 | font-family: "Microsoft YaHei"; 555 | color: #666; 556 | line-height: 24px; 557 | font-size: 14px; 558 | font-weight: 400 559 | } 560 | 561 | #categorys-mini-main a { 562 | color: #666; 563 | padding: 0; 564 | font-size: 12px 565 | } 566 | 567 | #categorys-mini { 568 | float: left; 569 | color: #666; 570 | font-size: 12px; 571 | font-weight: 400; 572 | position: relative; 573 | padding-top: 22px; 574 | height: 27px; 575 | font-family: simsun 576 | } 577 | 578 | #categorys-mini .cw-icon { 579 | color: #ccc; 580 | position: relative; 581 | width: 63px; 582 | height: 25px; 583 | border: 1px solid #ccc; 584 | line-height: 25px; 585 | z-index: 1; 586 | background: #fff; 587 | padding: 0 5px 588 | } 589 | 590 | #categorys-mini .cw-icon h2 { 591 | font-family: "Microsoft YaHei"; 592 | color: #666; 593 | font-size: 12px; 594 | font-weight: 400 595 | } 596 | 597 | #categorys-mini .cw-icon i { 598 | top: 9px; 599 | right: 5px; 600 | height: 7px; 601 | font: 400 15px/15px consolas 602 | } 603 | 604 | #categorys-mini .cw-icon s { 605 | position: relative; 606 | top: -7px; 607 | text-decoration: none 608 | } 609 | 610 | #categorys-mini .loading { 611 | display: block; 612 | height: 50px; 613 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/loading.gif) no-repeat center center 614 | } 615 | 616 | #categorys-mini .dorpdown-layer { 617 | width: 150px; 618 | border: 1px solid #ccc; 619 | padding: 10px; 620 | background: #fff 621 | } 622 | 623 | #categorys-mini .ci-right { 624 | top: 8px; 625 | right: 7px; 626 | height: 7px; 627 | overflow: hidden; 628 | font: 400 15px/15px consolas; 629 | color: #6A6A6A; 630 | transition: transform .1s ease-in 0s; 631 | -webkit-transition: -webkit-transform .1s ease-in 0s; 632 | display: block; 633 | position: absolute 634 | } 635 | 636 | #categorys-mini.hover .cw-icon { 637 | border-bottom: 0 638 | } 639 | 640 | #categorys-mini.hover .ci-right { 641 | transform: rotate(180deg); 642 | -webkit-transform: rotate(180deg) 643 | } 644 | 645 | #search-2014 { 646 | position: relative; 647 | z-index: 11; 648 | float: left; 649 | width: 462px; 650 | margin-top: 25px 651 | } 652 | 653 | #search-2014 .form { 654 | width: 462px; 655 | height: 36px 656 | } 657 | 658 | #search-2014 .text { 659 | float: left; 660 | width: 370px; 661 | /*height: 24px;*/ 662 | line-height: 24px; 663 | color: #666; 664 | padding: 4px; 665 | margin-bottom: 4px; 666 | border-width: 2px 0 2px 2px; 667 | border-color: #B61D1D; 668 | border-style: solid; 669 | outline: 0; 670 | font-size: 14px; 671 | font-family: "microsoft yahei" 672 | } 673 | 674 | #search-2014 .button { 675 | float: left; 676 | width: 82px; 677 | height: 36px; 678 | background: #B61D1D; 679 | border: none; 680 | line-height: 1; 681 | color: #fff; 682 | font-family: "Microsoft YaHei"; 683 | font-size: 16px; 684 | cursor: pointer 685 | } 686 | 687 | #search-2014 .cw-icon i { 688 | top: 0; 689 | left: 0; 690 | width: 82px; 691 | height: 36px 692 | } 693 | 694 | #hotwords-2014 { 695 | float: left; 696 | height: 20px; 697 | line-height: 20px; 698 | overflow: hidden 699 | } 700 | 701 | #hotwords-2014 em { 702 | color: red; 703 | } 704 | 705 | #shelper { 706 | overflow: hidden; 707 | position: absolute; 708 | top: 36px; 709 | left: 0; 710 | width: 379px; 711 | border: 1px solid #CCC; 712 | background: #fff 713 | } 714 | 715 | #shelper li { 716 | overflow: hidden; 717 | padding: 1px 6px; 718 | line-height: 22px; 719 | cursor: pointer 720 | } 721 | 722 | #shelper .search-item { 723 | float: left; 724 | width: 190px; 725 | white-space: nowrap; 726 | text-overflow: ellipsis; 727 | overflow: hidden 728 | } 729 | 730 | #shelper li.fore1 .search-item { 731 | width: 170px 732 | } 733 | 734 | #shelper .search-count { 735 | overflow: hidden; 736 | color: #aaa; 737 | text-align: right; 738 | *zoom: 1 739 | } 740 | 741 | #shelper .close { 742 | border-top: 1px solid #efefef; 743 | text-align: right 744 | } 745 | 746 | #shelper .item3 { 747 | cursor: default 748 | } 749 | 750 | #shelper .item3 a { 751 | float: left; 752 | margin-right: 10px; 753 | white-space: nowrap 754 | } 755 | 756 | #shelper li.fore1 { 757 | width: 100%; 758 | padding: 0; 759 | border-bottom: 1px solid #ddd 760 | } 761 | 762 | #shelper li.fore1 .item1 { 763 | height: 22px; 764 | overflow: hidden; 765 | zoom: 1 766 | } 767 | 768 | #shelper li.fore1 div.fore1 { 769 | padding: 0 6px 770 | } 771 | 772 | #shelper li.fore1 strong { 773 | color: #C00 774 | } 775 | 776 | #shelper li.fore1 .fore1 strong { 777 | color: #333 778 | } 779 | 780 | #shelper li.fore1 .item1,#shelper li.fore1 .item2 { 781 | float: none; 782 | width: auto; 783 | padding: 1px 6px 1px 20px 784 | } 785 | 786 | #shelper li.fore1 .item3 { 787 | float: none; 788 | width: auto; 789 | color: #9C9A9C 790 | } 791 | 792 | #shelper li.fore1 span { 793 | float: left 794 | } 795 | 796 | #shelper li:hover { 797 | background: #f5f5f5!important 798 | } 799 | 800 | #shelper li.close:hover,#shelper li.fore1:hover { 801 | background: 0 0 802 | } 803 | 804 | #shelper li.fore1 div:hover { 805 | background: #f5f5f5!important 806 | } 807 | 808 | .root61 #search-2014,.root61 #search-2014 .form { 809 | width: auto; 810 | _width: 538px 811 | } 812 | 813 | .root61 #search-2014 .text { 814 | width: 446px 815 | } 816 | 817 | .root61 #hotwords-2014 { 818 | width: 518px 819 | } 820 | 821 | .root61 #shelper { 822 | width: 455px 823 | } 824 | 825 | #appdownloadTop { 826 | display: none 827 | } 828 | /* jdf-1.0.0/ myjd.css Date:2015-09-15 18:39:11 */ 829 | @charset "UTF-8"; 830 | 831 | #ttbar-myjd .dt { 832 | width: 49px; 833 | padding-right: 25px 834 | } 835 | 836 | #ttbar-myjd .dorpdown-layer { 837 | width: 270px 838 | } 839 | 840 | #ttbar-myjd .userinfo { 841 | padding: 10px 15px; 842 | overflow: hidden 843 | } 844 | 845 | #ttbar-myjd .u-pic { 846 | float: left; 847 | margin-right: 10px 848 | } 849 | 850 | #ttbar-myjd .u-pic img { 851 | border-radius: 50%; 852 | -moz-border-radius: 50%; 853 | -webkit-border-radius: 50% 854 | } 855 | 856 | #ttbar-myjd .u-name { 857 | padding: 6px 0 0; 858 | font-weight: 700 859 | } 860 | 861 | #ttbar-myjd .orderlist { 862 | display: none; 863 | background: #000 864 | } 865 | 866 | #ttbar-myjd .otherlist { 867 | width: 255px; 868 | padding: 0 0 0 15px; 869 | margin: 5px 0; 870 | overflow: hidden; 871 | margin-bottom: 10px 872 | } 873 | 874 | #ttbar-myjd .otherlist .fore1,#ttbar-myjd .otherlist .fore2 { 875 | float: left; 876 | width: 126px 877 | } 878 | 879 | #ttbar-myjd .viewlist { 880 | width: 240px; 881 | padding: 0 15px 10px; 882 | border-top: 1px dotted #ccc; 883 | padding-top: 10px 884 | } 885 | 886 | #ttbar-myjd .viewlist .smt { 887 | zoom: 1 888 | } 889 | 890 | #ttbar-myjd .viewlist .smt h4 { 891 | float: left 892 | } 893 | 894 | #ttbar-myjd .viewlist .smt .extra { 895 | float: right 896 | } 897 | 898 | #ttbar-myjd .viewlist .item { 899 | float: left; 900 | padding: 4px; 901 | line-height: 0; 902 | font-size: 0 903 | } 904 | 905 | #ttbar-myjd .dd-spacer { 906 | left: 0; 907 | width: 82px 908 | } 909 | 910 | #ttbar-myjd .user-level1,#ttbar-myjd .user-level2,#ttbar-myjd .user-level3,#ttbar-myjd .user-level4,#ttbar-myjd .user-level5,#ttbar-myjd .user-level6 { 911 | display: inline-block; 912 | width: 17px; 913 | height: 17px; 914 | line-height: 17px; 915 | vertical-align: middle; 916 | margin-left: 5px; 917 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/myjd/2.0.0/i/rank2014.gif) 918 | } 919 | 920 | #ttbar-myjd .user-level2 { 921 | background-position: 0 -17px 922 | } 923 | 924 | #ttbar-myjd .user-level3 { 925 | background-position: 0 -34px 926 | } 927 | 928 | #ttbar-myjd .user-level4 { 929 | background-position: 0 -51px 930 | } 931 | 932 | #ttbar-myjd .user-level5 { 933 | background-position: 0 -68px 934 | } 935 | 936 | #ttbar-myjd .user-level6 { 937 | background-position: 0 -85px 938 | } 939 | /* jdf-1.0.0/ nav.css Date:2015-09-15 18:39:10 */ 940 | @charset "UTF-8"; 941 | 942 | #nav-2014 { 943 | height: 44px; 944 | border-bottom: 2px solid #B1191A; 945 | _overflow: hidden 946 | } 947 | 948 | #nav-2014 .w { 949 | position: relative; 950 | z-index: 9; 951 | height: 44px 952 | } 953 | 954 | #nav-2014 .w .w-spacer { 955 | display: none 956 | } 957 | 958 | #nav-2014 .w-spacer { 959 | position: absolute; 960 | top: -1px; 961 | z-index: 1; 962 | width: 100%; 963 | height: 44px; 964 | border-top: 1px solid #DDD; 965 | border-bottom: 2px solid #B1191A 966 | } 967 | 968 | #categorys-2014 { 969 | float: left; 970 | position: relative; 971 | z-index: 10; 972 | width: 210px; 973 | height: 44px; 974 | overflow: visible; 975 | background: #B1191A 976 | } 977 | 978 | #categorys-2014 .dt a { 979 | display: block; 980 | width: 190px; 981 | height: 44px; 982 | padding: 0 10px; 983 | background: #B1191A; 984 | font: 400 15px/44px "microsoft yahei"; 985 | color: #fff; 986 | text-decoration: none 987 | } 988 | 989 | #categorys-2014 .dt s { 990 | position: relative; 991 | top: -9px; 992 | text-decoration: none 993 | } 994 | 995 | #categorys-2014 .dt .ci-right { 996 | top: 20px; 997 | right: 7px; 998 | height: 7px; 999 | overflow: hidden; 1000 | font: 700 20px/16px simsun; 1001 | color: #fff; 1002 | transition: transform .1s ease-in 0s; 1003 | -webkit-transition: -webkit-transform .1s ease-in 0s; 1004 | display: block; 1005 | position: absolute 1006 | } 1007 | 1008 | #categorys-2014 .dd { 1009 | height: 466px; 1010 | background: #c81623; 1011 | margin-top: 2px 1012 | } 1013 | 1014 | #categorys-2014 .dd-inner .item { 1015 | border-left: 1px solid #b61d1d; 1016 | position: relative; 1017 | z-index: 1; 1018 | height: 31px; 1019 | color: #fff 1020 | } 1021 | 1022 | #categorys-2014 .dd-inner .item a { 1023 | color: #fff 1024 | } 1025 | 1026 | #categorys-2014 .dd-inner h3 { 1027 | position: absolute; 1028 | z-index: 2; 1029 | height: 31px; 1030 | padding: 0 10px; 1031 | line-height: 31px; 1032 | font-family: "microsoft yahei"; 1033 | font-size: 14px; 1034 | font-weight: 400 1035 | } 1036 | 1037 | #categorys-2014 .dd-inner i { 1038 | position: absolute; 1039 | z-index: 1; 1040 | top: 9px; 1041 | right: 14px; 1042 | width: 4px; 1043 | height: 14px; 1044 | font: 400 9px/14px consolas 1045 | } 1046 | 1047 | #categorys-2014 .dd-inner .hover { 1048 | background: #f7f7f7; 1049 | color: #B61D1D 1050 | } 1051 | 1052 | #categorys-2014 .dd-inner .hover a { 1053 | color: #B61D1D 1054 | } 1055 | 1056 | #categorys-2014 .dd-inner .hover i { 1057 | top: 0; 1058 | left: 205px; 1059 | width: 14px; 1060 | height: 31px; 1061 | background: #f7f7f7; 1062 | overflow: hidden; 1063 | line-height: 200px 1064 | } 1065 | 1066 | #categorys-2014 .dorpdown-layer { 1067 | display: none; 1068 | position: absolute; 1069 | left: 209px; 1070 | top: 45px; 1071 | width: 779px; 1072 | background: #f7f7f7; 1073 | border: 1px solid #b61d1d; 1074 | overflow: hidden 1075 | } 1076 | 1077 | #categorys-2014 .dorpdown-layer .hover { 1078 | display: block 1079 | } 1080 | 1081 | #categorys-2014 .item-sub { 1082 | display: none; 1083 | zoom: 1; 1084 | overflow: hidden 1085 | } 1086 | 1087 | #categorys-2014 .item-sub:after { 1088 | content: "."; 1089 | display: block; 1090 | height: 0; 1091 | clear: both 1092 | } 1093 | 1094 | #categorys-2014 .item-channels { 1095 | float: left; 1096 | display: inline; 1097 | width: 570px; 1098 | height: 24px; 1099 | padding: 20px 0 0 20px; 1100 | background: #f7f7f7; 1101 | overflow: hidden 1102 | } 1103 | 1104 | #categorys-2014 .item-channels a { 1105 | float: left; 1106 | display: inline; 1107 | display: inline-block; 1108 | *display: inline; 1109 | *zoom: 1; 1110 | padding: 0 0 0 8px; 1111 | margin-right: 10px; 1112 | line-height: 24px; 1113 | background: #7C7171; 1114 | color: #fff; 1115 | white-space: nowrap 1116 | } 1117 | 1118 | #categorys-2014 .item-channels a:hover { 1119 | background: #C81623 1120 | } 1121 | 1122 | #categorys-2014 .item-channels a:hover i { 1123 | background: #B1191A 1124 | } 1125 | 1126 | #categorys-2014 .item-channels i { 1127 | display: inline-block; 1128 | *zoom: 1; 1129 | _display: inline; 1130 | margin-left: 8px; 1131 | width: 23px; 1132 | height: 24px; 1133 | font: 400 9px/24px consolas; 1134 | background: #5c5251; 1135 | text-align: center; 1136 | cursor: pointer 1137 | } 1138 | 1139 | #categorys-2014 .item-channels .line { 1140 | border-left: 1px solid #dbdbdb; 1141 | display: inline; 1142 | float: left; 1143 | height: 24px; 1144 | margin-right: 7px; 1145 | width: 1px; 1146 | overflow: hidden 1147 | } 1148 | 1149 | #categorys-2014 .item-channels .img-link { 1150 | background: 0 0; 1151 | line-height: normal; 1152 | padding: 0 1153 | } 1154 | 1155 | #categorys-2014 .item-channels .img-link:hover { 1156 | background: 0 0 1157 | } 1158 | 1159 | #categorys-2014 .item-channels .style-red { 1160 | background: #c81623 1161 | } 1162 | 1163 | #categorys-2014 .item-channels .style-red i { 1164 | background: #b1191a 1165 | } 1166 | 1167 | #categorys-2014 .item-channels .style-red:hover { 1168 | background: #961019 1169 | } 1170 | 1171 | #categorys-2014 .item-channels .style-red:hover i { 1172 | background: #851313 1173 | } 1174 | 1175 | #categorys-2014 .subitems { 1176 | float: left; 1177 | width: 570px; 1178 | padding: 6px 0 1006px 20px; 1179 | margin-bottom: -1000px; 1180 | background: #f7f7f7; 1181 | min-height: 409px; 1182 | _height: 409px; 1183 | _overflow: visible 1184 | } 1185 | 1186 | #categorys-2014 .subitems dl { 1187 | width: 100%; 1188 | overflow: hidden; 1189 | line-height: 2em 1190 | } 1191 | 1192 | #categorys-2014 .subitems dl.fore1 dd { 1193 | border-top: none 1194 | } 1195 | 1196 | #categorys-2014 .subitems dt { 1197 | position: relative; 1198 | float: left; 1199 | width: 54px; 1200 | padding: 8px 30px 0 0; 1201 | text-align: right; 1202 | font-weight: 700 1203 | } 1204 | 1205 | #categorys-2014 .subitems dt i { 1206 | position: absolute; 1207 | top: 13px; 1208 | right: 18px; 1209 | width: 4px; 1210 | height: 14px; 1211 | font: 400 9px/14px consolas 1212 | } 1213 | 1214 | #categorys-2014 .subitems dd { 1215 | float: left; 1216 | width: 480px; 1217 | padding: 6px 0; 1218 | border-top: 1px solid #eee 1219 | } 1220 | 1221 | #categorys-2014 .subitems dd a { 1222 | float: left; 1223 | padding: 0 8px; 1224 | margin: 4px 0; 1225 | line-height: 16px; 1226 | height: 16px; 1227 | border-left: 1px solid #e0e0e0; 1228 | white-space: nowrap 1229 | } 1230 | 1231 | #categorys-2014 .subitems .style-red { 1232 | color: #c81623 1233 | } 1234 | 1235 | #categorys-2014 .item-brands { 1236 | float: right; 1237 | display: inline; 1238 | width: 168px; 1239 | overflow: hidden; 1240 | margin: 19px 20px 10px 0 1241 | } 1242 | 1243 | #categorys-2014 .item-brands a { 1244 | float: left; 1245 | display: inline; 1246 | margin: 1px 0 0 1px 1247 | } 1248 | 1249 | #categorys-2014 .item-promotions { 1250 | float: right; 1251 | display: inline; 1252 | width: 168px; 1253 | margin-right: 20px 1254 | } 1255 | 1256 | #categorys-2014 .item-promotions a { 1257 | display: block; 1258 | margin-bottom: 1px 1259 | } 1260 | 1261 | #nav-2014 .hover .dt .ci-right { 1262 | transform: rotate(180deg); 1263 | -webkit-transform: rotate(180deg); 1264 | _top: 17px 1265 | } 1266 | 1267 | #navitems-2014 { 1268 | float: left; 1269 | position: relative; 1270 | z-index: 2 1271 | } 1272 | 1273 | #navitems-2014 .spacer,#navitems-2014 a,#navitems-2014 li,#navitems-2014 ul { 1274 | float: left 1275 | } 1276 | 1277 | #navitems-2014 .spacer { 1278 | display: none 1279 | } 1280 | 1281 | #navitems-2014 a { 1282 | height: 44px; 1283 | padding: 0 20px; 1284 | text-align: center; 1285 | text-decoration: none; 1286 | font: 400 15px/44px "microsoft yahei"; 1287 | color: #333 1288 | } 1289 | 1290 | #navitems-2014 a:hover { 1291 | color: #C81623 1292 | } 1293 | 1294 | #navitems-2014 .spacer { 1295 | width: 1px; 1296 | height: 24px; 1297 | margin: 10px 0 0; 1298 | background: #DDD; 1299 | overflow: hidden 1300 | } 1301 | 1302 | #treasure { 1303 | float: right 1304 | } 1305 | 1306 | .root61 #categorys-2014 .item-channels { 1307 | width: 790px 1308 | } 1309 | 1310 | .root61 #categorys-2014 .dorpdown-layer { 1311 | width: 999px 1312 | } 1313 | 1314 | .root61 #categorys-2014 .subitems { 1315 | width: 790px 1316 | } 1317 | 1318 | .root61 #categorys-2014 .subitems dd { 1319 | width: 620px 1320 | } 1321 | 1322 | .root61 #categorys-2014 .subitems-main1,.root61 #categorys-2014 .subitems-main2 { 1323 | float: left; 1324 | width: 365px; 1325 | padding-right: 10px; 1326 | margin-right: 10px; 1327 | border-right: 1px solid #eee; 1328 | margin-top: 8px 1329 | } 1330 | 1331 | .root61 #categorys-2014 .subitems-main1 dd,.root61 #categorys-2014 .subitems-main2 dd { 1332 | width: 275px 1333 | } 1334 | 1335 | .root61 #categorys-2014 .subitems-main1 .fore1,.root61 #categorys-2014 .subitems-main1 .fore8,.root61 #categorys-2014 .subitems-main2 .fore1,.root61 #categorys-2014 .subitems-main2 .fore8 { 1336 | margin-top: -5px 1337 | } 1338 | 1339 | .root61 #categorys-2014 .subitems-main1 .fore1 dd,.root61 #categorys-2014 .subitems-main1 .fore8 dd,.root61 #categorys-2014 .subitems-main2 .fore1 dd,.root61 #categorys-2014 .subitems-main2 .fore8 dd { 1340 | border-top: 0 1341 | } 1342 | 1343 | .root61 #categorys-2014 .subitems-main2 { 1344 | border-right: 0 1345 | } 1346 | /* jdf-1.0.0/ shoppingcart.css Date:2015-09-15 18:39:10 */ 1347 | #settleup-2014 { 1348 | float: right; 1349 | z-index: 11; 1350 | height: 36px; 1351 | margin-top: 25px 1352 | } 1353 | 1354 | #settleup-2014 .cw-icon { 1355 | width: 75px; 1356 | height: 34px; 1357 | border: 1px solid #DFDFDF; 1358 | padding: 0 28px 0 36px; 1359 | background: #F9F9F9; 1360 | text-align: center; 1361 | line-height: 34px 1362 | } 1363 | 1364 | #settleup-2014 .ci-left { 1365 | top: 9px; 1366 | left: 18px; 1367 | width: 18px; 1368 | height: 16px; 1369 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/jd2015img.png) 0 -58px no-repeat; 1370 | _background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/jd2015img.png) 0 -91px no-repeat 1371 | } 1372 | 1373 | #settleup-2014 .ci-right { 1374 | top: 11px; 1375 | right: 10px; 1376 | width: 7px; 1377 | height: 13px; 1378 | overflow: hidden; 1379 | font: 400 13px/13px simsun; 1380 | color: #999 1381 | } 1382 | 1383 | #settleup-2014 .ci-count { 1384 | position: absolute; 1385 | top: -4px; 1386 | left: 104px; 1387 | display: inline-block; 1388 | *zoom: 1; 1389 | *display: inline; 1390 | padding: 1px 2px; 1391 | font-size: 12px; 1392 | line-height: 12px; 1393 | color: #fff; 1394 | background-color: #c81623; 1395 | border-radius: 7px 7px 7px 0; 1396 | min-width: 12px; 1397 | text-align: center 1398 | } 1399 | 1400 | #settleup-2014.hover .cw-icon,#settleup-2014.hover .dorpdown-layer,#settleup-2014:hover .cw-icon,#settleup-2014:hover .dorpdown-layer { 1401 | background: #fff; 1402 | border: 1px solid #ddd; 1403 | box-shadow: 0 0 5px rgba(0,0,0,.2) 1404 | } 1405 | 1406 | #settleup-2014.hover .dorpdown-layer,#settleup-2014:hover .dorpdown-layer { 1407 | display: block; 1408 | right: 0; 1409 | _right: -1px; 1410 | width: 308px 1411 | } 1412 | 1413 | #settleup-2014.hover .spacer,#settleup-2014:hover .spacer { 1414 | position: absolute; 1415 | right: 0; 1416 | top: -7px; 1417 | width: 139px; 1418 | height: 12px; 1419 | background: #fff 1420 | } 1421 | 1422 | #settleup-2014 .prompt { 1423 | padding: 10px 15px 1424 | } 1425 | 1426 | #settleup-2014 .nogoods { 1427 | padding-left: 30px; 1428 | height: 49px; 1429 | line-height: 49px; 1430 | overflow: hidden; 1431 | color: #999 1432 | } 1433 | 1434 | #settleup-2014 .nogoods b { 1435 | float: left; 1436 | width: 56px; 1437 | height: 49px; 1438 | background-image: url(http://misc.360buyimg.com/jdf/1.0.0/unit/shoppingcart/2.0.0/i/settleup-nogoods.png) 1439 | } 1440 | 1441 | #settleup-content { 1442 | position: relative; 1443 | z-index: 2; 1444 | width: 100%; 1445 | background: #fff 1446 | } 1447 | 1448 | #settleup-content .loading { 1449 | display: block; 1450 | height: 50px; 1451 | background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/loading.gif) no-repeat center center 1452 | } 1453 | 1454 | #settleup-content .smt { 1455 | height: 25px; 1456 | padding: 6px 8px; 1457 | line-height: 25px 1458 | } 1459 | 1460 | #settleup-content .smc { 1461 | background: #fff; 1462 | height: auto!important; 1463 | height: 344px; 1464 | max-height: 344px; 1465 | overflow-y: auto 1466 | } 1467 | 1468 | #settleup-content .smb { 1469 | padding: 8px; 1470 | background: #F5F5F5; 1471 | _height: 45px; 1472 | _padding-top: 15px; 1473 | _padding-bottom: 0 1474 | } 1475 | 1476 | #settleup-content .smb .p-total { 1477 | float: left; 1478 | line-height: 29px 1479 | } 1480 | 1481 | #settleup-content .smb span { 1482 | color: #c81623 1483 | } 1484 | 1485 | #settleup-content .smb a { 1486 | float: right; 1487 | height: 29px; 1488 | padding: 0 10px; 1489 | background: #E4393C; 1490 | color: #fff; 1491 | text-align: center; 1492 | font-weight: 700; 1493 | line-height: 29px; 1494 | border-radius: 3px; 1495 | -moz-border-radius: 3px; 1496 | -webkit-border-radius: 3px 1497 | } 1498 | 1499 | #settleup-content ul { 1500 | margin-top: -1px 1501 | } 1502 | 1503 | #settleup-content li { 1504 | padding: 8px 10px; 1505 | border-top: 1px dotted #ccc; 1506 | overflow: hidden; 1507 | line-height: 17px; 1508 | vertical-align: bottom; 1509 | *zoom: 1 1510 | } 1511 | 1512 | #settleup-content li.hover,#settleup-content li:hover { 1513 | background: #F5F5F5 1514 | } 1515 | 1516 | #settleup-content li .gift { 1517 | height: 17px; 1518 | width: 282px; 1519 | overflow: hidden; 1520 | text-overflow: ellipsis; 1521 | white-space: nowrap 1522 | } 1523 | 1524 | #settleup-content li .gift a { 1525 | color: #999 1526 | } 1527 | 1528 | #settleup-content li .gift-jq { 1529 | color: #999; 1530 | clear: both 1531 | } 1532 | 1533 | #settleup-content .p-img { 1534 | float: left; 1535 | width: 50px; 1536 | height: 50px; 1537 | border: 1px solid #ddd; 1538 | padding: 0; 1539 | margin-right: 10px; 1540 | font-size: 0 1541 | } 1542 | 1543 | #settleup-content .p-name { 1544 | float: left; 1545 | width: 120px; 1546 | height: 52px 1547 | } 1548 | 1549 | #settleup-content .p-detail { 1550 | float: right; 1551 | text-align: right 1552 | } 1553 | 1554 | #settleup-content .p-price { 1555 | font-weight: 700 1556 | } 1557 | 1558 | #settleup-iframe { 1559 | position: absolute; 1560 | left: 0; 1561 | top: 0; 1562 | z-index: 1; 1563 | width: 100%; 1564 | background: #fff 1565 | } 1566 | 1567 | #settleup-2014 .dt-mz { 1568 | color: #999; 1569 | width: 310px; 1570 | overflow: hidden; 1571 | text-overflow: ellipsis; 1572 | white-space: nowrap 1573 | } 1574 | 1575 | #settleup-2014 .dt-mz a { 1576 | color: #999 1577 | } 1578 | 1579 | #settleup-2014 .dt-mz:hover { 1580 | background: #fff 1581 | } 1582 | 1583 | #mcart-suit .dt,#mcart-suit .dt:hover { 1584 | background: #d3ebff 1585 | } 1586 | 1587 | #mcart-mj .dt,#mcart-mj .dt:hover,#mcart-mz .dt,#mcart-mz .dt:hover { 1588 | background: #bffab1 1589 | } 1590 | 1591 | #settleup-content .fr .hl-green,#settleup-content .fr .hl-orange { 1592 | margin-right: 0 1593 | } 1594 | 1595 | #settleup-content .hl-green,#settleup-content .hl-orange { 1596 | margin-right: 5px; 1597 | color: #fff; 1598 | display: inline-block; 1599 | *zoom: 1; 1600 | padding: 0 2px; 1601 | font: 12px/16px simsun 1602 | } 1603 | 1604 | #settleup-content .hl-green { 1605 | background: #3b0 1606 | } 1607 | 1608 | #settleup-content .hl-orange { 1609 | background: #f60 1610 | } 1611 | 1612 | .root61 #settleup-2014 { 1613 | margin-right: 65px 1614 | } 1615 | 1616 | #settleup-2014.hover .ci-left { 1617 | _background: url(http://misc.360buyimg.com/jdf/1.0.0/unit/globalImages/1.0.0/jd2015img.png) 0 -116px no-repeat 1618 | } 1619 | /* jdf-1.0.0/ global-footer.css Date:2015-09-15 18:39:12 */ 1620 | #footer-2014 { 1621 | border-top: 1px solid #E5E5E5; 1622 | padding: 20px 0 30px; 1623 | text-align: center 1624 | } 1625 | 1626 | #footer-2014 .links a { 1627 | margin: 0 10px 1628 | } 1629 | 1630 | #footer-2014 .copyright { 1631 | margin: 10px 0 1632 | } 1633 | 1634 | #footer-2014 .authentication a { 1635 | margin: 0 5px; 1636 | text-decoration: none 1637 | } 1638 | /* jdf-1.0.0/ service.css Date:2015-09-25 09:37:10 */ 1639 | #service-2014 { 1640 | margin-bottom: 20px 1641 | } 1642 | 1643 | #service-2014 dl { 1644 | float: left; 1645 | width: 222px 1646 | } 1647 | 1648 | #service-2014 dl.fore5 { 1649 | width: 100px 1650 | } 1651 | 1652 | #service-2014 dt { 1653 | padding: 6px 0; 1654 | font: 400 16px/24px "microsoft yahei" 1655 | } 1656 | 1657 | #service-2014 dd { 1658 | line-height: 20px 1659 | } 1660 | 1661 | #service-2014 .slogen { 1662 | position: relative; 1663 | height: 54px; 1664 | padding: 20px 0; 1665 | margin-bottom: 14px; 1666 | background: #F5F5F5; 1667 | text-align: center 1668 | } 1669 | 1670 | #service-2014 .slogen .item { 1671 | display: inline-block; 1672 | position: absolute; 1673 | left: 50%; 1674 | top: 20px; 1675 | width: 245px; 1676 | height: 54px; 1677 | text-align: left; 1678 | vertical-align: middle; 1679 | font: 400 18px/50px "microsoft yahei" 1680 | } 1681 | 1682 | #service-2014 .slogen .item i { 1683 | display: block; 1684 | position: absolute; 1685 | top: 0; 1686 | left: 10px; 1687 | width: 220px; 1688 | height: 54px; 1689 | background-repeat: no-repeat; 1690 | background-position: 0 0 1691 | } 1692 | 1693 | #service-2014 .slogen .item b { 1694 | padding: 0 10px; 1695 | font-size: 24px; 1696 | color: #C81623 1697 | } 1698 | 1699 | #service-2014 .slogen .fore1 { 1700 | margin-left: -490px 1701 | } 1702 | 1703 | #service-2014 .slogen .fore1 i { 1704 | background-image: url(http://misc.360buyimg.com/jdf/1.0.0/unit/service/1.0.0/i/service_items_1.png) 1705 | } 1706 | 1707 | #service-2014 .slogen .fore2 { 1708 | margin-left: -245px 1709 | } 1710 | 1711 | #service-2014 .slogen .fore2 i { 1712 | background-image: url(http://misc.360buyimg.com/jdf/1.0.0/unit/service/1.0.0/i/service_items_2.png) 1713 | } 1714 | 1715 | #service-2014 .slogen .fore3 { 1716 | margin-left: 0 1717 | } 1718 | 1719 | #service-2014 .slogen .fore3 i { 1720 | background-image: url(http://misc.360buyimg.com/jdf/1.0.0/unit/service/1.0.0/i/service_items_3.png) 1721 | } 1722 | 1723 | #service-2014 .slogen .fore4 { 1724 | margin-left: 245px 1725 | } 1726 | 1727 | #service-2014 .slogen .fore4 i { 1728 | background-image: url(http://misc.360buyimg.com/jdf/1.0.0/unit/service/1.0.0/i/service_items_4.png) 1729 | } 1730 | 1731 | #coverage { 1732 | float: right; 1733 | width: 310px; 1734 | height: 168px; 1735 | background: url(http://misc.360buyimg.com/product/skin/2013/i/20130330B_1.png) no-repeat 60px -131px 1736 | } 1737 | 1738 | #coverage .dt { 1739 | padding: 6px 40px 15px 80px; 1740 | font: 400 16px/24px "microsoft yahei" 1741 | } 1742 | 1743 | #coverage .dd { 1744 | padding: 0 40px 15px 80px 1745 | } 1746 | 1747 | .root61 #service-2014 dl { 1748 | width: 275px 1749 | } 1750 | 1751 | .root61 #service-2014 dl.fore5 { 1752 | width: 100px 1753 | } 1754 | 1755 | .root61 #service-2014 .slogen .item { 1756 | width: 302px 1757 | } 1758 | 1759 | .root61 #service-2014 .slogen .fore1 { 1760 | margin-left: -604px 1761 | } 1762 | 1763 | .root61 #service-2014 .slogen .fore2 { 1764 | margin-left: -304px 1765 | } 1766 | 1767 | .root61 #service-2014 .slogen .fore3 { 1768 | margin-left: 0 1769 | } 1770 | 1771 | .root61 #service-2014 .slogen .fore4 { 1772 | margin-left: 304px 1773 | } 1774 | /* jdf-1.0.0/ basePatch.css Date:2015-09-15 18:39:12 */ 1775 | .m,.mb,.mc,.mt,.sm,.smb,.smc,.smt { 1776 | overflow: hidden; 1777 | zoom: 1 1778 | } 1779 | 1780 | .m,.sm { 1781 | margin-bottom: 10px 1782 | } 1783 | 1784 | .mt h2,.smt h3 { 1785 | font-family: "microsoft yahei" 1786 | } 1787 | 1788 | .slide-controls span { 1789 | display: inline-block; 1790 | color: #fff 1791 | } 1792 | 1793 | .pagin a,.pagin span { 1794 | float: left; 1795 | height: 20px; 1796 | padding: 3px 10px; 1797 | border: 1px solid #ccc; 1798 | margin-left: 2px; 1799 | font-family: arial; 1800 | line-height: 20px; 1801 | font-size: 14px; 1802 | overflow: hidden; 1803 | -moz-border-radius: 5px; 1804 | -webkit-border-radius: 5px 1805 | } 1806 | 1807 | .pagin .current,.pagin .text { 1808 | border: none; 1809 | padding: 4px 11px 1810 | } 1811 | 1812 | .pagin a:link,.pagin a:visited { 1813 | color: #005aa0 1814 | } 1815 | 1816 | .pagin a:active,.pagin a:hover { 1817 | background: #005aa0; 1818 | color: #fff; 1819 | text-decoration: none 1820 | } 1821 | 1822 | .pagin .current,.pagin .current:link,.pagin .current:visited { 1823 | color: #f60; 1824 | font-weight: 700 1825 | } 1826 | 1827 | .pagin b { 1828 | display: block; 1829 | position: absolute; 1830 | top: 9px; 1831 | width: 5px; 1832 | height: 9px; 1833 | background-image: url(http://misc.360buyimg.com/201007/skin/df/i/bg_hotsale.gif); 1834 | background-repeat: no-repeat; 1835 | overflow: hidden 1836 | } 1837 | 1838 | .pagin .next,.pagin .next-disabled,.pagin .prev,.pagin .prev-disabled { 1839 | position: relative; 1840 | padding-top: 5px; 1841 | height: 18px; 1842 | line-height: 18px 1843 | } 1844 | 1845 | .pagin .next-disabled,.pagin .prev-disabled { 1846 | color: #ccc; 1847 | cursor: default 1848 | } 1849 | 1850 | .pagin .prev,.pagin .prev-disabled { 1851 | padding-left: 12px 1852 | } 1853 | 1854 | .pagin .prev b { 1855 | left: 3px; 1856 | background-position: -68px -608px 1857 | } 1858 | 1859 | .pagin .prev-disabled b { 1860 | left: 3px; 1861 | background-position: -80px -608px 1862 | } 1863 | 1864 | .pagin .next,.pagin .next-disabled { 1865 | padding-right: 12px 1866 | } 1867 | 1868 | .pagin .next b { 1869 | right: 3px; 1870 | background-position: -62px -608px 1871 | } 1872 | 1873 | .pagin .next-disabled b { 1874 | right: 3px; 1875 | background-position: -74px -608px 1876 | } 1877 | 1878 | .pagin-m a,.pagin-m span { 1879 | height: 14px; 1880 | line-height: 14px; 1881 | font-size: 12px 1882 | } 1883 | 1884 | .pagin-m b { 1885 | top: 5px 1886 | } 1887 | 1888 | .pagin-m .next,.pagin-m .next-disabled,.pagin-m .prev,.pagin-m .prev-disabled { 1889 | padding-top: 3px; 1890 | height: 14px; 1891 | line-height: 14px; 1892 | *line-height: 16px 1893 | } 1894 | 1895 | .thickframe { 1896 | position: fixed; 1897 | top: 0; 1898 | left: 0; 1899 | z-index: 10000000; 1900 | width: 100%; 1901 | height: 100%; 1902 | background: #000; 1903 | border: 0; 1904 | filter: alpha(opacity=0); 1905 | opacity: 0 1906 | } 1907 | 1908 | .thickdiv { 1909 | position: fixed; 1910 | top: 0; 1911 | left: 0; 1912 | z-index: 10000001; 1913 | width: 100%; 1914 | height: 100%; 1915 | background: #000; 1916 | border: 0; 1917 | filter: alpha(opacity=15); 1918 | opacity: .15 1919 | } 1920 | 1921 | .thickbox { 1922 | position: absolute; 1923 | z-index: 10000002; 1924 | overflow: hidden; 1925 | padding: 0; 1926 | border: 4px solid rgba(0,0,0,.1); 1927 | border-radius: 5px; 1928 | -moz-border-radius: 5px; 1929 | -webkit-border-radius: 5px 1930 | } 1931 | 1932 | .thicktitle { 1933 | height: 27px; 1934 | padding: 0 10px; 1935 | border: solid #C4C4C4; 1936 | border-width: 1px 1px 0; 1937 | background: #F3F3F3; 1938 | line-height: 27px; 1939 | font-family: arial,"\5b8b\4f53"; 1940 | font-size: 14px; 1941 | font-weight: 700; 1942 | color: #333 1943 | } 1944 | 1945 | .thickclose:link,.thickclose:visited { 1946 | display: block; 1947 | position: absolute; 1948 | z-index: 100000; 1949 | top: 7px; 1950 | right: 12px; 1951 | overflow: hidden; 1952 | width: 15px; 1953 | height: 15px; 1954 | background: url(http://misc.360buyimg.com/201007/skin/df/i/bg_thickbox.gif) no-repeat 0 -18px; 1955 | font-size: 0; 1956 | line-height: 100px 1957 | } 1958 | 1959 | .thickcon { 1960 | overflow: auto; 1961 | background: #fff; 1962 | border: solid #C4C4C4; 1963 | border-width: 1px; 1964 | padding: 10px 1965 | } 1966 | 1967 | .thickloading { 1968 | background: url(http://misc.360buyimg.com/201007/skin/df/i/loading.gif) #fff no-repeat center center 1969 | } 1970 | 1971 | .thickcountdown { 1972 | height: 20px; 1973 | padding-right: 6px; 1974 | margin-top: -20px; 1975 | text-align: right; 1976 | color: #999 1977 | } 1978 | 1979 | *html .thickdiv,*html .thickframe { 1980 | position: absolute 1981 | } 1982 | 1983 | #thicktitler { 1984 | padding: 0 11px; 1985 | background: #8DB7DC; 1986 | border: none; 1987 | color: #fff 1988 | } 1989 | 1990 | #thickcloser:link,#thickcloser:visited { 1991 | top: 6px; 1992 | right: 9px; 1993 | width: 16px; 1994 | height: 17px; 1995 | background-position: 0 0 1996 | } 1997 | 1998 | #thickconr { 1999 | border: solid #8DB7DC; 2000 | border-width: 1px 2001 | } 2002 | --------------------------------------------------------------------------------