Browse Source

新增个人物料索引下载、创建、更新方法

wangyc 6 years ago
parent
commit
f296695d64

+ 49 - 1
mall-search/src/main/java/com/uas/search/constant/SearchConstants.java

@@ -102,6 +102,10 @@ public class SearchConstants {
 	 * 物料表
 	 */
 	public static final String PRODUCTS_PRIVATE_TABLE_NAME = "v$product$private";
+	/**
+	 * 个人物料表
+	 */
+	public static final String PRODUCTS_USERS_TABLE_NAME = "product$users";
 
 
 	// 类目索引字段的key
@@ -311,6 +315,10 @@ public class SearchConstants {
 	public static final String PRODUCT_PRIVATE_ISSALE_FIELD = "pr_issale";
 	// 1可买  0 不可
 	public static final String PRODUCT_PRIVATE_ISPURCHASE_FIELD = "pr_ispurchase";
+	// 1可公开展示  0 不可
+	public static final String PRODUCT_PRIVATE_ISSHOW_FIELD = "pr_isshow";
+	// 1可公开销售  0 不可
+	public static final String PRODUCT_PRIVATE_ISPUBSALE_FIELD = "pr_ispubsale";
 
     /**
      * 非标字段
@@ -343,5 +351,45 @@ public class SearchConstants {
     // 标准英文品牌
     public static final String PRODUCT_PRIVATE_PBRANDEN_FIELD = "pr_pbranden";
 
-
+	// 个人物料表索引字段
+	// ID
+	public static final String PRODUCT_USER_ID_FIELD = "pu_id";
+	// 物料ID
+	public static final String PRODUCT_USER_PRID_FIELD = "pu_prid";
+	// 用户uu
+	public static final String PRODUCT_USER_USERUU_FIELD = "pu_useruu";
+	// 企业uu
+	public static final String PRODUCT_USER_ENUU_FIELD = "pu_enuu";
+	// 物料id
+	public static final String PRODUCT_USER_PRODUCT_ID_FIELD = "pr_id";
+	// 用户上传物料类目
+	public static final String PRODUCT_USER_PRODUCT_TITLE_FIELD = "pr_title";
+	// 用户上传物料规格
+	public static final String PRODUCT_USER_PRODUCT_SPEC_FIELD = "pr_spec";
+	// 用户上传物料型号
+	public static final String PRODUCT_USER_PRODUCT_CMPCODE_FIELD = "pr_cmpcode";
+	// 物料编号
+	public static final String PRODUCT_USER_PRODUCT_CODE_FIELD = "pr_code";
+	// 用户上传品牌
+	public static final String PRODUCT_USER_PRODUCT_BRAND_FIELD = "pr_brand";
+	// 类目
+	public static final String PRODUCT_USER_PRODUCT_KIND_FIELD = "pr_kind";
+	// 标准型号
+	public static final String PRODUCT_USER_PRODUCT_PCMPCODE_FIELD = "pr_pcmpcode";
+	// 标准品牌英文名
+	public static final String PRODUCT_USER_PRODUCT_PBRAND_EN_FIELD = "pr_pbranden";
+	// 标准品牌中文名
+	public static final String PRODUCT_USER_PRODUCT_PBRAND_CN_FIELD = "pr_pbrand";
+	// 是否标准
+	public static final String PRODUCT_USER_PRODUCT_STANDARD_FIELD = "standard";
+	// 是否可用
+	public static final String PRODUCT_USER_PRODUCT_B2CENABLED_FIELD = "pr_b2cenabled";
+	// 是否可卖
+	public static final String PRODUCT_USER_PRODUCT_ISSALE_FIELD = "pr_issale";
+	// 是否可买
+	public static final String PRODUCT_USER_PRODUCT_ISPURCHASE_FIELD = "pr_ispurchase";
+	// 是否可公开展示
+	public static final String PRODUCT_USER_PRODUCT_ISSHOW_FIELD = "pr_isshow";
+	// 是否可公开采购
+	public static final String PRODUCT_USER_PRODUCT_ISPUBSALE_FIELD = "pr_ispubsale";
 }

+ 20 - 1
mall-search/src/main/java/com/uas/search/controller/IndexController.java

@@ -90,7 +90,26 @@ public class IndexController {
     public String multiDownloadStandardProduct(Integer threads, Integer startFileIndex, Integer endFileIndex, String validateResult, HttpServletRequest request) {
         long start = System.currentTimeMillis();
         String message= "Downloaded: "+ indexService.multiDownloadProduct(threads, startFileIndex, endFileIndex,
-                StringUtils.isEmpty(validateResult) ? DownloadHelper.ValidateResult.NONE : DownloadHelper.ValidateResult.valueOf(validateResult.toUpperCase()));
+            StringUtils.isEmpty(validateResult) ? DownloadHelper.ValidateResult.NONE : DownloadHelper.ValidateResult.valueOf(validateResult.toUpperCase()));
+        message += String.format(", Time: %.2fs", (System.currentTimeMillis()-start)/1000.0);
+        return message;
+    }
+
+    /**
+     *  下载标准物料数据
+     * @param threads        线程数量,默认为 1
+     * @param startFileIndex 开始的文件,默认为 1
+     * @param endFileIndex   结束的文件,默认为 1024 * 1024 * 1024
+     * @param validateResult 下载完成后,是否对结果进行校验
+     * @param request
+     * @return
+     */
+    @RequestMapping("/multiDownloadProductUser")
+    @ResponseBody
+    public String multiDownloadStandardProductUser(Integer threads, Integer startFileIndex, Integer endFileIndex, String validateResult, HttpServletRequest request) {
+        long start = System.currentTimeMillis();
+        String message= "Downloaded: "+ indexService.multiDownloadProductUser(threads, startFileIndex, endFileIndex,
+            StringUtils.isEmpty(validateResult) ? DownloadHelper.ValidateResult.NONE : DownloadHelper.ValidateResult.valueOf(validateResult.toUpperCase()));
         message += String.format(", Time: %.2fs", (System.currentTimeMillis()-start)/1000.0);
         return message;
     }

+ 17 - 0
mall-search/src/main/java/com/uas/search/dao/ProductUsersSimpleInfoDao.java

@@ -0,0 +1,17 @@
+package com.uas.search.dao;
+
+import com.uas.search.model.ProductUsersSimpleInfo;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by wangyc on 2018/8/1.
+ *
+ * @version 2018/8/1 15:33 wangyc
+ */
+@Repository
+public interface ProductUsersSimpleInfoDao extends JpaRepository<ProductUsersSimpleInfo, Long>,
+    JpaSpecificationExecutor<ProductUsersSimpleInfo>{
+
+}

+ 1 - 1
mall-search/src/main/java/com/uas/search/jms/JmsListener.java

@@ -56,7 +56,7 @@ public class JmsListener {
     private static final String[] GOODS_INDEX_TABLES = {SearchConstants.GOODS_TABLE_NAME, SearchConstants.PCB_GOODS_TABLE_NAME};
 
     // 物料类包含的索引名称
-    private static final String[] PRODUCTS_INDEX_TABLES = {SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME};
+    private static final String[] PRODUCTS_INDEX_TABLES = {SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME, SearchConstants.PRODUCTS_USERS_TABLE_NAME};
 
     // 物料类包含的索引名称
     private static final String[] ORDERS_INDEX_TABLES = {SearchConstants.ORDER_TABLE_NAME, SearchConstants.ORDER_INVOICE_TABLE_NAME,

+ 26 - 0
mall-search/src/main/java/com/uas/search/jms/QueueMessageParser.java

@@ -41,6 +41,9 @@ public class QueueMessageParser {
 	@Autowired
 	private V_ProductsDao v_productsDao;
 
+	@Autowired
+	private ProductUsersSimpleInfoDao productUsersSimpleInfoDao;
+
 	/**
 	 * 对得到的json消息进行解析
 	 * 
@@ -87,6 +90,8 @@ public class QueueMessageParser {
 				object = parsePurchaseInvoice(dataId, methodType);
 			} else if (tableName.equals(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME)) {
 				object = parseProduct(dataId, methodType);
+			} else if (tableName.equals(SearchConstants.PRODUCTS_USERS_TABLE_NAME)) {
+				object = parseProductUser(dataId, methodType);
 			} else {
 				throw new IllegalStateException("unsupported table name: " + tableName);
 			}
@@ -141,6 +146,27 @@ public class QueueMessageParser {
 		return product;
 	}
 
+	/**
+	 * 对个人物料进行解析
+	 *
+	 * @param id id
+	 * @param methodType 改动类型
+	 * @return 个人物料对象
+	 * @throws JSONException
+	 */
+	private ProductUsersSimpleInfo parseProductUser(@NotEmpty("id") Long id, @NotEmpty("methodType") String methodType) throws JSONException {
+		ProductUsersSimpleInfo productUser;
+		// delete操作
+		// 删除后数据库中可能已经没有相应数据了,无法通过dao获取,需要手动创建对象
+		if (methodType.equalsIgnoreCase("delete")) {
+			productUser = new ProductUsersSimpleInfo();
+			productUser.setId(id);
+		} else {
+			productUser = productUsersSimpleInfoDao.findOne(id);
+		}
+		return productUser;
+	}
+
 	/**
 	 * 对brand品牌进行解析
 	 *

+ 116 - 0
mall-search/src/main/java/com/uas/search/model/ProductUsersSimpleInfo.java

@@ -0,0 +1,116 @@
+package com.uas.search.model;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.springframework.jdbc.core.RowMapper;
+
+/**
+ * Created by wangyc on 2018-08-01.
+ */
+@Table(name = "product$users")
+@Entity
+public class ProductUsersSimpleInfo implements Serializable, RowMapper{
+
+    /**
+     * id
+     */
+    @Id
+    @Column(name = "pu_id")
+    private Long id;
+
+    /**
+     * 用户uu号
+     */
+    @Column(name = "pu_useruu")
+    private Long useruu;
+
+    /**
+     * 企业uu
+     */
+    @Column(name = "pu_enuu")
+    private Long enuu;
+
+    /**
+     * 物料id
+     */
+    @Column(name = "pu_prid")
+    private Long prId;
+
+    /**
+     * 产品
+     */
+    @OneToOne(cascade = { CascadeType.REFRESH })
+    @JoinColumn(name = "pu_prid", insertable = false, updatable = false)
+    private V_Products product;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Long getUseruu() {
+        return useruu;
+    }
+
+    public void setUseruu(Long useruu) {
+        this.useruu = useruu;
+    }
+
+    public Long getEnuu() {
+        return enuu;
+    }
+
+    public void setEnuu(Long enuu) {
+        this.enuu = enuu;
+    }
+
+    public Long getPrId() {
+        return prId;
+    }
+
+    public void setPrId(Long prId) {
+        this.prId = prId;
+    }
+
+    public V_Products getProduct() {
+        return product;
+    }
+
+    public void setProduct(V_Products product) {
+        this.product = product;
+    }
+
+    @Override
+    public String toString() {
+        return "ProductUsersSimpleInfo{" +
+                "id=" + id +
+                ", useruu=" + useruu +
+                ", enuu=" + enuu +
+                ", prId=" + prId +
+                ", product=" + product +
+                '}';
+    }
+
+    @Override
+    public Object mapRow(ResultSet rs, int i) throws SQLException {
+        ProductUsersSimpleInfo user = new ProductUsersSimpleInfo();
+        user.setId(rs.getLong("pu_id"));
+        user.setUseruu(rs.getLong("pu_useruu"));
+        user.setEnuu(rs.getLong("pu_enuu"));
+        user.setPrId(rs.getLong("pu_prid"));
+        user.setProduct(new V_Products().mapRow(rs, i));
+        return user;
+    }
+
+}

+ 13 - 0
mall-search/src/main/java/com/uas/search/model/Products.java

@@ -127,4 +127,17 @@ public class Products implements RowMapper, Serializable {
         products.setStandard(rs.getShort("pr_standard"));
         return products;
     }
+
+    public Products() {
+
+    }
+
+    public Products(V_Products v_product) {
+        this.setId(v_product.getId());
+        this.setStandard(v_product.getStandard());
+        this.setpBrandCn(v_product.getpBrandCn());
+        this.setpBrandEn(v_product.getpBrandEn());
+        this.setPcmpCode(v_product.getpCmpCode());
+        this.setKind(v_product.getKind());
+    }
 }

+ 37 - 0
mall-search/src/main/java/com/uas/search/model/V_Products.java

@@ -116,6 +116,23 @@ public class V_Products implements RowMapper, Serializable {
     @Column(name = "pr_ispurchase")
     private Short isPurchase;
 
+    /**
+     * 公开展示<br>
+     * <p>
+     * 1. 是<br>
+     * 0. 否
+     */
+    @Column(name = "pr_isshow")
+    private Short isShow;
+
+    /**
+     * 公开销售 <br>
+     * 1. 是<br>
+     * 0. 否
+     */
+    @Column(name = "pr_ispubsale")
+    private Short isPubsale;
+
     public Long getId() {
         return id;
     }
@@ -236,6 +253,22 @@ public class V_Products implements RowMapper, Serializable {
         this.isPurchase = isPurchase;
     }
 
+    public Short getIsShow() {
+        return isShow;
+    }
+
+    public void setIsShow(Short isShow) {
+        this.isShow = isShow;
+    }
+
+    public Short getIsPubsale() {
+        return isPubsale;
+    }
+
+    public void setIsPubsale(Short isPubsale) {
+        this.isPubsale = isPubsale;
+    }
+
     @Override
     public String toString() {
         return "V_Products{" +
@@ -253,6 +286,8 @@ public class V_Products implements RowMapper, Serializable {
                 ", b2cEnabled=" + b2cEnabled + '\'' +
                 ", isSale=" + isSale +  '\'' +
                 ", isPurchase=" + isPurchase + '\'' +
+                ", isShow=" + isShow + '\'' +
+                ", isPubsale=" + isPubsale + '\'' +
                 '}';
     }
 
@@ -274,6 +309,8 @@ public class V_Products implements RowMapper, Serializable {
         products.setTitle(rs.getString("pr_title"));
         products.setIsSale(rs.getShort("pr_issale"));
         products.setIsPurchase(rs.getShort("pr_ispurchase"));
+        products.setIsShow(rs.getShort("pr_isshow"));
+        products.setIsPubsale(rs.getShort("pr_ispubsale"));
         return products;
     }
 }

+ 12 - 1
mall-search/src/main/java/com/uas/search/service/IndexService.java

@@ -37,7 +37,7 @@ public interface IndexService {
     public long multiDownloadComponent(Integer threads, Integer startFileIndex, Integer endFileIndex, DownloadHelper.ValidateResult validateResult);
 
     /**
-     * 多线程下载器件的数据至本地文件中,以供建索引用
+     * 多线程下载物料的数据至本地文件中,以供建索引用
      *
      * @param threads        线程数量,默认为 1
      * @param startFileIndex 开始的文件,默认为 1
@@ -47,6 +47,17 @@ public interface IndexService {
      */
     long multiDownloadProduct(Integer threads, Integer startFileIndex, Integer endFileIndex, DownloadHelper.ValidateResult validateResult);
 
+    /**
+     * 多线程下载个人物料的数据至本地文件中,以供建索引用
+     *
+     * @param threads        线程数量,默认为 1
+     * @param startFileIndex 开始的文件,默认为 1
+     * @param endFileIndex   结束的文件,默认为 1024 * 1024 * 1024
+     * @param validateResult 下载完成后,是否对结果进行校验
+     * @return 下载的数据条数
+     */
+    long multiDownloadProductUser(Integer threads, Integer startFileIndex, Integer endFileIndex, DownloadHelper.ValidateResult validateResult);
+
     /**
      * 多线程下载批次的数据至本地文件中,以供建索引用
      *

+ 127 - 6
mall-search/src/main/java/com/uas/search/service/impl/IndexServiceImpl.java

@@ -5,6 +5,7 @@ import static com.uas.search.constant.SearchConstants.GOODS_TABLE_NAME;
 import static com.uas.search.constant.SearchConstants.PCB_GOODS_TABLE_NAME;
 import static com.uas.search.constant.SearchConstants.PCB_TABLE_NAME;
 import static com.uas.search.constant.SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME;
+import static com.uas.search.constant.SearchConstants.PRODUCTS_USERS_TABLE_NAME;
 
 import com.alibaba.fastjson.JSONException;
 import com.alibaba.fastjson.JSONObject;
@@ -38,6 +39,8 @@ import com.uas.search.model.Order;
 import com.uas.search.model.OrderInvoice;
 import com.uas.search.model.PCB;
 import com.uas.search.model.PCBGoods;
+import com.uas.search.model.ProductUsersSimpleInfo;
+import com.uas.search.model.Products;
 import com.uas.search.model.Purchase;
 import com.uas.search.model.PurchaseInvoice;
 import com.uas.search.model.TradeGoods;
@@ -191,6 +194,8 @@ public class IndexServiceImpl implements IndexService {
                         size = createPurchaseInvoiceIndexes();
                     } else if (tableName.equals(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME)) {
                         size = createProductIndexesFromFiles();
+                    } else if (tableName.equals(SearchConstants.PRODUCTS_USERS_TABLE_NAME)) {
+                        size = createProductUserIndexesFromFiles();
                     } else {
                         logger.error("不支持创建该表索引:" + tableName);
                         continue;
@@ -631,6 +636,57 @@ public class IndexServiceImpl implements IndexService {
         return size;
     }
 
+    /**
+     * 根据本地文件转换个人物料为Document
+     * @return
+     * @throws IOException
+     */
+    private Long createProductUserIndexesFromFiles() throws IOException {
+        logger.info("正在创建物料索引...");
+        Long size = 0L;
+        BufferedReader bufferedReader = null;
+        try {
+            // 从本地路径读取器件数据
+            String productUserDataPath = SearchUtils.getDataPath(PRODUCTS_USERS_TABLE_NAME);
+            File[] files = new File(productUserDataPath).listFiles();
+            if (files == null || files.length == 0) {
+                logger.info("创建器件索引失败,原因:个人物料数据文件不存在!");
+                return 0L;
+            }
+            for (File file : files) {
+                logger.info("读取文件: " + file.getName());
+                bufferedReader = new BufferedReader(new FileReader(file));
+                String line;
+                while (!StringUtils.isEmpty(line = bufferedReader.readLine())) {
+                    ProductUsersSimpleInfo productUser;
+                    try {
+                        productUser = JSONObject.parseObject(line, ProductUsersSimpleInfo.class);
+                    } catch (JSONException e) {
+                        throw new IllegalArgumentException(line, e);
+                    }
+                    Document document = ObjectToDocumentUtils.toDocument(productUser);
+                    if (document != null) {
+                        size++;
+                        // 每创建10000条,打印一次进度
+                        if (size % 10000 == 0) {
+                            logger.info("ProductUsers indexed..................." + size);
+                        }
+                        indexWriter.addDocument(document);
+                    }
+                }
+                indexWriter.commit();
+            }
+        } catch (FileNotFoundException e) {
+            logger.error("创建物料索引失败,原因:物料数据文件不存在!");
+            return 0L;
+        } finally {
+            if (bufferedReader != null) {
+                bufferedReader.close();
+            }
+        }
+        return size;
+    }
+
     /**
      * 根据本地 PCB 的数据文件,转为 PCB 批次数据
      *
@@ -762,6 +818,11 @@ public class IndexServiceImpl implements IndexService {
         return multiDownloadData(PRODUCTS_PRIVATE_TABLE_NAME, threads, startFileIndex, endFileIndex, validateResult);
     }
 
+    @Override
+    public long multiDownloadProductUser(Integer threads, Integer startFileIndex, Integer endFileIndex, DownloadHelper.ValidateResult validateResult) {
+        return multiDownloadData(PRODUCTS_USERS_TABLE_NAME, threads, startFileIndex, endFileIndex, validateResult);
+    }
+
     @Override
     public long multiDownloadGoods(Integer threads, Integer startFileIndex, Integer endFileIndex, DownloadHelper.ValidateResult validateResult) {
         return multiDownloadData(GOODS_TABLE_NAME, threads, startFileIndex, endFileIndex, validateResult);
@@ -848,6 +909,14 @@ public class IndexServiceImpl implements IndexService {
             }
             DownloadHelper<V_Products> downloadHelper = new DownloadHelper<>(threads, startFileIndex, endFileIndex, tableName, sortField, new DownloadService<V_Products>() {}, validateResult, jdbcTemplate, jdbcService);
             return downloadHelper.getResult();
+        } else if (tableName.equals(PRODUCTS_USERS_TABLE_NAME)) {
+            try {
+                sortField = jdbcService.abstractTransform(ProductUsersSimpleInfo.class, "id");
+            } catch (NoSuchFieldException e) {
+
+            }
+            DownloadHelper<ProductUsersSimpleInfo> downloadHelper = new DownloadHelper<>(threads, startFileIndex, endFileIndex, tableName, sortField, new DownloadService<ProductUsersSimpleInfo>() {}, validateResult, jdbcTemplate, jdbcService);
+            return downloadHelper.getResult();
         } else {
             throw new IllegalArgumentException("多线程下载不支持该表:" + tableName);
         }
@@ -885,15 +954,14 @@ public class IndexServiceImpl implements IndexService {
                 try {
                     indexWriter = indexWriterManager.get(tableName);
                     if (obj instanceof Kind) {
-                        indexWriter.updateDocument(
-                                new Term(SearchConstants.KIND_ID_FIELD, String.valueOf(((Kind) obj).getId())),
-                                document);
+                        indexWriter.updateDocument(new Term(SearchConstants.KIND_ID_FIELD,
+                                String.valueOf(((Kind) obj).getId())), document);
                     } else if (obj instanceof Brand) {
                         Brand brand = (Brand) obj;
                         indexWriter.updateDocument(new Term(SearchConstants.BRAND_ID_FIELD,
                                 String.valueOf(brand.getId())), document);
                         // 更新关联批次(更新品牌权重)
-                        updateGoodsFields(new Term(SearchConstants.GOODS_BR_ID_FIELD, brand.getId().toString()), brand, null);
+                        updateGoodsFields(new Term(SearchConstants.GOODS_BR_ID_FIELD, brand.getId().toString()), brand, null, null);
                     } else if (obj instanceof Component) {
                         indexWriter.updateDocument(new Term(SearchConstants.COMPONENT_ID_FIELD,
                                 String.valueOf(((Component) obj).getId())), document);
@@ -910,8 +978,15 @@ public class IndexServiceImpl implements IndexService {
                         indexWriter.updateDocument(new Term(SearchConstants.PURCHASE_INVOICE_ID_FIELD,
                                 String.valueOf(((PurchaseInvoice) obj).getId())), document);
                     } else if (obj instanceof  V_Products) {
+                        V_Products v_product = (V_Products) obj;
                         indexWriter.updateDocument(new Term(SearchConstants.PRODUCT_PRIVATE_ID_FIELD,
-                                String.valueOf(((V_Products) obj).getId())), document);
+                                String.valueOf(v_product.getId())), document);
+                        Products product = new Products(v_product);
+                        updateGoodsFields(new Term(SearchConstants.GOODS_PR_ID_FIELD, product.getId().toString()), null, null, product);
+                        updateProductUsersFields(new Term(SearchConstants.PRODUCT_USER_PRID_FIELD, v_product.getId().toString()), v_product);
+                    } else if (obj instanceof ProductUsersSimpleInfo) {
+                        indexWriter.updateDocument(new Term(SearchConstants.PRODUCT_USER_ID_FIELD,
+                                String.valueOf(((ProductUsersSimpleInfo) obj).getId())), document);
                     } else {
                         throw new IllegalStateException("Message parsing failed!");
                     }
@@ -937,7 +1012,7 @@ public class IndexServiceImpl implements IndexService {
      * @param kind 新的类目
      * @throws IOException
      */
-    private void updateGoodsFields(Term term, Brand brand, Kind kind) throws IOException {
+    private void updateGoodsFields(Term term, Brand brand, Kind kind, Products products) throws IOException {
         if (brand == null && kind == null) {
             return;
         }
@@ -961,6 +1036,9 @@ public class IndexServiceImpl implements IndexService {
                     if (kind != null) {
                         goods.getComponent().setKind(kind);
                     }
+                    if (products != null) {
+                        goods.setProducts(products);
+                    }
                     writer.updateDocument(new Term(idField, document.get(idField)), ObjectToDocumentUtils.toDocument(goods));
                 }
                 logger.info("更新关联批次索引:count=" + tableName + ", count=" + (size * (page - 1) + documents.getContent().size()));
@@ -981,6 +1059,46 @@ public class IndexServiceImpl implements IndexService {
         }
     }
 
+    private void updateProductUsersFields(Term term, V_Products products) throws IOException {
+        if (products == null) {
+            return;
+        }
+        String tableName = SearchConstants.PRODUCTS_USERS_TABLE_NAME;
+        Query query = new TermQuery(term);
+        int page = 1;
+        int size = 1000;
+        SPage<Document> documents = SearchUtils.getDocuments(tableName, query, page, size);
+        logger.info("更新关联个人物料索引:total=" + documents.getTotalElement());
+        int totalPage = documents.getTotalPage();
+        IndexWriter writer = null;
+        try {
+            writer = indexWriterManager.get(tableName);
+            String idField = SearchUtils.getIdField(tableName);
+            while (true) {
+                for (Document document : documents.getContent()) {
+                    ProductUsersSimpleInfo productUser = DocumentToObjectUtils.toProductUser(document);
+                    productUser.setPrId(products.getId());
+                    productUser.setProduct(products);
+                    writer.updateDocument(new Term(idField, document.get(idField)), ObjectToDocumentUtils.toDocument(productUser));
+                }
+                logger.info("更新关联批次索引:count=" + tableName + ", count=" + (size * (page - 1) + documents.getContent().size()));
+                writer.commit();
+                page++;
+                if (page > totalPage) {
+                    break;
+                }
+                documents = SearchUtils.getDocuments(tableName, query, page, size);
+            }
+        } catch (InterruptedException e) {
+            logger.error("", e);
+        } finally {
+            if (writer != null) {
+                indexSearcherManager.flushCache(tableName, writer, null);
+                indexWriterManager.release(tableName);
+            }
+        }
+    }
+
     @Override
     public Object delete(Object obj) {
         if (obj != null) {
@@ -1015,6 +1133,9 @@ public class IndexServiceImpl implements IndexService {
                 } else if (obj instanceof V_Products) {
                     indexWriter.deleteDocuments(new Term(SearchConstants.PRODUCT_PRIVATE_ID_FIELD,
                             String.valueOf(((V_Products) obj).getId())));
+                } else if (obj instanceof ProductUsersSimpleInfo) {
+                    indexWriter.deleteDocuments(new Term(SearchConstants.PRODUCT_USER_ID_FIELD,
+                            String.valueOf(((ProductUsersSimpleInfo) obj).getId())));
                 } else {
                     throw new IllegalStateException("Message parsing failed!");
                 }

+ 9 - 3
mall-search/src/main/java/com/uas/search/service/impl/JdbcServiceImpl.java

@@ -2,6 +2,7 @@ package com.uas.search.service.impl;
 
 import static com.uas.search.constant.SearchConstants.PCB_TABLE_NAME;
 import static com.uas.search.constant.SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME;
+import static com.uas.search.constant.SearchConstants.PRODUCTS_USERS_TABLE_NAME;
 import static com.uas.search.constant.SearchConstants.TRADE_GOODS_TABLE_NAME;
 
 import com.uas.search.constant.SearchConstants;
@@ -10,8 +11,8 @@ import com.uas.search.model.Brand;
 import com.uas.search.model.Component;
 import com.uas.search.model.Kind;
 import com.uas.search.model.PCB;
+import com.uas.search.model.ProductUsersSimpleInfo;
 import com.uas.search.model.Products;
-import com.uas.search.model.Property;
 import com.uas.search.model.PropertyValue;
 import com.uas.search.model.TradeGoods;
 import com.uas.search.model.V_Products;
@@ -22,7 +23,6 @@ import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import javax.persistence.Column;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.EmptyResultDataAccessException;
@@ -105,7 +105,9 @@ public class JdbcServiceImpl<T> implements JdbcService{
         if (PRODUCTS_PRIVATE_TABLE_NAME.equals(tableName)) {
             data = queryVProducts(sql);
         }
-
+        if (PRODUCTS_USERS_TABLE_NAME.equals(tableName)) {
+            data = queryProductUser(sql);
+        }
         // Goods索引
         if (TRADE_GOODS_TABLE_NAME.equals(tableName)) {
             data = queryGoods(sql);
@@ -144,6 +146,10 @@ public class JdbcServiceImpl<T> implements JdbcService{
         return jdbcTemplate.query(sql, new V_Products());
     }
 
+    private List<T> queryProductUser(String sql) {
+        return jdbcTemplate.query(sql.replace("where", "left join v$product$private on product$users.pu_prid = v$product$private.pr_id where"), new ProductUsersSimpleInfo());
+    }
+
     /**
      * 获取Goods
      * @param sql sql

+ 74 - 1
mall-search/src/main/java/com/uas/search/util/DocumentToObjectUtils.java

@@ -42,7 +42,9 @@ public class DocumentToObjectUtils {
 		} else if (tableName.equals(SearchConstants.PURCHASE_INVOICE_TABLE_NAME)) {
 			return toPurchaseInvoice(document);
 		} else if (tableName.equals(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME)) {
-		    return toProduct(document);
+            return toProduct(document);
+        } else if (tableName.equals(SearchConstants.PRODUCTS_USERS_TABLE_NAME)) {
+            return toProductUser(document);
         }
 		throw new IllegalArgumentException("不支持的表:" + tableName);
 	}
@@ -84,6 +86,77 @@ public class DocumentToObjectUtils {
         return products;
     }
 
+    /**
+     * 将Document转换为个人物料对象
+     * @param document
+     * @return
+     */
+    public static ProductUsersSimpleInfo toProductUser(Document document) {
+        if (document == null) {
+            return null;
+        }
+        ProductUsersSimpleInfo productUser = new ProductUsersSimpleInfo();
+        productUser.setId(Long.valueOf(document.get(SearchConstants.PRODUCT_USER_ID_FIELD)));
+        productUser.setEnuu(Long.valueOf(document.get(SearchConstants.PRODUCT_USER_ENUU_FIELD)));
+        productUser.setUseruu(Long.valueOf(document.get(SearchConstants.PRODUCT_USER_USERUU_FIELD)));
+        productUser.setPrId(Long.valueOf(document.get(SearchConstants.PRODUCT_USER_PRID_FIELD)));
+
+        if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ID_FIELD))) {
+            V_Products products = new V_Products();
+            products.setId(Long.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ID_FIELD)));
+
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_TITLE_FIELD))) {
+                products.setTitle(document.get(SearchConstants.PRODUCT_USER_PRODUCT_TITLE_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_SPEC_FIELD))) {
+                products.setSpec(document.get(SearchConstants.PRODUCT_USER_PRODUCT_SPEC_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_CMPCODE_FIELD))) {
+                products.setCmpCode(document.get(SearchConstants.PRODUCT_USER_PRODUCT_CMPCODE_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_CODE_FIELD))) {
+                products.setCode(document.get(SearchConstants.PRODUCT_USER_PRODUCT_CODE_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_BRAND_FIELD))) {
+                products.setBrand(document.get(SearchConstants.PRODUCT_USER_PRODUCT_BRAND_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_KIND_FIELD))) {
+                products.setKind(document.get(SearchConstants.PRODUCT_USER_PRODUCT_KIND_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_PCMPCODE_FIELD))) {
+                products.setpCmpCode(document.get(SearchConstants.PRODUCT_USER_PRODUCT_PCMPCODE_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_PBRAND_EN_FIELD))) {
+                products.setpBrandEn(document.get(SearchConstants.PRODUCT_USER_PRODUCT_PBRAND_EN_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_PBRAND_CN_FIELD))) {
+                products.setpBrandCn(document.get(SearchConstants.PRODUCT_USER_PRODUCT_PBRAND_CN_FIELD));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_STANDARD_FIELD))) {
+                products.setStandard(Short.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_STANDARD_FIELD)));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_B2CENABLED_FIELD))) {
+                products.setB2cEnabled(Short.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_B2CENABLED_FIELD)));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISSALE_FIELD))) {
+                products.setIsSale(Short.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISSALE_FIELD)));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISPURCHASE_FIELD))) {
+                products.setIsPurchase(Short.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISPURCHASE_FIELD)));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISSHOW_FIELD))) {
+                products.setIsShow(Short.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISSHOW_FIELD)));
+            }
+            if (!StringUtils.isEmpty(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISPUBSALE_FIELD))) {
+                products.setIsPubsale(Short.valueOf(document.get(SearchConstants.PRODUCT_USER_PRODUCT_ISPUBSALE_FIELD)));
+            }
+
+
+            productUser.setProduct(products);
+        }
+        return productUser;
+    }
+
 	/**
 	 * 将Document转换为类目对象
 	 * 

+ 107 - 0
mall-search/src/main/java/com/uas/search/util/ObjectToDocumentUtils.java

@@ -56,6 +56,8 @@ public class ObjectToDocumentUtils {
 			return toDocument((PurchaseInvoice) object);
         } else if (object instanceof V_Products) {
 			return toDocument((V_Products) object);
+		} else if (object instanceof ProductUsersSimpleInfo) {
+			return toDocument((ProductUsersSimpleInfo) object);
 		} else {
 			throw new IllegalArgumentException("不支持将以下类型转换为Document:" + object.getClass().getName());
 		}
@@ -174,6 +176,111 @@ public class ObjectToDocumentUtils {
 		} else {
 			document.add(new StringField(SearchConstants.PRODUCT_PRIVATE_ISPURCHASE_FIELD, String.valueOf(0), Store.YES));
 		}
+
+		if (product.getIsShow() != null) {
+			document.add(new StringField(SearchConstants.PRODUCT_PRIVATE_ISSHOW_FIELD, String.valueOf(product.getIsShow()), Store.YES));
+		} else {
+			document.add(new StringField(SearchConstants.PRODUCT_PRIVATE_ISPUBSALE_FIELD, String.valueOf(0), Store.YES));
+		}
+		return document;
+	}
+
+	/**
+	 * ProductUsers对象转为Document
+	 *
+	 * @param productUser
+	 * @return
+	 */
+	public static Document toDocument(ProductUsersSimpleInfo productUser) {
+		if (productUser == null || productUser.getId() == null || null == productUser.getEnuu() || null == productUser.getUseruu()
+			|| null == productUser.getPrId() || null == productUser.getProduct() || null == productUser.getProduct().getId()) {
+			return null;
+		}
+		Document document = new Document();
+		// 不能用LongField,否则后续实时更新索引时,方法updateDocument(new Term("", ""),
+		// doc)无法根据id进行更新
+		document.add(new StringField(SearchConstants.PRODUCT_USER_ID_FIELD, String.valueOf(productUser.getId()), Store.YES));
+		document.add(new DoubleDocValuesField(SearchConstants.PRODUCT_USER_ID_FIELD, productUser.getId()));
+		document.add(new StringField(SearchConstants.PRODUCT_USER_USERUU_FIELD, String.valueOf(productUser.getUseruu()), Store.YES));
+		document.add(new StringField(SearchConstants.PRODUCT_USER_ENUU_FIELD, String.valueOf(productUser.getEnuu()), Store.YES));
+		document.add(new StringField(SearchConstants.PRODUCT_USER_PRID_FIELD, String.valueOf(productUser.getPrId()), Store.YES));
+		document.add(new DoubleDocValuesField(SearchConstants.PRODUCT_USER_PRID_FIELD, productUser.getPrId()));
+
+		if (productUser.getProduct() != null) {
+			V_Products product = productUser.getProduct();
+			// 不能用LongField,否则后续实时更新索引时,方法updateDocument(new Term("", ""),
+			// doc)无法根据id进行更新
+			document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ID_FIELD, String.valueOf(product.getId()), Store.YES));
+			document.add(new DoubleDocValuesField(SearchConstants.PRODUCT_USER_PRODUCT_ID_FIELD, product.getId()));
+			if (!StringUtils.isEmpty(product.getCode())) {
+				document.add(new TextField(SearchConstants.PRODUCT_USER_PRODUCT_CODE_FIELD, String.valueOf(product.getCode().toLowerCase()), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getTitle())) {
+				document.add(new TextField(SearchConstants.PRODUCT_USER_PRODUCT_TITLE_FIELD, product.getTitle().toLowerCase(), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getBrand())) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_BRAND_FIELD, product.getBrand().toLowerCase(), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getpBrandEn())) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_PBRAND_EN_FIELD, product.getpBrandEn().toLowerCase(), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getpBrandCn())) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_PBRAND_CN_FIELD, product.getpBrandCn().toLowerCase(), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getCmpCode())) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_CMPCODE_FIELD, product.getCmpCode().toLowerCase(), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getKind())) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_KIND_FIELD, product.getKind().toLowerCase(), Store.YES));
+			}
+
+			// 规格
+			if (!StringUtils.isEmpty(product.getSpec())) {
+				document.add(new TextField(SearchConstants.PRODUCT_USER_PRODUCT_SPEC_FIELD, product.getSpec().toLowerCase(), Store.YES));
+			}
+			if (!StringUtils.isEmpty(product.getpCmpCode())) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_PCMPCODE_FIELD, product.getpCmpCode().toLowerCase(), Store.YES));
+			}
+			if (product.getStandard() != null) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_STANDARD_FIELD, String.valueOf(product.getStandard()), Store.YES));
+			} else {
+				// 为空默认非标
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_STANDARD_FIELD, String.valueOf(0), Store.YES));
+			}
+			if (product.getB2cEnabled() != null) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_B2CENABLED_FIELD, String.valueOf(product.getB2cEnabled()), Store.YES));
+			} else {
+				// 为空默认可用
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_B2CENABLED_FIELD, String.valueOf(1), Store.YES));
+			}
+
+			// 是否可卖 为空则不可卖
+			if (product.getIsSale() != null) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISSALE_FIELD, String.valueOf(product.getIsSale()), Store.YES));
+			} else {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISSALE_FIELD, String.valueOf(0), Store.YES));
+			}
+
+			// 是否可买 为空则不可买
+			if (product.getIsPurchase() != null) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISPURCHASE_FIELD, String.valueOf(product.getIsPurchase()), Store.YES));
+			} else {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISPURCHASE_FIELD, String.valueOf(0), Store.YES));
+			}
+
+			if (product.getIsShow() != null) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISSHOW_FIELD, String.valueOf(product.getIsShow()), Store.YES));
+			} else {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISSHOW_FIELD, String.valueOf(0), Store.YES));
+			}
+
+			if (product.getIsPubsale() != null) {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISPUBSALE_FIELD, String.valueOf(product.getIsShow()), Store.YES));
+			} else {
+				document.add(new StringField(SearchConstants.PRODUCT_USER_PRODUCT_ISPUBSALE_FIELD, String.valueOf(0), Store.YES));
+			}
+
+		}
 		return document;
 	}
 

+ 7 - 2
mall-search/src/main/java/com/uas/search/util/SearchUtils.java

@@ -398,8 +398,10 @@ public class SearchUtils {
 		} else if (tableName.equals(SearchConstants.PURCHASE_INVOICE_TABLE_NAME)) {
 			return SearchConstants.PURCHASE_INVOICE_ID_FIELD;
 		} else if (tableName.equals(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME)) {
-			return SearchConstants.PRODUCT_PRIVATE_ID_FIELD;
-		}
+            return SearchConstants.PRODUCT_PRIVATE_ID_FIELD;
+        } else if (tableName.equals(SearchConstants.PRODUCTS_USERS_TABLE_NAME)) {
+            return SearchConstants.PRODUCT_USER_ID_FIELD;
+        }
 		throw new IllegalArgumentException("不支持的表:" + tableName);
 	}
 
@@ -420,6 +422,7 @@ public class SearchUtils {
 		tableNames.add(SearchConstants.PURCHASE_TABLE_NAME);
 		tableNames.add(SearchConstants.PURCHASE_INVOICE_TABLE_NAME);
 		tableNames.add(SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME);
+		tableNames.add(SearchConstants.PRODUCTS_USERS_TABLE_NAME);
 		return tableNames;
 	}
 
@@ -453,6 +456,8 @@ public class SearchUtils {
 			return SearchConstants.PURCHASE_INVOICE_TABLE_NAME;
 		} else if (clazz == V_Products.class) {
 			return SearchConstants.PRODUCTS_PRIVATE_TABLE_NAME;
+		} else if (clazz == ProductUsersSimpleInfo.class) {
+			return SearchConstants.PRODUCTS_USERS_TABLE_NAME;
 		} else {
 			throw new IllegalStateException("该实体类没有对应的需要建立索引的表:" + clazz);
 		}