Преглед изворни кода

新增公共服务轮询接口

hejq пре 8 година
родитељ
комит
84f689aa33

+ 68 - 0
src/main/java/com/uas/erp/schedular/ps/domain/Attach.java

@@ -0,0 +1,68 @@
+package com.uas.erp.schedular.ps.domain;
+
+import java.io.Serializable;
+
+/**
+ * 附件信息
+ * 
+ * @author suntg
+ * 
+ */
+public class Attach implements Serializable {
+
+	public static final String DOWN_FILE_ACTION = "/common/downloadbyId.action?id=";
+
+	/**
+	 * Default serialVersionUID
+	 */
+	private static final long serialVersionUID = 1L;
+	/**
+	 * ID
+	 */
+	private Long fp_id;
+	/**
+	 * 附件名称
+	 */
+	private String fp_name;
+	/**
+	 * 附件Url
+	 */
+	private String fp_url;
+	/**
+	 * 附件大小
+	 */
+	private Long fp_size;
+
+	public Long getFp_id() {
+		return fp_id;
+	}
+
+	public void setFp_id(Long fp_id) {
+		this.fp_id = fp_id;
+	}
+
+	public String getFp_name() {
+		return fp_name;
+	}
+
+	public void setFp_name(String fp_name) {
+		this.fp_name = fp_name;
+	}
+
+	public String getFp_url() {
+		return fp_url;
+	}
+
+	public void setFp_url(String fp_url) {
+		this.fp_url = fp_url;
+	}
+
+	public Long getFp_size() {
+		return fp_size;
+	}
+
+	public void setFp_size(Long fp_size) {
+		this.fp_size = fp_size;
+	}
+
+}

+ 88 - 0
src/main/java/com/uas/erp/schedular/ps/domain/BatchInProduct.java

@@ -0,0 +1,88 @@
+package com.uas.erp.schedular.ps.domain;
+
+/**
+ * 公共询价物料信息
+ *
+ * @author hejq
+ * @date 2018-01-17 14:30
+ */
+public class BatchInProduct {
+
+    /**
+     * 明细id
+     */
+    private Long bip_id;
+
+    /**
+     * 主表id
+     */
+    private Long bip_biid;
+
+    /**
+     * 序号
+     */
+    private Short bip_detno;
+
+    /**
+     * 物料编号
+     */
+    private String bip_prodcode;
+
+    /**
+     * 备注
+     */
+    private String bip_remark;
+
+    /**
+     * 币别
+     */
+    private String bip_currency;
+
+    public Long getBip_id() {
+        return bip_id;
+    }
+
+    public void setBip_id(Long bip_id) {
+        this.bip_id = bip_id;
+    }
+
+    public Long getBip_biid() {
+        return bip_biid;
+    }
+
+    public void setBip_biid(Long bip_biid) {
+        this.bip_biid = bip_biid;
+    }
+
+    public Short getBip_detno() {
+        return bip_detno;
+    }
+
+    public void setBip_detno(Short bip_detno) {
+        this.bip_detno = bip_detno;
+    }
+
+    public String getBip_prodcode() {
+        return bip_prodcode;
+    }
+
+    public void setBip_prodcode(String bip_prodcode) {
+        this.bip_prodcode = bip_prodcode;
+    }
+
+    public String getBip_remark() {
+        return bip_remark;
+    }
+
+    public void setBip_remark(String bip_remark) {
+        this.bip_remark = bip_remark;
+    }
+
+    public String getBip_currency() {
+        return bip_currency;
+    }
+
+    public void setBip_currency(String bip_currency) {
+        this.bip_currency = bip_currency;
+    }
+}

+ 228 - 0
src/main/java/com/uas/erp/schedular/ps/domain/BatchInquiry.java

@@ -0,0 +1,228 @@
+package com.uas.erp.schedular.ps.domain;
+
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 公共询价信息
+ * 
+ * @author hejq
+ * @date 2018-01-17 14:31
+ */
+public class BatchInquiry extends KeyEntity {
+
+    /**
+     * erp id
+     */
+    private Long bi_id;
+
+    /**
+     * 询价单号
+     */
+    private String bi_code;
+
+    /**
+     * 时间
+     */
+    private Date bi_date;
+
+    /**
+     * 询价类型
+     */
+    private String bi_kind;
+
+    /**
+     * 环保需求
+     */
+    private String bi_environment;
+
+    /**
+     * 使用范围
+     */
+    private String bi_purpose;
+
+    /**
+     * 价格类型
+     */
+    private String bi_pricekind;
+
+    /**
+     * 录入人
+     */
+    private String bi_recorder;
+
+    /**
+     * 录入人uu
+     */
+    private Long bi_recorduu;
+
+    /**
+     * 录入时间
+     */
+    private String bi_recorddate;
+
+    /**
+     * 报价截止日期
+     */
+    private Date bi_enddate;
+
+    /**
+     * 备注
+     */
+    private String bi_remark;
+
+    /**
+     * 价格种类
+     */
+    private String bi_pricetype;
+
+    /**
+     * 询价物料
+     */
+    private List<BatchInProduct> inProducts;
+
+    /**
+     * 附件
+     */
+    private String in_attach;
+
+    /**
+     *  所有的附件信息
+     */
+    private List<Attach> attaches;
+
+    public Long getBi_id() {
+        return bi_id;
+    }
+
+    public void setBi_id(Long bi_id) {
+        this.bi_id = bi_id;
+    }
+
+    public String getBi_code() {
+        return bi_code;
+    }
+
+    public void setBi_code(String bi_code) {
+        this.bi_code = bi_code;
+    }
+
+    public Date getBi_date() {
+        return bi_date;
+    }
+
+    public void setBi_date(Date bi_date) {
+        this.bi_date = bi_date;
+    }
+
+    public String getBi_kind() {
+        return bi_kind;
+    }
+
+    public void setBi_kind(String bi_kind) {
+        this.bi_kind = bi_kind;
+    }
+
+    public String getBi_environment() {
+        return bi_environment;
+    }
+
+    public void setBi_environment(String bi_environment) {
+        this.bi_environment = bi_environment;
+    }
+
+    public String getBi_purpose() {
+        return bi_purpose;
+    }
+
+    public void setBi_purpose(String bi_purpose) {
+        this.bi_purpose = bi_purpose;
+    }
+
+    public String getBi_pricekind() {
+        return bi_pricekind;
+    }
+
+    public void setBi_pricekind(String bi_pricekind) {
+        this.bi_pricekind = bi_pricekind;
+    }
+
+    public String getBi_recorder() {
+        return bi_recorder;
+    }
+
+    public void setBi_recorder(String bi_recorder) {
+        this.bi_recorder = bi_recorder;
+    }
+
+    public Long getBi_recorduu() {
+        return bi_recorduu;
+    }
+
+    public void setBi_recorduu(Long bi_recorduu) {
+        this.bi_recorduu = bi_recorduu;
+    }
+
+    public String getBi_recorddate() {
+        return bi_recorddate;
+    }
+
+    public void setBi_recorddate(String bi_recorddate) {
+        this.bi_recorddate = bi_recorddate;
+    }
+
+    public Date getBi_enddate() {
+        return bi_enddate;
+    }
+
+    public void setBi_enddate(Date bi_enddate) {
+        this.bi_enddate = bi_enddate;
+    }
+
+    public String getBi_remark() {
+        return bi_remark;
+    }
+
+    public void setBi_remark(String bi_remark) {
+        this.bi_remark = bi_remark;
+    }
+
+    public String getBi_pricetype() {
+        return bi_pricetype;
+    }
+
+    public void setBi_pricetype(String bi_pricetype) {
+        this.bi_pricetype = bi_pricetype;
+    }
+
+    public List<BatchInProduct> getInProducts() {
+        return inProducts;
+    }
+
+    public void setInProducts(List<BatchInProduct> inProducts) {
+        this.inProducts = inProducts;
+    }
+
+    public String getIn_attach() {
+        return in_attach;
+    }
+
+    public void setIn_attach(String in_attach) {
+        this.in_attach = in_attach;
+    }
+
+    public List<Attach> getAttaches() {
+        return attaches;
+    }
+
+    public void setAttaches(List<Attach> attaches) {
+        this.attaches = attaches;
+    }
+
+    @Override
+    public Object getKey() {
+        return bi_id;
+    }
+}

+ 49 - 0
src/main/java/com/uas/erp/schedular/ps/domain/Enterprise.java

@@ -0,0 +1,49 @@
+package com.uas.erp.schedular.ps.domain;
+
+/**
+ * 企业信息
+ *
+ * Created by hejq on 2018-01-19.
+ */
+public class Enterprise {
+
+    /**
+     * 企业地址
+     */
+    private String en_address;
+
+    /**
+     * 企业UU
+     */
+    private Long en_uu;
+
+    /**
+     * 企业名称
+     */
+    private String en_name;
+
+    public String getEn_address() {
+        return en_address;
+    }
+
+    public void setEn_address(String en_address) {
+        this.en_address = en_address;
+    }
+
+    public Long getEn_uu() {
+        return en_uu;
+    }
+
+    public void setEn_uu(Long en_uu) {
+        this.en_uu = en_uu;
+    }
+
+    public String getEn_name() {
+        return en_name;
+    }
+
+    public void setEn_name(String en_name) {
+        this.en_name = en_name;
+    }
+}
+

+ 181 - 0
src/main/java/com/uas/erp/schedular/ps/domain/Prod.java

@@ -0,0 +1,181 @@
+package com.uas.erp.schedular.ps.domain;
+
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+
+/**
+ * ERP系统的产品
+ * 
+ * @author yingp
+ * 
+ */
+public class Prod extends KeyEntity{
+
+	private Long pr_id;
+	private String pr_code;
+	private String pr_detail;
+	private String pr_spec;
+	private String pr_unit;
+	private Float pr_zxbzs;
+	private Float pr_zxdhl;
+	private Float pr_leadtime;
+	private Float pr_ltinstock;//备料提前期,天数
+	private String pr_brand;
+	private String pr_orispeccode;// 原厂型号
+	private String pr_uuid; // 标准料号
+	private String pr_status; // 状态: ‘已审核’->有效;‘已禁用’->失效
+	private Short pr_issale; // 可销售
+	private Short pr_ispurchase; // 可采购
+	private Short pr_isshow; // 开放采购物料
+	private Short pr_ispubsale; // 开发销售物料
+	private Long b2b_id;//平台id
+
+	public Long getPr_id() {
+		return pr_id;
+	}
+
+	public void setPr_id(Long pr_id) {
+		this.pr_id = pr_id;
+	}
+
+	public String getPr_code() {
+		return pr_code;
+	}
+
+	public void setPr_code(String pr_code) {
+		this.pr_code = pr_code;
+	}
+
+	public String getPr_detail() {
+		return pr_detail;
+	}
+
+	public void setPr_detail(String pr_detail) {
+		this.pr_detail = pr_detail;
+	}
+
+	public String getPr_spec() {
+		return pr_spec;
+	}
+
+	public void setPr_spec(String pr_spec) {
+		this.pr_spec = pr_spec;
+	}
+
+	public String getPr_unit() {
+		return pr_unit;
+	}
+
+	public void setPr_unit(String pr_unit) {
+		this.pr_unit = pr_unit;
+	}
+
+	public Float getPr_zxbzs() {
+		return pr_zxbzs;
+	}
+
+	public void setPr_zxbzs(Float pr_zxbzs) {
+		this.pr_zxbzs = pr_zxbzs;
+	}
+
+	public Float getPr_zxdhl() {
+		return pr_zxdhl;
+	}
+
+	public void setPr_zxdhl(Float pr_zxdhl) {
+		this.pr_zxdhl = pr_zxdhl;
+	}
+
+	public Float getPr_leadtime() {
+		return pr_leadtime;
+	}
+
+	public void setPr_leadtime(Float pr_leadtime) {
+		this.pr_leadtime = pr_leadtime;
+	}
+
+	public Float getPr_ltinstock() {
+		return pr_ltinstock;
+	}
+
+	public void setPr_ltinstock(Float pr_ltinstock) {
+		this.pr_ltinstock = pr_ltinstock;
+	}
+
+	@Override
+	public Object getKey() {
+		return this.pr_id;
+	}
+
+	public String getPr_brand() {
+		return pr_brand;
+	}
+
+	public void setPr_brand(String pr_brand) {
+		this.pr_brand = pr_brand;
+	}
+
+	public String getPr_orispeccode() {
+		return pr_orispeccode;
+	}
+
+	public void setPr_orispeccode(String pr_orispeccode) {
+		this.pr_orispeccode = pr_orispeccode;
+	}
+
+	public String getPr_uuid() {
+		return pr_uuid;
+	}
+
+	public void setPr_uuid(String pr_uuid) {
+		this.pr_uuid = pr_uuid;
+	}
+
+	public String getPr_status() {
+		return pr_status;
+	}
+
+	public void setPr_status(String pr_status) {
+		this.pr_status = pr_status;
+	}
+
+	public Short getPr_issale() {
+		return pr_issale;
+	}
+
+	public void setPr_issale(Short pr_issale) {
+		this.pr_issale = pr_issale;
+	}
+
+	public Short getPr_ispurchase() {
+		return pr_ispurchase;
+	}
+
+	public void setPr_ispurchase(Short pr_ispurchase) {
+		this.pr_ispurchase = pr_ispurchase;
+	}
+
+	public Short getPr_isshow() {
+		return pr_isshow;
+	}
+
+	public void setPr_isshow(Short pr_isshow) {
+		this.pr_isshow = pr_isshow;
+	}
+
+	public Short getPr_ispubsale() {
+		return pr_ispubsale;
+	}
+
+	public void setPr_ispubsale(Short pr_ispubsale) {
+		this.pr_ispubsale = pr_ispubsale;
+	}
+
+	public Long getB2b_id() {
+		return b2b_id;
+	}
+
+	public void setB2b_id(Long b2b_id) {
+		this.b2b_id = b2b_id;
+	}
+
+}

+ 327 - 0
src/main/java/com/uas/erp/schedular/ps/task/AbstractTask.java

@@ -0,0 +1,327 @@
+package com.uas.erp.schedular.ps.task;
+
+import com.alibaba.fastjson.JSON;
+import com.uas.api.crypto.util.FlexJsonUtils;
+import com.uas.erp.schedular.b2b.domain.KeyEntity;
+import com.uas.erp.schedular.core.Constant;
+import com.uas.erp.schedular.database.RestJdbcTemplate;
+import com.uas.erp.schedular.entity.Master;
+import com.uas.erp.schedular.ps.domain.Attach;
+import com.uas.erp.schedular.ps.domain.Enterprise;
+import com.uas.erp.schedular.ps.domain.Prod;
+import com.uas.erp.schedular.service.SettingService;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import com.uas.erp.schedular.util.DateUtil;
+import com.uas.erp.schedular.util.HmacUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 公共服务的轮询配置
+ * 
+ * @author hejq
+ * @date 2018-01-17 14:25
+ */
+public class AbstractTask {
+
+    // 数据传输单次大小限制
+    protected static final int DATA_SIZE_LIMIT = 500;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    protected RestJdbcTemplate jdbcTemplate;
+
+    @Autowired
+    protected SettingService settingService;
+
+    protected Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    /**
+     * 按账套环境,使用不同接口地址
+     * @return
+     */
+    private String getApiDomain() {
+        String key = "test".equals(ContextHolder.getMaster().getMa_env()) ? "api.ps.test.url" : "api.ps.url";
+        return settingService.getValue(key);
+    }
+
+    /**
+     * UAS系统外网地址
+     * @return
+     */
+    private String getUASUrl() {
+        return settingService.getValue("api.uas.outer.url");
+    }
+
+    /**
+     * URI加身份签名
+     * @param url
+     * @param vars
+     * @return
+     */
+    private String getURI(String url, Object... vars) {
+        Master master = ContextHolder.getMaster();
+        if (null == master.getMa_uu() || StringUtils.isEmpty(master.getMa_accesssecret())) {
+            throw new RuntimeException("未设置企业UU和私钥");
+        }
+        StringBuffer accessUrl = new StringBuffer(url);
+        accessUrl.append(url.contains("?") ? "&" : "?");
+        // 身份ID
+        accessUrl.append("access_id=").append(master.getMa_uu());
+        // 时间戳
+        accessUrl.append("&_timestamp=").append(System.currentTimeMillis());
+        URI uri = restTemplate.getUriTemplateHandler().expand(getApiDomain() + accessUrl.toString(), vars);
+        url = uri.toString();
+        // 签名
+        return url + "&_signature=" + HmacUtils.encode(url, master.getMa_accesssecret());
+    }
+
+    protected <T> T getForObject(String url, Class<T> objectClass, Object... vars) {
+        return restTemplate.getForObject(getURI(url, vars), objectClass);
+    }
+
+    protected <T> List<T> getForList(String url, Class<T> objectClass, Object... vars) {
+        String resultStr = restTemplate.getForObject(getURI(url, vars), String.class);
+        return JSON.parseArray(resultStr, objectClass);
+    }
+
+    /**
+     * b2b当前版本的接口只支持以form-data方式提交,requestBody方式暂不支持
+     * @param url
+     * @param vars
+     */
+    protected void post(String url, MultiValueMap<String, String> vars) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(vars, headers);
+        restTemplate.postForLocation(getURI(url), request);
+    }
+
+    protected ResponseEntity postForEntity(String url, MultiValueMap<String, String> vars) {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(vars, headers);
+        return restTemplate.postForEntity(getURI(url), request, String.class);
+    }
+
+    protected <T> List<T> postForList(String url, Class<T> objectClass, MultiValueMap<String, String> vars) {
+        ResponseEntity<String> resultEntity = postForEntity(url, vars);
+        return JSON.parseArray(resultEntity.getBody(), objectClass);
+    }
+
+    /**
+     * 封装成平台接口数据格式
+     * @param data
+     * @return
+     */
+    protected static MultiValueMap<String, String> dataWrap(Object data) {
+        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
+        String dataStr = null;
+        Class<?> cls = data.getClass();
+        if (cls.isAssignableFrom(String.class) || cls.isAssignableFrom(Number.class) ||
+                cls.isAssignableFrom(Character.class)) {
+            dataStr = data.toString();
+        } else {
+            dataStr = JSON.toJSONString(data);
+        }
+        try {
+            dataStr = URLEncoder.encode(dataStr, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+
+        }
+        map.set("data", dataStr);
+        return map;
+    }
+
+    /**
+     * 数据上传工具,封装了处理前、后置、错误处理方法
+     * @param <T>
+     */
+    protected abstract class AbstractHandler<T> {
+
+        private List<T> data;
+
+        public AbstractHandler(List<T> data) {
+            this.data = data;
+        }
+
+        /**
+         * onHandler方法前执行
+         */
+        protected void onBefore(){
+
+        }
+
+        protected abstract ResponseEntity onHandler(List<T> data);
+
+        /**
+         * onHandler方法执行成功后执行
+         */
+        protected void onSuccess(){
+
+        }
+
+        /**
+         * onHandler方法执行失败后执行
+         */
+        protected void onError(String message){
+            throw new RuntimeException(message);
+        }
+
+        /**
+         * 所有方法执行完成后执行
+         */
+        protected void onAfter(){
+
+        }
+
+        public void run() {
+            String errMsg = null;
+            onBefore();
+            try {
+                ResponseEntity response = onHandler(data);
+                if (!response.getStatusCode().is2xxSuccessful()) {
+                    errMsg = String.valueOf(response.getBody());
+                }
+            } catch (Exception e) {
+                errMsg = e.getMessage();
+            }
+            try {
+                if (null == errMsg) {
+                    onSuccess();
+                } else {
+                    onError(errMsg);
+                }
+            } finally {
+                onAfter();
+            }
+        }
+    }
+
+    /**
+     * POST方式处理工具
+     * @param <T>
+     */
+    protected class AbstractPostHandler<T> extends AbstractHandler<T> {
+        private String postUri;
+
+        public AbstractPostHandler(String postUri, List<T> data) {
+            super(data);
+            this.postUri = postUri;
+        }
+
+        @Override
+        protected ResponseEntity onHandler(List<T> data) {
+            return postForEntity(postUri, dataWrap(data));
+        }
+    }
+
+    /**
+     * 基于状态控制的处理工具
+     * @param <T>
+     */
+    protected abstract class AbstractStatusBasedHandler<T extends KeyEntity> extends AbstractPostHandler<T> {
+
+        private String idStr;
+        private String tableName;
+        private String idColumn;
+        private String statusColumn;
+
+        public AbstractStatusBasedHandler(String tableName, String idColumn, String statusColumn, String postUri, List<T> data) {
+            super(postUri, data);
+            this.idStr = CollectionUtil.getKeyString(data);
+            this.tableName = tableName;
+            this.idColumn = idColumn;
+            this.statusColumn = statusColumn;
+        }
+
+        @Override
+        protected void onBefore() {
+            jdbcTemplate.execute(String.format("update %s set %s='上传中' where %s in (%s)", tableName, statusColumn, idColumn, idStr));
+        }
+
+        @Override
+        protected void onSuccess() {
+            jdbcTemplate.execute(String.format("update %s set %s='已上传' where %s in (%s)", tableName, statusColumn, idColumn, idStr));
+        }
+
+        @Override
+        protected void onError(String message) {
+            jdbcTemplate.execute(String.format("update %s set %s='待上传' where %s in (%s) and %s='上传中'", tableName, statusColumn, idColumn, idStr, statusColumn));
+            super.onError(message);
+        }
+    }
+
+    /**
+     * 基于状态控制的处理工具
+     * @param <T>
+     */
+    protected class StatusBasedHandler<T extends KeyEntity> extends AbstractStatusBasedHandler<T> {
+
+        public StatusBasedHandler(String tableName, String idColumn, String statusColumn, String postUri, List<T> data) {
+            super(tableName, idColumn, statusColumn, postUri, data);
+        }
+    }
+
+    /**
+     * 处理物料上传的工具
+     */
+    protected final class ProductHandler extends StatusBasedHandler<Prod>{
+        public ProductHandler(List<Prod> data, Enterprise enterprise) {
+            super("product", "pr_id", "PR_SENDSTATUS", "/erp/product?enuu=" + enterprise.getEn_uu(), data);
+        }
+    }
+
+    /**
+     * 查找附件
+     * @param attachIds 附件ID
+     * @return
+     */
+    protected List<Attach> getAttachs(String[] attachIds) {
+        String erpUrl = getUASUrl();
+        List<Attach> attaches = jdbcTemplate.queryForBeanList("select fp_id, fp_size, fp_name from filepath where fp_id in ("
+                + StringUtils.arrayToDelimitedString(attachIds, ",") + ")", Attach.class);
+        if (!CollectionUtils.isEmpty(attaches)) {
+            for (Attach attach : attaches) {
+                attach.setFp_url(erpUrl + Attach.DOWN_FILE_ACTION + attach.getFp_id());
+            }
+        }
+        return attaches;
+    }
+
+    /**
+     * 创建消息
+     *
+     * @param caller
+     * @param sourceIds
+     * @param type
+     */
+    protected void createMessage(String caller, String sourceIds, String type) {
+        Integer mid = jdbcTemplate.getInt("select max(mm_id) from MESSAGEMODEL left join MESSAGEROLE on mm_id=mr_mmid where MR_ISUSED=-1 AND MM_ISUSED=-1 and mm_caller=? and MM_OPERATE='b2b' AND MM_ACTION=?",
+                caller, type);
+        if (null != mid) {
+            jdbcTemplate.callForString("{call SP_CREATEINFO(?,'ADMIN',?,?,?)}",
+                    mid, sourceIds, DateUtil.parseDateToOracleString(Constant.YMD_HMS, new Date()));
+        }
+    }
+
+}

+ 250 - 0
src/main/java/com/uas/erp/schedular/ps/task/InquiryTask.java

@@ -0,0 +1,250 @@
+package com.uas.erp.schedular.ps.task;
+
+import com.uas.erp.schedular.b2b.domain.Inquiry;
+import com.uas.erp.schedular.b2b.domain.InquiryDecide;
+import com.uas.erp.schedular.b2b.domain.InquiryDetail;
+import com.uas.erp.schedular.b2b.domain.RemoteFile;
+import com.uas.erp.schedular.database.SqlTemplate;
+import com.uas.erp.schedular.ps.domain.BatchInProduct;
+import com.uas.erp.schedular.ps.domain.BatchInquiry;
+import com.uas.erp.schedular.ps.domain.Enterprise;
+import com.uas.erp.schedular.ps.domain.Prod;
+import com.uas.erp.schedular.task.support.Method;
+import com.uas.erp.schedular.task.support.TaskMapping;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 轮询上传数据到公共服务平台
+ *
+ * Created by hejq on 2018-01-17.
+ */
+public class InquiryTask extends AbstractTask {
+
+    /**
+     * 上传物料资料
+     */
+    private void uploadProduct(Enterprise enterprise) {
+        final List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand from product p left join batchinprod b on p.pr_code = b.bip_prodcode left join batchinquiry i on b.bip_biid = i.bi_id where p.pr_sendstatus = '待上传' and i.bi_sendstatus = '待上传') where rownum <= 500",
+                Prod.class);
+        if (!CollectionUtils.isEmpty(prods)) {
+            new AbstractTask.ProductHandler(prods, enterprise).run();
+            if (prods.size() == DATA_SIZE_LIMIT) {
+                // 递归,直到相关物料全部传完
+                uploadProduct(enterprise);
+            }
+        }
+    }
+
+    /**
+     * 处理物料上传的工具
+     */
+    protected final class ProductHandler extends AbstractTask.StatusBasedHandler<Prod> {
+
+        public ProductHandler(List<Prod> data) {
+            super("product", "pr_id", "PR_SENDSTATUS", "/erp/product", data);
+        }
+    }
+
+    @TaskMapping(title = "上传询价单", fixedDelay = 30000)
+    public void uploadInquiry() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            uploadProduct(enterprise);
+            List<BatchInquiry> inquiries = getInquiryUpload();
+            if (!CollectionUtils.isEmpty(inquiries)) {
+                ContextHolder.setDataSize(inquiries.size());
+                logger.info("inquiries size: " + inquiries.size());
+                logger.info("inquiries keys: " + CollectionUtil.getKeyString(inquiries));
+                String url = "/inquiry/public?enuu=" + enterprise.getEn_uu() + "&address=" + enterprise.getEn_address();
+                new AbstractTask.StatusBasedHandler<BatchInquiry>("batchinquiry", "bi_id", "bi_sendstatus", url, inquiries).run();
+            }
+        }
+    }
+
+    @TaskMapping(title = "从公共服务下载供应商的报价信息", fixedDelay = 60000, method = Method.DOWNLOAD)
+    public void downloadReply() throws Exception{
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<InquiryDetail> details = getForList("/inquiry/public/quotation?enuu=" + enterprise.getEn_uu(), InquiryDetail.class);
+            if (!CollectionUtils.isEmpty(details)) {
+                ContextHolder.setDataSize(details.size());
+                saveInquiryReply(details);
+                // 回执
+                onReplySuccess(details, enterprise);
+                // 发消息
+                createMessageOnReplySuccess(details);
+                // 附件
+                saveInquiryDetailAttach(details);
+            }
+        }
+    }
+
+    /**
+     * 创建消息
+     * @param details
+     */
+    private void createMessageOnReplySuccess(List<InquiryDetail> details) {
+        String savedIdStr = CollectionUtil.getKeyString(details, new CollectionUtil.KeyIterator<InquiryDetail>() {
+            @Override
+            public Object getKey(InquiryDetail obj) {
+                return !"已报价".equals(obj.getId_status()) ? obj.getId_id() : null;
+            }
+        });
+        if (!savedIdStr.isEmpty()) {
+            createMessage("Inquiry", savedIdStr, "save");
+        }
+    }
+
+    /**
+     * 保存供应商的报价信息,存到ERP
+     *
+     * @author hejq
+     * @date 2018-01-10 16:39
+     * @param details 询价明细
+     * @throws Exception
+     */
+    private void saveInquiryReply(List<InquiryDetail> details) throws Exception {
+        Map<String, Object> model = new HashMap<>();
+        model.put("inquiryDetails", details);
+        // 解析sql模板
+        String sql = SqlTemplate.fromXmlFile("database/template/pubInquiryReply.xml", model);
+        jdbcTemplate.execute(sql);
+    }
+
+    /**
+     * 修改平台里面询价单的下载状态
+     *
+     * @author hejq
+     * @date 2018-01-10 16:40
+     * @param details 询价单明细
+     */
+    private void onReplySuccess(List<InquiryDetail> details, Enterprise enterprise) {
+        String idStr = CollectionUtil.getKeyString(details);
+        post("/inquiry/public/reply/back?enuu=" + enterprise.getEn_uu(), dataWrap(idStr));
+    }
+
+    /**
+     * 保存来自平台的公共询价单附件信息
+     *
+     * @author hejq
+     * @date 2018-01-10 16:41
+     * @param details 询价单明细
+     */
+    private void saveInquiryDetailAttach(List<InquiryDetail> details) {
+        List<String> sqls = new ArrayList<String>();
+        String remoteUrl = "B2B://file";
+        for (InquiryDetail detail : details) {
+            if (!CollectionUtils.isEmpty(detail.getFiles())) {
+                StringBuffer attachIds = new StringBuffer();
+                for (RemoteFile file : detail.getFiles()) {
+                    int id = jdbcTemplate.generate("filepath_seq");
+                    sqls.add(file.toSqlString(id, remoteUrl));
+                    attachIds.append(id).append(";");
+                }
+                sqls.add("update inquiryAutoDetail set id_attach='" + attachIds.toString() + "' where id_id=" + detail.getId_id());
+            }
+        }
+        jdbcTemplate.batchExecute(sqls);
+    }
+
+    /**
+     * ERP询价单提交后,同步到平台进行状态更新
+     *
+     * @author hejq
+     * @date 2018-01-10 19:32
+     */
+    @TaskMapping(title = "询价单提交后,上传平台", fixedDelay = 60000)
+    public void uploadCheckInquiry() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Inquiry> inquiries = jdbcTemplate.queryForBeanList("select * from (select in_id,in_code from inquiryAuto where in_checkStatus = '已提交' and in_checkSendStatus='待上传' and nvl(in_class,' ')<>'主动报价' and in_sendStatus='已上传' order by in_id) where rownum < 100", Inquiry.class);
+            if (!CollectionUtils.isEmpty(inquiries)) {
+                ContextHolder.setDataSize(inquiries.size());
+                new StatusBasedHandler<Inquiry>("inquiryAuto", "in_id", "in_checkSendStatus", "/erp/purchase/publicinquiry/checking?enuu=" + enterprise.getEn_uu(), inquiries).run();
+            }
+        }
+    }
+
+    /**
+     * ERP针对卖家报价信息的采纳状态传回平台
+     *
+     * @author hejq
+     * @date 2018-01-10 19:34
+     */
+    @TaskMapping(title = "上传买家对报价信息是否采纳的决策到平台", fixedDelay = 60000)
+    public void uploadInquiryDecide() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<InquiryDecide> replies = jdbcTemplate.queryForBeanList("select id_id,in_code,id_detno,id_isagreed id_agreed from InquiryAutoDetail left join InquiryAuto on id_inid=in_id left join vendor on id_vendcode=ve_code where IN_SENDSTATUS='已上传' and nvl(in_class,' ')<>'主动报价' and ID_SENDSTATUS='待上传' and id_isagreed is not null and ve_uu is not null and nvl(ve_b2benable,0)=1 and rownum < 100 order by in_code,id_detno",
+                    InquiryDecide.class);
+            if (!CollectionUtils.isEmpty(replies)) {
+                ContextHolder.setDataSize(replies.size());
+                post("/inquiry/public/reply/decide?enuu=" + enterprise.getEn_uu(), dataWrap(replies));
+                String idStr = CollectionUtil.getKeyString(replies);
+                logger.info("上传采纳决策到平台,ids: " + idStr);
+                jdbcTemplate.execute("update InquiryAutoDetail set id_sendstatus='已下载' where id_id in (" + idStr + ")");
+            }
+        }
+    }
+
+    /**
+     * ERP单据作废信息传回平台进行操作
+     *
+     * @author hejq
+     * @date 2018-01-10 19:34
+     */
+    @TaskMapping(title = "上传买家对报价信息作废的决策到平台", fixedDelay = 60000)
+    public void uploadInquiryInvalid() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Inquiry> inquiries = jdbcTemplate.queryForBeanList("select * from InquiryAuto left join InquiryAutoDetail on id_inid=in_id left join vendor on id_vendcode=ve_code where in_status = '已作废' and in_sendStatus <> '作废已上传' and nvl(in_class,' ')<>'主动报价'  and ve_uu is not null and nvl(ve_b2benable,0)=1 and rownum <= 100 order by in_code",
+                    Inquiry.class);
+            if (!CollectionUtils.isEmpty(inquiries)) {
+                ContextHolder.setDataSize(inquiries.size());
+                post("/erp/purchase/publicinquiry/invalid?enuu=" + enterprise.getEn_uu(), dataWrap(inquiries));
+                String idStr = CollectionUtil.getKeyString(inquiries);
+                logger.info("公共询价单作废单据,ids: " + idStr);
+                jdbcTemplate.execute("update InquiryAuto set in_sendStatus='作废已上传' where in_id in (" + idStr + ")");
+            }
+        }
+    }
+
+    /**
+     * 获取需要上传的询价单
+     *
+     * @return
+     */
+    private List<BatchInquiry> getInquiryUpload() {
+        List<BatchInquiry> inquiries = jdbcTemplate.queryForBeanList("select bi_id,bi_code,bi_date,bi_kind,bi_environment,bi_purpose,bi_pricekind,bi_recorder,bi_recorddate,bi_enddate,bi_remark,bi_pricetype,bi_recorduu,bi_attach from batchinquiry where bi_sendstatus = '待上传' and bi_status = '已审核' and bi_kind = '公开询价'",
+                BatchInquiry.class);
+        for (BatchInquiry inquiry : inquiries) {
+            // 获取询价单明细
+            List<BatchInProduct> details = jdbcTemplate.queryForBeanList("select * from batchinprod where bip_biid = ?",
+                    BatchInProduct.class, inquiry.getBi_id());
+            inquiry.setInProducts(details);
+            // 附件
+            if (StringUtils.hasText(inquiry.getIn_attach())) {
+                inquiry.setAttaches(getAttachs(inquiry.getIn_attach().split(";")));
+            }
+        }
+        return inquiries;
+    }
+
+    /**
+     * 获取企业信息
+     *
+     * @return
+     */
+    public Enterprise getEnterprise() {
+        Enterprise enterprise = jdbcTemplate.queryForBean("select en_address, en_uu, en_name from enterprise where en_uu is not null", Enterprise.class);
+        return enterprise;
+    }
+}

+ 99 - 0
src/main/java/com/uas/erp/schedular/ps/task/ProductTask.java

@@ -0,0 +1,99 @@
+package com.uas.erp.schedular.ps.task;
+
+import com.uas.erp.schedular.ps.domain.Enterprise;
+import com.uas.erp.schedular.ps.domain.Prod;
+import com.uas.erp.schedular.task.support.Method;
+import com.uas.erp.schedular.task.support.TaskMapping;
+import com.uas.erp.schedular.util.CollectionUtil;
+import com.uas.erp.schedular.util.ContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 公共服务物料上传
+ *
+ * @author hejq
+ * @date 2018-01-19 10:53
+ */
+@Component
+@TaskMapping(title = "物料")
+public class ProductTask extends AbstractTask {
+
+    /**
+     * 默认8到21点间每小时执行一次
+     */
+    @TaskMapping(title = "上传物料", cron = "0 0 8-21 * * *")
+    public void uploadProduct() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Prod> prods = jdbcTemplate.queryForBeanList("select * from (select pr_id,pr_code,pr_detail,pr_spec,pr_unit,pr_zxbzs,pr_zxdhl,pr_leadtime,pr_ltinstock,pr_brand,pr_issale,pr_ispurchase,pr_isshow,pr_ispubsale,pr_uuid,pr_orispeccode from product where  nvl(pr_sendstatus,' ')<>'已上传' and  nvl(pr_status, ' ') = '已审核' order by pr_id) where rownum <= 500",
+                    Prod.class);
+            if (!CollectionUtils.isEmpty(prods)) {
+                ContextHolder.increaseDataSize(prods.size());
+                new StatusBasedHandler<Prod>("product", "pr_id", "PR_SENDSTATUS", "/erp/product/cycleupdate", prods).run();
+                if (prods.size() == DATA_SIZE_LIMIT) {
+                    // 递归,直到没有需要上传的数据
+                    uploadProduct();
+                }
+            }
+        }
+    }
+
+    /**
+     * 默认8到21点间每小时第15分钟执行一次
+     */
+    @TaskMapping(title = "下载更新物料信息", cron = "0 15 8-21 * * *", method = Method.DOWNLOAD)
+    public void downloadProduct() {
+        Enterprise enterprise = getEnterprise();
+        if (null != enterprise) {
+            List<Prod> prods = getForList("/erp/product/backtouas", Prod.class);
+            if (!CollectionUtils.isEmpty(prods)) {
+                ContextHolder.setDataSize(prods.size());
+                saveProdDown(prods);
+                // 回执
+                downloadSuccess(prods);
+            }
+        }
+    }
+
+    /**
+     * 保存更新物料信息
+     *
+     * @param prods
+     */
+    private void saveProdDown(List<Prod> prods) {
+        List<String> sqls = new ArrayList<>();
+        for (Prod prod : prods) {
+            String sql = "update product set pr_uuid = '" + prod.getPr_uuid() + "' where pr_id = " + prod.getPr_id();
+            sqls.add(sql);
+        }
+        jdbcTemplate.batchExecute(sqls);
+    }
+
+    /**
+     * 更新平台的下载状态为已下载
+     * @param prods
+     */
+    private void downloadSuccess(List<Prod> prods) {
+        String idStr = CollectionUtil.getKeyString(prods, new CollectionUtil.KeyIterator<Prod>() {
+            @Override
+            public Object getKey(Prod obj) {
+                return obj.getB2b_id();
+            }
+        });
+        post("/erp/product/refreshDownloadstatus", dataWrap(idStr));
+    }
+
+    /**
+     * 获取企业信息
+     *
+     * @return
+     */
+    public com.uas.erp.schedular.ps.domain.Enterprise getEnterprise() {
+        Enterprise enterprise = jdbcTemplate.queryForBean("select en_address, en_uu, en_name from enterprise where en_uu is not null", com.uas.erp.schedular.ps.domain.Enterprise.class);
+        return enterprise;
+    }
+}

+ 10 - 24
src/main/resources/database/template/pubInquiryReply.xml

@@ -1,39 +1,25 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PLSQL>
     <declare>
-        v_in_id number;
         v_id_id number;
         v_id_detno number;
+        v_qu_count number;
     </declare>
     <body>
         <iterator loop="inquiryDetails" var="detail">
             <block>
-                -- 询价单
-                select max(in_id) into v_in_id from inquiryauto where in_code=${detail.in_code};
-                if v_in_id is null then
-                v_in_id := inquiryauto_seq.nextval;
-                insert into inquiryauto(in_id,in_code,in_date,in_recorddate,in_class,in_enddate,in_kind,in_recorder,in_prodtype,
-                in_pricetype,in_attach,in_cop,in_environment,in_purpose,in_source,in_sendstatus,in_status,in_statuscode)
-                select v_in_id,bi_code,bi_date,bi_recorddate,'公共询价',bi_enddate,bi_pricekind,bi_recorder,bi_kind,bi_pricetype,bi_attach,
-                bi_cop,bi_environment,bi_purpose,'公开询价单','已上传','已审核','AUDITED' from batchinquiry where bi_code=${detail.in_code};
-                end if;
                 -- 明细
-                select max(id_id) into v_id_id from inquiryautodetail where id_inid=v_in_id and id_vendyyzzh=${detail.id_vendyyzzh}
-                and id_prodcode=${detail.id_prodcode};
-                if v_id_id is null then
-                v_id_id := inquiryautodetail_seq.nextval;
-                select nvl(max(id_detno),0) + 1 into v_id_detno from inquiryautodetail where id_inid = v_in_id;
-                insert into inquiryautodetail(id_id,id_inid,id_detno,id_prodid,id_prodcode,id_vendname,id_vendyyzzh,id_currency,id_venduu,id_ptid)
-                select v_id_id,v_in_id,v_id_detno,pr_id,pr_code,${detail.id_vendname},${detail.id_vendyyzzh},${detail.id_currency},
-                ${detail.ve_uu},${detail.b2b_id_id} from product where pr_code=${detail.id_prodcode};
+                -- 判断报价信息是否已存在,公共询价不存在修改报价的情况,不做判断
+                select count(1) into v_qu_count from inquiryAutoDetail where id_incode = ${detail.in_code} and id_vendyyzzh = ${detail.id_vendyyzzh};
+                if v_qu_count = 0 then
+                v_id_id := inquiryAutoDetail_seq.nextval;
+                -- 序号按返回先后顺序插入
+                select nvl(max(id_detno),1) into v_id_detno from  inquiryAutoDetail where id_incode = ${detail.in_code};
+                insert into inquiryautodetail(id_id,id_inid,id_detno,id_prodid,id_prodcode,id_vendname,id_vendyyzzh,id_currency,id_venduu,id_ptid,id_incode )
+                select v_id_id,0,v_id_detno,pr_id,pr_code,${detail.id_vendname},${detail.id_vendyyzzh},${detail.id_currency},
+                ${detail.ve_uu},${detail.b2b_id_id},${detail.in_code} from product where pr_code=${detail.id_prodcode};
                 end if;
-                update inquiryautodetail set id_fromdate=nvl(${detail.id_fromdate}, id_myfromdate),
-                id_todate=nvl(${detail.id_todate}, id_mytodate),id_minbuyqty=${detail.id_minbuyqty},id_minqty=${detail.id_minqty},
-                id_brand=${detail.id_brand},id_vendorprodcode=${detail.id_vendorprodcode},id_leadtime=nvl(${detail.id_leadtime},0),
-                id_vendname=${detail.id_vendname},id_vendyyzzh=${detail.id_vendyyzzh},id_rate=nvl(${detail.id_rate},id_rate),
-                id_ptid=${detail.b2b_id_id} where id_id=v_id_id;
                 -- 分段价格
-                delete from inquiryautodetaildet where idd_idid=v_id_id;
             </block>
             <iterator loop="detail.dets" var="det">
                 insert into inquiryautodetaildet(idd_id,idd_idid,idd_lapqty,idd_price) values (inquiryautodetaildet_SEQ.nextval,v_id_id,