Browse Source

核价项目提交

liusw 7 years ago
commit
3e200eac0b
32 changed files with 3264 additions and 0 deletions
  1. 25 0
      .gitignore
  2. 123 0
      pom.xml
  3. 261 0
      src/main/java/com/uas/ps/pricing/DruidDBConfiguration.java
  4. 12 0
      src/main/java/com/uas/ps/pricing/PsPricingApplication.java
  5. 26 0
      src/main/java/com/uas/ps/pricing/RepositoryConfiguration.java
  6. 24 0
      src/main/java/com/uas/ps/pricing/Test.java
  7. 48 0
      src/main/java/com/uas/ps/pricing/controller/PriceLibraryController.java
  8. 17 0
      src/main/java/com/uas/ps/pricing/dao/BomDao.java
  9. 17 0
      src/main/java/com/uas/ps/pricing/dao/BomDetailDao.java
  10. 55 0
      src/main/java/com/uas/ps/pricing/dao/PriceLibraryDao.java
  11. 10 0
      src/main/java/com/uas/ps/pricing/entity/PriceType.java
  12. 327 0
      src/main/java/com/uas/ps/pricing/model/Bom.java
  13. 296 0
      src/main/java/com/uas/ps/pricing/model/BomDetail.java
  14. 421 0
      src/main/java/com/uas/ps/pricing/model/PriceLibrary.java
  15. 30 0
      src/main/java/com/uas/ps/pricing/service/PriceLibraryService.java
  16. 13 0
      src/main/java/com/uas/ps/pricing/service/PricingService.java
  17. 150 0
      src/main/java/com/uas/ps/pricing/service/impl/PriceLibraryServiceImpl.java
  18. 200 0
      src/main/java/com/uas/ps/pricing/util/DateUtils.java
  19. 46 0
      src/main/java/com/uas/ps/pricing/util/FlexJsonUtils.java
  20. 614 0
      src/main/java/com/uas/ps/pricing/util/HttpUtil.java
  21. 17 0
      src/main/java/com/uas/ps/pricing/util/ICallable.java
  22. 34 0
      src/main/java/com/uas/ps/pricing/util/ICallableAdapter.java
  23. 10 0
      src/main/java/com/uas/ps/pricing/util/IRunnable.java
  24. 20 0
      src/main/java/com/uas/ps/pricing/util/IRunnableAdapter.java
  25. 7 0
      src/main/java/com/uas/ps/pricing/util/Listener.java
  26. 29 0
      src/main/java/com/uas/ps/pricing/util/Listeners.java
  27. 80 0
      src/main/java/com/uas/ps/pricing/util/PathUtils.java
  28. 266 0
      src/main/java/com/uas/ps/pricing/util/ThreadUtils.java
  29. 13 0
      src/main/resources/application.yml
  30. 23 0
      src/main/resources/config/application-cloud.properties
  31. 27 0
      src/main/resources/config/application-dev.properties
  32. 23 0
      src/main/resources/config/application-test.properties

+ 25 - 0
.gitignore

@@ -0,0 +1,25 @@
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/build/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/

+ 123 - 0
pom.xml

@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+	<groupId>com.uas.ps.pricing</groupId>
+	<artifactId>ps-pricing</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>jar</packaging>
+
+	<name>ps-pricing</name>
+	<description>Demo project for Spring Boot</description>
+
+	<parent>
+		<groupId>org.springframework.boot</groupId>
+		<artifactId>spring-boot-starter-parent</artifactId>
+		<version>2.0.1.RELEASE</version>
+		<relativePath/> <!-- lookup parent from repository -->
+	</parent>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<java.version>1.8</java.version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.uas.ps</groupId>
+			<artifactId>ps-core</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>com.uas.ps</groupId>
+			<artifactId>ps-entity</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>com.uas.ps</groupId>
+			<artifactId>ps-httplog</artifactId>
+			<version>0.0.1-SNAPSHOT</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-jpa</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-web</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>1.0.24</version>
+		</dependency>
+		<dependency>
+			<groupId>com.alibaba</groupId>
+			<artifactId>fastjson</artifactId>
+			<version>1.2.15</version>
+		</dependency>
+		<dependency>
+			<groupId>mysql</groupId>
+			<artifactId>mysql-connector-java</artifactId>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-core</artifactId>
+			<version>2.8.8</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-annotations</artifactId>
+			<version>2.8.0</version>
+		</dependency>
+		<dependency>
+			<groupId>com.fasterxml.jackson.core</groupId>
+			<artifactId>jackson-databind</artifactId>
+			<version>2.8.8</version>
+		</dependency>
+
+		<dependency>
+			<groupId>net.sf.flexjson</groupId>
+			<artifactId>flexjson</artifactId>
+			<version>3.3</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpclient</artifactId>
+			<version>4.4</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.httpcomponents</groupId>
+			<artifactId>httpmime</artifactId>
+			<version>4.4</version>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+			</plugin>
+		</plugins>
+	</build>
+
+
+</project>

+ 261 - 0
src/main/java/com/uas/ps/pricing/DruidDBConfiguration.java

@@ -0,0 +1,261 @@
+package com.uas.ps.pricing;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.alibaba.druid.support.http.WebStatFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+
+@Component
+@ConfigurationProperties(prefix = "datasource")
+public class DruidDBConfiguration {
+
+    private Logger logger = LoggerFactory.getLogger(DruidDBConfiguration.class);
+
+    private String url;
+
+    private String username;
+
+    private String password;
+
+    private String driverClassName;
+
+    private int initialSize;
+
+    private int minIdle;
+
+    private int maxActive;
+
+    private int maxWait;
+
+    private int timeBetweenEvictionRunsMillis;
+
+    private int minEvictableIdleTimeMillis;
+
+    private String validationQuery;
+
+    private boolean testWhileIdle;
+
+    private boolean testOnBorrow;
+
+    private boolean testOnReturn;
+
+    private int timeBetweenLogStatsMillis;
+
+    private boolean poolPreparedStatements;
+
+    private int maxPoolPreparedStatementPerConnectionSize;
+
+    private String filters;
+
+    private String connectionProperties;
+
+    @Bean
+    @Primary
+    public DataSource dataSource() {
+        DruidDataSource dataSource = new DruidDataSource();
+
+        dataSource.setUrl(url);
+        dataSource.setUsername(username);
+        dataSource.setPassword(password);
+        dataSource.setDriverClassName(driverClassName);
+
+        // configuration
+        dataSource.setInitialSize(initialSize);
+        dataSource.setMinIdle(minIdle);
+        dataSource.setMaxActive(maxActive);
+        dataSource.setMaxWait(maxWait);
+        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
+        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
+        dataSource.setValidationQuery(validationQuery);
+        dataSource.setTestWhileIdle(testWhileIdle);
+        dataSource.setTestOnBorrow(testOnBorrow);
+        dataSource.setTestOnReturn(testOnReturn);
+        dataSource.setTimeBetweenLogStatsMillis(timeBetweenLogStatsMillis);
+        dataSource.setPoolPreparedStatements(poolPreparedStatements);
+        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
+        try {
+            dataSource.setFilters(filters);
+        } catch (SQLException e) {
+            logger.error("数据源初始化失败: setFilters", e);
+        }
+        dataSource.setConnectionProperties(connectionProperties);
+        return dataSource;
+    }
+
+    @Bean
+    public ServletRegistrationBean servletRegistrationBean() {
+        return new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
+    }
+
+    @Bean
+    public FilterRegistrationBean filterRegistrationBean() {
+        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
+        filterRegistrationBean.setFilter(new WebStatFilter());
+        filterRegistrationBean.addUrlPatterns("/*");
+        filterRegistrationBean.addInitParameter("exclusions",
+                "*.js,*.gif,*.jpg,*.png,*.bmp,*.css,*.ico,*.html,/druid/*");
+        return filterRegistrationBean;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getDriverClassName() {
+        return driverClassName;
+    }
+
+    public void setDriverClassName(String driverClassName) {
+        this.driverClassName = driverClassName;
+    }
+
+    public int getInitialSize() {
+        return initialSize;
+    }
+
+    public void setInitialSize(int initialSize) {
+        this.initialSize = initialSize;
+    }
+
+    public int getMinIdle() {
+        return minIdle;
+    }
+
+    public void setMinIdle(int minIdle) {
+        this.minIdle = minIdle;
+    }
+
+    public int getMaxActive() {
+        return maxActive;
+    }
+
+    public void setMaxActive(int maxActive) {
+        this.maxActive = maxActive;
+    }
+
+    public int getMaxWait() {
+        return maxWait;
+    }
+
+    public void setMaxWait(int maxWait) {
+        this.maxWait = maxWait;
+    }
+
+    public int getTimeBetweenEvictionRunsMillis() {
+        return timeBetweenEvictionRunsMillis;
+    }
+
+    public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
+        this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
+    }
+
+    public int getMinEvictableIdleTimeMillis() {
+        return minEvictableIdleTimeMillis;
+    }
+
+    public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
+        this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
+    }
+
+    public String getValidationQuery() {
+        return validationQuery;
+    }
+
+    public void setValidationQuery(String validationQuery) {
+        this.validationQuery = validationQuery;
+    }
+
+    public boolean isTestWhileIdle() {
+        return testWhileIdle;
+    }
+
+    public void setTestWhileIdle(boolean testWhileIdle) {
+        this.testWhileIdle = testWhileIdle;
+    }
+
+    public boolean isTestOnBorrow() {
+        return testOnBorrow;
+    }
+
+    public void setTestOnBorrow(boolean testOnBorrow) {
+        this.testOnBorrow = testOnBorrow;
+    }
+
+    public boolean isTestOnReturn() {
+        return testOnReturn;
+    }
+
+    public void setTestOnReturn(boolean testOnReturn) {
+        this.testOnReturn = testOnReturn;
+    }
+
+    public int getTimeBetweenLogStatsMillis() {
+        return timeBetweenLogStatsMillis;
+    }
+
+    public void setTimeBetweenLogStatsMillis(int timeBetweenLogStatsMillis) {
+        this.timeBetweenLogStatsMillis = timeBetweenLogStatsMillis;
+    }
+
+    public boolean isPoolPreparedStatements() {
+        return poolPreparedStatements;
+    }
+
+    public void setPoolPreparedStatements(boolean poolPreparedStatements) {
+        this.poolPreparedStatements = poolPreparedStatements;
+    }
+
+    public int getMaxPoolPreparedStatementPerConnectionSize() {
+        return maxPoolPreparedStatementPerConnectionSize;
+    }
+
+    public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
+        this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
+    }
+
+    public String getFilters() {
+        return filters;
+    }
+
+    public void setFilters(String filters) {
+        this.filters = filters;
+    }
+
+    public String getConnectionProperties() {
+        return connectionProperties;
+    }
+
+    public void setConnectionProperties(String connectionProperties) {
+        this.connectionProperties = connectionProperties;
+    }
+}

+ 12 - 0
src/main/java/com/uas/ps/pricing/PsPricingApplication.java

@@ -0,0 +1,12 @@
+package com.uas.ps.pricing;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class PsPricingApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(PsPricingApplication.class, args);
+	}
+}

+ 26 - 0
src/main/java/com/uas/ps/pricing/RepositoryConfiguration.java

@@ -0,0 +1,26 @@
+package com.uas.ps.pricing;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+
+import javax.sql.DataSource;
+
+/**
+ * @author liusw
+ * @date 2018-04-24 11:03
+ */
+public class RepositoryConfiguration {
+
+    @Autowired
+    private DataSource dataSource;
+
+    @Bean
+    @Primary
+    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
+        return builder.dataSource(dataSource)
+                .packages("com.uas.ps.entity", "com.uas.ps.pricing.**.*").build();
+    }
+}

+ 24 - 0
src/main/java/com/uas/ps/pricing/Test.java

@@ -0,0 +1,24 @@
+package com.uas.ps.pricing;
+
+import com.alibaba.druid.util.HttpClientUtils;
+import com.sun.deploy.net.HttpUtils;
+import com.uas.ps.pricing.model.Bom;
+import com.uas.ps.pricing.model.BomDetail;
+import com.uas.ps.pricing.util.FlexJsonUtils;
+import com.uas.ps.pricing.util.HttpUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author liusw
+ * @date 2018-04-24 11:41
+ */
+public class Test {
+
+    public static void main(String[] args) {
+       double a = 0.00000000;
+       double b = 0d;
+        System.out.println(a == b);
+    }
+}

+ 48 - 0
src/main/java/com/uas/ps/pricing/controller/PriceLibraryController.java

@@ -0,0 +1,48 @@
+package com.uas.ps.pricing.controller;
+
+import com.uas.ps.pricing.model.Bom;
+import com.uas.ps.pricing.model.PriceLibrary;
+import com.uas.ps.pricing.service.PriceLibraryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * 价格库控制器
+ *
+ * @author liusw
+ * @date 2018-04-23 11:13
+ */
+@RestController
+@RequestMapping("/pricing")
+public class PriceLibraryController {
+
+    @Autowired
+    private PriceLibraryService priceLibraryService;
+
+    /**
+     * 保存价格信息
+     * @param priceLibraries
+     * @return
+     */
+    @PostMapping(value = "/savePrice")
+    public ModelMap savePrice(@RequestBody List<PriceLibrary> priceLibraries){
+        return priceLibraryService.savePrice(priceLibraries);
+    }
+
+    /**
+     * bom核价
+     * @param bom
+     * @return
+     */
+    @PostMapping(value = "/bomPricing")
+    public ModelMap bomPricing(@RequestBody Bom bom) {
+        return priceLibraryService.bomPricing(bom);
+    }
+}

+ 17 - 0
src/main/java/com/uas/ps/pricing/dao/BomDao.java

@@ -0,0 +1,17 @@
+package com.uas.ps.pricing.dao;
+
+import com.uas.ps.pricing.model.Bom;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Bom
+ *
+ * @author liusw
+ * @since 2018/4/12 10:17
+ */
+@Repository
+public interface BomDao extends JpaRepository<Bom, Long>, JpaSpecificationExecutor<Bom> {
+
+}

+ 17 - 0
src/main/java/com/uas/ps/pricing/dao/BomDetailDao.java

@@ -0,0 +1,17 @@
+package com.uas.ps.pricing.dao;
+
+import com.uas.ps.pricing.model.BomDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+/**
+ * BomDetail
+ *
+ * @author liusw
+ * @since 2018/4/12 10:17
+ */
+@Repository
+public interface BomDetailDao extends JpaRepository<BomDetail, Long>, JpaSpecificationExecutor<BomDetail> {
+
+}

+ 55 - 0
src/main/java/com/uas/ps/pricing/dao/PriceLibraryDao.java

@@ -0,0 +1,55 @@
+package com.uas.ps.pricing.dao;
+
+import com.uas.ps.pricing.model.PriceLibrary;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.stereotype.Repository;
+
+import java.util.Set;
+
+/**
+ * PriceLibrary
+ *
+ * @author liusw
+ * @since 2018/4/12 10:17
+ */
+@Repository
+public interface PriceLibraryDao extends JpaRepository<PriceLibrary, Long>, JpaSpecificationExecutor<PriceLibrary> {
+    /**
+     * 通过原厂型号和品牌查询价格信息
+     * @param cmpCode
+     * @param inbrand
+     * @return
+     */
+    Set<PriceLibrary> findByCmpCodeAndInbrandAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(String cmpCode, String inbrand, String currency, Long vendorEnuu, Double price);
+
+    /**
+     * 通过原厂型号查询价格信息
+     * @param cmpCode
+     * @param currency
+     * @return
+     */
+    Set<PriceLibrary> findByCmpCodeAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(String cmpCode, String currency, Long vendorEnuu, Double price);
+
+    /**
+     * 通过型号和品牌查询价格信息
+     * @param code
+     * @param brand
+     * @return
+     */
+    Set<PriceLibrary> findByCodeAndBrandAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(String code, String brand, String currency, Long vendorEnuu, Double price);
+
+    /**
+     * 通过型号查询价格信息
+     * @param code
+     * @return
+     */
+    Set<PriceLibrary> findByCodeAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(String code, String currency, Long vendorEnuu, Double price);
+
+    /**
+     * 通过规格查询价格信息
+     * @param spec
+     * @return
+     */
+    Set<PriceLibrary> findBySpecAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(String spec, String currency, Long vendorEnuu, Double price);
+}

+ 10 - 0
src/main/java/com/uas/ps/pricing/entity/PriceType.java

@@ -0,0 +1,10 @@
+package com.uas.ps.pricing.entity;
+
+/**
+ * 价格类型
+ *
+ * @author liusw
+ * @date 2018-04-23 14:15
+ */
+public class PriceType {
+}

+ 327 - 0
src/main/java/com/uas/ps/pricing/model/Bom.java

@@ -0,0 +1,327 @@
+package com.uas.ps.pricing.model;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Bom
+ *
+ * @author liusw
+ * @since 2018/4/11 13:56
+ */
+@Entity
+@Table(name = "pricing$bom")
+public class Bom {
+    /**
+     * ID
+     */
+    @Id
+    @GeneratedValue
+    @Column(name = "b_id")
+    private Long bid;
+
+    /**
+     * 主表ID
+     */
+    @Column(name = "b_mid")
+    private Long mid;
+
+    /**
+     * 母件编号
+     */
+    @Column(name = "b_mothercode")
+    private String motherCode;
+
+    /**
+     * BOM ID
+     */
+    @Column(name = "b_bomId")
+    private Long bomId;
+
+
+    /**
+     * 名称
+     */
+    @Column(name = "b_title")
+    private String title;
+
+    /**
+     * 单位
+     */
+    @Column(name = "b_unit")
+    private String unit;
+
+    /**
+     * 规格
+     */
+    @Column(name = "b_spec")
+    private String spec;
+
+    /**
+     * 版本
+     */
+    @Column(name = "b_version")
+    private String version;
+
+    /**
+     * UAS预估总价
+     */
+    @Column(name = "b_uasestimateprice")
+    private Double uasEstimatePrice;
+
+    /**
+     * 币种
+     */
+    @Column(name = "b_currency")
+    private String currency;
+
+    /**
+     * 平台参考价
+     */
+    @Column(name = "b_refprice")
+    private Double refPrice;
+
+    /**
+     * 生效日期
+     */
+    @Column(name = "b_effectivedate")
+    private Date effectiveDate;
+
+    /**
+     * 失效日期
+     */
+    @Column(name = "b_deadline")
+    private Date deadline;
+
+    /**
+     * bom分类
+     */
+    @Column(name = "b_classify")
+    private String bomClassify;
+
+    /**
+     * BOM等级
+     */
+    @Column(name = "b_level")
+    private String bomLevel;
+
+    /**
+     * 编制人UU
+     */
+    @Column(name = "b_orguu")
+    private Long orgUU;
+
+    /**
+     * 录入人UU
+     */
+    @Column(name = "b_inputuu")
+    private Long inputUU;
+
+    /**
+     * 审核人UU
+     */
+    @Column(name = "b_checkuu")
+    private String checkUU;
+
+    /**
+     * 状态
+     */
+    @Column(name = "b_status")
+    private Integer bomStatus;
+
+    /**
+     * 所属企业UU
+     */
+    @Column(name = "b_enuu")
+    private Long enuu;
+
+    /**
+     * 录入日期
+     */
+    @Column(name = "b_inputdate")
+    private Date inputDate;
+
+    /**
+     * bom明细
+     */
+    @Transient
+    private List<BomDetail> bomDetails;
+
+    public Long getBid() {
+        return bid;
+    }
+
+    public void setBid(Long bid) {
+        this.bid = bid;
+    }
+
+    public Long getMid() {
+        return mid;
+    }
+
+    public void setMid(Long mid) {
+        this.mid = mid;
+    }
+
+    public String getMotherCode() {
+        return motherCode;
+    }
+
+    public void setMotherCode(String motherCode) {
+        this.motherCode = motherCode;
+    }
+
+    public Long getBomId() {
+        return bomId;
+    }
+
+    public void setBomId(Long bomId) {
+        this.bomId = bomId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getSpec() {
+        return spec;
+    }
+
+    public void setSpec(String spec) {
+        this.spec = spec;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public Double getUasEstimatePrice() {
+        return uasEstimatePrice;
+    }
+
+    public void setUasEstimatePrice(Double uasEstimatePrice) {
+        this.uasEstimatePrice = uasEstimatePrice;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public Double getRefPrice() {
+        return refPrice;
+    }
+
+    public void setRefPrice(Double refPrice) {
+        this.refPrice = refPrice;
+    }
+
+    public Date getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    public void setEffectiveDate(Date effectiveDate) {
+        this.effectiveDate = effectiveDate;
+    }
+
+    public Date getDeadline() {
+        return deadline;
+    }
+
+    public void setDeadline(Date deadline) {
+        this.deadline = deadline;
+    }
+
+    public String getBomClassify() {
+        return bomClassify;
+    }
+
+    public void setBomClassify(String bomClassify) {
+        this.bomClassify = bomClassify;
+    }
+
+    public String getBomLevel() {
+        return bomLevel;
+    }
+
+    public void setBomLevel(String bomLevel) {
+        this.bomLevel = bomLevel;
+    }
+
+    public Long getOrgUU() {
+        return orgUU;
+    }
+
+    public void setOrgUU(Long orgUU) {
+        this.orgUU = orgUU;
+    }
+
+    public Long getInputUU() {
+        return inputUU;
+    }
+
+    public void setInputUU(Long inputUU) {
+        this.inputUU = inputUU;
+    }
+
+    public String getCheckUU() {
+        return checkUU;
+    }
+
+    public void setCheckUU(String checkUU) {
+        this.checkUU = checkUU;
+    }
+
+    public Integer getBomStatus() {
+        return bomStatus;
+    }
+
+    public void setBomStatus(Integer bomStatus) {
+        this.bomStatus = bomStatus;
+    }
+
+    public Long getEnuu() {
+        return enuu;
+    }
+
+    public void setEnuu(Long enuu) {
+        this.enuu = enuu;
+    }
+
+    public Date getInputDate() {
+        return inputDate;
+    }
+
+    public void setInputDate(Date inputDate) {
+        this.inputDate = inputDate;
+    }
+
+    public List<BomDetail> getBomDetails() {
+        return bomDetails;
+    }
+
+    public void setBomDetails(List<BomDetail> bomDetails) {
+        this.bomDetails = bomDetails;
+    }
+}

+ 296 - 0
src/main/java/com/uas/ps/pricing/model/BomDetail.java

@@ -0,0 +1,296 @@
+package com.uas.ps.pricing.model;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * Bom明细
+ *
+ * @author liusw
+ * @since 2018/4/11 13:58
+ */
+@Entity
+@Table(name = "pricing$bom_detail")
+public class BomDetail {
+    /**
+     * ID
+     */
+    @Id
+    @GeneratedValue
+    @Column(name = "bd_id")
+    private Long bdId;
+
+    /**
+     * bomId
+     */
+    @Column(name = "bd_bomid")
+    private Long bomId;
+
+    /**
+     * 物料编号
+     */
+    @Column(name = "bd_productcode")
+    private String productCode;
+
+    /**
+     * 物料名称
+     */
+    @Column(name = "bd_producttitle")
+    private String productTitle;
+
+    /**
+     * 型号
+      */
+    @Column(name = "bd_code")
+    private String code;
+
+    /**
+     * 品牌
+     */
+    @Column(name = "bd_brand")
+    private String brand;
+
+    /**
+     * 原产型号
+     */
+    @Column(name = "bd_cmpcode")
+    private String cmpCode;
+
+    /**
+     * 原产品牌
+     */
+    @Column(name = "bd_inbrand")
+    private String inbrand;
+
+    /**
+     * 规格描述
+      */
+    @Column(name = "bd_spec")
+    private String spec;
+
+    /**
+     * 单位用量
+     */
+    @Column(name = "bd_unitconsumption")
+    private Integer unitConsumption;
+
+    /**
+     * UAS预估单价
+     */
+    @Column(name = "bd_uasestimateprice")
+    private Double uasEstimatePrice;
+
+    /**
+     * 单位
+     */
+    @Column(name = "bd_unit")
+    private String unit;
+
+    /**
+     * 币种
+     */
+    @Column(name = "bd_currency")
+    private String currency;
+
+    /**
+     * 税率
+     */
+    @Column(name = "bd_taxrate")
+    private Double taxRate;
+
+    /**
+     * 含税单价
+     */
+    @Column(name = "bd_taxunitprice")
+    private Double taxUnitPrice;
+
+    /**
+     * 供应商UU
+      */
+    @Column(name = "bd_vendinfo")
+    private Long vendUU;
+
+    /**
+     * 供应商名称
+     */
+    @Column(name = "bd_vendname")
+    private String vendName;
+
+    /**
+     * 核价后价格
+      */
+    @Column(name = "bd_pricingprice")
+    private Double pricingPrice;
+
+    /**
+     * 当前价格在价格库的编号
+     */
+    @Column(name = "pl_id")
+    private Long pid;
+
+    /**
+     * 核价时间
+     */
+    @Column(name = "bd_pricingtime")
+    private Date pricingTime;
+
+    public Long getBomId() {
+        return bomId;
+    }
+
+    public void setBomId(Long bomId) {
+        this.bomId = bomId;
+    }
+
+    public Long getBdId() {
+        return bdId;
+    }
+
+    public void setBdId(Long bdId) {
+        this.bdId = bdId;
+    }
+
+    public String getProductCode() {
+        return productCode;
+    }
+
+    public void setProductCode(String productCode) {
+        this.productCode = productCode;
+    }
+
+    public String getProductTitle() {
+        return productTitle;
+    }
+
+    public void setProductTitle(String productTitle) {
+        this.productTitle = productTitle;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getBrand() {
+        return brand;
+    }
+
+    public void setBrand(String brand) {
+        this.brand = brand;
+    }
+
+    public String getCmpCode() {
+        return cmpCode;
+    }
+
+    public void setCmpCode(String cmpCode) {
+        this.cmpCode = cmpCode;
+    }
+
+    public String getInbrand() {
+        return inbrand;
+    }
+
+    public void setInbrand(String inbrand) {
+        this.inbrand = inbrand;
+    }
+
+    public String getSpec() {
+        return spec;
+    }
+
+    public void setSpec(String spec) {
+        this.spec = spec;
+    }
+
+    public Integer getUnitConsumption() {
+        return unitConsumption;
+    }
+
+    public void setUnitConsumption(Integer unitConsumption) {
+        this.unitConsumption = unitConsumption;
+    }
+
+    public Double getUasEstimatePrice() {
+        return uasEstimatePrice;
+    }
+
+    public void setUasEstimatePrice(Double uasEstimatePrice) {
+        this.uasEstimatePrice = uasEstimatePrice;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public Double getTaxRate() {
+        return taxRate;
+    }
+
+    public void setTaxRate(Double taxRate) {
+        this.taxRate = taxRate;
+    }
+
+    public Double getTaxUnitPrice() {
+        return taxUnitPrice;
+    }
+
+    public void setTaxUnitPrice(Double taxUnitPrice) {
+        this.taxUnitPrice = taxUnitPrice;
+    }
+
+    public Long getVendUU() {
+        return vendUU;
+    }
+
+    public void setVendUU(Long vendUU) {
+        this.vendUU = vendUU;
+    }
+
+    public String getVendName() {
+        return vendName;
+    }
+
+    public void setVendName(String vendName) {
+        this.vendName = vendName;
+    }
+
+    public Double getPricingPrice() {
+        return pricingPrice;
+    }
+
+    public void setPricingPrice(Double pricingPrice) {
+        this.pricingPrice = pricingPrice;
+    }
+
+    public Long getPid() {
+        return pid;
+    }
+
+    public void setPid(Long pid) {
+        this.pid = pid;
+    }
+
+    public Date getPricingTime() {
+        return pricingTime;
+    }
+
+    public void setPricingTime(Date pricingTime) {
+        this.pricingTime = pricingTime;
+    }
+}

+ 421 - 0
src/main/java/com/uas/ps/pricing/model/PriceLibrary.java

@@ -0,0 +1,421 @@
+package com.uas.ps.pricing.model;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "pricing$price_library")
+public class PriceLibrary {
+
+    @Id
+    @GeneratedValue
+    @Column(name = "pl_id")
+    private Long id;
+
+    /**
+     * UAS物料编号
+     */
+    @Column(name = "pl_uascode")
+    private String uasCode;
+
+    /**
+     * 是否是标准物料<br>
+     * 1.YES<br>
+     * 0.NO
+     */
+    @Column(name = "pl_standard")
+    private Short standard;
+
+    /**
+     * 类目(平台)(中文)
+     */
+    @Column(name = "pl_kind")
+    private String kind;
+
+    /**
+     * 类目(平台)(英文)
+     */
+    @Column(name = "pl_kinden")
+    private String kindEn;
+
+    /**
+     * 型号
+     */
+    @Column(name = "pl_code")
+    private String code;
+
+    /**
+     * 品牌
+     */
+    @Column(name = "pl_brand")
+    private String brand;
+
+    /**
+     * 原厂型号
+     */
+    @Column(name = "pl_cmpcode")
+    private String cmpCode;
+
+    /**
+     * 原厂品牌
+     */
+    @Column(name = "pl_inbrand")
+    private String inbrand;
+
+    /**
+     * 规格
+     */
+    @Column(name = "pl_spec")
+    private String spec;
+
+    /**
+     * 币种
+     */
+    @Column(name = "pl_currency")
+    private String currency;
+
+    /**
+     * 单价
+     */
+    @Column(name = "pl_price")
+    private Double price;
+
+    /**
+     * 分段数量
+     */
+    @Column(name = "pl_lapqty")
+    private Double lapQty;
+
+    /**
+     * 价格类型
+     */
+    @Column(name = "pl_pricetype")
+    private String priceType;
+
+    /**
+     * 来源
+     */
+    @Column(name = "pl_source")
+    private String source;
+
+    /**
+     * 价格有效期
+     */
+    @Column(name = "pl_pricedeadline")
+    private Date priceDeadline;
+
+    /**
+     * 税率
+     */
+    @Column(name = "pl_taxrate")
+    private Double taxRate;
+
+    /**
+     * 单位
+     */
+    @Column(name = "pl_unit")
+    private String unit;
+
+    /**
+     * 交期
+     */
+    @Column(name = "pl_delivery")
+    private String delivery;
+
+    /**
+     * 最小包装量
+     */
+    @Column(name = "pl_minpack")
+    private Double minPack;
+
+    /**
+     * 最小起订量
+     */
+    @Column(name = "pr_minorder")
+    private Double minOrder;
+
+    /**
+     * 收款条件
+     */
+    @Column(name = "pl_collectionterms")
+    private String collectionTerms;
+
+    /**
+     * 卖家企业uu
+     */
+    @Column(name = "pl_vendorenuu")
+    private Long vendorEnuu;
+
+    /**
+     * 卖家个人uu
+     */
+    @Column(name = "pl_vendoruu")
+    private Long vendorUU;
+
+    /**
+     * 买家企业uu
+     */
+    @Column(name = "pl_buyerenuu")
+    private Long buyerEnuu;
+
+    /**
+     * 买家个人uu
+     */
+    @Column(name = "pl_buyeruu")
+    private Long buyerUU;
+
+    /**
+     * 最近一次发生时间
+     */
+    @Column(name = "pl_lasttime")
+    private Date lastTime;
+
+    public Double getLapQty() {
+        return lapQty;
+    }
+
+    public void setLapQty(Double lapQty) {
+        this.lapQty = lapQty;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getUasCode() {
+        return uasCode;
+    }
+
+    public void setUasCode(String uasCode) {
+        this.uasCode = uasCode;
+    }
+
+    public Short getStandard() {
+        return standard;
+    }
+
+    public void setStandard(Short standard) {
+        this.standard = standard;
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public void setKind(String kind) {
+        this.kind = kind;
+    }
+
+    public String getKindEn() {
+        return kindEn;
+    }
+
+    public void setKindEn(String kindEn) {
+        this.kindEn = kindEn;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getBrand() {
+        return brand;
+    }
+
+    public void setBrand(String brand) {
+        this.brand = brand;
+    }
+
+    public String getCmpCode() {
+        return cmpCode;
+    }
+
+    public void setCmpCode(String cmpCode) {
+        this.cmpCode = cmpCode;
+    }
+
+    public String getInbrand() {
+        return inbrand;
+    }
+
+    public void setInbrand(String inbrand) {
+        this.inbrand = inbrand;
+    }
+
+    public String getSpec() {
+        return spec;
+    }
+
+    public void setSpec(String spec) {
+        this.spec = spec;
+    }
+
+    public String getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(String currency) {
+        this.currency = currency;
+    }
+
+    public Double getPrice() {
+        return price;
+    }
+
+    public void setPrice(Double price) {
+        this.price = price;
+    }
+
+    public String getPriceType() {
+        return priceType;
+    }
+
+    public void setPriceType(String priceType) {
+        this.priceType = priceType;
+    }
+
+    public String getSource() {
+        return source;
+    }
+
+    public void setSource(String source) {
+        this.source = source;
+    }
+
+    public Date getPriceDeadline() {
+        return priceDeadline;
+    }
+
+    public void setPriceDeadline(Date priceDeadline) {
+        this.priceDeadline = priceDeadline;
+    }
+
+    public Double getTaxRate() {
+        return taxRate;
+    }
+
+    public void setTaxRate(Double taxRate) {
+        this.taxRate = taxRate;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getDelivery() {
+        return delivery;
+    }
+
+    public void setDelivery(String delivery) {
+        this.delivery = delivery;
+    }
+
+    public Double getMinPack() {
+        return minPack;
+    }
+
+    public void setMinPack(Double minPack) {
+        this.minPack = minPack;
+    }
+
+    public Double getMinOrder() {
+        return minOrder;
+    }
+
+    public void setMinOrder(Double minOrder) {
+        this.minOrder = minOrder;
+    }
+
+    public String getCollectionTerms() {
+        return collectionTerms;
+    }
+
+    public void setCollectionTerms(String collectionTerms) {
+        this.collectionTerms = collectionTerms;
+    }
+
+    public Long getVendorEnuu() {
+        return vendorEnuu;
+    }
+
+    public void setVendorEnuu(Long vendorEnuu) {
+        this.vendorEnuu = vendorEnuu;
+    }
+
+    public Long getVendorUU() {
+        return vendorUU;
+    }
+
+    public void setVendorUU(Long vendorUU) {
+        this.vendorUU = vendorUU;
+    }
+
+    public Long getBuyerEnuu() {
+        return buyerEnuu;
+    }
+
+    public void setBuyerEnuu(Long buyerEnuu) {
+        this.buyerEnuu = buyerEnuu;
+    }
+
+    public Long getBuyerUU() {
+        return buyerUU;
+    }
+
+    public void setBuyerUU(Long buyerUU) {
+        this.buyerUU = buyerUU;
+    }
+
+    public Date getLastTime() {
+        return lastTime;
+    }
+
+    public void setLastTime(Date lastTime) {
+        this.lastTime = lastTime;
+    }
+
+    @Override
+    public String toString() {
+        return "PriceLibrary{" +
+                "id=" + id +
+                ", uasCode='" + uasCode + '\'' +
+                ", standard=" + standard +
+                ", kind='" + kind + '\'' +
+                ", kindEn='" + kindEn + '\'' +
+                ", code='" + code + '\'' +
+                ", brand='" + brand + '\'' +
+                ", cmpCode='" + cmpCode + '\'' +
+                ", inbrand='" + inbrand + '\'' +
+                ", spec='" + spec + '\'' +
+                ", currency='" + currency + '\'' +
+                ", price=" + price +
+                ", lapQty=" + lapQty +
+                ", priceType='" + priceType + '\'' +
+                ", source='" + source + '\'' +
+                ", priceDeadline=" + priceDeadline +
+                ", taxRate=" + taxRate +
+                ", unit='" + unit + '\'' +
+                ", delivery='" + delivery + '\'' +
+                ", minPack=" + minPack +
+                ", minOrder=" + minOrder +
+                ", collectionTerms='" + collectionTerms + '\'' +
+                ", vendorEnuu=" + vendorEnuu +
+                ", vendorUU=" + vendorUU +
+                ", buyerEnuu=" + buyerEnuu +
+                ", buyerUU=" + buyerUU +
+                ", lastTime=" + lastTime +
+                '}';
+    }
+}

+ 30 - 0
src/main/java/com/uas/ps/pricing/service/PriceLibraryService.java

@@ -0,0 +1,30 @@
+package com.uas.ps.pricing.service;
+
+import com.uas.ps.pricing.model.Bom;
+import com.uas.ps.pricing.model.PriceLibrary;
+import org.springframework.ui.ModelMap;
+
+import java.util.List;
+
+/**
+ * 价格库业务层
+ *
+ * @author liusw
+ * @date 2018-04-23 11:10
+ */
+public interface PriceLibraryService {
+
+    /**
+     * 保存价格数据
+     * @param priceLibraries
+     * @return
+     */
+    ModelMap savePrice(List<PriceLibrary> priceLibraries);
+
+    /**
+     * bom核价
+     * @param bom
+     * @return
+     */
+    ModelMap bomPricing(Bom bom);
+}

+ 13 - 0
src/main/java/com/uas/ps/pricing/service/PricingService.java

@@ -0,0 +1,13 @@
+package com.uas.ps.pricing.service;
+
+import com.uas.ps.pricing.model.Bom;
+
+/**
+ * 核价业务
+ *
+ * @author liusw
+ * @since 2018/4/12 10:18
+ */
+public interface PricingService {
+    Bom pricing(Bom bom);
+}

+ 150 - 0
src/main/java/com/uas/ps/pricing/service/impl/PriceLibraryServiceImpl.java

@@ -0,0 +1,150 @@
+package com.uas.ps.pricing.service.impl;
+
+import com.uas.ps.pricing.dao.BomDao;
+import com.uas.ps.pricing.dao.BomDetailDao;
+import com.uas.ps.pricing.dao.PriceLibraryDao;
+import com.uas.ps.pricing.model.Bom;
+import com.uas.ps.pricing.model.BomDetail;
+import com.uas.ps.pricing.model.PriceLibrary;
+import com.uas.ps.pricing.service.PriceLibraryService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.ui.ModelMap;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+
+/**
+ * 价格库实现类
+ *
+ * @author liusw
+ * @date 2018-04-23 11:12
+ */
+@Service
+public class PriceLibraryServiceImpl implements PriceLibraryService{
+
+    @Autowired
+    private PriceLibraryDao priceLibraryDao;
+
+    @Autowired
+    private BomDetailDao bomDetailDao;
+
+    @Autowired
+    private BomDao bomDao;
+
+    /**
+     * 核价规则
+     */
+    private static String[] PRICERULES = {"VALIDPURCPRICE", "ORDERPURCPRICE", "CHECKUNITPRICE", "WAREHOUSINGPRICE", "MATSTANDARDUNITPRICE", "REPAVGUNITPRICE", "OFFERPRICE"};
+
+    @Override
+    public ModelMap savePrice(List<PriceLibrary> priceLibraries) {
+        ModelMap modelMap = new ModelMap();
+        try {
+            priceLibraries = priceLibraryDao.saveAll(priceLibraries);
+            modelMap.put("success", true);
+            modelMap.put("data", priceLibraries.size());
+        } catch (Exception e) {
+            e.printStackTrace();
+            modelMap.put("success", false);
+            modelMap.put("message", e.getMessage());
+        }
+        return modelMap;
+    }
+
+    @Override
+    public ModelMap bomPricing(Bom bom) {
+        ModelMap modelMap = new ModelMap();
+        try {
+            List<BomDetail> bomDetails = bom.getBomDetails();
+            for (BomDetail bomDetail : bomDetails) {
+                if (!StringUtils.isEmpty(bomDetail.getTaxUnitPrice()) && bomDetail.getTaxUnitPrice() != 0) {
+                    // 进行核价
+                    bomDetail = countPrice(bomDetail, bom.getEnuu());
+                }
+                bomDetailDao.save(bomDetail);
+            }
+            bom = bomDao.save(bom);
+            bom.setBomDetails(bomDetails);
+            modelMap.put("success", true);
+            modelMap.put("data", bom);
+        } catch (Exception e) {
+            e.printStackTrace();
+            modelMap.put("success", false);
+            modelMap.put("message", e.getMessage());
+        }
+        return modelMap;
+    }
+
+    /**
+     * 核价
+     * @param bomDetail
+     * @return
+     */
+    private BomDetail countPrice(BomDetail bomDetail, Long enuu) {
+        // 匹配 如果bomDetail里面有原厂型号和品牌
+        Set<PriceLibrary> prices = matchPrice(bomDetail, enuu);
+        if (!CollectionUtils.isEmpty(prices)) {
+            // 去最小价格
+            Map<String, PriceLibrary> priceLibraryMap = getMinValues(prices);
+
+            // 核价
+            for (String type : PRICERULES) {
+                PriceLibrary priceLibrary = priceLibraryMap.get(type);
+                if (!StringUtils.isEmpty(priceLibrary) && !StringUtils.isEmpty(priceLibrary.getPrice()) && priceLibrary.getPrice() != 0 && priceLibrary.getPrice() <= bomDetail.getTaxUnitPrice()) {
+                    bomDetail.setPid(priceLibrary.getId());
+                    double price = ((bomDetail.getTaxUnitPrice() - priceLibrary.getPrice()) * 0.618) + priceLibrary.getPrice();
+                    bomDetail.setPricingPrice((double) Math.round(price * 1000000) / 1000000);
+                    break;
+                }
+            }
+        }
+        bomDetail.setPricingTime(new Date());
+        return bomDetail;
+    }
+
+    /**
+     * 匹配价格
+     * @param bomDetail
+     * @return
+     */
+    public Set<PriceLibrary> matchPrice(BomDetail bomDetail, Long enuu) {
+        Set<PriceLibrary> prices = new HashSet<>();
+        if (StringUtils.isEmpty(bomDetail.getCurrency())) {
+            bomDetail.setCurrency("RMB");
+        }
+        if (!StringUtils.isEmpty(bomDetail.getCmpCode()) && !StringUtils.isEmpty(bomDetail.getInbrand())) {
+            prices = priceLibraryDao.findByCmpCodeAndInbrandAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(bomDetail.getCmpCode(), bomDetail.getInbrand(), bomDetail.getCurrency(), enuu, 0d);
+        } else if (!StringUtils.isEmpty(bomDetail.getCmpCode())) {
+            prices = priceLibraryDao.findByCmpCodeAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(bomDetail.getCmpCode(), bomDetail.getCurrency(), enuu, 0d);
+        }else if (!StringUtils.isEmpty(bomDetail.getCode()) && !StringUtils.isEmpty(bomDetail.getBrand())) {// 如果bomDetail里面有型号和品牌
+            prices = priceLibraryDao.findByCodeAndBrandAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(bomDetail.getCode(), bomDetail.getBrand(), bomDetail.getCurrency(), enuu, 0d);
+        } else if (!StringUtils.isEmpty(bomDetail.getCode())) {// 如果bomDetail只有型号
+            prices = priceLibraryDao.findByCodeAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(bomDetail.getCode(), bomDetail.getCurrency(), enuu, 0d);
+        } else if (!StringUtils.isEmpty(bomDetail.getSpec())) {// 如果bomDetail 规格不为空
+            prices = priceLibraryDao.findBySpecAndCurrencyAndPriceIsNotNullAndVendorEnuuNotAndPriceNot(bomDetail.getSpec(), bomDetail.getCurrency(), enuu, 0d);
+        }
+        return prices;
+    }
+
+    /**
+     * 取出各个价格中最小值
+     * @param prices
+     * @return
+     */
+    public Map<String, PriceLibrary> getMinValues(Set<PriceLibrary> prices) {
+        Map<String, PriceLibrary> priceLibraryMap = new HashMap<>();
+        for (PriceLibrary priceLibrary : prices) {
+            PriceLibrary oldPriceLibrary = priceLibraryMap.get(priceLibrary.getPriceType());
+            if (StringUtils.isEmpty(oldPriceLibrary)) {
+                priceLibraryMap.put(priceLibrary.getPriceType(), priceLibrary);
+            } else {
+                if (oldPriceLibrary.getPrice() > priceLibrary.getPrice()) {
+                    priceLibraryMap.put(priceLibrary.getPriceType(), priceLibrary);
+                }
+            }
+        }
+        return priceLibraryMap;
+    }
+}

+ 200 - 0
src/main/java/com/uas/ps/pricing/util/DateUtils.java

@@ -0,0 +1,200 @@
+package com.uas.ps.pricing.util;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+public class DateUtils {
+
+	public static final int COMPARE_NONE = 0;
+	public static final int COMPARE_SECOND = 1;
+	public static final int COMPARE_MINUTE = 2;
+	public static final int COMPARE_HOUR = 3;
+	public static final int COMPARE_DAY = 4;
+	static final SimpleDateFormat ym = new SimpleDateFormat("yyyyMM");
+	static final SimpleDateFormat YM = new SimpleDateFormat("yyyy-MM");
+	static final SimpleDateFormat YMD = new SimpleDateFormat("yyyy-MM-dd");
+	static final SimpleDateFormat YMD_HMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+	/**
+	 * 获取月份起始日期
+	 * 
+	 * @param date
+	 * @return
+	 */
+	public static Date getMinMonthDate(Date date) {
+		date = date == null ? new Date() : date;
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
+		return calendar.getTime();
+	}
+
+	/**
+	 * 获取月份起始日期
+	 * 
+	 * @param date
+	 * @return
+	 */
+	public static String getMinMonthDateS(Date date) {
+		return YMD.format(getMinMonthDate(date));
+	}
+
+	/**
+	 * 获取月份最后日期
+	 * 
+	 * @param date
+	 * @return
+	 */
+	public static Date getMaxMonthDate(Date date) {
+		date = date == null ? new Date() : date;
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
+		return calendar.getTime();
+	}
+
+	/**
+	 * 获取月份最后日期
+	 * 
+	 * @param date
+	 * @return
+	 */
+	public static String getMaxMonthDateS(Date date) {
+		return YMD.format(getMaxMonthDate(date));
+	}
+
+	/**
+	 * 比较日期大小
+	 * 
+	 * @param dateParam1
+	 * @param dateParam2
+	 * @param compareType
+	 *            精确位(天、小时、分钟、秒)
+	 * @return 1表示dateParam1大于dateParam2,0表示等于,-1表示小于
+	 */
+	public static int compare(Date dateParam1, Date dateParam2, int compareType) {
+		Calendar calendar1 = Calendar.getInstance();
+		calendar1.setTime(dateParam1);
+		calendar1.clear(Calendar.MILLISECOND);
+		if (compareType >= COMPARE_SECOND)
+			calendar1.clear(Calendar.SECOND);
+		if (compareType >= COMPARE_MINUTE)
+			calendar1.clear(Calendar.MINUTE);
+		if (compareType >= COMPARE_HOUR) {
+			calendar1.clear(Calendar.HOUR_OF_DAY);
+			calendar1.clear(Calendar.HOUR);
+			calendar1.clear(Calendar.AM_PM);
+		}
+		if (compareType >= COMPARE_DAY)
+			calendar1.clear(Calendar.DAY_OF_MONTH);
+		Calendar calendar2 = Calendar.getInstance();
+		calendar2.setTime(dateParam2);
+		calendar2.clear(Calendar.MILLISECOND);
+		if (compareType >= COMPARE_SECOND)
+			calendar2.clear(Calendar.SECOND);
+		if (compareType >= COMPARE_MINUTE)
+			calendar2.clear(Calendar.MINUTE);
+		if (compareType >= COMPARE_HOUR) {
+			calendar2.clear(Calendar.HOUR_OF_DAY);
+			calendar2.clear(Calendar.HOUR);
+			calendar2.clear(Calendar.AM_PM);
+		}
+		if (compareType >= COMPARE_DAY)
+			calendar2.clear(Calendar.DAY_OF_MONTH);
+		return calendar1.compareTo(calendar2);
+	}
+
+	/**
+	 * 截取指定日期的年月
+	 * 
+	 * @param date
+	 * @return
+	 */
+	public static Integer getYearmonth(Date date) {
+		if (date == null) {
+			date = new Date();
+		}
+		return Integer.parseInt(ym.format(date));
+	}
+
+	/**
+	 * 截取指定日期的年月
+	 * 
+	 * @param date
+	 * @return
+	 */
+	public static Integer getYearmonth(String date) {
+		return Integer.parseInt(ym.format(parse(date, null)));
+	}
+
+	public static Date parse(String date, String f) {
+		if (date == null || "".equals(date)) {
+			return new Date();
+		}
+		if (f == null || "".equals(f)) {
+			try {
+				return date.contains(" ") ? YMD_HMS.parse(date) : YMD.parse(date);
+			} catch (ParseException e) {
+				return new Date();
+			}
+		}
+		SimpleDateFormat sdf = new SimpleDateFormat(f);
+		try {
+			return sdf.parse(date);
+		} catch (ParseException e) {
+			return new Date();
+		}
+	}
+
+	/**
+	 * 当前时间
+	 * 
+	 * @return <h3>String</h3>
+	 */
+	public static String getCurrentDate() {
+		return format(new Date(), null);
+	}
+
+	public static String format(Date date, String f) {
+		if (date == null) {
+			date = new Date();
+		}
+		if (f == null) {
+			return YMD.format(date);
+		}
+		SimpleDateFormat sdf = new SimpleDateFormat(f);
+		return sdf.format(date);
+	}
+
+	/**
+	 * 月份加减
+	 * 
+	 * @param date
+	 * @param increase
+	 *            加减月份数,负数表示减
+	 * @return
+	 */
+	public static Integer addMonth(Date date, int increase) {
+		if (date == null)
+			date = new Date();
+		Calendar calendar = new GregorianCalendar();
+		calendar.setTime(date);
+		calendar.add(Calendar.MONTH, increase);
+		return getYearmonth(calendar.getTime());
+	}
+
+	/**
+	 * 月份加减
+	 * 
+	 * @param date
+	 * @param increase
+	 *            加减月份数,负数表示减
+	 * @return
+	 */
+	public static Integer addMonth(String date, int increase) {
+		return addMonth(parse(date, null), increase);
+	}
+}

+ 46 - 0
src/main/java/com/uas/ps/pricing/util/FlexJsonUtils.java

@@ -0,0 +1,46 @@
+package com.uas.ps.pricing.util;
+
+import flexjson.JSONDeserializer;
+import flexjson.JSONSerializer;
+
+import java.util.*;
+
+public abstract class FlexJsonUtils {
+	public static <T> T fromJson(String json, Class<T> cls) {
+		return new JSONDeserializer<T>().use(null, cls).deserialize(json);
+	}
+
+	public static <K, V> Map<K, V> fromJson(String json) {
+		Map<K, V> map = new HashMap<K, V>();
+		return new JSONDeserializer<Map<K, V>>().use(null, map.getClass()).deserialize(json);
+	}
+
+	public static <K, V> LinkedHashMap<K, V> fromLinkedJson(String json) {
+		Map<K, V> map = new LinkedHashMap<K, V>();
+		return new JSONDeserializer<LinkedHashMap<K, V>>().use(null, map.getClass()).deserialize(json);
+	}
+
+	public String toJson() {
+		return new JSONSerializer().exclude("*.class").serialize(this);
+	}
+
+	public static String toJson(Object obj) {
+		return new JSONSerializer().exclude("*.class").serialize(obj);
+	}
+	
+	public static String toJsonDeep(Object obj) {
+		return new JSONSerializer().exclude("*.class").deepSerialize(obj);
+	}
+
+	public static <T> String toJsonArray(Collection<?> collection) {
+		return new JSONSerializer().exclude("*.class").serialize(collection);
+	}
+	
+	public static <T> List<T> fromJsonArray(String json, Class<?> cls) {
+		return new JSONDeserializer<List<T>>().use(null, ArrayList.class).use("values", cls).deserialize(json);
+	}
+	
+	public static <T> Map<String,T> fromJsonHashMap(String json, Class<?> cls) {
+		return new JSONDeserializer<Map<String,T>>().use(null, HashMap.class).use("values", cls).deserialize(json);
+	}
+}

+ 614 - 0
src/main/java/com/uas/ps/pricing/util/HttpUtil.java

@@ -0,0 +1,614 @@
+package com.uas.ps.pricing.util;
+
+import org.apache.http.Consts;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.*;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.entity.mime.content.FileBody;
+import org.apache.http.entity.mime.content.StringBody;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.util.EntityUtils;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.StreamUtils;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * HTTP工具类,封装http请求
+ * 
+ * @author suntg
+ * @date 2015年3月5日14:20:40
+ */
+public class HttpUtil {
+
+	/**
+	 * 发送GET请求
+	 * 
+	 * @param url
+	 * @param params
+	 * @return
+	 * @throws Exception
+	 */
+	public static Response sendGetRequest(String url, Map<String, ?> params) throws Exception {
+		return sendGetRequest(url, params, false);
+	}
+
+	/**
+	 * 发送GET请求
+	 * 
+	 * @param url
+	 * @param params
+	 * @param sign
+	 *            是否发送签名
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public static Response sendGetRequest(String url, Map<String, ?> params, boolean sign) throws Exception {
+		return sendRequest(RequestMethod.GET, url, (Map<String, Object>) params, sign, false);
+	}
+
+	/**
+	 * 暂时先使用这种方法(短信接口调用)
+	 */
+	public static String sendPost(String url, String param) {
+		PrintWriter out = null;
+		BufferedReader in = null;
+		String result = "";
+		try {
+			URL realUrl = new URL(url);
+			// 打开和URL之间的连接
+			URLConnection conn = realUrl.openConnection();
+			// 设置通用的请求属性
+			conn.setRequestProperty("content-type", "application/json");
+			conn.setRequestProperty("accept", "*/*");
+			conn.setRequestProperty("connection", "Keep-Alive");
+			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+			// 发送POST请求必须设置如下两行
+			conn.setDoOutput(true);
+			conn.setDoInput(true);
+			// 获取URLConnection对象对应的输出流
+			out = new PrintWriter(conn.getOutputStream());
+			// 发送请求参数
+			out.print(param);
+			// flush输出流的缓冲
+			out.flush();
+			// 定义BufferedReader输入流来读取URL的响应
+			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+			String line;
+			while ((line = in.readLine()) != null) {
+				result += line;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		// 使用finally块来关闭输出流、输入流
+		finally {
+			try {
+				if (out != null) {
+					out.close();
+				}
+				if (in != null) {
+					in.close();
+				}
+			} catch (IOException ex) {
+				ex.printStackTrace();
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * 发送POST请求
+	 * 
+	 * @param url
+	 * @param params
+	 * @return
+	 * @throws Exception
+	 */
+	public static Response sendPostRequest(String url, Map<String, ?> params) throws Exception {
+		return sendPostRequest(url, params, false);
+	}
+
+	/**
+	 * 发送POST请求
+	 * 
+	 * @param url
+	 * @param params
+	 * @param sign
+	 *            是否发送签名
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public static Response sendPostRequest(String url, Map<String, ?> params, boolean sign) throws Exception {
+		return sendRequest(RequestMethod.POST, url, (Map<String, Object>) params, sign, true);
+	}
+
+	/**
+	 * 发送POST请求
+	 * 
+	 * @param url
+	 * @param params
+	 * @param sign
+	 *            是否发送签名
+	 * @param encode
+	 *            是否使用URLEncode
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public static Response sendPostRequest(String url, Map<String, ?> params, boolean sign, boolean encode)
+			throws Exception {
+		return sendRequest(RequestMethod.POST, url, (Map<String, Object>) params, sign, encode);
+	}
+
+	/**
+	 * 发送Post请求,直接将List类型放入其中
+	 *
+	 * @param postUrl
+	 * @param formData
+	 * @return
+	 * @throws Exception
+	 */
+	public static String doPost(String postUrl, String formData) throws Exception {
+		HttpClient httpClient = new DefaultHttpClient();
+		HttpPost post = new HttpPost(postUrl);
+		StringEntity postingString = new StringEntity(formData,  HTTP.UTF_8);
+		post.setEntity(postingString);
+		post.setHeader("Content-type", "application/json");
+		HttpResponse response = httpClient.execute(post);
+		String content = EntityUtils.toString(response.getEntity());
+		return content;
+	}
+
+	/**
+	 * 发送DELETE请求
+	 * 
+	 * @param url
+	 * @param params
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	public static Response sendDeleteRequest(String url, Map<String, ?> params) throws Exception {
+		return sendDeleteRequest(url, params, false);
+	}
+
+	/**
+	 * 发送DELETE请求
+	 * 
+	 * @param url
+	 * @param params
+	 * @param sign
+	 *            是否发送签名
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked")
+	public static Response sendDeleteRequest(String url, Map<String, ?> params, boolean sign) throws Exception {
+		return sendRequest(RequestMethod.DELETE, url, (Map<String, Object>) params, sign, false);
+	}
+
+	/**
+	 * 发起http请求
+	 *
+	 * @param method
+	 *            请求方法GET、POST、PUT、DELETE
+	 * @param url
+	 *            请求链接
+	 * @param params
+	 *            参数
+	 * @param sign
+	 *            是否签名
+	 * @return
+	 * @throws Exception
+	 */
+	public static Response sendRequest(RequestMethod method, String url, Map<String, Object> params, boolean sign,
+                                       boolean encode) throws Exception {
+		switch (method) {
+		case GET:
+			return sendHttpUriRequest(new HttpGet(getRequestUrl(url, params, sign)));
+		case POST:
+			return sendHttpEntityEnclosingRequest(new HttpPost(getRequestUrl(url, sign)), params, encode);
+		case PUT:
+			return sendHttpEntityEnclosingRequest(new HttpPut(getRequestUrl(url, sign)), params, encode);
+		case DELETE:
+			return sendHttpUriRequest(new HttpDelete(getRequestUrl(url, params, sign)));
+		default:
+			return sendHttpUriRequest(new HttpGet(getRequestUrl(url, params, sign)));
+		}
+	}
+
+	/**
+	 * 发起GET、DELETE请求
+	 * 
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	public static Response sendHttpUriRequest(HttpRequestBase request) throws Exception {
+		CloseableHttpClient httpClient = HttpClients.createDefault();
+		CloseableHttpResponse response = null;
+		try {
+			response = httpClient.execute(request);
+			return Response.getResponse(response);
+		} finally {
+			try {
+				httpClient.close();
+			} catch (IOException e) {
+			}
+			if (response != null) {
+				try {
+					response.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	/**
+	 * 发起POST、PUT请求
+	 * 
+	 * @param request
+	 * @param params
+	 * @return
+	 * @throws Exception
+	 */
+	public static Response sendHttpEntityEnclosingRequest(HttpEntityEnclosingRequestBase request,
+                                                          Map<String, Object> params, boolean encode) throws Exception {
+		CloseableHttpClient httpClient = HttpClients.createDefault();
+		CloseableHttpResponse response = null;
+		try {
+			if (!encode) {
+				request.setEntity(new StringEntity(FlexJsonUtils.toJson(params), ContentType.APPLICATION_JSON));
+			} else {
+				List<NameValuePair> nvps = new ArrayList<NameValuePair>();
+				if (params != null && !params.isEmpty()) {
+					Set<Entry<String, Object>> entrys = params.entrySet();
+					for (Entry<String, Object> entry : entrys) {
+						Object entryValue = entry.getValue();
+						String entryValueStr = null;
+						if (entryValue instanceof String) {
+							entryValueStr = entryValue.toString();
+						} else {
+							entryValueStr = FlexJsonUtils.toJson(entry.getValue());
+						}
+						nvps.add(new BasicNameValuePair(entry.getKey(), URLEncoder.encode(entryValueStr, "UTF-8")));
+					}
+				}
+				request.setEntity(new UrlEncodedFormEntity(nvps));
+			}
+			response = httpClient.execute(request);
+			return Response.getResponse(response);
+		} finally {
+			request.releaseConnection();
+			try {
+				httpClient.close();
+			} catch (IOException e) {
+			}
+			if (response != null) {
+				try {
+					response.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+	}
+
+	/**
+	 * 将请求参数添加到链接中
+	 *
+	 * @param url
+	 * @param params
+	 * @param sign
+	 *            是否签名
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String getRequestUrl(String url, Map<String, Object> params, boolean sign)
+			throws UnsupportedEncodingException {
+		StringBuilder buf = new StringBuilder(url);
+		if (url.indexOf("?") == -1)
+			buf.append("?");
+		else if (!url.endsWith("&"))
+			buf.append("&");
+		// 如果是GET请求,则请求参数在URL中
+		if (params != null && !params.isEmpty()) {
+			Set<Entry<String, Object>> entrys = params.entrySet();
+			for (Entry<String, Object> entry : entrys) {
+				buf.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue().toString(), "UTF-8"))
+						.append("&");
+			}
+		}
+		if (sign) {
+			// 加时间戳,保持相同请求每次签名均不一样
+			buf.append("_timestamp=").append(System.currentTimeMillis());
+			String message = buf.toString();
+			// 对请求串进行签名
+//			buf.append("&_signature=").append(HmacUtils.encode(message));
+		} else
+			buf.deleteCharAt(buf.length() - 1);
+		return buf.toString();
+	}
+
+	/**
+	 * 将签名信息添加到链接中
+	 *
+	 * @param url
+	 * @param sign
+	 *            是否签名
+	 * @return
+	 */
+	public static String getRequestUrl(String url, boolean sign) {
+		try {
+			return getRequestUrl(url, null, sign);
+		} catch (UnsupportedEncodingException e) {
+		}
+		return null;
+	}
+
+	/**
+	 * 将输入流转为字节数组
+	 * 
+	 * @param inStream
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] read2Byte(InputStream inStream) throws Exception {
+		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
+		byte[] buffer = new byte[1024];
+		int len = 0;
+		while ((len = inStream.read(buffer)) != -1) {
+			outSteam.write(buffer, 0, len);
+		}
+		outSteam.close();
+		inStream.close();
+		return outSteam.toByteArray();
+	}
+
+	/**
+	 * 将输入流转为字符串
+	 * 
+	 * @param inStream
+	 * @return
+	 * @throws Exception
+	 */
+	public static String read2String(InputStream inStream) throws Exception {
+		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
+		byte[] buffer = new byte[1024];
+		int len = 0;
+		while ((len = inStream.read(buffer)) != -1) {
+			outSteam.write(buffer, 0, len);
+		}
+		try {
+			outSteam.close();
+			inStream.close();
+		} catch (Exception e) {
+
+		}
+		return new String(outSteam.toByteArray(), "UTF-8");
+	}
+
+	/**
+	 * 发送xml数据
+	 * 
+	 * @param path
+	 *            请求地址
+	 * @param xml
+	 *            xml数据
+	 * @param encoding
+	 *            编码
+	 * @return
+	 * @throws Exception
+	 */
+	public static byte[] postXml(String path, String xml, String encoding) throws Exception {
+		byte[] data = xml.getBytes(encoding);
+		URL url = new URL(path);
+		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+		conn.setRequestMethod("POST");
+		conn.setDoOutput(true);
+		conn.setRequestProperty("Content-Type", "text/xml; charset=" + encoding);
+		conn.setRequestProperty("Content-Length", String.valueOf(data.length));
+		conn.setConnectTimeout(5 * 1000);
+		OutputStream outStream = conn.getOutputStream();
+		outStream.write(data);
+		outStream.flush();
+		outStream.close();
+		if (conn.getResponseCode() == HttpStatus.OK.value()) {
+			return read2Byte(conn.getInputStream());
+		}
+		return null;
+	}
+
+	/**
+	 * http上传文件
+	 * 
+	 * @param postUrl
+	 *            请求地址
+	 * @param filePath
+	 *            附件路径
+	 * @param params
+	 *            参数
+	 * @return
+	 * @throws Exception
+	 * @throws IOException
+	 * @throws IllegalStateException
+	 */
+	public static Response upload(String postUrl, String filePath, Map<String, String> params)
+			throws IllegalStateException, IOException, Exception {
+		CloseableHttpClient httpClient = null;
+		CloseableHttpResponse response = null;
+		try {
+			httpClient = HttpClients.createDefault();
+			HttpPost httpPost = new HttpPost(postUrl);
+			FileBody fileBody = new FileBody(new File(filePath));
+			MultipartEntityBuilder builder = MultipartEntityBuilder.create();
+			builder.addPart("file", fileBody);
+			if (params != null) {
+				for (String paramKey : params.keySet()) {
+					StringBody body = new StringBody(params.get(paramKey), ContentType.create("text/plain",
+							Consts.UTF_8));
+					builder.addPart(paramKey, body);
+				}
+			}
+			HttpEntity reqEntity = builder.build();
+			httpPost.setEntity(reqEntity);
+			response = httpClient.execute(httpPost);
+		} finally {
+			try {
+				if (response != null) {
+					response.close();
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			try {
+				if (httpClient != null) {
+					httpClient.close();
+				}
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+		return Response.getResponse(response);
+	}
+
+	/**
+	 * 下载
+	 * 
+	 * @param postUrl
+	 * @return
+	 * @throws ClientProtocolException
+	 * @throws IOException
+	 */
+	public static InputStream download(String postUrl) throws ClientProtocolException, IOException {
+		CloseableHttpClient httpClient = HttpClients.createDefault();
+		HttpGet httpGet = new HttpGet(postUrl);
+		CloseableHttpResponse response = httpClient.execute(httpGet);
+		return response.getEntity().getContent();
+	}
+
+	/**
+	 * 获取请求客户端的IP地址
+	 * 
+	 * @param request
+	 * @return
+	 * @throws Exception
+	 */
+	public static String getIpAddr(HttpServletRequest request) {
+		String ip = request.getHeader("x-forwarded-for");
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("WL-Proxy-Client-IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("HTTP_CLIENT_IP");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+		}
+		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+			ip = request.getRemoteAddr();
+		}
+		return ip;
+	}
+	
+	/**
+	 * POST发送
+	 * 
+	 * @param url
+	 * @param data
+	 * @throws Exception
+	 */
+	public static String post(String url, String data) throws Exception {
+		URL urls = new URL(url);
+		HttpURLConnection http = (HttpURLConnection) urls.openConnection();
+		http.setRequestMethod("POST");
+		http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+		http.setDoOutput(true);
+		http.setDoInput(true);
+		System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
+		System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
+		http.connect();
+		OutputStream os = http.getOutputStream();
+		os.write(data.getBytes("UTF-8"));// 传入参数
+		os.flush();
+		os.close();
+		// 从服务器读取响应
+		String encoding = http.getContentEncoding();
+		if (encoding == null)
+			encoding = "UTF-8";
+		return StreamUtils.copyToString(http.getInputStream(), Charset.forName(encoding));
+	}
+
+	public static class Response {
+		private int statusCode;
+		private String responseText;
+		private HttpResponse response;
+
+		public int getStatusCode() {
+			return statusCode;
+		}
+
+		public void setStatusCode(int statusCode) {
+			this.statusCode = statusCode;
+		}
+
+		public String getResponseText() {
+			return responseText;
+		}
+
+		public void setResponseText(String responseText) {
+			this.responseText = responseText;
+		}
+
+		public HttpResponse getResponse() {
+			return response;
+		}
+
+		public void setResponse(HttpResponse response) {
+			this.response = response;
+		}
+
+		public Response() {
+		}
+
+		public Response(HttpResponse response) throws IllegalStateException, IOException, Exception {
+			this.statusCode = response.getStatusLine().getStatusCode();
+			this.responseText = HttpUtil.read2String(response.getEntity().getContent());
+			this.response = response;
+		}
+
+		public static Response getResponse(HttpResponse response) throws IllegalStateException, IOException, Exception {
+			if (response != null)
+				return new Response(response);
+			return null;
+		}
+	}
+}

+ 17 - 0
src/main/java/com/uas/ps/pricing/util/ICallable.java

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

+ 34 - 0
src/main/java/com/uas/ps/pricing/util/ICallableAdapter.java

@@ -0,0 +1,34 @@
+package com.uas.ps.pricing.util;
+
+import java.util.concurrent.Callable;
+
+/**
+ * 代理callable来执行
+ * 
+ * <pre>
+ * 涉及到一个callable对象调用不同参数循环执行的问题,不能直接在ICallable对象里面设置参数,需要代理执行
+ * </pre>
+ * 
+ * @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);
+	}
+
+}

+ 10 - 0
src/main/java/com/uas/ps/pricing/util/IRunnable.java

@@ -0,0 +1,10 @@
+package com.uas.ps.pricing.util;
+
+/**
+ * 线程执行
+ *
+ * Created by hejq on 2018-01-14.
+ */
+public interface IRunnable<T> {
+    void run(T var1);
+}

+ 20 - 0
src/main/java/com/uas/ps/pricing/util/IRunnableAdapter.java

@@ -0,0 +1,20 @@
+package com.uas.ps.pricing.util;
+
+/**
+ * 线程方法
+ *
+ * Created by hejq on 2018-01-14.
+ */
+public 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;
+    }
+
+    public void run() {
+        this.task.run(this.param);
+    }
+}

+ 7 - 0
src/main/java/com/uas/ps/pricing/util/Listener.java

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

+ 29 - 0
src/main/java/com/uas/ps/pricing/util/Listeners.java

@@ -0,0 +1,29 @@
+package com.uas.ps.pricing.util;
+
+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();
+		}
+	}
+
+}

+ 80 - 0
src/main/java/com/uas/ps/pricing/util/PathUtils.java

@@ -0,0 +1,80 @@
+package com.uas.ps.pricing.util;
+
+import com.uas.ps.core.util.ContextUtils;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+/**
+ * 路径
+ * 
+ * @author yingp
+ *
+ */
+public class PathUtils {
+
+	private static String classPath;
+
+	private static String appPath;
+
+	private static String filePath;
+
+	/**
+	 * classes文件目录
+	 * 
+	 * @return
+	 */
+	public static String getClassPath() {
+		if (classPath == null)
+			setClassPath();
+		return classPath;
+	}
+
+	/**
+	 * 应用程序目录
+	 * 
+	 * @return
+	 */
+	public static String getAppPath() {
+		if (appPath == null)
+			setAppPath();
+		return appPath;
+	}
+
+	/**
+	 * 日志、附件文件等存放目录,与程序同级
+	 * 
+	 * @return
+	 */
+	public static String getFilePath() {
+		if (filePath == null)
+			setFilePath();
+		return filePath;
+	}
+
+	private static void setClassPath() {
+		Class<?> objClass = ContextUtils.getApplicationContext().getClass();
+		String strRealPath = objClass.getClassLoader().getResource("").getFile();
+		try {
+			strRealPath = URLDecoder.decode(strRealPath, "UTF-8");
+		} catch (UnsupportedEncodingException e) {
+			e.printStackTrace();
+		}
+		File objFile = new File(strRealPath);
+		classPath = objFile.getParent() + File.separator;
+		if (classPath.contains("/")) {
+			classPath = "/" + classPath;
+		}
+	}
+
+	private static void setAppPath() {
+		File file = new File(getClassPath());
+		appPath = file.getParent() + File.separator;
+	}
+
+	private static void setFilePath() {
+		File file = new File(getAppPath());
+		filePath = file.getParent() + File.separator;
+	}
+}

+ 266 - 0
src/main/java/com/uas/ps/pricing/util/ThreadUtils.java

@@ -0,0 +1,266 @@
+package com.uas.ps.pricing.util;
+
+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;
+		}
+
+	}
+}

+ 13 - 0
src/main/resources/application.yml

@@ -0,0 +1,13 @@
+spring:
+ jpa:
+  database: MYSQL
+  show-sql: false
+  properties:
+   hibernate:
+    dialect: org.hibernate.dialect.MySQL5Dialect
+    hbm2ddl:
+     auto: update
+ profiles:
+   active: dev
+server:
+  port: 8888

+ 23 - 0
src/main/resources/config/application-cloud.properties

@@ -0,0 +1,23 @@
+datasource.url=jdbc:mysql://10.10.0.208:3306/mall_prod?characterEncoding=utf-8&useSSL=false
+datasource.username=sa
+datasource.password=Select123!#%*(
+datasource.driverClassName=com.mysql.jdbc.Driver
+datasource.initialSize=1
+datasource.minIdle=1
+datasource.maxActive=100
+datasource.maxWait=60000
+datasource.timeBetweenEvictionRunsMillis=60000
+datasource.minEvictableIdleTimeMillis=300000
+datasource.validationQuery=SELECT 1 FROM DUAL
+datasource.testWhileIdle=true
+datasource.testOnBorrow=true
+datasource.testOnReturn=false
+datasource.poolPreparedStatements=true
+datasource.timeBetweenLogStatsMillis=300000
+datasource.maxPoolPreparedStatementPerConnectionSize=20
+datasource.filters=stat,slf4j
+datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
+
+# Access path
+ps.product.url=https://api-product.usoftmall.com/
+ps.message.url=http://api-message.ubtob.com/

+ 27 - 0
src/main/resources/config/application-dev.properties

@@ -0,0 +1,27 @@
+datasource.url=jdbc:mysql://192.168.253.12:3306/mall_test_dev?characterEncoding=utf-8&useSSL=false
+datasource.username=root
+datasource.password=select111***
+datasource.driverClassName=com.mysql.jdbc.Driver
+datasource.initialSize=1
+datasource.minIdle=1
+datasource.maxActive=20
+datasource.maxWait=60000
+datasource.timeBetweenEvictionRunsMillis=60000
+datasource.minEvictableIdleTimeMillis=300000
+datasource.validationQuery=SELECT 1 FROM DUAL
+datasource.testWhileIdle=true
+datasource.testOnBorrow=true
+datasource.testOnReturn=false
+datasource.poolPreparedStatements=true
+datasource.timeBetweenLogStatsMillis=60000
+datasource.maxPoolPreparedStatementPerConnectionSize=20
+datasource.filters=stat,slf4j
+datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
+
+# Access path
+#ps.product.url=http://192.168.253.12:24000/product/
+#dong localhost
+ps.product.url=http://192.168.253.12:24000/
+ps.message.url=http://192.168.253.12:24000/message/
+# wang localhost
+#ps.message.url=http://192.168.253.131:20000/

+ 23 - 0
src/main/resources/config/application-test.properties

@@ -0,0 +1,23 @@
+datasource.url=jdbc:mysql://192.168.253.6:3306/mall_test_dev?characterEncoding=utf-8&useSSL=false
+datasource.username=root
+datasource.password=select111***
+datasource.driverClassName=com.mysql.jdbc.Driver
+datasource.initialSize=1
+datasource.minIdle=1
+datasource.maxActive=20
+datasource.maxWait=60000
+datasource.timeBetweenEvictionRunsMillis=60000
+datasource.minEvictableIdleTimeMillis=300000
+datasource.validationQuery=SELECT 1 FROM DUAL
+datasource.testWhileIdle=true
+datasource.testOnBorrow=true
+datasource.testOnReturn=false
+datasource.poolPreparedStatements=true
+datasource.timeBetweenLogStatsMillis=60000
+datasource.maxPoolPreparedStatementPerConnectionSize=20
+datasource.filters=stat,slf4j
+datasource.connectionProperties=druid.stat.mergeSql=false;druid.stat.slowSqlMillis=5000
+
+# Access path
+ps.product.url=http://218.17.158.219:24000/
+ps.message.url=http://218.17.158.219:24000/message/