Browse Source

B2B物料操作接口提取到公共服务

dongbw 8 năm trước cách đây
mục cha
commit
ed7345dd46

+ 12 - 0
pom.xml

@@ -66,6 +66,18 @@
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
         </dependency>
+
+        <!-- jxls -->
+        <dependency>
+            <groupId>net.sf.jxls</groupId>
+            <artifactId>jxls-core</artifactId>
+            <version>1.0.4</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.jxls</groupId>
+            <artifactId>jxls-reader</artifactId>
+            <version>1.0.4</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 15 - 0
src/main/java/com/uas/ps/product/concurrent/Callback.java

@@ -0,0 +1,15 @@
+package com.uas.ps.product.concurrent;
+
+/**
+ * 能传入参数执行的callable
+ * 
+ * @author yingp
+ * 
+ * @param <T>
+ *            参数类型
+ */
+public abstract interface Callback<T> {
+
+	public abstract void call(T param) throws Exception;
+
+}

+ 17 - 0
src/main/java/com/uas/ps/product/concurrent/ICallable.java

@@ -0,0 +1,17 @@
+package com.uas.ps.product.concurrent;
+
+/**
+ * 能传入参数执行的callable
+ * 
+ * @author yingp
+ * 
+ * @param <V>
+ *            返回结果类型
+ * @param <T>
+ *            参数类型
+ */
+public abstract interface ICallable<V, T> {
+
+	public abstract V call(T param) throws Exception;
+
+}

+ 36 - 0
src/main/java/com/uas/ps/product/concurrent/ICallableAdapter.java

@@ -0,0 +1,36 @@
+package com.uas.ps.product.concurrent;
+
+import java.util.concurrent.Callable;
+
+/**
+ * 代理callable来执行
+ * 
+ * <pre>
+ * 涉及到一个callable对象调用不同参数循环执行的问题,不能直接在ICallable对象里面设置参数,需要代理执行
+ * </pre>
+ * 
+ * @see Callback
+ * 
+ * @author yingp
+ * 
+ * @param <V>
+ *            返回结果类型
+ * @param <T>
+ *            参数类型
+ */
+public final class ICallableAdapter<V, T> implements Callable<V> {
+
+	private final ICallable<V, T> task;
+	private final T param;
+
+	public ICallableAdapter(ICallable<V, T> task, T param) {
+		this.task = task;
+		this.param = param;
+	}
+
+	@Override
+	public V call() throws Exception {
+		return task.call(param);
+	}
+
+}

+ 15 - 0
src/main/java/com/uas/ps/product/concurrent/IRunnable.java

@@ -0,0 +1,15 @@
+package com.uas.ps.product.concurrent;
+
+/**
+ * 能传入参数执行的runnable
+ * 
+ * @author yingp
+ * 
+ * @param <T>
+ *            参数类型
+ */
+public abstract interface IRunnable<T> {
+
+	public abstract void run(T param);
+
+}

+ 33 - 0
src/main/java/com/uas/ps/product/concurrent/IRunnableAdapter.java

@@ -0,0 +1,33 @@
+package com.uas.ps.product.concurrent;
+
+
+/**
+ * 代理runnable来执行
+ * 
+ * <pre>
+ * 涉及到一个runnable对象调用不同参数循环执行的问题,不能直接在IRunnable对象里面设置参数,需要代理执行
+ * </pre>
+ * 
+ * @see Runnable
+ * 
+ * @author yingp
+ * 
+ * @param <T>
+ *            参数类型
+ */
+public final class IRunnableAdapter<T> implements Runnable {
+
+	private final IRunnable<T> task;
+	private final T param;
+
+	public IRunnableAdapter(IRunnable<T> task, T param) {
+		this.task = task;
+		this.param = param;
+	}
+
+	@Override
+	public void run() {
+		task.run(param);
+	}
+
+}

+ 7 - 0
src/main/java/com/uas/ps/product/concurrent/Listener.java

@@ -0,0 +1,7 @@
+package com.uas.ps.product.concurrent;
+
+public abstract interface Listener {
+
+	void handler();
+
+}

+ 29 - 0
src/main/java/com/uas/ps/product/concurrent/Listeners.java

@@ -0,0 +1,29 @@
+package com.uas.ps.product.concurrent;
+
+import java.util.Vector;
+
+public class Listeners {
+
+	private Vector<Listener> listeners = new Vector<Listener>();
+
+	public synchronized void addListener(Listener e) {
+		listeners.addElement(e);
+	}
+
+	public synchronized void removeListener(Listener e) {
+		listeners.removeElement(e);
+	}
+
+	@SuppressWarnings("unchecked")
+	public void fire() {
+		Vector<Listener> currentListeners = null;
+		synchronized (this) {
+			currentListeners = (Vector<Listener>) listeners.clone();
+		}
+		for (int i = 0; i < currentListeners.size(); i++) {
+			Listener listener = (Listener) currentListeners.elementAt(i);
+			listener.handler();
+		}
+	}
+
+}

+ 118 - 8
src/main/java/com/uas/ps/product/controller/ProductController.java

@@ -1,6 +1,12 @@
 package com.uas.ps.product.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.uas.ps.core.util.CollectionUtils;
+import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductSaler;
+import com.uas.ps.entity.Status;
+import com.uas.ps.product.entity.Constant;
 import com.uas.ps.product.entity.Prod;
 import com.uas.ps.product.service.ProductService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,6 +19,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -32,36 +39,56 @@ public class ProductController {
 //    private UserDao userDao;
 
     /**
-     * 将ERP的产品资料写到平台
+     * 将ERP的产品资料写到公共物料库
      *
-     * @param data
+     * @param data 物料信息
+     * @param enUU 企业uu
      * @return
      * @throws UnsupportedEncodingException
      */
-    @RequestMapping(value = "/save", method = RequestMethod.POST)
-    public void saveProducts(@RequestParam("data") String data) throws UnsupportedEncodingException {
+    @RequestMapping(value = "/erp/save", method = RequestMethod.POST)
+    public void saveProducts(@RequestParam("data") String data, @RequestParam("enUU") Long enUU) throws UnsupportedEncodingException {
         String jsonStr = URLDecoder.decode(data, "UTF-8");
         List<Prod> prods = JSONObject.parseArray(jsonStr, Prod.class);
-        productService.save(productService.convertProduct(prods));
+        productService.save(productService.convertProduct(prods, enUU));
         log(prods, "上传物料资料");
     }
 
     /**
      * 定时任务更新物料信息
      *
-     * @param data
+     * @param data 物料信息
+     * @param enUU 企业UU
      * @return
      * @throws UnsupportedEncodingException
      */
     @RequestMapping(value = "/cycleupdate", method = RequestMethod.POST)
     @ResponseBody
-    public void updateProducts(@RequestParam("data") String data) throws UnsupportedEncodingException {
+    public void updateProducts(@RequestParam("data") String data, @RequestParam("enUU") Long enUU) throws UnsupportedEncodingException {
         String jsonStr = URLDecoder.decode(data, "UTF-8");
         List<Prod> prods = JSONObject.parseArray(jsonStr, Prod.class);
-        productService.save(productService.convertProduct(prods));
+        productService.save(productService.convertProduct(prods, enUU));
         log(prods, "定时任务更新物料资料");
     }
 
+    /**
+     * 新增、更新物料信息
+     *
+     * @param data 物料信息
+     * @return
+     */
+    @RequestMapping(value = "/update", method = RequestMethod.POST)
+    @ResponseBody
+    public ModelMap updateProdInfo(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        // TODO 物料信息中的企业UU和用户UU,需要在调用接口之前设置。有id为更新,无id为新增
+        Product productInfo = JSONObject.parseObject(URLDecoder.decode(data, "utf-8"), Product.class);
+        ModelMap map = new ModelMap();
+        productInfo = productService.save(productInfo);
+//        logger.log("更新物料", "[" + productInfo.getUserUU() + "]更新了id为" + productInfo.getId() + "的["
+//                + productInfo.getTitle() + "]");
+        return map;
+    }
+
     private void log(List<Prod> prods, String message) {
 //        if (prods.size() < 1) {
 //            throw new IllegalArgumentException("物料资料为空");
@@ -98,4 +125,87 @@ public class ProductController {
     public ModelMap assignPersonalProduct(@RequestParam Long userUU, @RequestParam Long productId) {
         return productService.assignPersonalProduct(userUU, productId);
     }
+
+    /**
+     * 将更新的ERP的物料数据回传回ERP
+     *
+     * @return
+     */
+    @RequestMapping(value = "/backtouas", method = RequestMethod.GET)
+    @ResponseBody
+    public List<Prod> getProds(@RequestParam Long enUU) {
+        List<Prod> prods = new ArrayList<Prod>();
+        List<Product> products = productService.findByEnUUAndSourceAppAndDownloadStatus(enUU, "ERP", Status.NOT_UPLOAD.value());
+        if (!CollectionUtils.isEmpty(products)) {
+            for (Product product : products) {
+                Prod prod = new Prod();
+                prod.setPr_uuid(product.getCmpUuid());
+                prod.setPr_id(product.getSourceId());
+                prod.setB2b_id(product.getId());
+                prods.add(prod);
+            }
+        }
+        return prods;
+    }
+
+    /**
+     * 更新下载成功的状态
+     *
+     * @param data
+     * @throws UnsupportedEncodingException
+     */
+    @RequestMapping(value = "/refreshDownloadStatus", method = RequestMethod.POST)
+    @ResponseBody
+    public void refreshDownloadStatus(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        productService.onProductDownSuccess(URLDecoder.decode(data, "UTF-8").split(","));
+    }
+
+    /**
+     * UAS端禁用物料时调用此接口禁用此物料
+     * 通过物料编码(code)
+     *
+     * @param data
+     */
+    @RequestMapping(value = "/updateEnabled", method = RequestMethod.POST)
+    @ResponseBody
+    public int updateB2bEnabled(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String json = URLDecoder.decode(data, "UTF-8");
+        JSONObject object = JSON.parseObject(json, JSONObject.class);
+        Short enabled = Constant.NO;
+        return productService.updateEnabled((Long)object.get("enUU"), (String)object.get("code"), enabled);
+    }
+
+    /**
+     * ERP个人物料同步到公共物料库
+     *
+     * @author hejq
+     * @date 2018-01-12 19:11
+     * @param data
+     * @throws UnsupportedEncodingException
+     */
+    @RequestMapping(value = "/produser", method = RequestMethod.POST)
+    @ResponseBody
+    public void updateProdSaler(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String jsonStr = URLDecoder.decode(data, "UTF-8");
+        List<ProductSaler> productSalers = JSONObject.parseArray(jsonStr, ProductSaler.class);
+        productService.updateProdSaler(productSalers);
+//        logger.log("物料资料", "上传个人物料资料", productSalers.size());
+    }
+
+    /**
+     * ERP个人物料删除同步状态到平台
+     *
+     * @author hejq
+     * @date 2018-01-12 19:11
+     * @param data
+     * @throws UnsupportedEncodingException
+     */
+    @RequestMapping(value = "/produser/quit", method = RequestMethod.POST)
+    @ResponseBody
+    public void uploadProductSalerForCancel(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String jsonStr = URLDecoder.decode(data, "UTF-8");
+        List<ProductSaler> productSalers = JSONObject.parseArray(jsonStr, ProductSaler.class);
+        productService.quitProdSaler(productSalers);
+//        logger.log("物料资料", "ERP取消个人物料同步到公共物料库", productSalers.size());
+    }
 }

+ 168 - 0
src/main/java/com/uas/ps/product/controller/ProductUsersController.java

@@ -0,0 +1,168 @@
+package com.uas.ps.product.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductUsers;
+import com.uas.ps.product.entity.FileUpload;
+import com.uas.ps.product.service.ProductUsersService;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.List;
+
+/**
+ * 用户个人产品库
+ *
+ * Created by hejq on 2017-11-08.
+ */
+@RequestMapping(value = "/productuser")
+@RestController
+public class ProductUsersController {
+
+    @Autowired
+    private ProductUsersService productUsersService;
+
+    /**
+     * 保存用户个人物料信息
+     *
+     * @param data 用户个人物料信息
+     * @return
+     */
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public ModelMap saveProductUsers(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String json = URLDecoder.decode(data, "utf-8");
+        List<ProductUsers> productUsers = JSONObject.parseArray(json, ProductUsers.class);
+        productUsersService.save(productUsers);
+        ModelMap map = new ModelMap();
+//        logger.log("商品批次", "[" + SystemSession.getUser().getUserName() + "]通过excel导入了个人物料,数量为" + map.size());
+        return map;
+    }
+
+    /**
+     * 通过excel批量导入物料
+     *
+     * @param data excel文件及企业uu与用户uu(uploadItem, enUU, userUU)
+     * @return
+     */
+    @RequestMapping(value = "/edit/release/excel", method = RequestMethod.POST)
+    public ModelMap releaseByExcel(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String json = URLDecoder.decode(data, "utf-8");
+        JSONObject jsonObject = JSONObject.parseObject(json, JSONObject.class);
+        FileUpload uploadItem = JSON.parseObject(String.valueOf(jsonObject.get("uploadItem")), FileUpload.class);
+        Long enUU = (Long) jsonObject.get("enUU");
+        Long userUU = (Long) jsonObject.get("userUU");
+        ModelMap map = new ModelMap();
+        String fileName = uploadItem.getFile().getOriginalFilename();
+        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
+        InputStream is = null;
+        Workbook workbook = null;
+        try {
+            is = uploadItem.getFile().getInputStream();
+            if ("xls".equals(suffix)) {
+                workbook = new HSSFWorkbook(is);
+            } else if ("xlsx".equals(suffix)) {
+                workbook = new XSSFWorkbook(is);
+            } else {
+                throw new RuntimeException("文件格不正确,请上传.xls或.xlsx的文件");
+            }
+            map = productUsersService.releaseByWorkbook(workbook, enUU, userUU);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+//        logger.log("商品批次", "[" + SystemSession.getUser().getUserName() + "]通过excel导入了个人物料,数量为" + map.size());
+        return map;
+    }
+
+    /**
+     * 新增物料
+     *
+     * @param data  物料信息
+     * @return
+     */
+    @RequestMapping(value = "/edit/addNewProduct", method = RequestMethod.POST)
+    public ModelMap addNewProduct(@RequestParam("data") String data) throws Exception {
+        String json = URLDecoder.decode(data, "utf-8");
+        // TODO 传过来的物料就应包含企业UU和用户UU
+        Product product = JSON.parseObject(json, Product.class);
+        return productUsersService.addNewProduct(product);
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param id 个人物料信息的id
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/edit/delete", method = RequestMethod.POST)
+    public ModelMap deleteById(@RequestParam("id") Long id) {
+        ModelMap map = new ModelMap();
+        try {
+            productUsersService.deleteById(id);
+//            logger.log("删除个人产品",  "删除了id为 [" + id + "]个人产品");
+        } catch (Exception e) {
+            map.put("error", "删除个人产品失败");
+        }
+        return map;
+    }
+
+    /**
+     * 通过id删除
+     *
+     * @param ids 个人物料信息的ids
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/edit/deleteByBatch", method = RequestMethod.POST)
+    public ModelMap deleteByBatch(@RequestParam("ids") String ids) {
+        List<Long> idList = JSONObject.parseArray(ids, Long.class);
+        ModelMap map = new ModelMap();
+        try {
+            productUsersService.deleteByBatch(idList);
+//            logger.log("删除个人产品",  "数量:" + idList.size());
+        } catch (Exception e) {
+            map.put("error", "删除个人产品失败");
+        }
+        return map;
+    }
+
+    /**
+     * 批量转入我的物料
+     *
+     * @param data (ids 物料ids, userUU 当前用户UU, enUU 当前企业UU)
+     */
+    @RequestMapping(value = "/coverToUserByIds", method = RequestMethod.POST)
+    public ModelMap coverToUserByIds(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String json = URLDecoder.decode(data, "utf-8");
+        JSONObject jsonObject = JSON.parseObject(json, JSONObject.class);
+        String ids = (String) jsonObject.get("ids");
+        Long enUU = (Long) jsonObject.get("enUU");
+        Long userUU = (Long) jsonObject.get("userUU");
+        return productUsersService.coverToUserProdByIds(ids, userUU, enUU);
+    }
+
+    /**
+     * 单个转入我的物料
+     *
+     * @param data (id 物料id, userUU 当前用户UU, enUU 当前企业UU)
+     * @return
+     */
+    @RequestMapping(value = "/covertToUser", method = RequestMethod.POST)
+    public void coverToUserById(@RequestParam("data") String data) throws UnsupportedEncodingException {
+        String json = URLDecoder.decode(data, "utf-8");
+        JSONObject jsonObject = JSON.parseObject(json, JSONObject.class);
+        Long id = (Long) jsonObject.get("id");
+        Long enUU = (Long) jsonObject.get("enUU");
+        Long userUU = (Long) jsonObject.get("userUU");
+        productUsersService.coverToUserProdById(id, userUU, enUU);
+    }
+}

+ 15 - 0
src/main/java/com/uas/ps/product/entity/FileUpload.java

@@ -0,0 +1,15 @@
+package com.uas.ps.product.entity;
+
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+public class FileUpload {
+	private CommonsMultipartFile file;
+
+	public CommonsMultipartFile getFile() {
+		return file;
+	}
+
+	public void setFile(CommonsMultipartFile file) {
+		this.file = file;
+	}
+}

+ 14 - 1
src/main/java/com/uas/ps/product/entity/Prod.java

@@ -135,6 +135,11 @@ public class Prod implements Serializable {
      */
     private Short standard;
 
+    /**
+     * 物料所属企业UU(需要在erp调用接口时,设置到product实体)
+     */
+    private Long pr_enuu;
+
     public Long getPr_id() {
         return pr_id;
     }
@@ -327,6 +332,14 @@ public class Prod implements Serializable {
         this.standard = standard;
     }
 
+    public Long getPr_enuu() {
+        return pr_enuu;
+    }
+
+    public void setPr_enuu(Long pr_enuu) {
+        this.pr_enuu = pr_enuu;
+    }
+
     /**
      * 转为平台的产品
      *
@@ -351,7 +364,7 @@ public class Prod implements Serializable {
         product.setSourceId(this.pr_id);
         product.setBrand(this.pr_brand);
         product.setCode(this.pr_code);
-        // TODO 这里设置企业UU号
+        product.setEnUU(this.pr_enuu);
         // 默认设置为非标准,到平台做匹配更新
         product.setStandard(Constant.NO);
         // 默认采购状态开启

+ 56 - 0
src/main/java/com/uas/ps/product/repository/ProductDao.java

@@ -3,8 +3,14 @@ package com.uas.ps.product.repository;
 import com.uas.ps.entity.Product;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
+import javax.transaction.Transactional;
+import java.util.List;
+
 /**
  * @author sunyj
  * @since 2018/1/6 17:20
@@ -12,4 +18,54 @@ import org.springframework.stereotype.Repository;
 @Repository
 public interface ProductDao extends JpaSpecificationExecutor<Product>, JpaRepository<Product, Long> {
 
+    /**
+     * 根据enUU和code查找物料
+     * @param pr_enuu 物料企业UU
+     * @param pr_code 物料编号
+     * @return 查询结果
+     */
+    List<Product> findByEnUUAndCode(Long pr_enuu, String pr_code);
+
+    /**
+     * 根据物料所属enUU、来源app和下载状态查询物料
+     * @param enUU 物料企业UU
+     * @param app 来源app
+     * @param status 物料更新下载状态
+     * @return
+     */
+    List<Product> findByEnUUAndSourceAppAndDownloadStatus(Long enUU, String app, Integer status);
+
+    /**
+     * 通过企业uu和物料编号禁用物料
+     *
+     * @param enUU 物料所属企业UU
+     * @param code 物料号
+     * @param enabled 是否启用字段
+     */
+    @Transactional
+    @Modifying
+    @Query("update Product p set p.enabled = :enabled where p.enUU = :enUU and p.code = :code")
+    int updateEnabled(@Param("enUU") Long enUU, @Param("code") String code, @Param("enabled") Short enabled);
+
+    /**
+     * 通过企业UU,物料名称、规格、品牌(非标准)
+     *
+     * @param enUU 企业UU
+     * @param title 物料名称
+     * @param cmpcode 规格
+     * @param brand 品牌
+     * @return
+     */
+    List<Product> findByTitleAndCmpCodeAndBrandAndEnUU(String title, String cmpcode, String brand, Long enUU);
+
+    /**
+     * 通过企业UU,物料名称、规格、品牌(标准)
+     *
+     * @param title 物料名称
+     * @param cmpcode 原厂型号
+     * @param brand 品牌
+     * @param enUU 企业UU
+     * @return
+     */
+    List<Product> findByTitleAndPCmpCodeAndPBrandAndEnUU(String title, String cmpcode, String brand, Long enUU);
 }

+ 66 - 0
src/main/java/com/uas/ps/product/repository/ProductUsersDao.java

@@ -0,0 +1,66 @@
+package com.uas.ps.product.repository;
+
+import com.uas.ps.entity.ProductUsers;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.jpa.repository.query.Procedure;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Created by dongbw
+ * 18/01/14 14:40.
+ */
+@Repository
+public interface ProductUsersDao extends JpaSpecificationExecutor<ProductUsers>, JpaRepository<ProductUsers, Long>{
+
+    /**
+     * 通过企业UU,个人uu和物料id查询我的产品库物料信息
+     *
+     * @param enuu 企业UU
+     * @param useruu 用户UU
+     * @param prid 物料id
+     * @return 个人产品库list
+     */
+    List<ProductUsers> findByEnuuAndUseruuAndPrid(Long enuu, Long useruu, Long prid);
+
+    /**
+     * 通过ERPid查询个人物料信息
+     *
+     * @param enuu 企业UU
+     * @param em_uu 个人uu
+     * @param ps_id erpid
+     * @return 个人物料信息
+     */
+    ProductUsers findByEnuuAndUseruuAndErpid(Long enuu, Long em_uu, Long ps_id);
+
+    /**
+     * 通过个人,企业和物料名称、规格、品牌查询个人产品是否存在
+     *
+     * @param enuu 企业uu
+     * @param useruu 用户uu
+     * @param title 物料名称
+     * @param spec 物料规格
+     * @param brand 物料品牌
+     * @return 个人物料
+     */
+    @Query("select p from ProductUsers p where p.enuu = :enuu and p.useruu = :useruu and p.product.title = :title and p.product.cmpCode = :spec and p.product.brand = :brand")
+    List<ProductUsers> findByEnuuAndUseruuAndTitleAndCmpCodeAndBrand(@Param("enuu") Long enuu, @Param("useruu") Long useruu, @Param("title") String title, @Param("spec") String spec, @Param("brand") String brand);
+
+    /**
+     * 通过选择的id批量转入我的物料
+     *
+     * @param ids 物料ids
+     */
+    @Procedure(procedureName = "product_coverto_user")
+    Integer coverToUserProdByIds(String ids, Long useruu, Long enuu);
+
+    /**
+     * 通过物料id,enuu,useruu精确
+     */
+    @Procedure(procedureName = "prid_covertouser")
+    void coverToUserByPrid(Long prid, Long enuu, Long useruu);
+}

+ 57 - 3
src/main/java/com/uas/ps/product/service/ProductService.java

@@ -1,6 +1,7 @@
 package com.uas.ps.product.service;
 
 import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductSaler;
 import com.uas.ps.product.entity.Prod;
 import org.springframework.ui.ModelMap;
 
@@ -12,6 +13,14 @@ import java.util.List;
  */
 public interface ProductService {
 
+    /**
+     * 保存物料
+     *
+     * @param productInfo 物料信息
+     * @return
+     */
+    Product save(Product productInfo);
+
     /**
      * 批量保存产品
      *
@@ -21,12 +30,13 @@ public interface ProductService {
     List<Product> save(List<Product> products);
 
     /**
-     * 将ERP系统的产品,转为平台的产品
+     * 将ERP系统的产品,转为物料库的产品
      *
-     * @param prods
+     * @param prods erp物料信息
+     * @param enUU 物料所属企业UU
      * @return
      */
-    List<Product> convertProduct(List<Prod> prods);
+    List<Product> convertProduct(List<Prod> prods, Long enUU);
 
     /**
      * 通过 enUU 查询非标准器件进行存储
@@ -45,4 +55,48 @@ public interface ProductService {
      * @return
      */
     ModelMap assignPersonalProduct(Long userUU, Long productId);
+
+    /**
+     * 通过所属企业UU、应用和下载状态查询物料信息
+     *
+     * @param enUU
+     * @param app
+     * @param status
+     * @return
+     */
+    List<Product> findByEnUUAndSourceAppAndDownloadStatus(Long enUU, String app, Integer status);
+
+    /**
+     * 物料下载成功,更新下载状态
+     *
+     * @param idArray
+     */
+    public void onProductDownSuccess(String[] idArray);
+
+    /**
+     * 禁用物料
+     *
+     * @param enUU 物料所属企业UU
+     * @param code 物料号
+     * @param enabled 是否启用字段
+     */
+    public int updateEnabled(Long enUU, String code, Short enabled);
+
+    /**
+     * ERP个人物料同步到物料库
+     *
+     * @author hejq
+     * @date 2018-01-12 19:15
+     * @param productSalers 个人物料信息
+     */
+    void updateProdSaler(List<ProductSaler> productSalers);
+
+    /**
+     * ERP取消个人物料同步到物料库
+     *
+     * @author hejq
+     * @date 2018-01-12 19:31
+     * @param productSalers
+     */
+    void quitProdSaler(List<ProductSaler> productSalers);
 }

+ 76 - 0
src/main/java/com/uas/ps/product/service/ProductUsersService.java

@@ -0,0 +1,76 @@
+package com.uas.ps.product.service;
+
+import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductUsers;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.ui.ModelMap;
+
+import java.util.List;
+
+/**
+ * 个人物料接口方法
+ *
+ * Created by hejq on 2017-11-08.
+ */
+public interface ProductUsersService {
+
+    /**
+     * 保存个人物料信息
+     * @param productUsers 个人物料信息
+     */
+    void save(List<ProductUsers> productUsers);
+
+    /**
+     * 新增个人物料信息
+     *
+     * @param prodInfo
+     * @return
+     */
+    ModelMap addNewProduct(Product prodInfo);
+
+    /**
+     * 通过id解除物料绑定关系
+     *
+     * @param id
+     */
+    void deleteById(Long id);
+
+    /**
+     * 批量导入物料信息
+     *
+     * @param workbook excel解析的物料信息
+     * @param enUU 企业UU
+     * @param userUU 用户UU
+     * @return
+     */
+    ModelMap releaseByWorkbook(Workbook workbook, Long enUU, Long userUU);
+
+    /**
+     * 批量转入我的产品库
+     *
+     * @param ids
+     */
+    ModelMap coverToUserProdByIds(String ids, Long userUU, Long enUU);
+
+    /**
+     * 单个转入我的物料
+     *
+     * @param id
+     */
+    void coverToUserProdById(Long id, Long userUU, Long enUU);
+
+    /**
+     * 批量删除我的产品
+     * @param idList
+     */
+    void deleteByBatch(List<Long> idList);
+
+    /**
+     * 转入我的物料库
+     *
+     * @param id
+     * @param enuu
+     * @param useruu
+     */
+    void coverToMyProduct(Long id, Long enuu, Long useruu, String method);
+}

+ 125 - 2
src/main/java/com/uas/ps/product/service/impl/ProductServiceImpl.java

@@ -1,15 +1,21 @@
 package com.uas.ps.product.service.impl;
 
 import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductSaler;
+import com.uas.ps.entity.ProductUsers;
+import com.uas.ps.entity.Status;
 import com.uas.ps.product.entity.Prod;
 import com.uas.ps.product.repository.ProductDao;
 import com.uas.ps.product.repository.ProductMatchResultDao;
+import com.uas.ps.product.repository.ProductUsersDao;
 import com.uas.ps.product.service.ProductService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.ui.ModelMap;
+import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -25,15 +31,44 @@ public class ProductServiceImpl implements ProductService {
     @Autowired
     private ProductMatchResultDao productMatchResultDao;
 
+    @Autowired
+    private ProductUsersDao productUsersDao;
+
+    /**
+     * 保存物料
+     *
+     * @param productInfo 物料信息
+     * @return
+     */
+    @Override
+    public Product save(Product productInfo) {
+        return productDao.save(productInfo);
+    }
+
     @Override
     public List<Product> save(List<Product> products) {
         return productDao.save(products);
     }
 
     @Override
-    public List<Product> convertProduct(List<Prod> prods) {
+    public List<Product> convertProduct(List<Prod> prods, Long enUU) {
         List<Product> products = new ArrayList<Product>();
-        // TODO
+        for (Prod prod : prods) {
+            prod.setPr_enuu(enUU);
+            prod.setKind(prod.getPr_detail());
+            if (prod.getPr_orispeccode() == null) {// 如果原厂型号不存在,将规格赋值给原厂型号
+                prod.setPr_orispeccode(prod.getPr_spec());
+            }
+            List<Product> prodResult = productDao.findByEnUUAndCode(prod.getPr_enuu(), prod.getPr_code());
+            if (CollectionUtils.isEmpty(prodResult)) {// 不存在的新上传上来的物料,新增
+                products.add(prod.convert());
+            } else {// 物料库上已经存在的物料,修改
+                Product product = prod.convert();
+                product.setId(prodResult.get(0).getId());
+                product.setCode(prodResult.get(0).getCode());
+                products.add(product);
+            }
+        }
         return products;
     }
 
@@ -51,4 +86,92 @@ public class ProductServiceImpl implements ProductService {
         return map;
     }
 
+    /**
+     * 通过应用和下载状态查询物料信息
+     *
+     * @param app
+     * @param status
+     * @return
+     */
+    @Override
+    public List<Product> findByEnUUAndSourceAppAndDownloadStatus(Long enUU, String app, Integer status) {
+        return productDao.findByEnUUAndSourceAppAndDownloadStatus(enUU, app, status);
+    }
+
+    /**
+     * 物料下载成功,更新下载状态
+     *
+     * @param idArray
+     */
+    @Override
+    public void onProductDownSuccess(String[] idArray) {
+        for (String id : idArray) {
+            Product product = productDao.findOne(Long.parseLong(id));
+            if (product != null) {
+                product.setDownloadStatus(Status.DOWNLOADED.value());
+                productDao.save(product);
+            }
+        }
+    }
+
+    /**
+     * 禁用物料
+     *
+     * @param enUU 物料所属enUU
+     * @param code 物料号
+     * @param enabled 是否启用
+     */
+    @Override
+    public int updateEnabled(Long enUU, String code, Short enabled) {
+        return productDao.updateEnabled(enUU, code, enabled);
+    }
+
+    /**
+     * ERP个人物料同步到物料库
+     *
+     * @param productSalers 个人物料信息
+     * @author hejq
+     * @date 2018-01-12 19:15
+     */
+    @Override
+    public void updateProdSaler(List<ProductSaler> productSalers) {
+        for (ProductSaler productSaler : productSalers) {
+            Long enUU = productSaler.getEn_uu();
+            List<Product> prods = productDao.findByEnUUAndCode(enUU, productSaler.getPs_code());
+            if (CollectionUtils.isEmpty(prods)) {
+                throw new RuntimeException("[" + productSaler.getPs_code() + "]物料没找到");
+            } else {
+                Product product = prods.get(0);
+                List<ProductUsers> productUsers = productUsersDao.findByEnuuAndUseruuAndPrid(enUU, productSaler.getEm_uu(), product.getId());
+                if (CollectionUtils.isEmpty(productUsers)) {
+                    ProductUsers info = new ProductUsers();
+                    info.setDate(new Date());
+                    info.setEnuu(enUU);
+                    info.setPrid(product.getId());
+                    info.setUseruu(productSaler.getEm_uu());
+                    info.setErpid(productSaler.getPs_id());
+                    info = productUsersDao.save(info);
+//                    erpLogger.log("ERP个人物料信息同步", "关联物料id:" + info.getPrid(), 1);
+                }
+            }
+        }
+    }
+
+    /**
+     * ERP取消个人物料同步到物料库
+     *
+     * @param productSalers
+     * @author hejq
+     * @date 2018-01-12 19:31
+     */
+    @Override
+    public void quitProdSaler(List<ProductSaler> productSalers) {
+        for (ProductSaler productSaler : productSalers) {
+            ProductUsers prod = productUsersDao.findByEnuuAndUseruuAndErpid(productSaler.getEn_uu(), productSaler.getEm_uu(), productSaler.getPs_id());
+            if (null != prod) {
+                productUsersDao.delete(prod);
+//                erpLogger.log("ERP删除个人物料信息同步", "关联物料id: " + prod.getPrid(), 1);
+            }
+        }
+    }
 }

+ 349 - 0
src/main/java/com/uas/ps/product/service/impl/ProductUsersServiceImpl.java

@@ -0,0 +1,349 @@
+package com.uas.ps.product.service.impl;
+
+import com.uas.ps.core.util.CollectionUtils;
+import com.uas.ps.entity.Product;
+import com.uas.ps.entity.ProductUsers;
+import com.uas.ps.product.entity.Constant;
+import com.uas.ps.product.repository.ProductDao;
+import com.uas.ps.product.repository.ProductUsersDao;
+import com.uas.ps.product.service.ProductUsersService;
+import com.uas.ps.product.util.ThreadUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.ModelMap;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by hejq on 2017-11-08.
+ */
+@Service
+public class ProductUsersServiceImpl implements ProductUsersService {
+
+    @Autowired
+    private ProductUsersDao productUsersDao;
+
+    @Autowired
+    private ProductDao productDao;
+
+    /**
+     * 保存个人物料信息
+     *
+     * @param productUsers 个人物料信息
+     */
+    @Override
+    public void save(List<ProductUsers> productUsers) {
+        productUsersDao.save(productUsers);
+    }
+
+    @Override
+    public ModelMap addNewProduct(Product prodInfo) {
+        ModelMap map = new ModelMap();
+        // 先查找以前的个人物料是否存在
+        List<ProductUsers> productUsers = productUsersDao.findByEnuuAndUseruuAndTitleAndCmpCodeAndBrand(prodInfo.getEnUU(), prodInfo.getUserUU(), prodInfo.getTitle(), prodInfo.getCmpCode(), prodInfo.getBrand());
+        if(CollectionUtils.isEmpty(productUsers)) {// 如果不存在则进行其他操作,存在不处理(先查询非标)
+            List<Product> productList = productDao.findByTitleAndCmpCodeAndBrandAndEnUU(prodInfo.getTitle(), prodInfo.getCmpCode(), prodInfo.getBrand(), prodInfo.getEnUU());
+            if(CollectionUtils.isEmpty(productList)) {// 如果非标不存在再查询标准
+                productList = productDao.findByTitleAndPCmpCodeAndPBrandAndEnUU(prodInfo.getTitle(), prodInfo.getCmpCode(), prodInfo.getBrand(), prodInfo.getEnUU());
+            }
+            if(!CollectionUtils.isEmpty(productList)) { // 如果存在,找出其中一个进行绑定
+                ProductUsers prod = new ProductUsers();
+                prod.setDate(new Date());
+                prod.setEnuu(prodInfo.getEnUU());
+                prod.setPrid(productList.get(0).getId());
+                prod.setUseruu(prodInfo.getUserUU());
+                productUsersDao.save(prod);
+//                logger.log("个人产品库增加产品", "关联:" + productList.get(0).getId());
+                map.put("success", "新增成功");
+            } else {// 不存在的话新增再绑定
+                SimpleDateFormat sdf = new SimpleDateFormat("mmsssss");
+                if(null == prodInfo.getCode()) {
+                    String code = prodInfo.getEnUU() + sdf.format(new Date());
+                    prodInfo.setCode(code);
+                } else {
+                    List<Product> products = productDao.findByEnUUAndCode(prodInfo.getEnUU(), prodInfo.getCode());
+                    String code = prodInfo.getEnUU() + sdf.format(new Date());
+                    if(products.size() != 0) // 如果该企业下该编号的物料存在,重新赋值
+                        prodInfo.setCode(code);
+
+                }
+//                List<Role> roles = roleService.findByEnUUAndUserUU(enuu, useruu);
+//                if(!CollectionUtils.isEmpty(roles)) {
+//                    for(Role role : roles) {
+//                        if(role.getDesc().equals("业务员") || role.getDesc().equals("销售经理")) {
+//                            prodInfo.setIsSale(Constant.YES);
+//                        } else  if(role.getDesc().equals("采购员")) {
+//                            prodInfo.setIsPurchase(Constant.YES);
+//                        }
+//                    }
+//                }
+//                prodInfo.setEnUU(enuu);
+                if (null == prodInfo.getUnit())
+                    prodInfo.setUnit("PCS");
+                prodInfo.setSourceApp("B2B");
+                prodInfo.setIsPubsale(Constant.NO);
+                prodInfo.setIsShow(Constant.NO);
+                prodInfo.setStandard(Constant.NO);
+                prodInfo.setErpDate(new Date());
+                prodInfo = productDao.save(prodInfo);
+                ProductUsers prod = new ProductUsers();
+                prod.setDate(new Date());
+                prod.setEnuu(prodInfo.getEnUU());
+                prod.setPrid(prodInfo.getId());
+                prod.setUseruu(prodInfo.getUserUU());
+                productUsersDao.save(prod);
+//                logger.log("个人产品库增加产品", "关联:" + prodInfo.getId());
+                map.put("success", "新增成功");
+            }
+        } else {
+            map.put("info", "产品“" + prodInfo.getTitle() + "”已存在");
+        }
+        return map;
+    }
+
+    @Override
+    public void deleteById(Long id) {
+        productUsersDao.delete(id);
+    }
+
+    @Override
+    public ModelMap releaseByWorkbook(Workbook workbook, Long enUU, Long userUU) {
+        ModelMap modelMap = new ModelMap();
+        List<ProductUsers> productUsers = new ArrayList<>();
+        List<String> alters = new ArrayList<>();
+        Sheet sheet = workbook.getSheetAt(0);
+        int rowNum = sheet.getLastRowNum();
+        Row headerRow = sheet.getRow(0);
+        int total = 0;
+        if (headerRow != null) {
+            for (int r = 3; r <= rowNum; r++) {
+                Row row = sheet.getRow(r);
+                if (row != null && row.getCell(0) != null && row.getCell(0).getCellType() != Cell.CELL_TYPE_BLANK) {
+                    total++;
+                    Product product = new Product();
+                    ProductUsers prod = new ProductUsers();
+                    // 物料编号
+                    if (row.getCell(0) != null) {
+                        row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
+                        product.setCode(row.getCell(0).getStringCellValue().trim());
+                    }
+
+                    // 物料名称
+                    if (row.getCell(1) != null) {
+                        row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
+                        product.setTitle(row.getCell(1).getStringCellValue().trim());
+                    }
+
+                    // 原厂型号
+                    if (row.getCell(2) != null) {
+                        row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
+                        product.setCmpCode(row.getCell(2).getStringCellValue().trim());
+                    }
+
+                    // 品牌
+                    if (row.getCell(3) != null) {
+                        row.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
+                        product.setBrand(row.getCell(3).getStringCellValue().trim());
+                    }
+
+                    // 单位
+                    if (row.getCell(4) != null) {
+                        row.getCell(4).setCellType(Cell.CELL_TYPE_STRING);
+                        product.setUnit(row.getCell(4).getStringCellValue().trim());
+                    }
+
+                    // 最小包装量
+                    if (row.getCell(5) != null) {
+                        row.getCell(5).setCellType(Cell.CELL_TYPE_STRING);
+                        if (null != row.getCell(5).getStringCellValue()
+                                && !row.getCell(5).getStringCellValue().trim().equals("")) {
+                            product.setMinPack(Double.valueOf(row.getCell(5).getStringCellValue()));
+                        }
+                    }
+                    // 最小订购量
+                    if (row.getCell(6) != null) {
+                        row.getCell(6).setCellType(Cell.CELL_TYPE_STRING);
+                        if (null != row.getCell(6).getStringCellValue().trim()
+                                && !row.getCell(6).getStringCellValue().trim().equals("")) {
+                            product.setMinOrder(Double.valueOf(row.getCell(6).getStringCellValue()));
+                        }
+                    }
+                    // 交货周期
+                    if (row.getCell(7) != null) {
+                        row.getCell(7).setCellType(Cell.CELL_TYPE_STRING);
+                        if (null != row.getCell(7).getStringCellValue().trim()
+                                && !row.getCell(7).getStringCellValue().trim().equals("")) {
+                            product.setLeadTime(Double.valueOf(row.getCell(7).getStringCellValue()));
+                        }
+                    }
+                    // 交货提前期
+                    if (row.getCell(8) != null) {
+                        row.getCell(8).setCellType(Cell.CELL_TYPE_STRING);
+                        if (null != row.getCell(8).getStringCellValue().trim()
+                                && !row.getCell(8).getStringCellValue().trim().equals("")) {
+                            product.setLtinstock(Double.valueOf(row.getCell(8).getStringCellValue()));
+                        }
+                    }
+                    // 判断物料编号是否存在
+                    if(product.getCode() != null ) {
+                        List<Product> prods = productDao.findByEnUUAndCode(enUU, product.getCode());
+                        if(prods.size() > 0) {
+                            // 生成随机物料编码
+                            SimpleDateFormat sdf = new SimpleDateFormat("mmsssss");
+                            String code = enUU + sdf.format(new Date());
+                            product.setCode(code);
+                        }
+
+                    } else {
+                        // 生成随机物料编码
+                        SimpleDateFormat sdf = new SimpleDateFormat("mmsssss");
+                        String code = enUU + sdf.format(new Date());
+                        product.setCode(code);
+                    }
+                    List<ProductUsers> existProds = productUsersDao.findByEnuuAndUseruuAndTitleAndCmpCodeAndBrand
+                            (enUU, userUU, product.getTitle(), product.getCmpCode(), product.getBrand());
+                    if(CollectionUtils.isEmpty(existProds)) {
+                        List<Product> prods = productDao.findByTitleAndCmpCodeAndBrandAndEnUU(
+                                product.getTitle(), product.getCmpCode(), product.getBrand(), enUU);
+                        if(CollectionUtils.isEmpty(prods)) {// 如果非标不存在再查询标准
+                            prods = productDao.findByTitleAndPCmpCodeAndPBrandAndEnUU(product.getTitle(), product.getCmpCode(), product.getBrand(), enUU);
+                        }
+                        if (CollectionUtils.isEmpty(prods)) {
+                            // 如果物料不存在,先生成物料信息
+                            product.setEnUU(enUU);
+                            product.setUserUU(userUU);
+                            product.setSourceApp("B2B");
+                            product.setIsPubsale(Constant.NO);
+                            product.setIsShow(Constant.NO);
+                            product.setStandard(Constant.NO);
+                            product.setErpDate(new Date());
+//                            List<Role> roles = roleService.findByEnUUAndUserUU(enuu, useruu);
+//                            if(!CollectionUtils.isEmpty(roles)) {
+//                                for(Role role : roles) {
+//                                    if(role.getDesc().equals("业务员") || role.getDesc().equals("销售经理")) {
+//                                        product.setIsSale(Constant.YES);
+//                                    } else if(role.getDesc().equals("采购员")) {
+//                                        product.setIsPurchase(Constant.YES);
+//                                    }
+//                                }
+//                            }
+                            product = productDao.save(product);
+                            prod.setDate(new Date());
+                            prod.setEnuu(enUU);
+                            prod.setPrid(product.getId());
+                            prod.setUseruu(userUU);
+                        } else {
+                            Product oldProd = prods.get(0);
+                            prod.setDate(new Date());
+                            prod.setEnuu(enUU);
+                            prod.setPrid(oldProd.getId());
+                            prod.setUseruu(userUU);
+                        }
+                        productUsers.add(prod);
+                    } else {
+	                    alters.add(existProds.get(0).getProduct().getTitle());
+                    }
+                }
+            }
+            modelMap.put("total", total);
+            if (!CollectionUtils.isEmpty(productUsers)) {
+                try {
+                    productUsers = productUsersDao.save(productUsers);
+                    modelMap.put("success", productUsers.size());
+                    if(alters.size() > 0)
+                    	modelMap.put("alters", alters);
+                } catch (Exception e) {
+                    modelMap.put("error", "物料添加失败");
+                }
+            } else {
+                modelMap.put("success", 0);
+	            if(alters.size() > 0)
+		            modelMap.put("alters", alters);
+            }
+        }
+        return modelMap;
+    }
+
+    @Override
+    public ModelMap coverToUserProdByIds(String ids, Long userUU, Long enUU) {
+        ids = ids.replace("["," ");
+        ids = ids.replace("]"," ");
+        Integer count = productUsersDao.coverToUserProdByIds(ids, userUU, enUU);
+//        // 存储过程改为代码实现
+//        List<Long> prIds = JSON.parseArray(ids, Long.class);
+//        // 保存的个人产品
+//        List<ProductUsers> productUsersList = new ArrayList<>();
+//        for (Long prId : prIds) {
+//            List<ProductUsers> productUsers = productUsersDao.findByEnuuAndUseruuAndPrid(enUU, userUU, prId);
+//            // 不存在才保存
+//            if (CollectionUtils.isEmpty(productUsers)) {
+//                ProductUsers productUser = new ProductUsers(enUU, userUU, prId);
+//                productUsersList.add(productUser);
+//            }
+//        }
+//        productUsersList = productUsersDao.save(productUsersList);
+//        logger.log("我的产品库", "新增了我产品信息", "size:" + count);
+        return new ModelMap("count", count);
+    }
+
+    @Override
+    public void coverToUserProdById(Long id, Long userUU, Long enUU) {
+        List<ProductUsers> prods = productUsersDao.findByEnuuAndUseruuAndPrid(enUU, userUU, id);
+        if(CollectionUtils.isEmpty(prods)) {
+//        	Product product = productDao.findOne(id);
+//	        List<Role> roles = roleService.findByEnUUAndUserUU(enuu, useruu);
+//	        // 根据当前用户角色更新物料销售采购属性
+//	        if(!CollectionUtils.isEmpty(roles)) {
+//		        for(Role role : roles) {
+//			        if(role.getDesc().equals("业务员") || role.getDesc().equals("销售经理")) {
+//			        	if(product.getIsSale() == null || product.getIsSale().equals(Constant.NO)) {
+//					        product.setIsSale(Constant.YES);
+//					        productDao.save(product);
+//				        }
+//			        } else if(role.getDesc().equals("采购员")) {
+//				        if(product.getIsPurchase() == null || product.getIsPurchase().equals(Constant.NO)) {
+//					        product.setIsPurchase(Constant.YES);
+//					        productDao.save(product);
+//				        }
+//			        }
+//		        }
+//	        }
+            ProductUsers prod = new ProductUsers();
+            prod.setUseruu(userUU);
+            prod.setEnuu(enUU);
+            prod.setPrid(id);
+            prod.setDate(new Date());
+            prod = productUsersDao.save(prod);
+//            logger.log("我的产品库", "新增了我产品信息", "id:" + prod.getId());
+        }
+    }
+
+    @Override
+    public void deleteByBatch(List<Long> idList) {
+        List<ProductUsers> prods = productUsersDao.findAll(idList);
+        productUsersDao.delete(prods);
+    }
+
+    /**
+     * 将物料信息同步到个人信息库
+     *
+     * @param productId
+     */
+    public void coverToMyProduct(final Long productId, final Long enuu, final Long useruu, final String method) {
+//        logger.log("我的产品库", method + ":" + productId);
+        ThreadUtils.task(new Runnable() {
+
+            @Override
+            public void run() {
+                productUsersDao.coverToUserByPrid(productId, enuu, useruu);
+            }
+        }).run();
+    }
+}

+ 267 - 0
src/main/java/com/uas/ps/product/util/ThreadUtils.java

@@ -0,0 +1,267 @@
+package com.uas.ps.product.util;
+
+import com.uas.ps.product.concurrent.*;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * 多线程处理工具
+ */
+public class ThreadUtils {
+
+	public static <T> Runner<T> tasks(IRunnable<T> runnable, List<T> paramList) {
+		return new Runner<T>(runnable).tasks(paramList);
+	}
+
+	public static <T> void run(IRunnable<T> runnable, List<T> paramList) {
+		tasks(runnable, paramList).run();
+	}
+
+	public static <T> Runner<T> pool(IRunnable<T> runnable, int poolSize) {
+		return new Runner<T>(runnable, poolSize);
+	}
+
+	public static <V, T> Caller<V, T> tasks(ICallable<V, T> callable, List<T> paramList) {
+		return new Caller<V, T>(callable).tasks(paramList);
+	}
+
+	public static <V, T> List<V> call(ICallable<V, T> callable, List<T> paramList) {
+		return tasks(callable, paramList).call();
+	}
+
+	public static <V, T> Caller<V, T> pool(ICallable<V, T> callable, int poolSize) {
+		return new Caller<V, T>(callable, poolSize);
+	}
+
+	public static Executor task(Runnable runnable) {
+		return new Executor().task(runnable);
+	}
+
+	public static Executor pool(int poolSize) {
+		return new Executor(poolSize);
+	}
+
+	/**
+	 * @param <T>
+	 *            参数类型
+	 */
+	public static class Runner<T> {
+		private final ExecutorService threadPool;
+		private IRunnable<T> runner;
+		private int timeout = 900;
+		private int taskCount = 0;
+
+		public Runner() {
+			this.threadPool = Executors.newCachedThreadPool();
+		}
+
+		public Runner(int poolSize) {
+			this.threadPool = Executors.newFixedThreadPool(poolSize);
+		}
+
+		public Runner(IRunnable<T> runner) {
+			this();
+			this.runner = runner;
+		}
+
+		public Runner(IRunnable<T> runner, int poolSize) {
+			this(poolSize);
+			this.runner = runner;
+		}
+
+		public Runner<T> setTimeout(int timeout) {
+			this.timeout = timeout;
+			return this;
+		}
+
+		public Runner<T> task(T param) {
+			threadPool.execute(new IRunnableAdapter<T>(runner, param));
+			taskCount++;
+			return this;
+		}
+
+		public Runner<T> tasks(List<T> params) {
+			if (!CollectionUtils.isEmpty(params)) {
+				for (T param : params)
+					task(param);
+			}
+			return this;
+		}
+
+		public void run() {
+			if (taskCount > 0) {
+				threadPool.shutdown();
+				try {
+					threadPool.awaitTermination(timeout, TimeUnit.SECONDS);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		public Runner<T> shutdownIf(Listeners closer) {
+			closer.addListener(new Listener() {
+
+				@Override
+				public void handler() {
+					threadPool.shutdownNow();
+				}
+			});
+			return this;
+		}
+
+	}
+
+	/**
+	 * @param <V>
+	 *            返回类型
+	 * @param <T>
+	 *            参数类型
+	 */
+	public static class Caller<V, T> {
+		private final ExecutorService threadPool;
+		private final CompletionService<V> service;
+		private ICallable<V, T> caller;
+		private int taskCount = 0;
+		private AtomicBoolean closed = new AtomicBoolean(false);
+
+		public Caller() {
+			this.threadPool = Executors.newCachedThreadPool();
+			this.service = new ExecutorCompletionService<V>(threadPool);
+		}
+
+		public Caller(int poolSize) {
+			this.threadPool = Executors.newFixedThreadPool(poolSize);
+			this.service = new ExecutorCompletionService<V>(threadPool);
+		}
+
+		public Caller(ICallable<V, T> caller) {
+			this();
+			this.caller = caller;
+		}
+
+		public Caller(ICallable<V, T> caller, int poolSize) {
+			this(poolSize);
+			this.caller = caller;
+		}
+
+		public Caller<V, T> task(T param) {
+			service.submit(new ICallableAdapter<V, T>(caller, param));
+			taskCount++;
+			return this;
+		}
+
+		public Caller<V, T> tasks(List<T> params) {
+			if (!CollectionUtils.isEmpty(params)) {
+				for (T param : params)
+					task(param);
+			}
+			return this;
+		}
+
+		public List<V> call() {
+			threadPool.shutdown();
+			int finish = 0;
+			List<V> results = new ArrayList<V>();
+			while (finish < taskCount && !closed.get()) {
+				Future<V> val = service.poll();
+				// 采用非阻塞方式
+				if (null != val) {
+					try {
+						results.add(val.get());
+					} catch (InterruptedException e) {
+						e.printStackTrace();
+					} catch (ExecutionException e) {
+						e.printStackTrace();
+					}
+					finish++;
+				}
+				try {
+					TimeUnit.MILLISECONDS.sleep(50);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+			closed.set(true);
+			return results;
+		}
+
+		public Caller<V, T> shutdownIf(Listeners closer) {
+			closer.addListener(new Listener() {
+
+				@Override
+				public void handler() {
+					if (!closed.get()) {
+						threadPool.shutdownNow();
+						closed.set(true);
+					}
+				}
+			});
+			return this;
+		}
+
+	}
+
+	/**
+	 * 无参、无返回执行
+	 */
+	public static class Executor {
+		private final ExecutorService threadPool;
+		private int timeout = 900;// 15 min
+		private int taskCount = 0;
+
+		public Executor() {
+			this.threadPool = Executors.newCachedThreadPool();
+		}
+
+		public Executor(int poolSize) {
+			this.threadPool = Executors.newFixedThreadPool(poolSize);
+		}
+
+		public Executor setTimeout(int timeout) {
+			this.timeout = timeout;
+			return this;
+		}
+
+		public Executor task(Runnable runnable) {
+			threadPool.execute(runnable);
+			taskCount++;
+			return this;
+		}
+
+		public Executor tasks(List<Runnable> runnables) {
+			if (!CollectionUtils.isEmpty(runnables)) {
+				for (Runnable runnable : runnables)
+					task(runnable);
+			}
+			return this;
+		}
+
+		public void run() {
+			if (taskCount > 0) {
+				threadPool.shutdown();
+				try {
+					threadPool.awaitTermination(timeout, TimeUnit.SECONDS);
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+
+		public Executor shutdownIf(Listeners closer) {
+			closer.addListener(new Listener() {
+
+				@Override
+				public void handler() {
+					threadPool.shutdownNow();
+				}
+			});
+			return this;
+		}
+
+	}
+}

+ 1 - 1
src/main/resources/application.yml

@@ -14,7 +14,7 @@ spring:
 security:
  basic:
   enabled: true
-  path: /**
+  path: /
  user:
   name: product-admin
   password: select111***