Sfoglia il codice sorgente

增加关于个人物料和企业物料的搜索方法

hejq 7 anni fa
parent
commit
9d371e79f4

+ 20 - 0
src/main/java/com/uas/ps/config/RestTemplateConfig.java

@@ -0,0 +1,20 @@
+package com.uas.ps.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * RestTemplate配置bean
+ * @author suntg
+ * @create 2017/2/15
+ * @version 2017年8月2日16:07:06 suntg 修改文件类名
+ */
+@Configuration
+public class RestTemplateConfig {
+
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+}

+ 35 - 7
src/main/java/com/uas/ps/product/controller/ProductGetController.java

@@ -1,25 +1,27 @@
 package com.uas.ps.product.controller;
 
 import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import com.uas.ps.core.page.PageInfo;
-import com.uas.ps.core.page.criteria.CriterionExpression;
+import com.uas.ps.core.util.ContextUtils;
 import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductUsers;
+import com.uas.ps.product.search.SPageUtils;
 import com.uas.ps.product.service.ProductService;
+import com.uas.ps.product.search.model.SPage;
+import com.uas.ps.product.search.service.SearchService;
+import com.uas.ps.properties.UrlProperties;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Sort;
+import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-import javax.servlet.http.HttpServletRequest;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * 物料相关的查询接口
@@ -33,6 +35,9 @@ public class ProductGetController {
     @Autowired
     private ProductService productService;
 
+    @Autowired
+    private SearchService searchService;
+
     /**
      * 根据enUU和code查找企业物料
      * @param enUU  企业UU
@@ -77,12 +82,34 @@ public class ProductGetController {
      * @return  物料
      */
     @RequestMapping(value = "/findByPageInfo", method = RequestMethod.GET)
-    public Page<Product> findByPageInfo(int pageNumber, int pageSize, String filters, Sort sort, String keyword) {
+    public SPage<Product> findByPageInfo(int pageNumber, int pageSize, String filters, Sort sort, String keyword) {
         PageInfo pageInfo = new PageInfo(pageNumber, pageSize);
         Map<String, Object> map = JSON.parseObject(filters);
         pageInfo.setFilters(map);
         pageInfo.setSort(sort);
-        return productService.findByPageInfo(pageInfo, keyword);
+        if (StringUtils.isEmpty(keyword)) {
+            return SPageUtils.covert(productService.findByPageInfo(pageInfo, keyword));
+        } else {
+            return searchService.searchProducts(keyword, pageInfo);
+        }
+    }
+
+    /**
+     * 根据分页信息查找个人物料
+     *
+     * @param pageNumber  页码
+     * @param pageSize 分页大小
+     * @param sort 排序
+     * @param keyword  关键词   不建议使用关键词搜索,jpa获取会很慢
+     * @return  物料
+     */
+    @RequestMapping(value = "/findProductUsers", method = RequestMethod.GET)
+    public SPage<ProductUsers> findProductUsersByPageInfo(int pageNumber, int pageSize, String filters, Sort sort, String keyword) {
+        PageInfo pageInfo = new PageInfo(pageNumber, pageSize);
+        Map<String, Object> map = JSON.parseObject(filters);
+        pageInfo.setFilters(map);
+        pageInfo.setSort(sort);
+        return searchService.searchProductUsers(keyword, pageInfo);
     }
 
     /**
@@ -186,4 +213,5 @@ public class ProductGetController {
     public Long countByEnUU(@RequestParam("enUU") Long enUU) {
         return productService.countByEnUU(enUU);
     }
+
 }

+ 28 - 0
src/main/java/com/uas/ps/product/search/SPageUtils.java

@@ -0,0 +1,28 @@
+package com.uas.ps.product.search;
+
+import com.uas.ps.product.search.model.SPage;
+import org.springframework.data.domain.Page;
+
+/**
+ * SPage<T> 与 Page<T>转换
+ *
+ * @author hejq
+ * @date 2018-08-01 14:26
+ */
+public class SPageUtils {
+
+    /**
+     * 将Page<T> 转成平台封装的SPage<T>
+     * @param page page信息
+     * @param <T> 实体对象
+     * @return
+     */
+    public static <T> SPage<T> covert(Page<T> page) {
+        SPage<T> sPage = new SPage<T>();
+        sPage.setTotalElement(page.getTotalElements());
+        sPage.setSize(page.getSize());
+        sPage.setPage(page.getNumber());
+        sPage.setContent(page.getContent());
+        return sPage;
+    }
+}

+ 62 - 0
src/main/java/com/uas/ps/product/search/model/MultiValue.java

@@ -0,0 +1,62 @@
+package com.uas.ps.product.search.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 搜索时,一个字段可能对应多个值
+ * 
+ * @author sunyj
+ * @since 2016年11月28日 上午8:47:54
+ */
+public class MultiValue implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 字段对应的多个值
+	 */
+	private List<Object> values;
+
+	/**
+	 * 多个值之间默认是AND逻辑关系,若该成员变量为true,则为OR逻辑关系
+	 */
+	private boolean or = false;
+
+	public MultiValue() {
+		super();
+	}
+
+	public MultiValue(List<Object> values) {
+		super();
+		this.values = values;
+	}
+
+	public MultiValue(List<Object> values, boolean or) {
+		super();
+		this.values = values;
+		this.or = or;
+	}
+
+	public List<Object> getValues() {
+		return values;
+	}
+
+	public void setValues(List<Object> values) {
+		this.values = values;
+	}
+
+	public boolean isOr() {
+		return or;
+	}
+
+	public void setOr(boolean or) {
+		this.or = or;
+	}
+
+	@Override
+	public String toString() {
+		return "MultiValueField [values=" + values + ", or=" + or + "]";
+	}
+
+}

+ 61 - 0
src/main/java/com/uas/ps/product/search/model/MultiValueField.java

@@ -0,0 +1,61 @@
+package com.uas.ps.product.search.model;
+
+
+/**
+ * 多条件封装
+ *
+ * @author hejq
+ * @date 2018-07-06 16:59
+ */
+public class MultiValueField {
+
+    /**
+     * 字段
+     */
+    private String field;
+
+    /**
+     * 值
+     */
+    private MultiValue multiValue;
+
+    public String getField() {
+        return field;
+    }
+
+    public void setField(String field) {
+        this.field = field;
+    }
+
+    public MultiValue getMultiValue() {
+        return multiValue;
+    }
+
+    public void setMultiValue(MultiValue multiValue) {
+        this.multiValue = multiValue;
+    }
+
+    /**
+     * 无参构造
+     */
+    public MultiValueField(){}
+
+    /**
+     * 通过传入字段和multiValue构造MultiValueField
+     *
+     * @param field 字段
+     * @param multiValue multiValue
+     */
+    public MultiValueField(String field, MultiValue multiValue) {
+        this.field = field;
+        this.multiValue = multiValue;
+    }
+
+    @Override
+    public String toString() {
+        return "MultiValueField{" +
+                "field='" + field + '\'' +
+                ", multiValue=" + multiValue +
+                '}';
+    }
+}

+ 118 - 0
src/main/java/com/uas/ps/product/search/model/SPage.java

@@ -0,0 +1,118 @@
+package com.uas.ps.product.search.model;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 自定义分页参数新
+ * @param <T>
+ *     
+ * @author hejq
+ * @date 2018-08-01 9:57
+ */
+public class SPage<T> implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+
+	private int totalPage;
+
+	private long totalElement;
+
+	private int page;
+
+	private int size;
+
+	private boolean first;
+
+	private boolean last;
+
+	private List<T> content;
+
+	private String token;
+
+	public SPage() {
+		super();
+	}
+
+	public SPage(int totalPage, long totalElement, int page, int size, boolean first, boolean last) {
+		super();
+		this.totalPage = totalPage;
+		this.totalElement = totalElement;
+		this.page = page;
+		this.size = size;
+		this.first = first;
+		this.last = last;
+	}
+
+	public int getTotalPage() {
+		return totalPage;
+	}
+
+	public void setTotalPage(int totalPage) {
+		this.totalPage = totalPage;
+	}
+
+	public long getTotalElement() {
+		return totalElement;
+	}
+
+	public void setTotalElement(long totalElement) {
+		this.totalElement = totalElement;
+	}
+
+	public int getPage() {
+		return page;
+	}
+
+	public void setPage(int page) {
+		this.page = page;
+	}
+
+	public int getSize() {
+		return size;
+	}
+
+	public void setSize(int size) {
+		this.size = size;
+	}
+
+	public boolean isFirst() {
+		return first;
+	}
+
+	public void setFirst(boolean first) {
+		this.first = first;
+	}
+
+	public boolean isLast() {
+		return last;
+	}
+
+	public void setLast(boolean last) {
+		this.last = last;
+	}
+
+	public List<T> getContent() {
+		return content;
+	}
+
+	public void setContent(List<T> content) {
+		this.content = content;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+
+	@Override
+	public String toString() {
+		return "SPage [totalPage=" + totalPage + ", totalElement=" + totalElement + ", page=" + page + ", size=" + size
+				+ ", first=" + first + ", last=" + last + ", content=" + content + ", token=" + token + "]";
+	}
+
+
+}

+ 17 - 0
src/main/java/com/uas/ps/product/search/model/SearchUrl.java

@@ -0,0 +1,17 @@
+package com.uas.ps.product.search.model;
+
+/**
+ * 搜索链接
+ *
+ * @author hejq
+ * @date 2018-07-05 16:15
+ */
+public class SearchUrl {
+
+    /**
+     * 获取id链接
+     */
+    public static final String ID_LIST = "/search?keyword={keyword}&tableName={tableName}&page={page}&size={size}" +
+            "&filters={filters}&sort={sort}";
+
+}

+ 27 - 0
src/main/java/com/uas/ps/product/search/service/RestTempSearchService.java

@@ -0,0 +1,27 @@
+package com.uas.ps.product.search.service;
+
+
+import com.uas.ps.core.page.PageInfo;
+import com.uas.ps.product.search.model.SPage;
+import net.sf.ehcache.search.SearchException;
+
+/**
+ * 采用restTempLate方式重写搜索功能
+ *
+ * @author hejq
+ * @date 2018-07-05 16:04
+ */
+public interface RestTempSearchService {
+
+    /**
+     * 通过表名,关键词,分页参数查询id信息
+     *
+     * @param tableName 表名
+     * @param keyword 关键词
+     * @param pageInfo 分页参数
+     * @throws SearchException
+     * @return
+     */
+    SPage<Long> searchIds(String keyword, String tableName, PageInfo pageInfo) throws SearchException;
+
+}

+ 84 - 0
src/main/java/com/uas/ps/product/search/service/RestTempSearchServiceImpl.java

@@ -0,0 +1,84 @@
+package com.uas.ps.product.search.service;
+
+import com.alibaba.fastjson.JSON;
+import com.uas.platform.core.util.serializer.FlexJsonUtils;
+import com.uas.ps.core.page.PageInfo;
+import com.uas.ps.core.util.ContextUtils;
+import com.uas.ps.core.util.StringUtils;
+import com.uas.ps.properties.UrlProperties;
+import com.uas.ps.product.search.model.SPage;
+import com.uas.ps.product.search.model.SearchUrl;
+import net.sf.ehcache.search.SearchException;
+import org.apache.commons.collections.map.HashedMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.Map;
+
+/**
+ * 采用restTempLate方式重写搜索功能
+ *
+ * @author hejq
+ * @date 2018-07-05 16:05
+ */
+@Service
+public class RestTempSearchServiceImpl implements RestTempSearchService {
+
+    private final RestTemplate restTemplate;
+
+    /**
+     * 搜索地址
+     */
+    final String SEARCH_URL = ContextUtils.getBean(UrlProperties.class).getSearchUrl();
+
+    @Autowired
+    public RestTempSearchServiceImpl(RestTemplate restTemplate) {
+        this.restTemplate = restTemplate;
+    }
+
+    /**
+     * 通过表名,关键词,分页参数查询id信息
+     *
+     * @param tableName  表名
+     * @param keyword    关键词
+     * @param pageInfo 分页参数
+     * @throws SearchException
+     * @return
+     */
+    @Override
+    public SPage<Long> searchIds(String keyword, String tableName, PageInfo pageInfo) throws SearchException {
+        Map<String, Object> map = initSearchMap(tableName.toString(), keyword, pageInfo);
+        String str = restTemplate.getForObject(SEARCH_URL + SearchUrl.ID_LIST, String.class, map);
+        if (StringUtils.isEmpty(str)) {
+            return new SPage<>();
+        } else {
+            try {
+                SPage<Long> sPage = FlexJsonUtils.fromJson(str, SPage.class);
+                return sPage;
+            } catch (Exception e) {
+                e.printStackTrace();
+                return new SPage<>();
+            }
+        }
+    }
+
+    /**
+     * 定义搜索属性
+     *
+     * @param tableName 表名
+     * @param keyword 关键字
+     * @param pageInfo 分页属性
+     * @return
+     */
+    public Map<String, Object> initSearchMap(String tableName, String keyword, PageInfo pageInfo) {
+        Map<String, Object> map = new HashedMap();
+        map.put("tableName", tableName);
+        map.put("page", pageInfo.getPageNumber());
+        map.put("size", pageInfo.getPageSize());
+        map.put("keyword", keyword);
+        map.put("sort", FlexJsonUtils.toJsonDeep(pageInfo.getFilters().get("sort")));
+        map.put("filters", JSON.toJSONString(pageInfo.getFilters()));
+        return map;
+    }
+}

+ 33 - 0
src/main/java/com/uas/ps/product/search/service/SearchService.java

@@ -0,0 +1,33 @@
+package com.uas.ps.product.search.service;
+
+import com.uas.ps.core.page.PageInfo;
+import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductUsers;
+import com.uas.ps.product.search.model.SPage;
+
+/**
+ * 搜索服务接口
+ *
+ * @author hejq
+ * @date 2018-08-01 10:36
+ */
+public interface SearchService {
+
+    /**
+     * 通过关键词和分页信息查询物料信息
+     *
+     * @param keyword 搜索关键词
+     * @param pageInfo 分页信息
+     * @return
+     */
+    SPage<Product> searchProducts(String keyword, PageInfo pageInfo);
+
+    /**
+     * 通过关键词和分页信息查询个人物料信息
+     *
+     * @param keyword 搜索关键词
+     * @param pageInfo 分页信息
+     * @return
+     */
+    SPage<ProductUsers> searchProductUsers(String keyword, PageInfo pageInfo);
+}

+ 157 - 0
src/main/java/com/uas/ps/product/search/service/SearchServiceImpl.java

@@ -0,0 +1,157 @@
+package com.uas.ps.product.search.service;
+
+import com.uas.ps.core.page.PageInfo;
+import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductUsers;
+import com.uas.ps.product.repository.ProductDao;
+import com.uas.ps.product.repository.ProductUsersDao;
+import com.uas.ps.product.search.model.SPage;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 搜索接口
+ *
+ * @author hejq
+ * @date 2018-08-01 10:38
+ */
+@Service
+public class SearchServiceImpl implements SearchService {
+
+    @Autowired
+    private RestTempSearchService searchService;
+
+    @Autowired
+    private ProductDao productDao;
+
+    @Autowired
+    private ProductUsersDao productUsersDao;
+
+    /**
+     * 物料信息表
+     */
+    final String PRODUCT_TABLE_NAME = "products";
+
+    /**
+     * 个人物料信息表
+     */
+    final String PRODUCT_USER_TABLE_NAME = "product$users";
+
+    private ConcurrentHashMap<String, Field> sortFields = new ConcurrentHashMap<>();
+
+    /**
+     * 将id的SPage信息、数据合并
+     *
+     * @param idsPage
+     *            id的SPage信息
+     * @param content
+     *            数据
+     * @return 合并后的结果
+     */
+    private <T> SPage<T> toSPage(SPage<Long> idsPage, List<T> content) {
+        if (idsPage == null) {
+            return null;
+        }
+        SPage<T> result = new SPage<>();
+        result.setContent(content);
+        result.setFirst(idsPage.isFirst());
+        result.setLast(idsPage.isLast());
+        result.setPage(idsPage.getPage());
+        result.setSize(idsPage.getSize());
+        result.setTotalElement(idsPage.getTotalElement());
+        result.setTotalPage(idsPage.getTotalPage());
+        return result;
+    }
+
+    /**
+     * 自定义排序规则
+     *
+     * @param content 数据集合
+     * @param targetCls 目标类
+     * @param properyName 字段名
+     * @param propertyList 字段
+     * @param <T>
+     */
+    private <T> void sortByProperty(List<T> content, Class<T> targetCls, String properyName,
+                                    final List<Long> propertyList) {
+        final Field field = getPropertyField(targetCls, properyName);
+        if (null != field) {
+            Collections.sort(content, new Comparator<T>() {
+
+                @Override
+                public int compare(T param1, T param2) {
+                    try {
+                        return Integer.compare(propertyList.indexOf((long) field.get(param1)),
+                                propertyList.indexOf((long) field.get(param2)));
+                    } catch (IllegalArgumentException e) {
+                        e.printStackTrace();
+                    } catch (IllegalAccessException e) {
+                        e.printStackTrace();
+                    }
+                    return 0;
+                }
+
+            });
+        }
+    }
+
+    /**
+     * 获取字段列名
+     *
+     * @param targetCls 目标类
+     * @param properyName
+     * @return
+     */
+    private Field getPropertyField(Class<?> targetCls, String properyName) {
+        Field field = sortFields.get(targetCls.toString());
+        if (null == field) {
+            Field[] fields = targetCls.getDeclaredFields();
+            for (Field f : fields) {
+                if (f.getName().equals(properyName)) {
+                    field = f;
+                    field.setAccessible(true);
+                    sortFields.put(targetCls.toString(), f);
+                    break;
+                }
+            }
+        }
+        return field;
+    }
+
+    /**
+     * 通过关键词和分页信息查询物料信息
+     *
+     * @param keyword 搜索关键词
+     * @param pageInfo 分页信息
+     * @return
+     */
+    @Override
+    public SPage<Product> searchProducts(String keyword, PageInfo pageInfo) {
+        SPage<Long> idsPage = searchService.searchIds(keyword, PRODUCT_TABLE_NAME, pageInfo);
+        List<Product> content = productDao.findAll(idsPage.getContent());
+        sortByProperty(content, Product.class, "id", idsPage.getContent());
+        return toSPage(idsPage, content);
+    }
+
+    /**
+     * 通过关键词和分页信息查询个人物料信息
+     *
+     * @param keyword  搜索关键词
+     * @param pageInfo 分页信息
+     * @return
+     */
+    @Override
+    public SPage<ProductUsers> searchProductUsers(String keyword, PageInfo pageInfo) {
+        SPage<Long> idsPage = searchService.searchIds(keyword, PRODUCT_USER_TABLE_NAME, pageInfo);
+        List<ProductUsers> content = productUsersDao.findAll(idsPage.getContent());
+        sortByProperty(content, ProductUsers.class, "id", idsPage.getContent());
+        return toSPage(idsPage, content);
+    }
+
+}

+ 17 - 0
src/main/java/com/uas/ps/properties/UrlProperties.java

@@ -9,8 +9,17 @@ import org.springframework.stereotype.Component;
 @Component
 @ConfigurationProperties(prefix = "url")
 public class UrlProperties {
+
+    /**
+     * B2C url
+     */
     private String b2cUrl;
 
+    /**
+     * search service url
+     */
+    private String searchUrl;
+
     public String getB2cUrl() {
         return b2cUrl;
     }
@@ -18,4 +27,12 @@ public class UrlProperties {
     public void setB2cUrl(String b2cUrl) {
         this.b2cUrl = b2cUrl;
     }
+
+    public String getSearchUrl() {
+        return searchUrl;
+    }
+
+    public void setSearchUrl(String searchUrl) {
+        this.searchUrl = searchUrl;
+    }
 }

+ 4 - 1
src/main/resources/config/application-cloud.properties

@@ -21,4 +21,7 @@ datasource.maxPoolPreparedStatementPerConnectionSize=20
 datasource.filters=stat,slf4j
 datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
 
-url.b2c-url=https://www.usoftmall.com
+url.b2c-url=https://www.usoftmall.com
+
+#search url
+url.search-url=http://10.10.100.179:8081

+ 4 - 1
src/main/resources/config/application-dev.properties

@@ -20,4 +20,7 @@ datasource.timeBetweenLogStatsMillis=60000
 datasource.maxPoolPreparedStatementPerConnectionSize=20
 datasource.filters=stat,slf4j
 datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
-url.b2c-url=http://192.168.253.12:23400/
+url.b2c-url=http://192.168.253.12:23400/
+
+#search url
+url.search-url=http://10.10.100.191:8081

+ 4 - 1
src/main/resources/config/application-test.properties

@@ -21,4 +21,7 @@ datasource.maxPoolPreparedStatementPerConnectionSize=20
 datasource.filters=stat,slf4j
 datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
 
-url.b2c-url=http://218.17.158.219:9090/platform-b2c
+url.b2c-url=http://218.17.158.219:9090/platform-b2c
+
+#search url
+url.search-url=http://10.10.100.191:8081