xielq 4 anni fa
parent
commit
3a5ea0695d
36 ha cambiato i file con 1736 aggiunte e 0 eliminazioni
  1. 0 0
      README.md
  2. 58 0
      build.gradle
  3. 20 0
      gradle/dependencies-base.gradle
  4. 12 0
      gradle/tasks.gradle
  5. BIN
      gradle/wrapper/gradle-wrapper.jar
  6. 6 0
      gradle/wrapper/gradle-wrapper.properties
  7. 164 0
      gradlew
  8. 90 0
      gradlew.bat
  9. 2 0
      settings.gradle
  10. 6 0
      src/main/docker/Dockerfile
  11. 16 0
      src/main/java/com/uas/cloud/mall/store/cms/Application.java
  12. 5 0
      src/main/java/com/uas/cloud/mall/store/cms/README.md
  13. 71 0
      src/main/java/com/uas/cloud/mall/store/cms/api/RecommendProductController.java
  14. 52 0
      src/main/java/com/uas/cloud/mall/store/cms/api/StoreCmsController.java
  15. 39 0
      src/main/java/com/uas/cloud/mall/store/cms/component/KafkaConsumerDev.java
  16. 39 0
      src/main/java/com/uas/cloud/mall/store/cms/component/KafkaConsumerProd.java
  17. 39 0
      src/main/java/com/uas/cloud/mall/store/cms/component/KafkaConsumerTest.java
  18. 15 0
      src/main/java/com/uas/cloud/mall/store/cms/configuration/CorsConfig.java
  19. 242 0
      src/main/java/com/uas/cloud/mall/store/cms/domain/AdvantageCommodity.java
  20. 75 0
      src/main/java/com/uas/cloud/mall/store/cms/domain/Message.java
  21. 315 0
      src/main/java/com/uas/cloud/mall/store/cms/domain/RecommendProduct.java
  22. 17 0
      src/main/java/com/uas/cloud/mall/store/cms/facade/AdvantageCommodityFacade.java
  23. 35 0
      src/main/java/com/uas/cloud/mall/store/cms/facade/impl/AdvantageCommodityFacadeImpl.java
  24. 18 0
      src/main/java/com/uas/cloud/mall/store/cms/repository/AdvantageCommodityRepository.java
  25. 35 0
      src/main/java/com/uas/cloud/mall/store/cms/repository/RecommendProductDao.java
  26. 31 0
      src/main/java/com/uas/cloud/mall/store/cms/service/AdvantageCommodityService.java
  27. 39 0
      src/main/java/com/uas/cloud/mall/store/cms/service/RecommendProductService.java
  28. 67 0
      src/main/java/com/uas/cloud/mall/store/cms/service/impl/AdvantageCommodityServiceImpl.java
  29. 84 0
      src/main/java/com/uas/cloud/mall/store/cms/service/impl/RecommendProductServiceImpl.java
  30. 20 0
      src/main/java/com/uas/cloud/mall/store/cms/util/CommonUtils.java
  31. 68 0
      src/main/java/com/uas/cloud/mall/store/cms/util/JacksonUtils.java
  32. 13 0
      src/main/resources/application-dev.yml
  33. 14 0
      src/main/resources/application-prod.yml
  34. 13 0
      src/main/resources/application-test.yml
  35. 5 0
      src/main/resources/application.yml
  36. 11 0
      src/test/java/com/uas/cloud/mall/store/cms/SpringBase.java

+ 0 - 0
README.md


+ 58 - 0
build.gradle

@@ -0,0 +1,58 @@
+// Gradle build file for Gradle 2.14.1
+// Created by huxz on 2017-3-17 13:38:59
+buildscript {
+    ext {
+        springBootVersion = '1.5.3.RELEASE'
+        // 0.12.0 升级到了 Gradle 3.4,Gradle 2.14.1 只能使用 0.11.0及以下
+        dockerVersion = '0.11.0'
+        dcokerRegistry = "10.10.100.200:5000"
+    }
+    repositories {
+        maven { url "https://plugins.gradle.org/m2/" }
+        maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+        mavenCentral()
+        jcenter()
+    }
+    dependencies {
+        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+        classpath "gradle.plugin.com.palantir.gradle.docker:gradle-docker:${dockerVersion}"
+    }
+}
+
+group 'com.uas.cloud.mall'
+version '0.1.14'
+
+apply plugin: 'java'
+apply plugin: 'maven'
+apply plugin: "com.palantir.docker"
+apply plugin: "org.springframework.boot"
+
+apply from: "$rootDir/gradle/tasks.gradle"
+apply from: "$rootDir/gradle/dependencies-base.gradle"
+
+jar {
+    baseName = project.name
+    version = ''
+}
+
+allprojects {
+    sourceCompatibility = 1.8
+}
+
+dependencies {
+    compile("org.springframework.boot:spring-boot-starter-web")
+    compile("org.springframework.boot:spring-boot-starter-data-mongodb")
+
+	// kafka 依赖
+    compile("org.springframework.kafka:spring-kafka:1.2.2.RELEASE")
+}
+
+uploadArchives {
+    repositories {
+        mavenDeployer {
+            repository(url: "http://10.10.101.21:8081/artifactory/libs-release-local") {
+                authentication(userName: "yingp", password: "111111")
+            }
+        }
+    }
+}.dependsOn build

+ 20 - 0
gradle/dependencies-base.gradle

@@ -0,0 +1,20 @@
+// Gradle Base Dependencies Configurations
+// Created by huxz on 2017-3-17 14:39:36
+repositories {
+	mavenLocal()
+	maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
+	maven {
+		url 'http://10.10.101.21:8081/artifactory/libs-release'
+	}
+	maven {
+		url 'http://10.10.101.21:8081/artifactory/libs-snapshot'
+	}
+	maven {
+		url 'http://10.10.101.21:8081/artifactory/plugins-snapshot'
+	}
+	mavenCentral()
+}
+
+dependencies {
+	testCompile('org.springframework.boot:spring-boot-starter-test')
+}

+ 12 - 0
gradle/tasks.gradle

@@ -0,0 +1,12 @@
+// Gradle Tasks Configurations
+// Created by huxz on 2017-3-17 14:39:36
+bootRun {
+	addResources = true
+}
+
+docker {
+	name "${dcokerRegistry}/${project.name}:${project.version}"
+	tags "latest"
+	dockerfile "${projectDir}/src/main/docker/Dockerfile"
+	files "${buildDir}/libs/${project.name}.jar"
+}.dependsOn build

BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Fri Mar 03 10:34:25 CST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip

+ 164 - 0
gradlew

@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 2 - 0
settings.gradle

@@ -0,0 +1,2 @@
+rootProject.name = 'mall-storecms-service'
+

+ 6 - 0
src/main/docker/Dockerfile

@@ -0,0 +1,6 @@
+FROM hub.c.163.com/library/java:8-jre-alpine
+VOLUME /tmp
+ADD mall-storecms-service.jar app.jar
+RUN sh -c "touch /app.jar"
+ENV JAVA_OPTS=""
+ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar"]

+ 16 - 0
src/main/java/com/uas/cloud/mall/store/cms/Application.java

@@ -0,0 +1,16 @@
+package com.uas.cloud.mall.store.cms;
+
+import org.springframework.boot.Banner;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+
+@SpringBootApplication
+public class Application {
+
+	public static void main(String[] args) {
+		new SpringApplicationBuilder(Application.class)
+				.bannerMode(Banner.Mode.OFF)
+				.web(true)
+				.run(args);
+	}
+}

+ 5 - 0
src/main/java/com/uas/cloud/mall/store/cms/README.md

@@ -0,0 +1,5 @@
+# 功能记录
+
+## version 0.1.11
+
+* 添加异步通信,删除已经下架或失效的产品推荐

+ 71 - 0
src/main/java/com/uas/cloud/mall/store/cms/api/RecommendProductController.java

@@ -0,0 +1,71 @@
+package com.uas.cloud.mall.store.cms.api;
+
+import com.uas.cloud.mall.store.cms.domain.Message;
+import com.uas.cloud.mall.store.cms.domain.RecommendProduct;
+import com.uas.cloud.mall.store.cms.service.RecommendProductService;
+import com.uas.cloud.mall.store.cms.util.JacksonUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/api/recommend")
+public class RecommendProductController {
+
+	private final Logger logger = Logger.getLogger(getClass());
+
+	private final RecommendProductService productService;
+
+	@Autowired
+	public RecommendProductController(RecommendProductService productService) {
+		this.productService = productService;
+	}
+
+	/**
+	 * 当卖家修改产品推荐时,根据卖家企业UU获取产品推荐信息
+	 *
+	 * @param enuu		卖家企业UU
+	 */
+	@RequestMapping(value = "/products", method = RequestMethod.GET, produces = "application/json", params = "condition=enuu")
+	public List<RecommendProduct> findProductsWhenSellerUpdate(Long enuu) {
+		logger.info(String.format("Find products when seller[%d] update", enuu));
+		return productService.findProductsWhenSellerUpdate(enuu);
+	}
+
+	/**
+	 * 当用户访问店铺首页时,根据店铺的UUID获取产品推荐信息
+	 *
+	 * @param uuid	店铺UUID
+	 */
+	@RequestMapping(value = "/products", method = RequestMethod.GET, produces = "application/json", params = "condition=store_uuid")
+	public List<RecommendProduct> findProductsWhenUserVisitStore(String uuid) {
+		logger.info(String.format("Find products when user visit store[%s]", uuid));
+		return productService.findProductsWhenUserVisitStore(uuid);
+	}
+
+	/**
+	 * 暂时不用kafaka时候的  监听产品推荐删除消息
+	 *
+	 * @param content	待持久化的产品推荐信息列表
+	 */
+	@RequestMapping(value = "/products/delete", method = RequestMethod.POST, produces = "application/json")
+	public void deleteProductsWhenSellerUpdate( @RequestBody String content) {
+		logger.info(String.format("Process message: %s", content));
+		Message message = JacksonUtils.fromJson(content, Message.class);
+		productService.deleteProductsWhenSellerUpdateReserve(message.getUuid(), message.getBatchCodes());
+	}
+
+	/**
+	 * 当卖家新增或修改产品推荐时,创建或更新产品推荐信息
+	 *
+	 * @param recommendProducts	待持久化的产品推荐信息列表
+	 */
+	@RequestMapping(value = "/products", method = RequestMethod.POST, produces = "application/json")
+	public List<RecommendProduct> saveProductsWhenSellerUpdate(String uuid, @RequestBody List<RecommendProduct> recommendProducts) {
+		logger.info("Save products when user update");
+		return productService.saveProductsWhenSellerUpdate(uuid, recommendProducts);
+	}
+
+}

+ 52 - 0
src/main/java/com/uas/cloud/mall/store/cms/api/StoreCmsController.java

@@ -0,0 +1,52 @@
+package com.uas.cloud.mall.store.cms.api;
+
+import com.uas.cloud.mall.store.cms.domain.AdvantageCommodity;
+import com.uas.cloud.mall.store.cms.facade.AdvantageCommodityFacade;
+import com.uas.cloud.mall.store.cms.service.AdvantageCommodityService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/store-cms")
+public class StoreCmsController {
+
+	private static final Logger logger = LoggerFactory.getLogger(StoreCmsController.class);
+
+	private final AdvantageCommodityFacade advantageCommodityFacade;
+
+	private final AdvantageCommodityService advantageCommodityService;
+
+	@Autowired
+	public StoreCmsController(AdvantageCommodityFacade advantageCommodityFacade, AdvantageCommodityService advantageCommodityService) {
+		this.advantageCommodityFacade = advantageCommodityFacade;
+		this.advantageCommodityService = advantageCommodityService;
+	}
+
+	/**
+	 * 添加优势库存信息
+	 *
+	 * @param commodities	优势库存信息
+	 * @param enUU			所属公司UU
+	 * @param storeUuid		店铺UUID
+	 */
+	@RequestMapping(value = "/advantages", method = RequestMethod.POST, produces = "application/json")
+	public List<AdvantageCommodity> addAdvantages(@RequestBody List<AdvantageCommodity> commodities, @RequestParam Long enUU, @RequestParam String storeUuid) {
+		logger.info("Add advantage commodity information");
+		return advantageCommodityFacade.addAdvantages(commodities, enUU, storeUuid);
+	}
+
+	/**
+	 * 根据店铺UUID获取优势库存信息
+	 *
+	 * @param storeUuid		店铺UUID
+	 */
+	@RequestMapping(value = "/advantages", method = RequestMethod.GET, produces = "application/json")
+	public List<AdvantageCommodity> findByStoreUuid(@RequestParam String storeUuid) {
+		logger.info(String.format("Find advantage commodity information by store uuid %s", storeUuid));
+		return advantageCommodityService.findByStoreUuid(storeUuid);
+	}
+}

+ 39 - 0
src/main/java/com/uas/cloud/mall/store/cms/component/KafkaConsumerDev.java

@@ -0,0 +1,39 @@
+package com.uas.cloud.mall.store.cms.component;
+
+import com.uas.cloud.mall.store.cms.domain.Message;
+import com.uas.cloud.mall.store.cms.service.RecommendProductService;
+import com.uas.cloud.mall.store.cms.util.JacksonUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * Kafka 消息接受者
+ *
+ * @author huxz
+ * @version 2017-08-03 14:26:06 监听产品推荐删除消息
+ */
+@Component
+@Profile("dev")
+public class KafkaConsumerDev {
+
+	private final Logger logger = Logger.getLogger(KafkaConsumerDev.class);
+
+	private final RecommendProductService recommendProductService;
+
+	@Autowired
+	public KafkaConsumerDev(RecommendProductService recommendProductService) {
+		this.recommendProductService = recommendProductService;
+	}
+
+	@KafkaListener(topics = "recommend-products-delete-dev")
+	public void processMessage(String content) {
+		logger.info(String.format("[Dev]Process message: %s", content));
+		Message message = JacksonUtils.fromJson(content, Message.class);
+
+		// 删除推荐的产品
+		recommendProductService.deleteProductsWhenSellerUpdateReserve(message.getUuid(), message.getBatchCodes());
+	}
+}

+ 39 - 0
src/main/java/com/uas/cloud/mall/store/cms/component/KafkaConsumerProd.java

@@ -0,0 +1,39 @@
+package com.uas.cloud.mall.store.cms.component;
+
+import com.uas.cloud.mall.store.cms.domain.Message;
+import com.uas.cloud.mall.store.cms.service.RecommendProductService;
+import com.uas.cloud.mall.store.cms.util.JacksonUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * Kafka 消息接受者
+ *
+ * @author huxz
+ * @version 2017-08-03 14:26:06 监听产品推荐删除消息
+ */
+@Component
+@Profile("prod")
+public class KafkaConsumerProd {
+
+	private final Logger logger = Logger.getLogger(KafkaConsumerProd.class);
+
+	private final RecommendProductService recommendProductService;
+
+	@Autowired
+	public KafkaConsumerProd(RecommendProductService recommendProductService) {
+		this.recommendProductService = recommendProductService;
+	}
+
+	@KafkaListener(topics = "recommend-products-delete-prod")
+	public void processMessage(String content) {
+		logger.info(String.format("[Prod]Process message: %s", content));
+		Message message = JacksonUtils.fromJson(content, Message.class);
+
+		// 删除推荐的产品
+		recommendProductService.deleteProductsWhenSellerUpdateReserve(message.getUuid(), message.getBatchCodes());
+	}
+}

+ 39 - 0
src/main/java/com/uas/cloud/mall/store/cms/component/KafkaConsumerTest.java

@@ -0,0 +1,39 @@
+package com.uas.cloud.mall.store.cms.component;
+
+import com.uas.cloud.mall.store.cms.domain.Message;
+import com.uas.cloud.mall.store.cms.service.RecommendProductService;
+import com.uas.cloud.mall.store.cms.util.JacksonUtils;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Profile;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+/**
+ * Kafka 消息接受者
+ *
+ * @author huxz
+ * @version 2017-08-03 14:26:06 监听产品推荐删除消息
+ */
+@Component
+@Profile("test")
+public class KafkaConsumerTest {
+
+	private final Logger logger = Logger.getLogger(KafkaConsumerTest.class);
+
+	private final RecommendProductService recommendProductService;
+
+	@Autowired
+	public KafkaConsumerTest(RecommendProductService recommendProductService) {
+		this.recommendProductService = recommendProductService;
+	}
+
+	@KafkaListener(topics = "recommend-products-delete-test")
+	public void processMessage(String content) {
+		logger.info(String.format("[Test]Process message: %s", content));
+		Message message = JacksonUtils.fromJson(content, Message.class);
+
+		// 删除推荐的产品
+		recommendProductService.deleteProductsWhenSellerUpdateReserve(message.getUuid(), message.getBatchCodes());
+	}
+}

+ 15 - 0
src/main/java/com/uas/cloud/mall/store/cms/configuration/CorsConfig.java

@@ -0,0 +1,15 @@
+package com.uas.cloud.mall.store.cms.configuration;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+
+@Configuration
+public class CorsConfig extends WebMvcConfigurerAdapter {
+
+	@Override
+	public void addCorsMappings(CorsRegistry registry) {
+		registry.addMapping("/api/**")
+				.allowedOrigins("*");
+	}
+}

+ 242 - 0
src/main/java/com/uas/cloud/mall/store/cms/domain/AdvantageCommodity.java

@@ -0,0 +1,242 @@
+package com.uas.cloud.mall.store.cms.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+import java.util.Date;
+
+/**
+ * 优势库存信息
+ *
+ * history:
+ * Created by huxz on 2017-3-3 10:44:16
+ */
+@Document(collection = "store_cms_advantage")
+public class AdvantageCommodity {
+
+	/**
+	 * 主键UUID
+	 */
+	@Id
+	private String id;
+
+	/*=========================================================================
+	 * 基础信息
+	 *=========================================================================*/
+
+	/**
+	 * 创建时间
+	 */
+	@Field(value = "ad_create_time")
+	private Date createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@Field(value = "ad_update_time")
+	private Date updateTime;
+
+	/**
+	 * 排序
+	 */
+	@Field(value = "ad_order")
+	private int order;
+
+	/*=========================================================================
+	 * 商品基础信息
+	 *=========================================================================*/
+
+	/**
+	 * 商品批次号
+	 */
+	@Field(value = "ad_com_batchCode")
+	private String batchCode;
+
+	/**
+	 * 对应的器件uuid
+	 */
+	@Field(value = "ad_com_uuid")
+	private String comUuid;
+
+	/**
+	 * 原厂型号
+	 */
+	@Field(value = "ad_com_code")
+	private String comCode;
+
+	/**
+	 * 图片path
+	 */
+	@Field(value = "ad_com_img")
+	private String comImg;
+
+	/**
+	 * 类名UUID
+	 */
+	@Field(value = "ad_kind_uuid")
+	private String kindUuid;
+
+	/**
+	 * 类目的名称
+	 */
+	@Field(value = "ad_kind_name_cn")
+	private String kindNameCn;
+
+	/**
+	 * 品牌中文名称
+	 */
+	@Field(value = "ad_brand_name_cn")
+	private String brandNameCn;
+
+	/**
+	 * 本批次的最低人民币价格
+	 */
+	@Field(value = "ad_min_price_rmb")
+	private Double minPriceRMB;
+
+	/**
+	 * 本批次的最低美元价格
+	 */
+	@Field(value = "ad_min_price_usd")
+	private Double minPriceUSD;
+
+	/*=========================================================================
+	 * 店铺信息
+	 *=========================================================================*/
+
+	/**
+	 * 店铺所属公司
+	 */
+	@Field(value = "ad_store_enuu")
+	private Long storeEnUU;
+
+	/**
+	 * 店铺UUID
+	 */
+	@Field(value = "ad_store_uuid")
+	private String storeUuid;
+
+	public AdvantageCommodity() {
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Date getUpdateTime() {
+		return updateTime;
+	}
+
+	public void setUpdateTime(Date updateTime) {
+		this.updateTime = updateTime;
+	}
+
+	public int getOrder() {
+		return order;
+	}
+
+	public void setOrder(int order) {
+		this.order = order;
+	}
+
+	public String getBatchCode() {
+		return batchCode;
+	}
+
+	public void setBatchCode(String batchCode) {
+		this.batchCode = batchCode;
+	}
+
+	public String getComUuid() {
+		return comUuid;
+	}
+
+	public void setComUuid(String comUuid) {
+		this.comUuid = comUuid;
+	}
+
+	public String getComCode() {
+		return comCode;
+	}
+
+	public void setComCode(String comCode) {
+		this.comCode = comCode;
+	}
+
+	public String getComImg() {
+		return comImg;
+	}
+
+	public void setComImg(String comImg) {
+		this.comImg = comImg;
+	}
+
+	public String getKindUuid() {
+		return kindUuid;
+	}
+
+	public void setKindUuid(String kindUuid) {
+		this.kindUuid = kindUuid;
+	}
+
+	public String getKindNameCn() {
+		return kindNameCn;
+	}
+
+	public void setKindNameCn(String kindNameCn) {
+		this.kindNameCn = kindNameCn;
+	}
+
+	public String getBrandNameCn() {
+		return brandNameCn;
+	}
+
+	public void setBrandNameCn(String brandNameCn) {
+		this.brandNameCn = brandNameCn;
+	}
+
+	public Double getMinPriceRMB() {
+		return minPriceRMB;
+	}
+
+	public void setMinPriceRMB(Double minPriceRMB) {
+		this.minPriceRMB = minPriceRMB;
+	}
+
+	public Double getMinPriceUSD() {
+		return minPriceUSD;
+	}
+
+	public void setMinPriceUSD(Double minPriceUSD) {
+		this.minPriceUSD = minPriceUSD;
+	}
+
+	public Long getStoreEnUU() {
+		return storeEnUU;
+	}
+
+	public void setStoreEnUU(Long storeEnUU) {
+		this.storeEnUU = storeEnUU;
+	}
+
+	public String getStoreUuid() {
+		return storeUuid;
+	}
+
+	public void setStoreUuid(String storeUuid) {
+		this.storeUuid = storeUuid;
+	}
+}

+ 75 - 0
src/main/java/com/uas/cloud/mall/store/cms/domain/Message.java

@@ -0,0 +1,75 @@
+package com.uas.cloud.mall.store.cms.domain;
+
+import com.uas.cloud.mall.store.cms.util.JacksonUtils;
+
+import java.util.Date;
+import java.util.Set;
+
+/**
+ * Kafka 消息实体类
+ *
+ * @author huxz
+ * @version 2017-08-03 14:28:01 创建消息实体类
+ */
+public class Message {
+
+	/**
+	 * ID
+	 */
+	private long id;
+
+	/**
+	 * 发送时间
+	 */
+	private Date sendTime;
+
+	/**
+	 * 店铺UUID
+	 */
+	private String uuid;
+
+	/**
+	 * 批次信息
+	 */
+	private Set<String> batchCodes;
+
+	public Message() {
+	}
+
+	public long getId() {
+		return id;
+	}
+
+	public void setId(long id) {
+		this.id = id;
+	}
+
+	public Date getSendTime() {
+		return sendTime;
+	}
+
+	public void setSendTime(Date sendTime) {
+		this.sendTime = sendTime;
+	}
+
+	public String getUuid() {
+		return uuid;
+	}
+
+	public void setUuid(String uuid) {
+		this.uuid = uuid;
+	}
+
+	public Set<String> getBatchCodes() {
+		return batchCodes;
+	}
+
+	public void setBatchCodes(Set<String> batchCodes) {
+		this.batchCodes = batchCodes;
+	}
+
+	@Override
+	public String toString() {
+		return JacksonUtils.toJson(this);
+	}
+}

+ 315 - 0
src/main/java/com/uas/cloud/mall/store/cms/domain/RecommendProduct.java

@@ -0,0 +1,315 @@
+package com.uas.cloud.mall.store.cms.domain;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+
+import java.util.Date;
+
+/**
+ * 优势库存信息
+ *
+ * history:
+ * Created by huxz on 2017-3-3 10:44:16
+ */
+@Document(collection = "store_product_recommendation")
+public class RecommendProduct {
+
+	/**
+	 * 主键UUID
+	 */
+	@Id
+	private String id;
+
+	/*=========================================================================
+	 * 基础信息
+	 *=========================================================================*/
+
+	/**
+	 * 创建时间
+	 */
+	@Field(value = "create_time")
+	private Date createTime;
+
+	/**
+	 * 修改时间
+	 */
+	@Field(value = "update_time")
+	private Date updateTime;
+
+	/**
+	 * 排序
+	 */
+	@Field(value = "order")
+	private int order;
+
+	/*=========================================================================
+	 * 商品基础信息
+	 *=========================================================================*/
+
+	/**
+	 * 商品批次号
+	 */
+	@Field(value = "batch_code")
+	private String batchCode;
+
+	/**
+	 * 对应的器件uuid
+	 */
+	@Field(value = "com_uuid")
+	private String comUuid;
+
+	/**
+	 * 原厂型号
+	 */
+	@Field(value = "com_code")
+	private String comCode;
+
+	/**
+	 * 图片path
+	 */
+	@Field(value = "com_img")
+	private String comImg;
+
+	/**
+	 * 类名UUID
+	 */
+	@Field(value = "kind_uuid")
+	private String kindUuid;
+
+	/**
+	 * 类目的名称
+	 */
+	@Field(value = "kind_name_cn")
+	private String kindNameCn;
+
+	/**
+	 * 品牌中文名称
+	 */
+	@Field(value = "brand_name_cn")
+	private String brandNameCn;
+
+	/**
+	 * 本批次的最低人民币价格
+	 */
+	@Field(value = "min_price_rmb")
+	private Double minPriceRMB;
+
+	/**
+	 * 本批次的最低美元价格
+	 */
+	@Field(value = "min_price_usd")
+	private Double minPriceUSD;
+
+	/**
+	 * 商品库存量
+	 */
+	@Field(value = "reserve")
+	private Double reserve;
+
+	/**
+	 * 最小起订量
+	 */
+	@Field(value = "min_buy_qty")
+	private Double minBuyQty;
+
+	/**
+	 * 币别
+	 */
+	@Field(value = "currency")
+	private String currency;
+
+	/**
+	 * 产品上架的店铺的UUID
+	 */
+	@Field(value = "store_second_id")
+	private String storeId;
+
+	/*=========================================================================
+	 * 店铺信息
+	 *=========================================================================*/
+
+	/**
+	 * 产品推荐拥有者所属公司UU
+	 */
+	@Indexed
+	@Field(value = "store_enuu")
+	private Long storeEnUU;
+
+	/**
+	 * 产品推荐拥有者的店铺UUID
+	 */
+	@Indexed
+	@Field(value = "store_uuid")
+	private String storeUuid;
+
+	/**
+	 * 售罄状态
+	 */
+	@Field(value = "status")
+	private Integer status;
+
+	public RecommendProduct() {
+	}
+
+	public Integer getStatus() {
+		return status;
+	}
+
+	public void setStatus(Integer status) {
+		this.status = status;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public Date getCreateTime() {
+		return createTime;
+	}
+
+	public void setCreateTime(Date createTime) {
+		this.createTime = createTime;
+	}
+
+	public Date getUpdateTime() {
+		return updateTime;
+	}
+
+	public void setUpdateTime(Date updateTime) {
+		this.updateTime = updateTime;
+	}
+
+	public int getOrder() {
+		return order;
+	}
+
+	public void setOrder(int order) {
+		this.order = order;
+	}
+
+	public String getBatchCode() {
+		return batchCode;
+	}
+
+	public void setBatchCode(String batchCode) {
+		this.batchCode = batchCode;
+	}
+
+	public String getComUuid() {
+		return comUuid;
+	}
+
+	public void setComUuid(String comUuid) {
+		this.comUuid = comUuid;
+	}
+
+	public String getComCode() {
+		return comCode;
+	}
+
+	public void setComCode(String comCode) {
+		this.comCode = comCode;
+	}
+
+	public String getComImg() {
+		return comImg;
+	}
+
+	public void setComImg(String comImg) {
+		this.comImg = comImg;
+	}
+
+	public String getKindUuid() {
+		return kindUuid;
+	}
+
+	public void setKindUuid(String kindUuid) {
+		this.kindUuid = kindUuid;
+	}
+
+	public String getKindNameCn() {
+		return kindNameCn;
+	}
+
+	public void setKindNameCn(String kindNameCn) {
+		this.kindNameCn = kindNameCn;
+	}
+
+	public String getBrandNameCn() {
+		return brandNameCn;
+	}
+
+	public void setBrandNameCn(String brandNameCn) {
+		this.brandNameCn = brandNameCn;
+	}
+
+	public Double getMinPriceRMB() {
+		return minPriceRMB;
+	}
+
+	public void setMinPriceRMB(Double minPriceRMB) {
+		this.minPriceRMB = minPriceRMB;
+	}
+
+	public Double getMinPriceUSD() {
+		return minPriceUSD;
+	}
+
+	public void setMinPriceUSD(Double minPriceUSD) {
+		this.minPriceUSD = minPriceUSD;
+	}
+
+	public Double getReserve() {
+		return reserve;
+	}
+
+	public void setReserve(Double reserve) {
+		this.reserve = reserve;
+	}
+
+	public Double getMinBuyQty() {
+		return minBuyQty;
+	}
+
+	public void setMinBuyQty(Double minBuyQty) {
+		this.minBuyQty = minBuyQty;
+	}
+
+	public String getCurrency() {
+		return currency;
+	}
+
+	public void setCurrency(String currency) {
+		this.currency = currency;
+	}
+
+	public String getStoreId() {
+		return storeId;
+	}
+
+	public void setStoreId(String storeId) {
+		this.storeId = storeId;
+	}
+
+	public Long getStoreEnUU() {
+		return storeEnUU;
+	}
+
+	public void setStoreEnUU(Long storeEnUU) {
+		this.storeEnUU = storeEnUU;
+	}
+
+	public String getStoreUuid() {
+		return storeUuid;
+	}
+
+	public void setStoreUuid(String storeUuid) {
+		this.storeUuid = storeUuid;
+	}
+}

+ 17 - 0
src/main/java/com/uas/cloud/mall/store/cms/facade/AdvantageCommodityFacade.java

@@ -0,0 +1,17 @@
+package com.uas.cloud.mall.store.cms.facade;
+
+import com.uas.cloud.mall.store.cms.domain.AdvantageCommodity;
+
+import java.util.List;
+
+public interface AdvantageCommodityFacade {
+
+	/**
+	 * 批量添加优势库存
+	 *
+	 * @param commodities	待持久化的优势库存列表
+	 * @param enUU			公司所属UU
+	 * @param storeUuid		店铺UUID
+	 */
+	List<AdvantageCommodity> addAdvantages(List<AdvantageCommodity> commodities, Long enUU, String storeUuid);
+}

+ 35 - 0
src/main/java/com/uas/cloud/mall/store/cms/facade/impl/AdvantageCommodityFacadeImpl.java

@@ -0,0 +1,35 @@
+package com.uas.cloud.mall.store.cms.facade.impl;
+
+import com.uas.cloud.mall.store.cms.domain.AdvantageCommodity;
+import com.uas.cloud.mall.store.cms.facade.AdvantageCommodityFacade;
+import com.uas.cloud.mall.store.cms.service.AdvantageCommodityService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+
+@Service
+public class AdvantageCommodityFacadeImpl implements AdvantageCommodityFacade {
+
+	private final AdvantageCommodityService advantageCommodityService;
+
+	@Autowired
+	public AdvantageCommodityFacadeImpl(AdvantageCommodityService advantageCommodityService) {
+		this.advantageCommodityService = advantageCommodityService;
+	}
+
+	@Override
+	public List<AdvantageCommodity> addAdvantages(List<AdvantageCommodity> commodities, Long enUU, String storeUuid) {
+		if (CollectionUtils.isEmpty(commodities) || enUU == null || StringUtils.isEmpty(storeUuid)) {
+			return null;
+		}
+		// 删除原有的优势库存信息
+		List<AdvantageCommodity> commodityList = advantageCommodityService.findByStoreUuid(storeUuid);
+		if (!CollectionUtils.isEmpty(commodityList)) {
+			advantageCommodityService.batchDeleteAdvantage(commodityList);
+		}
+		return advantageCommodityService.batchCreateAdvantage(commodities, enUU, storeUuid);
+	}
+}

+ 18 - 0
src/main/java/com/uas/cloud/mall/store/cms/repository/AdvantageCommodityRepository.java

@@ -0,0 +1,18 @@
+package com.uas.cloud.mall.store.cms.repository;
+
+import com.uas.cloud.mall.store.cms.domain.AdvantageCommodity;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface AdvantageCommodityRepository extends MongoRepository<AdvantageCommodity, String> {
+
+	/**
+	 * 根据店铺UUID获取优势库存信息
+	 *
+	 * @param storeUuid		店铺UUID
+	 */
+	List<AdvantageCommodity> findByStoreUuid(String storeUuid);
+}

+ 35 - 0
src/main/java/com/uas/cloud/mall/store/cms/repository/RecommendProductDao.java

@@ -0,0 +1,35 @@
+package com.uas.cloud.mall.store.cms.repository;
+
+import com.uas.cloud.mall.store.cms.domain.RecommendProduct;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.Set;
+
+@Repository
+public interface RecommendProductDao extends MongoRepository<RecommendProduct, String> {
+
+	/**
+	 * 根据店铺企业UU获取产品推荐信息
+	 *
+	 * @param storeEnUU		店铺企业UU
+	 */
+	List<RecommendProduct> findByStoreEnUUOrderByOrderAsc(Long storeEnUU);
+
+	/**
+	 * 根据店铺UUID获取产品推荐信息
+	 *
+	 * @param storeUuid		店铺UUID
+	 */
+	List<RecommendProduct> findByStoreUuidOrderByOrderAsc(String storeUuid);
+
+	/**
+	 * 根据店铺和商品批次号获取产品推荐信息列表
+	 *
+	 * @param storeUuid		店铺UUID
+	 * @param batchCodes	商品批次号集合
+	 * @return	产品推荐信息列表
+	 */
+	List<RecommendProduct> findByStoreUuidAndBatchCodeIn(String storeUuid, Set<String> batchCodes);
+}

+ 31 - 0
src/main/java/com/uas/cloud/mall/store/cms/service/AdvantageCommodityService.java

@@ -0,0 +1,31 @@
+package com.uas.cloud.mall.store.cms.service;
+
+import com.uas.cloud.mall.store.cms.domain.AdvantageCommodity;
+
+import java.util.List;
+
+public interface AdvantageCommodityService {
+
+	/**
+	 * 批量添加优势库存
+	 *
+	 * @param advantageCommodities	待持久化的优势库存列表
+	 * @param enUU			公司所属UU
+	 * @param storeUuid		店铺UUID
+	 */
+	List<AdvantageCommodity> batchCreateAdvantage(List<AdvantageCommodity> advantageCommodities, Long enUU, String storeUuid);
+
+	/**
+	 * 批量删除优势库存信息
+	 *
+	 * @param advantageCommodities	待删除的优势库存列表
+	 */
+	boolean batchDeleteAdvantage(List<AdvantageCommodity> advantageCommodities);
+
+	/**
+	 * 根据店铺UUID获取优势库存列表信息
+	 *
+	 * @param storeUuid	店铺UUID
+	 */
+	List<AdvantageCommodity> findByStoreUuid(String storeUuid);
+}

+ 39 - 0
src/main/java/com/uas/cloud/mall/store/cms/service/RecommendProductService.java

@@ -0,0 +1,39 @@
+package com.uas.cloud.mall.store.cms.service;
+
+import com.uas.cloud.mall.store.cms.domain.RecommendProduct;
+
+import java.util.List;
+import java.util.Set;
+
+public interface RecommendProductService {
+
+	/**
+	 * 当卖家修改产品推荐时,根据卖家企业UU获取产品推荐信息
+	 *
+	 * @param enUU		卖家企业UU
+	 */
+	List<RecommendProduct> findProductsWhenSellerUpdate(Long enUU);
+
+	/**
+	 * 当用户访问店铺首页时,根据店铺的UUID获取产品推荐信息
+	 *
+	 * @param storeUuid	店铺UUID
+	 */
+	List<RecommendProduct> findProductsWhenUserVisitStore(String storeUuid);
+
+	/**
+	 * 当卖家新增或修改产品推荐时,创建或更新产品推荐信息
+	 *
+	 * @param uuid	店铺UUID
+	 * @param recommendProducts    待持久化的产品推荐信息列表
+	 */
+	List<RecommendProduct> saveProductsWhenSellerUpdate(String uuid, List<RecommendProduct> recommendProducts);
+
+	/**
+	 * 当卖家更新商品库存时,异步更新已下架或已失效的推荐产品信息
+	 *
+	 * @param storeUuid		店铺UUID
+	 * @param batchCodes	待更新的产品批次号
+	 */
+	void deleteProductsWhenSellerUpdateReserve(String storeUuid, Set<String> batchCodes);
+}

+ 67 - 0
src/main/java/com/uas/cloud/mall/store/cms/service/impl/AdvantageCommodityServiceImpl.java

@@ -0,0 +1,67 @@
+package com.uas.cloud.mall.store.cms.service.impl;
+
+import com.uas.cloud.mall.store.cms.domain.AdvantageCommodity;
+import com.uas.cloud.mall.store.cms.repository.AdvantageCommodityRepository;
+import com.uas.cloud.mall.store.cms.service.AdvantageCommodityService;
+import com.uas.cloud.mall.store.cms.util.CommonUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.List;
+
+@Service
+public class AdvantageCommodityServiceImpl implements AdvantageCommodityService {
+
+	private final AdvantageCommodityRepository advantageCommodityDao;
+
+	@Autowired
+	public AdvantageCommodityServiceImpl(AdvantageCommodityRepository advantageCommodityDao) {
+		this.advantageCommodityDao = advantageCommodityDao;
+	}
+
+	@Override
+	public List<AdvantageCommodity> batchCreateAdvantage(List<AdvantageCommodity> advantageCommodities, Long enUU, String storeUuid) {
+		if (CollectionUtils.isEmpty(advantageCommodities) || enUU == null || StringUtils.isEmpty(storeUuid)) {
+			return null;
+		}
+		int i = 0;
+		for (AdvantageCommodity advantageCommodity : advantageCommodities) {
+			Date date = new Date();
+			advantageCommodity.setId(CommonUtils.generateUUid());
+			advantageCommodity.setOrder(i);
+			advantageCommodity.setCreateTime(date);
+			advantageCommodity.setUpdateTime(date);
+			advantageCommodity.setStoreEnUU(enUU);
+			advantageCommodity.setStoreUuid(storeUuid);
+			advantageCommodityDao.save(advantageCommodity);
+			i ++;
+		}
+		return advantageCommodities;
+	}
+
+	@Override
+	public boolean batchDeleteAdvantage(List<AdvantageCommodity> advantageCommodities) {
+		if (CollectionUtils.isEmpty(advantageCommodities)) {
+			return false;
+		}
+		for (AdvantageCommodity advantageCommodity : advantageCommodities) {
+			try {
+				advantageCommodityDao.delete(advantageCommodity.getId());
+			} catch (Exception e) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	@Override
+	public List<AdvantageCommodity> findByStoreUuid(String storeUuid) {
+		if (StringUtils.isEmpty(storeUuid)) {
+			return null;
+		}
+		return advantageCommodityDao.findByStoreUuid(storeUuid);
+	}
+}

+ 84 - 0
src/main/java/com/uas/cloud/mall/store/cms/service/impl/RecommendProductServiceImpl.java

@@ -0,0 +1,84 @@
+package com.uas.cloud.mall.store.cms.service.impl;
+
+import com.uas.cloud.mall.store.cms.domain.RecommendProduct;
+import com.uas.cloud.mall.store.cms.repository.RecommendProductDao;
+import com.uas.cloud.mall.store.cms.service.RecommendProductService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+@Service
+public class RecommendProductServiceImpl implements RecommendProductService {
+
+	private final RecommendProductDao productDao;
+
+	@Autowired
+	public RecommendProductServiceImpl(RecommendProductDao productDao) {
+		this.productDao = productDao;
+	}
+
+	@Override
+	public List<RecommendProduct> findProductsWhenSellerUpdate(Long enUU) {
+		if (enUU == null) {
+			return Collections.emptyList();
+		}
+
+		List<RecommendProduct> products = productDao.findByStoreEnUUOrderByOrderAsc(enUU);
+		return CollectionUtils.isEmpty(products) ? Collections.emptyList() : products;
+	}
+
+	@Override
+	public List<RecommendProduct> findProductsWhenUserVisitStore(String storeUuid) {
+		if (StringUtils.isEmpty(storeUuid)) {
+			return Collections.emptyList();
+		}
+
+		List<RecommendProduct> products = productDao.findByStoreUuidOrderByOrderAsc(storeUuid);
+		return CollectionUtils.isEmpty(products) ? Collections.emptyList() : products;
+	}
+
+	@Override
+	public List<RecommendProduct> saveProductsWhenSellerUpdate(String uuid, List<RecommendProduct> recommendProducts) {
+		if (StringUtils.isEmpty(uuid)) {
+			return Collections.emptyList();
+		}
+
+		List<RecommendProduct> products = productDao.findByStoreUuidOrderByOrderAsc(uuid);
+		if (!CollectionUtils.isEmpty(products)) {
+			productDao.delete(products);
+		}
+
+		if (CollectionUtils.isEmpty(recommendProducts)) {
+			return Collections.emptyList();
+		}
+
+		for (RecommendProduct product : recommendProducts) {
+			Date nowDate = new Date();
+
+			product.setStoreUuid(uuid);
+			product.setCreateTime(nowDate);
+			product.setUpdateTime(nowDate);
+			productDao.save(product);
+		}
+		return recommendProducts;
+	}
+
+	@Override
+	public void deleteProductsWhenSellerUpdateReserve(String storeUuid, Set<String> batchCodes) {
+		if (StringUtils.isEmpty(storeUuid) || CollectionUtils.isEmpty(batchCodes)) {
+			return ;
+		}
+		List<RecommendProduct> products = productDao.findByStoreUuidAndBatchCodeIn(storeUuid, batchCodes);
+
+		// 如果查询到了产品推荐信息,则删除对应的推荐产品
+		if (!CollectionUtils.isEmpty(products)) {
+			productDao.delete(products);
+		}
+	}
+}

+ 20 - 0
src/main/java/com/uas/cloud/mall/store/cms/util/CommonUtils.java

@@ -0,0 +1,20 @@
+package com.uas.cloud.mall.store.cms.util;
+
+import java.util.UUID;
+
+/**
+ * 通用工具类
+ *
+ * history:
+ * Created by huxz on 2017-2-23 11:42:16
+ */
+public class CommonUtils {
+
+	/**
+	 * 生成UUID
+	 */
+	public static String generateUUid() {
+		String uuid = UUID.randomUUID().toString();
+		return uuid.replace("-", "");
+	}
+}

+ 68 - 0
src/main/java/com/uas/cloud/mall/store/cms/util/JacksonUtils.java

@@ -0,0 +1,68 @@
+package com.uas.cloud.mall.store.cms.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * JSON 工具类
+ *
+ * history:
+ * Created by huxz on 2017-3-1 10:16:03
+ */
+public final class JacksonUtils {
+
+	private static ObjectMapper objectMapper;
+
+	/**
+	 * 把JSON文本parse为JavaBean
+	 */
+	public static <T> T fromJson(String text, Class<T> clazz) {
+		if (objectMapper == null) {
+			objectMapper = new ObjectMapper();
+		}
+		try {
+			return objectMapper.readValue(text, clazz);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * 把JSON文本parse成JavaBean集合
+	 */
+	public static <T> List<T> fromJsonArray(String text, Class<T> clazz) {
+		if (objectMapper == null) {
+			objectMapper = new ObjectMapper();
+		}
+		JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, clazz);
+		try {
+			return objectMapper.readValue(text, javaType);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return Collections.emptyList();
+	}
+
+	/**
+	 * 将JavaBean序列化为JSON文本
+	 */
+	public static String toJson(Object object) {
+		if (objectMapper == null) {
+			objectMapper = new ObjectMapper();
+		}
+		try {
+			return objectMapper.writeValueAsString(object);
+		} catch (JsonProcessingException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+}

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

@@ -0,0 +1,13 @@
+server:
+  port: 20100
+
+spring:
+  data:
+    mongodb:
+      uri: mongodb://10.10.101.22:27017/mall_cms
+  kafka:
+    bootstrap-servers: 10.10.100.11:9292,10.10.100.12:9292,10.10.100.13:9292,10.10.100.14:9292,10.10.100.15:9292,10.10.100.16:9292
+    consumer:
+      group-id: recommend-products-dev
+      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

+ 14 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,14 @@
+server:
+  port: 20100
+
+spring:
+  data:
+    mongodb:
+       uri: mongodb://10.10.0.218:27017/mall_cms
+#      uri: mongodb://10.10.100.18:27017/mall_cms@prod
+#  kafka:
+#    bootstrap-servers: 10.10.100.11:9292,10.10.100.12:9292,10.10.100.13:9292,10.10.100.14:9292,10.10.100.15:9292,10.10.100.16:9292
+#    consumer:
+#      group-id: recommend-products-prod
+#      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+#      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

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

@@ -0,0 +1,13 @@
+server:
+  port: 20100
+
+spring:
+  data:
+    mongodb:
+      uri: mongodb://10.10.101.22:27017/mall_cms
+  kafka:
+    bootstrap-servers: 10.10.100.11:9292,10.10.100.12:9292,10.10.100.13:9292,10.10.100.14:9292,10.10.100.15:9292,10.10.100.16:9292
+    consumer:
+      group-id: recommend-products-test
+      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
+      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

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

@@ -0,0 +1,5 @@
+spring:
+  application:
+    name: mall-storecms-service
+  profiles:
+    active: dev

+ 11 - 0
src/test/java/com/uas/cloud/mall/store/cms/SpringBase.java

@@ -0,0 +1,11 @@
+package com.uas.cloud.mall.store.cms;
+
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public abstract class SpringBase {
+
+}