소스 검색

optimize the recommended course

guozhaoshun 6 년 전
부모
커밋
b9de4f6722

+ 57 - 3
rankin-api-web/src/main/java/cn/rankin/apiweb/controller/RecommendController.java

@@ -2,11 +2,14 @@ package cn.rankin.apiweb.controller;
 
 import cn.rankin.apiweb.assist.resolver.NeedUser;
 import cn.rankin.apiweb.code.ApiWebCode;
+import cn.rankin.apiweb.service.event.EventService;
 import cn.rankin.apiweb.service.product.ProductService;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.data.api.app.vo.DeviceUserVo;
 import cn.rankin.data.api.app.vo.RecommendVo;
+import cn.rankin.data.api.product.entity.Course;
 import cn.rankin.data.api.product.entity.Poster;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
@@ -15,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
-
+@Slf4j
 @RestController
 @RequestMapping(value = "/recommend")
 public class RecommendController {
@@ -23,14 +26,65 @@ public class RecommendController {
     @Autowired
     private ProductService productService;
 
+    @Autowired
+    private EventService eventService;
+
+    public static final int RECOMMEND_NUM = 5;
+
     @RequestMapping(value = "/courses", method = RequestMethod.GET)
     public APIResult<List<RecommendVo>> getRecommend(@NeedUser DeviceUserVo user) {
         if (user == null) {
             return APIResult.error(ApiWebCode.NOT_EXISTS);
         }
 
-        String merchantId = user.getMerchantId();
-        return productService.getRecommendCourses(merchantId);
+        List<RecommendVo> result = new ArrayList<>();
+
+        //查询浏览历史课程ID,已去重
+        List<String> courseIds = eventService.getCoursesFromLogs(user.getUid());
+//        log.info("get course ids from logs, courseIds={}", courseIds);
+        if(courseIds != null && courseIds.size() > 0){
+            //如果有浏览历史,提取浏览历史前五展示    (目前推荐位为5)
+            courseIds.forEach(courseId -> {
+                if(result.size() <= RECOMMEND_NUM){
+                    Course course = productService.getCourse(courseId);
+                    if(course != null){
+                        RecommendVo vo = new RecommendVo();
+                        vo.setId(course.getId());
+                        vo.setCode(course.getCode());
+                        vo.setTitle(course.getTitle());
+                        vo.setSubTitle(course.getSubTitle());
+                        vo.setBreadCrumb(course.getBreadCrumb());
+                        vo.setCoverUrl(course.getCoverUrl());
+                        result.add(vo);
+                    }
+                }
+            });
+
+
+            if(result.size() < RECOMMEND_NUM){
+                //浏览历史少于五,追加推荐,补足五  (目前推荐位为5)
+                String merchantId = user.getMerchantId();
+                APIResult<List<RecommendVo>> apiResult = productService.getRecommendCourses(merchantId);
+                if(!apiResult.getSuccess()){
+                    return apiResult;
+                }
+
+                List<RecommendVo> data = apiResult.getData();
+
+                log.info("get recommend course , size={}", data.size());
+                int num = RECOMMEND_NUM - result.size();
+                for (int i = 0; i < num; i++) {
+                    result.add(data.get(i));
+                }
+            }
+            return APIResult.ok(result);
+        }else{
+            //不存在浏览历史,直接使用推荐
+            String merchantId = user.getMerchantId();
+            return productService.getRecommendCourses(merchantId);
+        }
+
+
     }
 
     /**

+ 8 - 3
rankin-api-web/src/main/java/cn/rankin/apiweb/service/event/EventClient.java

@@ -1,15 +1,20 @@
 package cn.rankin.apiweb.service.event;
 
 import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.data.api.product.entity.Course;
 import cn.rankin.data.api.user.dto.EventLogDTO;
+import cn.rankin.data.api.user.entity.EventLog;
 import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 @FeignClient(name = "${service.user.name}")
 public interface EventClient {
 
     @RequestMapping(value = "/event", method = RequestMethod.POST)
     APIResult<Boolean> addLog(@RequestBody EventLogDTO eventLogDTO);
+
+    @RequestMapping(value = "/event/{uid}", method = RequestMethod.GET)
+    List<String> getCoursesFromLogs(@RequestParam("uid") String uid);
 }

+ 7 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/service/event/EventService.java

@@ -6,6 +6,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 @Service
 @Slf4j
 public class EventService {
@@ -16,4 +18,9 @@ public class EventService {
     public APIResult<Boolean> addLog(EventLogDTO eventLogDTO) {
         return eventClient.addLog(eventLogDTO);
     }
+
+
+    public List<String> getCoursesFromLogs(String uid) {
+        return eventClient.getCoursesFromLogs(uid);
+    }
 }

+ 7 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/service/product/ProductClient.java

@@ -79,6 +79,8 @@ public interface ProductClient {
     @RequestMapping(value = "/merchant/{merchantId}/product/{pid}", method = RequestMethod.GET)
     Product getProduct(@PathVariable("merchantId") String merchantId, @PathVariable("pid") String pid);
 
+    @RequestMapping(value = "/app/course/{id}", method = RequestMethod.GET)
+    Course getCourse(@PathVariable("id") String id);
 
 
     @Component
@@ -173,5 +175,10 @@ public interface ProductClient {
             return null;
         }
 
+        @Override
+        public Course getCourse(String id) {
+            return null;
+        }
+
     }
 }

+ 4 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/service/product/ProductService.java

@@ -106,4 +106,8 @@ public class ProductService {
         return productClient.getPosters(merchantId, 0L, 10, "sort", Sort.Direction.ASC);
     }
 
+    public Course getCourse(String id) {
+        return productClient.getCourse(id);
+    }
+
 }

+ 5 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/app/CourseController.java

@@ -41,4 +41,9 @@ public class CourseController {
         List<ItemVo> itemVoList = itemService.findSupportByCourseId(courseId, merchantId);
         return APIResult.ok(itemVoList);
     }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public Course getCourse(@PathVariable("id") String id) {
+        return courseService.findByIdAndStatus(id);
+    }
 }

+ 3 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseRepository.java

@@ -19,6 +19,9 @@ public interface CourseRepository extends BasicJpaRepository<Course, String> {
     @Query(value = "select c from Course c where c.id = ?1 ")
     Course findCourseById(String id);
 
+    @Query(value = "select c from Course c where c.id = ?1 and c.status = ?2")
+    Course findByIdAndStatus(String id, BaseStatusEnum status);
+
 
     @Modifying
     @Query(value = "update Course c set c.status = 1 where c.id = ?1")

+ 4 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/CourseService.java

@@ -252,4 +252,8 @@ public class CourseService {
         });
         return APIResult.ok(sortCourseList);
     }
+
+    public Course findByIdAndStatus(String id) {
+        return courseRepository.findByIdAndStatus(id, BaseStatusEnum.NORMAL);
+    }
 }

+ 24 - 4
rankin-user-service/src/main/java/cn/rankin/userservice/controller/EventLogController.java

@@ -2,12 +2,14 @@ package cn.rankin.userservice.controller;
 
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.data.api.user.dto.EventLogDTO;
+import cn.rankin.data.api.user.entity.EventLog;
 import cn.rankin.userservice.service.EventLogService;
+import org.apache.commons.lang.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
 
 @RestController
 @RequestMapping(value = "/event")
@@ -20,4 +22,22 @@ public class EventLogController {
     public APIResult<Boolean> addLog(@RequestBody EventLogDTO eventLogDTO) {
         return eventLogService.addLog(eventLogDTO);
     }
+
+    @RequestMapping(value = "/{uid}", method = RequestMethod.GET)
+    public List<String> getCoursesFromLogs(@PathVariable("uid") String uid){
+        List<EventLog> eventLogs = eventLogService.findEventLogs(uid);
+        List<String> courseIds = new ArrayList<>();
+        eventLogs.forEach(eventLog ->{
+            String tarId = eventLog.getTarId();
+            if(StringUtils.isNotEmpty(tarId)){
+                String courseId = tarId.split("_")[0];
+                if(!courseIds.contains(courseId))
+                    courseIds.add(courseId);
+            }
+        });
+
+        List<String> result = new ArrayList<>(courseIds);
+        return result;
+    }
+
 }

+ 7 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/EventLogRepository.java

@@ -2,6 +2,13 @@ package cn.rankin.userservice.repository;
 
 import cn.rankin.common.utils.jpa.BasicJpaRepository;
 import cn.rankin.data.api.user.entity.EventLog;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
 
 public interface EventLogRepository extends BasicJpaRepository<EventLog, String> {
+
+    @Query(value = "select e from EventLog e where e.userId = :uid AND e.tarName='LESSON_WATCH' ORDER BY e.gmtCreated DESC ")
+    List<EventLog> findEventLogs(@Param("uid") String uid);
 }

+ 6 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/EventLogService.java

@@ -7,6 +7,8 @@ import cn.rankin.userservice.repository.EventLogRepository;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 import static cn.rankin.userservice.utils.DTOConverter.convert;
 
 @Service
@@ -20,4 +22,8 @@ public class EventLogService {
         eventLogRepository.save(eventLog);
         return APIResult.ok(Boolean.TRUE);
     }
+
+    public List<EventLog> findEventLogs(String uid) {
+        return eventLogRepository.findEventLogs(uid);
+    }
 }