Bladeren bron

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	src/main/java/com/uas/ps/product/service/ProductService.java
dongbw 7 jaren geleden
bovenliggende
commit
a368c0e94d

+ 14 - 0
src/main/java/com/uas/ps/product/controller/ProductController.java

@@ -13,6 +13,8 @@ import com.uas.ps.product.entity.ProductSaler;
 import com.uas.ps.product.service.ProductService;
 import com.uas.ps.product.support.ProductBufferedLogger;
 import com.uas.ps.product.sync.WaitSyncHelper;
+import com.uas.ps.support.ResultMap;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -190,6 +192,18 @@ public class ProductController {
         return ids;
     }
 
+    /**
+     * 物料不存在,重新同步物料
+     * @param miss 丢失的物料
+     * @return
+     */
+    @HttpLog
+    @RequestMapping(value = "/reupload/b2b", method = RequestMethod.POST)
+    @ResponseBody
+    public ResultMap reuploadProduct(@RequestBody List<Map<String, Object>> miss) {
+        return productService.reuploadProduct(miss);
+    }
+
     /**
      * B2B批量更新物料信息并加入个人物料库
      *

+ 206 - 0
src/main/java/com/uas/ps/product/entity/SyncMessage.java

@@ -0,0 +1,206 @@
+package com.uas.ps.product.entity;
+
+import com.alibaba.fastjson.JSONObject;
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * 记录变化的消息
+ *
+ * @author sunyj
+ * @since 2018/1/14 16:35
+ */
+@Entity
+@Table(name = "sync$message")
+public class SyncMessage implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @Column(name = "me_id")
+    private Long id;
+
+    /**
+     * 表名
+     */
+    @Column(name = "me_table_name")
+    private String tableName;
+
+    /**
+     * 更改类型
+     */
+    @Column(name = "me_method_type")
+    private String methodType;
+
+    /**
+     * 决定数据唯一的条件(JSON 格式)
+     */
+    @Column(name = "me_data_key")
+    private JSONObject dataKey;
+
+    /**
+     * 更改的数据(JSON 格式),delete 情况下可为空
+     */
+    @Column(name = "me_data")
+    private JSONObject data;
+
+    /**
+     * 优先级
+     */
+    @Column(name = "me_priority")
+    private Long priority;
+
+    /**
+     * 尝试次数
+     */
+    @Column(name = "me_retry_count")
+    private Long retryCount;
+
+    /**
+     * 请求来自哪个应用
+     */
+    @Column(name = "me_source_app")
+    private String sourceApp;
+
+    /**
+     * 批次 code
+     */
+    @Column(name = "me_batch_code")
+    private String batchCode;
+
+    /**
+     * 批次数量
+     */
+    @Column(name = "me_batch_size")
+    private Integer batchSize;
+
+    /**
+     * 批次序号
+     */
+    @Column(name = "me_batch_detno")
+    private Integer batchDetno;
+
+    /**
+     * 时间
+     */
+    @Column(name = "me_create_time")
+    private Date createTime;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
+    public String getMethodType() {
+        return methodType;
+    }
+
+    public void setMethodType(String methodType) {
+        this.methodType = methodType;
+    }
+
+    public JSONObject getDataKey() {
+        return dataKey;
+    }
+
+    public void setDataKey(JSONObject dataKey) {
+        this.dataKey = dataKey;
+    }
+
+    public JSONObject getData() {
+        return data;
+    }
+
+    public void setData(JSONObject data) {
+        this.data = data;
+    }
+
+    public Long getPriority() {
+        return priority;
+    }
+
+    public void setPriority(Long priority) {
+        this.priority = priority;
+    }
+
+    public Long getRetryCount() {
+        return retryCount;
+    }
+
+    public void setRetryCount(Long retryCount) {
+        this.retryCount = retryCount;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getSourceApp() {
+        return sourceApp;
+    }
+
+    public void setSourceApp(String sourceApp) {
+        this.sourceApp = sourceApp;
+    }
+
+    public String getBatchCode() {
+        return batchCode;
+    }
+
+    public void setBatchCode(String batchCode) {
+        this.batchCode = batchCode;
+    }
+
+    public Integer getBatchSize() {
+        return batchSize;
+    }
+
+    public void setBatchSize(Integer batchSize) {
+        this.batchSize = batchSize;
+    }
+
+    public Integer getBatchDetno() {
+        return batchDetno;
+    }
+
+    public void setBatchDetno(Integer batchDetno) {
+        this.batchDetno = batchDetno;
+    }
+
+    @Override
+    public String toString() {
+        return "SyncMessage{" +
+                "id=" + id +
+                ", tableName='" + tableName + '\'' +
+                ", methodType='" + methodType + '\'' +
+                ", dataKey=" + dataKey +
+                ", data=" + data +
+                ", priority=" + priority +
+                ", retryCount=" + retryCount +
+                ", sourceApp='" + sourceApp + '\'' +
+                ", batchCode='" + batchCode + '\'' +
+                ", batchSize=" + batchSize +
+                ", batchDetno=" + batchDetno +
+                ", createTime=" + createTime +
+                '}';
+    }
+}

+ 28 - 0
src/main/java/com/uas/ps/product/repository/SyncMessageDao.java

@@ -0,0 +1,28 @@
+package com.uas.ps.product.repository;
+
+import com.uas.ps.product.entity.SyncMessage;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.query.Procedure;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Created by wangyc on 2018/7/3.
+ *
+ * @version 2018/7/3 10:20 wangyc
+ */
+@Repository
+public interface SyncMessageDao extends JpaRepository<SyncMessage, Long>, JpaSpecificationExecutor<SyncMessage>{
+
+    /**
+     * 插入操作同步消息
+     * @param tableName 表名
+     * @param methodType 操作类型
+     * @param dataKey 主键
+     * @param data 数据
+     * @param priority 权重
+     */
+    @Procedure(procedureName = "sync$enqueue_message")
+    void callSyncEnqueneMessage(String tableName, String methodType, String dataKey, String data, Integer priority);
+
+}

+ 9 - 0
src/main/java/com/uas/ps/product/service/ProductService.java

@@ -3,6 +3,8 @@ package com.uas.ps.product.service;
 import com.uas.ps.entity.Product;
 import com.uas.ps.product.entity.Prod;
 import com.uas.ps.product.entity.ProductSaler;
+import com.uas.ps.support.ResultMap;
+import java.util.Map;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.ModelMap;
 
@@ -359,4 +361,11 @@ public interface ProductService {
      * @return
      */
     Long countByEnUU(Long enUU);
+
+    /**
+     * 物料不存在,重新同步物料
+     * @param miss 丢失的物料
+     * @return
+     */
+    ResultMap reuploadProduct(List<Map<String, Object>> miss);
 }

+ 127 - 39
src/main/java/com/uas/ps/product/service/impl/ProductServiceImpl.java

@@ -21,10 +21,25 @@ import com.uas.ps.product.repository.ProductMatchResultDao;
 import com.uas.ps.product.repository.ProductPrivateDao;
 import com.uas.ps.product.repository.ProductReplaceDao;
 import com.uas.ps.product.repository.ProductUsersDao;
+import com.uas.ps.product.repository.SyncMessageDao;
 import com.uas.ps.product.service.ProductService;
 import com.uas.ps.product.sync.WaitSyncHelper;
 import com.uas.ps.properties.UrlProperties;
+import com.uas.ps.support.CodeType;
+import com.uas.ps.support.ResultMap;
+import java.lang.reflect.Field;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.Column;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.map.HashedMap;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.core.BatchPreparedStatementSetter;
@@ -34,15 +49,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.ModelMap;
 import org.springframework.web.client.RestTemplate;
 
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
 /**
  * @author sunyj
  * @since 2018/1/6 17:19
@@ -77,6 +83,9 @@ public class ProductServiceImpl implements ProductService {
     @Autowired
     private ProductReplaceDao productReplaceDao;
 
+    @Autowired
+    private SyncMessageDao syncMessageDao;
+
     /**
      * B2C物料可用属性
      */
@@ -89,6 +98,14 @@ public class ProductServiceImpl implements ProductService {
 
     private static final Logger log = Logger.getLogger(Logger.class);
 
+    private final String PRODUCT_TABLE_NAME = "products";
+
+    private final String METHOD_TYPE_INSERT = "insert";
+
+    private final Integer PRIORITY = 1;
+
+    private final String PR_ID = "{\"pr_id\": }";
+
     /**
      * 保存物料
      *
@@ -114,9 +131,13 @@ public class ProductServiceImpl implements ProductService {
             product.setSpec(productInfo.getSpec());
         }
         String newkind = productInfo.getKind();
-        if ((product.getStandard() == Constant.NO) && !StringUtils.isEmpty(newkind)) {
-            product.setKind(newkind);
-            product.setTitle(newkind);
+        if (!StringUtils.isEmpty(newkind)) {
+            if (Constant.YES == product.getStandard()) {
+                product.setTitle(newkind);
+            } else {
+                product.setKind(newkind);
+                product.setTitle(newkind);
+            }
         }
         return productDao.save(product);
     }
@@ -154,16 +175,11 @@ public class ProductServiceImpl implements ProductService {
                 products.add(prod.convert());
             } else { // 物料库上已经存在的物料,修改
                 Product product = prod.convert();
-                // 如果已存在物料类目不为空,erp上传的类目就不覆盖
+                // 如果已存在物料类目不为空且为标准物料,erp上传的类目就不覆盖kind属性
                 Product existProduct = prodResult.get(0);
-                if (!StringUtils.isEmpty(existProduct.getKind())) {
-                    product.setTitle(existProduct.getKind());
+                if (!StringUtils.isEmpty(existProduct.getKind()) && Constant.YES == existProduct.getStandard()) {
                     product.setKind(existProduct.getKind());
                 }
-                // 如果已存在物料规格不为空,erp上传的规格就不用覆盖
-                if (!StringUtils.isEmpty(existProduct.getSpec())) {
-                    product.setSpec(existProduct.getSpec());
-                }
                 product.setId(existProduct.getId());
                 product.setCode(existProduct.getCode());
                 products.add(product);
@@ -184,16 +200,11 @@ public class ProductServiceImpl implements ProductService {
             return (prod.convert());
         } else { // 物料库上已经存在的物料,修改
             Product product = prod.convert();
-            // 如果已存在物料类目不为空,erp上传的类目就不覆盖
+            // 如果已存在物料类目不为空且为标准物料,erp上传的类目就不覆盖kind属性
             Product existProduct = prodResult.get(0);
-            if (!StringUtils.isEmpty(existProduct.getKind())) {
-                product.setTitle(existProduct.getKind());
+            if (!StringUtils.isEmpty(existProduct.getKind()) && Constant.YES == existProduct.getStandard()) {
                 product.setKind(existProduct.getKind());
             }
-            // 如果已存在物料规格不为空,erp上传的规格就不用覆盖
-            if (!StringUtils.isEmpty(existProduct.getSpec())) {
-                product.setSpec(existProduct.getSpec());
-            }
             product.setId(prodResult.get(0).getId());
             product.setCode(prodResult.get(0).getCode());
             return product;
@@ -295,7 +306,7 @@ public class ProductServiceImpl implements ProductService {
     public List<Product> updateB2bProdInfo(List<Product> productInfo) {
         List<Product> saveList = new ArrayList<>();
         for (Product product : productInfo) {
-            List<Product> products = productDao.findByEnUUAndCode(product.getEnUU(),product.getCode());
+            List<Product> products = productDao.findByEnUUAndCode(product.getEnUU(), product.getCode());
             if (!CollectionUtils.isEmpty(products) && null == product.getId()) {
                 Product existedProd = products.get(0);
                 existedProd.setTitle(product.getTitle());
@@ -303,9 +314,9 @@ public class ProductServiceImpl implements ProductService {
                 if (!StringUtils.isEmpty(product.getSpec())) {
                     existedProd.setSpec(product.getSpec());
                 }
-                if (!StringUtils.isEmpty(product.getTitle())) {
+                // 如果物料已存在,新上传物料存在类目且原物料为非标,则更新kind属性
+                if (!StringUtils.isEmpty(product.getTitle()) && Constant.NO == existedProd.getStandard()) {
                     existedProd.setKind(product.getTitle());
-                    existedProd.setTitle(product.getTitle());
                 }
                 existedProd.setCmpCode(product.getCmpCode());
                 existedProd.setUnit(product.getUnit());
@@ -741,15 +752,12 @@ public class ProductServiceImpl implements ProductService {
                 newList.add(product);
             } else {
                 Product existProduct = productDao.findOne(product.getId());
-                // 如果物料已存在,且新上传物料存在类目、规格信息时,更新已存在物料字段
-                if (product != null) {
-                    if (StringUtils.isEmpty(product.getTitle()) && !StringUtils.isEmpty(existProduct.getKind())) {
-                        product.setTitle(existProduct.getKind());
-                        product.setTitle(existProduct.getKind());
-                    }
-
-                    if (StringUtils.isEmpty(product.getSpec()) && !StringUtils.isEmpty(existProduct.getSpec())) {
-                        product.setSpec(existProduct.getSpec());
+                // 如果物料已存在并为标准物料时,kind属性不更新
+                if (existProduct != null) {
+                    if (StringUtils.isEmpty(product.getTitle())) {
+                        if (Constant.YES == existProduct.getStandard()) {
+                            product.setKind(existProduct.getKind());
+                        }
                     }
                     updateList.add(product);
                     ids.add(product.getId());
@@ -976,7 +984,6 @@ public class ProductServiceImpl implements ProductService {
         product.setKind(component.getKind().getNameCn());
         product.setKindEn(component.getKind().getNameEn());
         product.setKindId(component.getKindid());
-        product.setTitle(component.getKind().getNameCn());
         product.setStandard(ProductConstant.STANDARD);
     }
 
@@ -1099,4 +1106,85 @@ public class ProductServiceImpl implements ProductService {
             productUsersDao.delete(deleteList);
         }
     }
+
+    @Override
+    public ResultMap reuploadProduct(List<Map<String, Object>> miss) {
+        if (!CollectionUtils.isEmpty(miss)) {
+            List<Long> productIds = new ArrayList<>();
+            for (Map<String, Object> missProduct : miss) {
+                try {
+                    List<Product> products = productDao.findByEnUUAndCode(Long.valueOf(missProduct.get("enuu").toString()), missProduct.get("code").toString());
+                    if (CollectionUtils.isNotEmpty(products)) {
+                        for (Product product : products) {
+                            Map<String, Object> dataMap = convertToInsertProduct(product);
+                            try {
+                                syncMessageDao.callSyncEnqueneMessage(dataMap.get("tableName").toString(), dataMap.get("methodType").toString(), dataMap.get("dataKey").toString(), dataMap.get("data").toString(), Integer.valueOf(dataMap.get("priority").toString()));
+                                productIds.add(product.getId());
+                            } catch (Exception e) {
+
+                            }
+
+                        }
+                    }
+                } catch (Exception e) {
+                    continue;
+                }
+            }
+            return ResultMap.success(productIds);
+        }
+        return new ResultMap(CodeType.NO_INFO, "无有效信息");
+    }
+
+    /**
+     * 返回需要拼装的数据
+     * @param product 物料信息
+     * @return
+     */
+    private Map<String, Object> convertToInsertProduct(Product product) {
+        Map<String, Object> map = new HashedMap();
+        map.put("tableName", PRODUCT_TABLE_NAME);
+        map.put("methodType", METHOD_TYPE_INSERT);
+        map.put("priority", PRIORITY);
+
+        // 配置dataKey
+        StringBuffer sb = new StringBuffer(PR_ID);
+        sb.insert(9, product.getId());
+        map.put("dataKey", sb.toString());
+
+        // 配置data
+        product.setMatchResults(null);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String json = JSON.toJSONString(product);
+
+        Field [] fields = product.getClass().getDeclaredFields();
+        for (Field field : fields) {
+            Column column = field.getAnnotation(Column.class);
+            if (column != null && !StringUtils.isEmpty(column.name())) {
+                json = json.replace(field.getName(), column.name());
+                // 处理date类型数据
+                if (field.getType().equals(Date.class) && json.indexOf(column.name()) > -1) {
+                    String value = json.substring(json.indexOf(column.name()) + column.name().length(), ordinalIndexOf(json, "\"", json.indexOf(column.name()), 2));
+                    json = json.replace(value, "\":\"" + sdf.format(Long.valueOf(value.replaceAll("\"", "").replace(":","").replace(",", ""))) + "\",");
+                }
+            }
+        }
+
+        map.put("data", json);
+        return map;
+    }
+
+    /**
+     * 获取字符串在源字符串第几次出现的位置
+     * @param str 源字符串
+     * @param substr 判断字符串
+     * @param start 起始位置
+     * @param n 第几次出现
+     * @return
+     */
+    public int ordinalIndexOf(String str, String substr, int start, int n) {
+        int pos = str.indexOf(substr, start);
+        while (--n > 0 && pos != -1)
+            pos = str.indexOf(substr, pos + 1);
+        return pos;
+    }
 }

+ 99 - 0
src/main/java/com/uas/ps/support/CodeType.java

@@ -0,0 +1,99 @@
+package com.uas.ps.support;
+
+/**
+ * 响应码
+ *
+ * history:
+ * Created by huxz on 2017-3-29 16:30:50
+ */
+public enum CodeType {
+
+	/**
+	 * 操作成功
+	 */
+	OK(1, "SUCCESS"),
+	/**
+	 * 参数信息缺失
+	 */
+	NO_INFO(2, "NO_INFO"),
+	/**
+	 * 操作实体信息不全
+	 */
+	NOT_COMPLETE_INFO(3, "NOT_COMPLETE_INFO"),
+	/**
+	 * 操作实体已存在
+	 */
+	SAVED(4, "SAVED"),
+	/**
+	 * 非法状态
+	 */
+	ERROR_STATE(5, "ERROR_STATE"),
+	/**
+	 * 操作不允许
+	 */
+	NOT_PERMIT(6, "NOT_PERMIT"),
+	/**
+	 * 操作实体不存在
+	 */
+	NOT_EXiST(7, "NOT_EXiST"),
+	/**
+	 * 参数异常,不在取值范围之内等原因
+	 */
+	PARAMETER_ERROR(8, "PARAMETER_ERROR"),
+	/**
+	 * 系统的基础参数不存在
+	 */
+	SYSTEM_NOT_EXIST(9, "SYSTEM_NOT_EXIST"),
+
+	/**
+	 * 系统异常
+	 */
+	SYSTEM_ERROR(10, "SYSTEM_ERROR"),
+
+	/**
+	 * 信息不一致
+	 */
+	INFO_UPDATE(11, "信息不一致"),
+
+	/**
+	 * 超时请求
+	 */
+	TIME_OUT(12, "TIME_OUT"),
+
+	/**
+	 * 无操作权限
+	 */
+	NO_AUTHORITY(13, "NO_AUTHORITY"),
+
+	/**
+	 * 信息已修改
+	 */
+	INFO_MODIFY(14, "INFO_MODIFY"),
+
+	/**
+	 * 信息未修改
+	 */
+	INFO_NO_MODIFY(15, "INFO_NO_MODIFY");
+
+	private int code;
+
+	private String message;
+
+	CodeType(int code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+
+	public int code() {
+		return this.code;
+	}
+
+	public String message() {
+		return this.message;
+	}
+
+	@Override
+	public String toString() {
+		return Integer.toString(code);
+	}
+}

+ 93 - 0
src/main/java/com/uas/ps/support/ResultMap.java

@@ -0,0 +1,93 @@
+package com.uas.ps.support;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+/**
+ * 请求结果集
+ * Created by wangyc on 2018/7/3.
+ *
+ * @version 2018/7/3 11:37 wangyc
+ */
+@JsonInclude(JsonInclude.Include.NON_EMPTY)
+public class ResultMap implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer code;
+
+    private boolean success;
+
+    private String message;
+
+    private Object data;
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public ResultMap(int status, String message) {
+        if (CodeType.OK.code() == status) {
+            this.success = true;
+        } else {
+            this.success = false;
+        }
+        this.code = status;
+        this.message = message;
+    }
+
+    public ResultMap(CodeType status, String message) {
+        if (CodeType.OK.code() == status.code()) {
+            this.success = true;
+        } else {
+            this.success = false;
+        }
+        this.message = message;
+        this.code = status.code();
+    }
+
+    public ResultMap(int status, String message, Object data) {
+        if (CodeType.OK.code() == status) {
+            this.success = true;
+        } else {
+            this.success = false;
+        }
+        this.code = status;
+        this.message = message;
+        this.data = data;
+    }
+
+    public static ResultMap success(Object data) {
+        ResultMap result = new ResultMap(CodeType.OK.code(), null);
+        result.data = data;
+        return result;
+    }
+}