230 커밋 05b1012be8 ... 2bce02f682

작성자 SHA1 메시지 날짜
  guozhaoshun 2bce02f682 fix change video resource url | https:// 6 년 전
  guozhaoshun 1e5447c99c fix change video resource url | https:// 6 년 전
  guozhaoshun 8c6c5e2f6f fix 6 년 전
  guozhaoshun 84fcec2c52 fix 6 년 전
  guozhaoshun addf733cef optimize change video resource url | https:// 6 년 전
  guozhaoshun e25a1087b2 API support UserTag UserRecommend module 6 년 전
  guozhaoshun c1cafa0dde CMS support UserTag UserRecommend module 6 년 전
  guozhaoshun b7f7ae4fbd CMS support UserTag UserRecommend module 6 년 전
  guozhaoshun 68e668299a change ItemController package 6 년 전
  guozhaoshun 179ebf9818 support UserTag UserRecommend module 6 년 전
  guozhaoshun 53870c5081 add UserTag UserRecommend module 6 년 전
  guozhaoshun 9a91434191 add UserTag module 6 년 전
  guozhaoshun 3f669d5d8d add UserRecommend module 6 년 전
  guozhaoshun f342259060 UserTag UserRecommend UserTagProductRelation 6 년 전
  guozhaoshun bcf2a31407 img resource replace the blank space 6 년 전
  guozhaoshun f222501fd2 optimize poster 6 년 전
  guozhaoshun 13173f2b4d optimize poster 6 년 전
  guozhaoshun e9a0dde366 optimize 6 년 전
  guozhaoshun bac3f345a1 video list sort by createTime DESC 6 년 전
  guozhaoshun 7553ae7a1e video list sort by updateTime DESC 6 년 전
  guozhaoshun 394cf45ea7 video list sort by createTime DESC 6 년 전
  guozhaoshun 4e742c737a restore file 6 년 전
  guozhaoshun 1549a46a4d fix tag support update typeCode,merchant; 6 년 전
  guozhaoshun 33b5c15d60 change video resource url | https:// 6 년 전
  guozhaoshun 506effdb57 change video resource url | https:// 6 년 전
  guozhaoshun 9e8234ef28 terminalUser add deviceStatus 6 년 전
  guozhaoshun 816b823469 change video resource url | https:// 6 년 전
  guozhaoshun 6272cefc73 fix optimize the recommended course 6 년 전
  guozhaoshun b9de4f6722 optimize the recommended course 6 년 전
  guozhaoshun 3ffe8c3f5e fix updateResource 6 년 전
  guozhaoshun f3fb2065fc fix updateResource 6 년 전
  guozhaoshun a387a6d808 fix updateResource 6 년 전
  guozhaoshun f477dadf3d fix updateResource 6 년 전
  guozhaoshun 9311a32594 fix updateResource 6 년 전
  guozhaoshun f9b5490ab0 fix updateResource 6 년 전
  guozhaoshun 9d1b06ca5e fix poster 6 년 전
  guozhaoshun b1444f5476 fix poster 6 년 전
  guozhaoshun 6bdbf70ab7 fix picture list sort by gmtModified DESC 6 년 전
  guozhaoshun f7dd51ab62 from the update resource document; 1 video | 0 audio 6 년 전
  xuchaolang 9933ecdbfe Merge branch 'fix_bug.0525' 7 년 전
  xuchaolang 28d6e829ce Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 7 년 전
  xuchaolang 56ef2ae8da Fix bug, check idList if empty while find in repo 7 년 전
  guozhaoshun 1a88c54723 fix tag support update typeCode,merchant; 7 년 전
  guozhaoshun 7d2928ebf6 fix poster 7 년 전
  guozhaoshun c8a3defbf6 fix poster 7 년 전
  guozhaoshun fef1be4ad4 fix saveRemoteResource 7 년 전
  guozhaoshun 2232e69783 fix poster 7 년 전
  guozhaoshun d64df3cd1d fix poster 7 년 전
  guozhaoshun c6323af106 Merge branch 'dev001' 7 년 전
  xuchaolang 33f4ed14cc cms-web-api, /resource PUT, id pass in body 7 년 전
  xuchaolang 42d7a7fde9 web-api, /package/<pid>, return goods 7 년 전
  xuchaolang 80337f7aee Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 7 년 전
  xuchaolang e0359d50e8 Accomplish /user/messages/productExpiredAlert, /package/<pid> 7 년 전
  xuchaolang 4f2db3edf5 Merge branch 'master' of http://gogs.efunbox.cn:3000/Rankin/rankin 7 년 전
  xuchaolang a6153d0f3e ProductService.getRelatedPackages, filter offline pkgs by status 7 년 전
  xuchaolang 5b06485ee2 return code in /product/<pid>/relatedPkg, move shopQR into Goods 7 년 전
  xuchaolang a6a6614946 ProductService.getRelatedPkgs, set goods 7 년 전
  xuchaolang 4c631931cd ProductService.getRelatedPackges, check pkgId but not productId while scaning relatedPkgs 7 년 전
  xuchaolang 6991a10393 ProductService, move ProductController from controller.cms package to controller package 7 년 전
  xuchaolang c6b6a14078 Accomplish Api /product/<pid>/relatedPkg 7 년 전
  xuchaolang e06c345575 Add /merchant prefix to Api /merchant/<merchantId>/posters 7 년 전
  xuchaolang cdc99ef674 service /user/<uid>/product/valid Resturn [] while user have no valid products 7 년 전
  xuchaolang 9e62064f53 Print product Log while get valid product from service 7 년 전
  xuchaolang 9ca21fe5ad Print User 7 년 전
  xuchaolang 6d90ff45c9 Temporarily add /user/product/valid in product service 7 년 전
  xuchaolang 027257e268 Merge branch 'dev.3.0' 7 년 전
  guozhaoshun 279f88c027 change TagTypeController /controller/app to /controller/ 7 년 전
  guozhaoshun f3ca8a50f5 add support video upload 7 년 전
  guozhaoshun d8011a4be3 tag create/update support tagType 7 년 전
  guozhaoshun 2f51c018ab tagType 7 년 전
  guozhaoshun 3d0665565c Tag create/update support typeCode 7 년 전
  guozhaoshun 671925bb7c merchant product name change source 7 년 전
  guozhaoshun 4f4b2067cd add /tagType/{code} 7 년 전
  guozhaoshun 150ce1a65d add 7 년 전
  guozhaoshun ebb60529f4 add 7 년 전
  xuchaolang fdcb5a30ea Fix getTagType request mapping value 7 년 전
  xuchaolang bb4f968336 restore pom.xml 7 년 전
  xuchaolang c3df828bef check if sign is empty while get it from header 7 년 전
  xuchaolang 00103a8f10 use Authentication while sign not Exist, For compatition with 2.x app verions 7 년 전
  guozhaoshun e35f33f816 recover yml 7 년 전
  guozhaoshun 967949bded test commit 7 년 전
  guozhaoshun eec791684a Merge remote-tracking branch 'origin/master' into dev 7 년 전
  guozhaoshun 75b5a94017 repair bug 7 년 전
  xuchaolang e554490545 skip shelf in relatedSupport 7 년 전
  xuchaolang 0ee63c8bde set dateDesc,openTime,closeTime 7 년 전
  xuchaolang 1cf7041a5d fix /training/{id} request map bug 7 년 전
  xuchaolang a5feaf286d change service api /app/training/{id} to /training/{id} 7 년 전
  xuchaolang d55840f63b TrainingController add log 7 년 전
  xuchaolang 150e531e17 check productid is null in findByIds 7 년 전
  xuchaolang c01366a887 fix training update 7 년 전
  xuchaolang 926e20469b return Training type in ProductService 7 년 전
  xuchaolang c35e78559c training.get only return training entity 7 년 전
  xuchaolang ba6772a241 add traing cms api 7 년 전
  xuchaolang 2a2b0f02ff add traing cms api 7 년 전
  xuchaolang 0839854e30 加入/training/<id>接口 7 년 전
  xuchaolang 1c593901be add course title to course/lesson 7 년 전
  huodongdong 8fb41e9d7e fix 7 년 전
  huodongdong 33dfe9086d fix white user search 7 년 전
  huodongdong 12ee9bd962 fix white user search request body 7 년 전
  huodongdong 46bb611eac fix 7 년 전
  huodongdong a7c33c52fe fix feign pathvariable error 7 년 전
  huodongdong 7450e47d4f fix 7 년 전
  huodongdong c9ecf201a9 add merchantId of white user 7 년 전
  huodongdong 8bb7d1122a add merchant name of white user 7 년 전
  huodongdong 50a2dd42d0 add api binder cms white user 7 년 전
  huodongdong ac39c034af add white user model 7 년 전
  huodongdong 2798495bf0 add white user table 7 년 전
  huodongdong e03a581e5a fix 7 년 전
  huodongdong de4cb52101 cms log level 7 년 전
  huodongdong 445c3c5ae5 cms delete redis app login data 7 년 전
  huodongdong 83fe73e0b3 add cms unbind device 7 년 전
  huodongdong db8ea62107 fix tag product sort bug 7 년 전
  huodongdong aeee85f461 add timeout session 7 년 전
  huodongdong 973392ebf0 fix 7 년 전
  huodongdong 6757e24f70 remove session 7 년 전
  huodongdong 938ebbaf0c fix lesson search 7 년 전
  huodongdong f37e9b6eb4 fix lesson empty exception 7 년 전
  huodongdong c635cbc670 add log 7 년 전
  huodongdong 9edd40418a fix 7 년 전
  huodongdong 9637fee49d fix group code 7 년 전
  huodongdong 27c762f9a1 add field of merchant simple 7 년 전
  huodongdong 473394bd12 fix 7 년 전
  huodongdong 9e1fe10b8f fix video url error 7 년 전
  huodongdong 190f0e601b fix bing terminal field null and log error 7 년 전
  huodongdong c27e8c256a add web login force 7 년 전
  huodongdong 73c7c88a25 fix terminal name 7 년 전
  huodongdong 19d3c3e4f7 modifiy terminal name to campusName + terminalName 7 년 전
  huodongdong fb221ea346 fix campus name remove - 7 년 전
  huodongdong c561799f73 fix 7 년 전
  huodongdong e9f308a413 fix 7 년 전
  huodongdong 5bc08795d5 fix 7 년 전
  huodongdong 69fe592df2 fix 7 년 전
  huodongdong 74f882a885 完成pushmsg push 7 년 전
  huodongdong 9585210305 complete app api 7 년 전
  huodongdong ed9f6583d9 fix device_code null 7 년 전
  huodongdong 8b7fc151e6 refresh token not signature 7 년 전
  huodongdong 53d28c7191 fix api recommend 7 년 전
  huodongdong 1c36c05943 fix recommend 7 년 전
  huodongdong 9bca91cc2a add refresh token 7 년 전
  huodongdong 05927ed824 remove test intercepter, same the terminal user id 7 년 전
  huodongdong b96f1f4298 fix 7 년 전
  huodongdong 5913d3072d valid login 7 년 전
  huodongdong 9c3aaf41f5 fix 7 년 전
  huodongdong b300458a22 fix 7 년 전
  huodongdong 5a764d1100 fix 7 년 전
  huodongdong c817e33b16 add status terminal user filter search 7 년 전
  huodongdong 4c5881db37 add product merchantId when search 7 년 전
  huodongdong ca84c38189 add tag sort 7 년 전
  huodongdong f813b6b318 deploy 7 년 전
  huodongdong cfbbf4c3c8 fix header and option request bug 7 년 전
  huodongdong 61522ff50e fix 7 년 전
  huodongdong 1f54a29d64 fix receive 7 년 전
  huodongdong 0a7d232e36 web api stash and fix charge 7 년 전
  huodongdong 8dfc0d3ea3 fix 7 년 전
  huodongdong b1908c474c add code and name order goods 7 년 전
  huodongdong 4f2560e16a order detail api 7 년 전
  huodongdong 1cd5f51282 fix transactional 7 년 전
  huodongdong 74b94275b4 add charge 7 년 전
  huodongdong a71b1653d0 add charge api 7 년 전
  huodongdong 9f8ce28658 fix MySQL5DialectUTF8 7 년 전
  huodongdong 29fbd94fa5 fix create table utf8 7 년 전
  huodongdong 23569b09dd fix 7 년 전
  huodongdong 2e49f4d8bd fix 7 년 전
  huodongdong 42bb7557bd modified yml config 7 년 전
  huodongdong 54ebcd3e0c fix 7 년 전
  huodongdong 43b3b23379 add merchantPrice of pakcageProductVo 7 년 전
  huodongdong af3de4ab65 add merchant price of product in package 7 년 전
  huodongdong c73ae0883f add category of courseware 7 년 전
  huodongdong e3bc647fdb fix 7 년 전
  huodongdong 504b10c476 config test 7 년 전
  huodongdong 4ddca8254e profile act 7 년 전
  huodongdong cc65c80444 test 7 년 전
  huodongdong 7ed2337ea0 add sub title 7 년 전
  huodongdong c36277375e modified cancel order api 7 년 전
  huodongdong 08bd31ccdf order search to post feign 7 년 전
  huodongdong c2cabfc0ac add goods type auto 7 년 전
  huodongdong 6b8d5122d3 same order status and order detail status 7 년 전
  huodongdong 75c5cd1338 fix 7 년 전
  huodongdong 4ef6d6bb47 add terminal user address 7 년 전
  huodongdong aa34b15a14 add merchant product list package info 7 년 전
  huodongdong 049d6eb4c8 add oderdetail and snapshot search api 7 년 전
  huodongdong d6aef08774 fix log 7 년 전
  huodongdong 30ccda2563 complete task 7 년 전
  huodongdong 4a50d6038c size 7 년 전
  huodongdong db4847d06a fix name 7 년 전
  huodongdong aa15ceede3 fix 7 년 전
  huodongdong b28be55f44 add status of goods package when put on sale 7 년 전
  huodongdong d20807fba1 fix 7 년 전
  huodongdong 072ea17be3 add sort when put on sale product 7 년 전
  huodongdong 21aa6d4df2 add cms merchantProduct 7 년 전
  huodongdong 466c98dfe4 add package update and on sale goods relation add and update 7 년 전
  huodongdong fc7f9598dd fix lesson api cms 7 년 전
  huodongdong bd88622c1f fix 7 년 전
  huodongdong 503a8f4481 fix lesson warelist 7 년 전
  huodongdong 3c50ba20cd add tag and group info 7 년 전
  huodongdong ea7d4da2c7 no 7 년 전
  huodongdong 72c1434dc3 @Modifying remove clearAutomatically=true 7 년 전
  huodongdong 72ae842ea9 add status product create 7 년 전
  huodongdong f99e29af74 fix 7 년 전
  huodongdong 47afdb4c32 product search string format error 7 년 전
  huodongdong 6b421cec99 fix support 7 년 전
  huodongdong 446296f16f fix ware data structure 7 년 전
  huodongdong 187f7f622b 订单分拆初版 7 년 전
  huodongdong ac7e27719b modified table name and createtime 7 년 전
  huodongdong 97e636322c api web test remove token check 7 년 전
  huodongdong 012209cc64 fix resource name 7 년 전
  huodongdong 723cceb4bb fix 7 년 전
  huodongdong 3214cf4a72 fix pom config 7 년 전
  huodongdong 76798122fa fix pom config 7 년 전
  huodongdong 7f082bf582 fix pom build config 7 년 전
  huodongdong 120f9de598 tmp 7 년 전
  huodongdong 1fe47abcc0 complete pay ok 7 년 전
  huodongdong 2bd43244b7 save 7 년 전
  huodongdong 857b5bb181 add package 7 년 전
  huodongdong 3b6e896596 complete product and goods recoding 7 년 전
  huodongdong 225693bfc7 product idea period 1 7 년 전
  huodongdong f15b6dbe00 stash 7 년 전
  huodongdong bbb144a1c9 campus and termianl user complete 7 년 전
  huodongdong 2ddd9d23e8 add cms web 7 년 전
  huodongdong 31ca7939f3 tag 7 년 전
  huodongdong 98f4431dcf version 1.0 dev 7 년 전
  huodongdong 1d57b2f9f0 shit commit and reset 7 년 전
  huodongdong 34a6cad675 nothing 7 년 전
  huodongdong d69395e6a7 version 1.1: id string and relation; hibernate relation 7 년 전
  huodongdong e428f275b5 resource service complete 7 년 전
  huodongdong 2f57ba34a8 first version 7 년 전
  huodongdong 05dfbac277 fix 7 년 전
  huodongdong bdc9fa3299 rename 7 년 전
  huodongdong 08fb34581d add ignore 7 년 전
  huodongdong dd01ec7ace first framework 7 년 전
60개의 변경된 파일1817개의 추가작업 그리고 103개의 파일을 삭제
  1. 126 3
      rankin-api-web/src/main/java/cn/rankin/apiweb/controller/RecommendController.java
  2. 44 1
      rankin-api-web/src/main/java/cn/rankin/apiweb/controller/TagController.java
  3. 8 3
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/event/EventClient.java
  4. 7 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/event/EventService.java
  5. 16 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/product/ProductClient.java
  6. 9 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/product/ProductService.java
  7. 20 0
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserClient.java
  8. 10 1
      rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserService.java
  9. 7 2
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/product/PosterController.java
  10. 16 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/MerchantController.java
  11. 112 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/UserController.java
  12. 117 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/UserTagController.java
  13. 7 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/product/MerchantProductService.java
  14. 10 1
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/product/PosterServiceInterface.java
  15. 12 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/product/ProductService.java
  16. 21 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserRecommendService.java
  17. 16 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserTagProductRelationServiceInterface.java
  18. 35 0
      rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserTagServiceInterface.java
  19. 32 0
      rankin-data-api/src/main/java/cn/rankin/data/api/product/vo/UserRecommendVo.java
  20. 30 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserTagDTO.java
  21. 24 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserTagSearchDTO.java
  22. 3 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/TerminalUser.java
  23. 74 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/UserRecommend.java
  24. 66 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/UserTag.java
  25. 46 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/UserTagProductRelation.java
  26. 2 0
      rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/TerminalUserVo.java
  27. 11 4
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/app/ItemController.java
  28. 61 49
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/PosterController.java
  29. 5 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/ProductController.java
  30. 5 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/app/CourseController.java
  31. 9 2
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/app/ItemController.java
  32. 10 0
      rankin-product-service/src/main/java/cn/rankin/productservice/controller/cms/MerchantProductController.java
  33. 3 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/CourseRepository.java
  34. 2 1
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/MerchantProductRepository.java
  35. 9 0
      rankin-product-service/src/main/java/cn/rankin/productservice/repository/PosterRepository.java
  36. 4 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/CourseService.java
  37. 27 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/MerchantProductService.java
  38. 41 18
      rankin-product-service/src/main/java/cn/rankin/productservice/service/PosterService.java
  39. 4 0
      rankin-product-service/src/main/java/cn/rankin/productservice/service/ProductService.java
  40. 5 0
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/controller/ResourceController.java
  41. 8 1
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/dto/ResourceDetail.java
  42. 10 2
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/dto/ResourceRemote.java
  43. 1 1
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/proxy/RemoteResourceProxy.java
  44. 10 8
      rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java
  45. 24 4
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/EventLogController.java
  46. 7 1
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalDeviceController.java
  47. 31 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalUserController.java
  48. 32 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserRecommendController.java
  49. 124 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserTagController.java
  50. 24 0
      rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserTagProductRelationController.java
  51. 7 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/EventLogRepository.java
  52. 17 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserRecommendRepository.java
  53. 42 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserTagProductRelationRepository.java
  54. 33 0
      rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserTagRepository.java
  55. 6 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/EventLogService.java
  56. 5 1
      rankin-user-service/src/main/java/cn/rankin/userservice/service/TerminalDeviceService.java
  57. 88 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/UserRecommendService.java
  58. 87 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/UserTagProductRelationService.java
  59. 189 0
      rankin-user-service/src/main/java/cn/rankin/userservice/service/UserTagService.java
  60. 6 0
      rankin-user-service/src/main/java/cn/rankin/userservice/utils/DTOConverter.java

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

@@ -2,11 +2,16 @@ 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.apiweb.service.user.UserService;
 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 cn.rankin.data.api.user.entity.UserRecommend;
+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 +20,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,16 +28,121 @@ public class RecommendController {
     @Autowired
     private ProductService productService;
 
+    @Autowired
+    private UserService userService;
+
+    @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> pids = eventService.getCoursesFromLogs(user.getUid());
+        if(pids != null && pids.size() > 0){
+            log.info("get course ids from logs, courseIds={}", pids);
+            //如果有浏览历史,提取浏览历史前五展示    (目前推荐位为5)
+            pids.forEach(pid -> {
+                if(result.size() <= RECOMMEND_NUM){
+                    Course course = productService.getCourse(pid);
+                    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());*/
+                        RecommendVo vo = courseToRecommendVo(course);
+                        result.add(vo);
+                    }else{
+                        log.info("not found course by pid, pid={}", pid);
+                    }
+                }
+            });
+
+            if(result.size() < RECOMMEND_NUM){
+                //浏览历史少于五,追加用户推荐,补足五  (目前推荐位为5)
+                String uid = user.getUid();
+                List<UserRecommend> userData = userService.getUserRecommendCourses(uid);
+                if(null != userData && userData.size() > 0){
+                    log.info("get user recommend course , size={}", userData.size());
+                    userData.forEach(userRecommend -> {
+                        if(result.size() < RECOMMEND_NUM){
+                            Course course = productService.getCourse(userRecommend.getPid());
+                            if(course != null){
+                                RecommendVo vo = courseToRecommendVo(course);
+                                //如果用户浏览课程不包含推荐课程,追加推荐课程 |(此处为避免推荐位课程重复)
+                                if(!result.contains(vo)){
+                                    result.add(vo);
+                                }
+                            }else{
+                                log.info("not found course by pid, pid={}", userRecommend.getPid());
+                            }
+                        }
+                    });
+                }else{
+                    //浏览历史少于五,没有用户推荐  追加   渠道推荐,补足五  (目前推荐位为5)
+                    String merchantId = user.getMerchantId();
+                    APIResult<List<RecommendVo>> apiResult = productService.getRecommendCourses(merchantId);
+                    if(!apiResult.getSuccess()){
+                        return apiResult;
+                    }
+
+                    List<RecommendVo> data = apiResult.getData();
+                    if(data != null){
+                        log.info("get merchant recommend course , size={}", data.size());
+                        data.forEach(vo -> {
+                            if(result.size() < RECOMMEND_NUM){
+                                //如果用户浏览课程不包含推荐课程,追加推荐课程 |(此处为避免推荐位课程重复)
+                                if(!result.contains(vo)){
+                                    result.add(vo);
+                                }
+                            }
+                        });
+                    }
+                }
+            }
+            return APIResult.ok(result);
+        }else{
+
+            //不存在浏览历史,使用用户推荐
+            String uid = user.getUid();
+            List<UserRecommend> userData = userService.getUserRecommendCourses(uid);
+            if(null != userData && userData.size() > 0){
+                log.info("get user recommend course , size={}", userData.size());
+                userData.forEach(userRecommend -> {
+                    if(result.size() < RECOMMEND_NUM){
+                        Course course = productService.getCourse(userRecommend.getPid());
+                        if(course != null){
+                            RecommendVo vo = courseToRecommendVo(course);
+                            //如果用户浏览课程不包含推荐课程,追加推荐课程 |(此处为避免推荐位课程重复)
+                            if(!result.contains(vo)){
+                                result.add(vo);
+                            }
+                        }else{
+                            log.info("not found course by pid, pid={}", userRecommend.getPid());
+                        }
+                    }
+                });
+                return APIResult.ok(result);
+            }else{
+                //不存在浏览历史,不存在用户推荐;使用渠道推荐
+                String merchantId = user.getMerchantId();
+                return productService.getRecommendCourses(merchantId);
+            }
+        }
     }
 
+
+
     /**
      * Get recommend posters
       * @param user
@@ -59,4 +169,17 @@ public class RecommendController {
 
         return APIResult.ok(data);
     }
+
+
+
+    private RecommendVo courseToRecommendVo(Course course) {
+        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());
+        return vo;
+    }
 }

+ 44 - 1
rankin-api-web/src/main/java/cn/rankin/apiweb/controller/TagController.java

@@ -1,21 +1,35 @@
 package cn.rankin.apiweb.controller;
 
 import cn.rankin.apiweb.assist.resolver.NeedUser;
+import cn.rankin.apiweb.service.product.ProductService;
 import cn.rankin.apiweb.service.tag.TagService;
+import cn.rankin.apiweb.service.user.UserService;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
 import cn.rankin.data.api.app.vo.*;
+import cn.rankin.data.api.user.entity.UserTag;
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-
+@Slf4j
 @RestController
 public class TagController {
 
     @Autowired
     private TagService tagService;
 
+    @Autowired
+    private UserService userService;
+
+    @Autowired
+    private ProductService productService;
+
     @RequestMapping(value = "/tagGroup/{code}", method = RequestMethod.GET)
     public APIResult<TagGroupVo> getTagGroup(@NeedUser DeviceUserVo user, @PathVariable("code") String code) {
         String merchantId = user.getMerchantId();
@@ -31,7 +45,36 @@ public class TagController {
 
     @RequestMapping(value = "/tagType/{code}", method = RequestMethod.GET)
     public APIResult<List<TagVo>> getTagType(@NeedUser DeviceUserVo user,@PathVariable("code") String code) {
+        List<TagVo> result = new ArrayList<>();
+
+        //先去取用户标签,没有用户标签再使用渠道标签
+        String uid = user.getUid();
         String merchantId = user.getMerchantId();
+
+        //用户标签列表
+        List<UserTag> userTagList = userService.findUserTagByCodeUid(code,uid);
+        if(null != userTagList && userTagList.size() > 0){
+            log.info("get userTag By code and uid, size={}", userTagList.size());
+            //组装数据   用户标签下   课程数据
+            userTagList.forEach(userTag -> {
+                List<UserTagProductRelation> relationList = userTag.getRelationList();
+                log.info("userTag relationList , size={}", relationList);
+                if(!CollectionUtils.isEmpty(relationList)){
+                    List<String> productIdList = new ArrayList<>();
+                    relationList.forEach(relation -> productIdList.add(relation.getPid()) );
+                    List<ItemVo> itemVoList = productService.findItemByPids(productIdList,merchantId);
+
+                    TagVo vo = new TagVo();
+                    vo.setId(userTag.getId());
+                    vo.setName(userTag.getName());
+                    vo.setRecs(itemVoList);
+                    result.add(vo);
+                }
+            });
+            return APIResult.ok(result);
+        }
+
+        //没有用户标签数据,使用渠道标签数据
         return tagService.findTagTypeByCode(code, 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);
+    }
 }

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

@@ -79,6 +79,12 @@ 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);
+
+    @RequestMapping(value = "/item/pids", method = RequestMethod.POST)
+    List<ItemVo> findItemByPids(@RequestBody List<String> productIdList,
+                                @RequestParam("merchantId") String merchantId);
 
 
     @Component
@@ -173,5 +179,15 @@ public interface ProductClient {
             return null;
         }
 
+        @Override
+        public Course getCourse(String id) {
+            return null;
+        }
+
+        @Override
+        public List<ItemVo> findItemByPids(List<String> productIdList, String merchantId) {
+            return null;
+        }
+
     }
 }

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

@@ -106,4 +106,13 @@ public class ProductService {
         return productClient.getPosters(merchantId, 0L, 10, "sort", Sort.Direction.ASC);
     }
 
+    public Course getCourse(String id) {
+        return productClient.getCourse(id);
+    }
+
+
+    public List<ItemVo> findItemByPids(List<String> productIdList, String merchantId) {
+        return productClient.findItemByPids(productIdList,merchantId);
+    }
+
 }

+ 20 - 0
rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserClient.java

@@ -3,6 +3,8 @@ package cn.rankin.apiweb.service.user;
 import cn.rankin.apiweb.code.ApiWebCode;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.data.api.user.dto.TerminalDeviceDTO;
+import cn.rankin.data.api.user.entity.UserRecommend;
+import cn.rankin.data.api.user.entity.UserTag;
 import cn.rankin.data.api.user.vo.TerminalDeviceVo;
 import cn.rankin.data.api.user.vo.TerminalUserVo;
 import cn.rankin.data.api.user.vo.WhiteUserVo;
@@ -10,6 +12,8 @@ import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @FeignClient(name = "${service.user.name}", fallback = UserClient.UserServiceHystrix.class)
 public interface UserClient {
 
@@ -34,6 +38,12 @@ public interface UserClient {
     @RequestMapping(value = "/white/user/{userId}", method = RequestMethod.GET)
     APIResult<WhiteUserVo> findWhiteUserById(@PathVariable("userId") String userId);
 
+    @RequestMapping(value = "/userRecommend/courses/uid/{uid}", method = RequestMethod.GET)
+    List<UserRecommend> getUserRecommendCourses(@RequestParam("uid") String uid);
+
+    @RequestMapping(value = "/userTag/code/{code}", method = RequestMethod.GET)
+    List<UserTag> findUserTagByCodeUid(@PathVariable("code") String code, @RequestParam("uid") String uid);
+
 
     @Component
     class UserServiceHystrix implements UserClient {
@@ -73,5 +83,15 @@ public interface UserClient {
             return APIResult.error(ApiWebCode.SERVER_ERROR);
         }
 
+        @Override
+        public List<UserRecommend> getUserRecommendCourses(String uid) {
+            return null;
+        }
+
+        @Override
+        public List<UserTag> findUserTagByCodeUid(String code, String uid) {
+            return null;
+        }
+
     }
 }

+ 10 - 1
rankin-api-web/src/main/java/cn/rankin/apiweb/service/user/UserService.java

@@ -11,8 +11,9 @@ import cn.rankin.common.utils.service.RedisService;
 import cn.rankin.data.api.app.dto.LoginInfoDTO;
 import cn.rankin.data.api.app.vo.DeviceUserVo;
 import cn.rankin.data.api.app.vo.UserInfoVo;
-import cn.rankin.data.api.product.entity.Product;
 import cn.rankin.data.api.user.dto.TerminalDeviceDTO;
+import cn.rankin.data.api.user.entity.UserRecommend;
+import cn.rankin.data.api.user.entity.UserTag;
 import cn.rankin.data.api.user.vo.TerminalDeviceVo;
 import cn.rankin.data.api.user.vo.TerminalUserVo;
 import com.alibaba.fastjson.JSON;
@@ -261,4 +262,12 @@ public class UserService {
         //TODO: move this method to userCient
         return productClient.getProductValid(uid, 0L, 50, "endTime", Sort.Direction.ASC);
     }
+
+    public List<UserTag> findUserTagByCodeUid(String code, String uid) {
+        return userClient.findUserTagByCodeUid(code, uid);
+    }
+
+    public List<UserRecommend> getUserRecommendCourses(String uid) {
+        return userClient.getUserRecommendCourses(uid);
+    }
 }

+ 7 - 2
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/product/PosterController.java

@@ -3,12 +3,15 @@ package cn.rankin.cmsweb.controller.product;
 import cn.rankin.cmsweb.service.product.PosterServiceInterface;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.util.BeanUtil;
 import cn.rankin.data.api.product.dto.PosterDTO;
 import cn.rankin.data.api.product.entity.Poster;
+import cn.rankin.data.api.product.vo.RecommendVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.List;
 
 @RestController
 @RequestMapping(value = "/poster")
@@ -18,8 +21,8 @@ public class PosterController {
     private PosterServiceInterface posterServiceInterface;
 
     @RequestMapping(value = "/list", method = RequestMethod.GET)
-    public APIResult<Page<Poster>> getPosterList(@Valid @RequestBody  PosterDTO posterDTO) {
-        return posterServiceInterface.search(posterDTO);
+    public APIResult<List<Poster>> getPosterList(PosterDTO posterDTO) {
+        return posterServiceInterface.search(BeanUtil.convertToMap(posterDTO));
     }
 
     @RequestMapping(value = "/{id}", method = RequestMethod.GET)
@@ -41,4 +44,6 @@ public class PosterController {
     public APIResult delete(@PathVariable("id") String id) {
         return posterServiceInterface.delete(id);
     }
+
+
 }

+ 16 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/MerchantController.java

@@ -1,9 +1,11 @@
 package cn.rankin.cmsweb.controller.user;
 
+import cn.rankin.cmsweb.service.product.PosterServiceInterface;
 import cn.rankin.cmsweb.service.product.RecommendService;
 import cn.rankin.cmsweb.service.user.MerchantService;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.product.entity.Poster;
 import cn.rankin.data.api.product.vo.RecommendVo;
 import cn.rankin.data.api.user.dto.MerchantDTO;
 import cn.rankin.data.api.user.dto.MerchantSearchDTO;
@@ -25,6 +27,9 @@ public class MerchantController {
     @Autowired
     private RecommendService recommendService;
 
+    @Autowired
+    private PosterServiceInterface posterServiceInterface;
+
     @RequestMapping(value = {"", "/list"}, method = RequestMethod.GET)
     public APIResult<Page<MerchantVo>> getPage(MerchantSearchDTO searchDTO) {
         return merchantService.search(BeanUtil.convertToMap(searchDTO));
@@ -61,4 +66,15 @@ public class MerchantController {
         return recommendService.put(merchantId, recommendIdList);
     }
 
+    //海报设置
+    @RequestMapping(value = "/poster/{merchantId}", method = RequestMethod.GET)
+    public APIResult<List<Poster>> getPoster(@PathVariable("merchantId") String merchantId) {
+        return posterServiceInterface.getPosters(merchantId);
+    }
+
+    @RequestMapping(value = "/poster/{merchantId}", method = RequestMethod.PUT)
+    public APIResult<List<Poster>> updatePoster(@PathVariable("merchantId") String merchantId, @RequestBody List<String> posterIdList) {
+        return posterServiceInterface.updatePosters(merchantId, posterIdList);
+    }
+
 }

+ 112 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/UserController.java

@@ -0,0 +1,112 @@
+package cn.rankin.cmsweb.controller.user;
+
+import cn.rankin.cmsweb.service.product.MerchantProductService;
+import cn.rankin.cmsweb.service.product.ProductService;
+import cn.rankin.cmsweb.service.user.UserRecommendService;
+import cn.rankin.cmsweb.service.user.UserTagServiceInterface;
+import cn.rankin.common.utils.api.model.APICode;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.data.api.product.entity.MerchantProduct;
+import cn.rankin.data.api.product.vo.ProductVo;
+import cn.rankin.data.api.product.vo.UserRecommendVo;
+import cn.rankin.data.api.user.entity.UserRecommend;
+import cn.rankin.data.api.user.entity.UserTag;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/user")
+public class UserController {
+
+    @Autowired
+    private UserRecommendService userRecommendService;
+
+    @Autowired
+    private UserTagServiceInterface userTagService;
+
+    @Autowired
+    private ProductService productService;
+
+    @Autowired
+    private MerchantProductService merchantProductService;
+
+    // 用户推荐位设置
+    @RequestMapping(value = "/userRecommend/uid/{uid}", method = RequestMethod.GET)
+    public APIResult<List<UserRecommendVo>> getUserRecommend(@PathVariable("uid") String uid) {
+        if (StringUtils.isEmpty(uid)) {
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        List<UserRecommend> userRecommendList = userRecommendService.get(uid);
+
+        setProductInfo(userRecommendList);
+        return APIResult.ok(userRecommendList);
+    }
+
+
+
+    @RequestMapping(value = "/userRecommend/uid/{uid}", method = RequestMethod.PUT)
+    public APIResult<List<UserRecommendVo>> updateUserRecommend(@PathVariable("uid") String uid, @RequestBody List<String> productIdList) {
+        if (StringUtils.isEmpty(uid) || CollectionUtils.isEmpty(productIdList)) {
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        List<MerchantProduct> merchantProducts = new ArrayList<>();
+        productIdList.forEach(pid -> {
+            MerchantProduct merchantProduct = merchantProductService.findMerchantProductByPid(pid);
+            if(null != merchantProduct){
+                merchantProducts.add(merchantProduct);
+            }else{
+                log.info("Not found MerchantProduct by pid , pid={}",pid);
+            }
+        });
+
+        List<UserRecommend> userRecommendList = userRecommendService.put(uid, merchantProducts);
+
+        setProductInfo(userRecommendList);
+        return APIResult.ok(userRecommendList);
+    }
+
+    //用户标签配置
+    @RequestMapping(value = "/userTag/uid/{uid}", method = RequestMethod.GET)
+    public APIResult<UserTag> getUserTagsByUid(@PathVariable("uid") String uid) {
+        List<UserTag> userTags = userTagService.findUserTagByUid(uid);
+        if (userTags != null && userTags.size() > 0) {
+            /*userTags.forEach(userTag -> {
+                List<UserTagProductRelation> relationList = userTagProductRelationServiceInterface.findByUserTagId(userTag.getId());
+                List<String>  productIdList = new ArrayList<>();
+                if(null != relationList && relationList.size() > 0){
+                    relationList.forEach(relation -> {
+                        productIdList.add(relation.getPid());
+                    });
+                    List<ItemVo> itemVoList = productService.findItemByPids(productIdList, merchantId);
+                    userTag.setRecs(itemVoList);
+                }
+
+            });*/
+            return APIResult.ok(userTags);
+        }else{
+            return APIResult.error(APICode.NOT_EXISTS);
+        }
+    }
+
+
+
+    private void setProductInfo(List<UserRecommend> userRecommendList) {
+        userRecommendList.forEach(userRecommend -> {
+            ProductVo productVo = productService.findProductByPid(userRecommend.getPid());
+            if(null != productVo){
+                userRecommend.setName(productVo.getName());
+                userRecommend.setCode(productVo.getCode());
+            }else{
+                log.info("Not found Product by pid , pid={}",userRecommend.getPid());
+            }
+        });
+    }
+
+}

+ 117 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/controller/user/UserTagController.java

@@ -0,0 +1,117 @@
+package cn.rankin.cmsweb.controller.user;
+
+import cn.rankin.cmsweb.assist.resolver.NeedUser;
+import cn.rankin.cmsweb.entity.UserDetails;
+import cn.rankin.cmsweb.service.product.MerchantProductService;
+import cn.rankin.cmsweb.service.user.UserTagProductRelationServiceInterface;
+import cn.rankin.cmsweb.service.user.UserTagServiceInterface;
+import cn.rankin.common.utils.api.model.APICode;
+import cn.rankin.common.utils.api.model.APIResult;
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.util.BeanUtil;
+import cn.rankin.data.api.product.entity.MerchantProduct;
+import cn.rankin.data.api.user.dto.UserTagDTO;
+import cn.rankin.data.api.user.dto.UserTagSearchDTO;
+import cn.rankin.data.api.user.entity.UserTag;
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "/userTag")
+public class UserTagController {
+
+    @Autowired
+    private UserTagServiceInterface userTagService;
+
+    @Autowired
+    private UserTagProductRelationServiceInterface userTagProductRelationServiceInterface;
+
+    @Autowired
+    private MerchantProductService merchantProductService;
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public APIResult<Page<UserTag>> search(@NeedUser UserDetails user, UserTagSearchDTO searchDTO) {
+        if (!user.isPlatForm()) {
+            searchDTO.setUid(user.getId());
+        }
+        Page<UserTag> userTagPage = userTagService.search(BeanUtil.convertToMap(searchDTO));
+        if (userTagPage != null) {
+            return APIResult.ok(userTagPage);
+        }else{
+            return APIResult.error(APICode.NOT_EXISTS);
+        }
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public APIResult<UserTag> getUserTag(@PathVariable("id") String id) {
+        UserTag userTag = userTagService.getUserTag(id);
+        if (userTag != null) {
+            List<UserTagProductRelation> relationList = userTagProductRelationServiceInterface.findByUserTagId(userTag.getId());
+            if( !CollectionUtils.isEmpty(relationList)){
+                //开始组装产品数据
+                List<MerchantProduct> merchantProductList = new ArrayList<>();
+                relationList.forEach(relation -> {
+                    String pid = relation.getPid();
+                    MerchantProduct merchantProduct = merchantProductService.findMerchantProductByPid(pid);
+                    if(null != merchantProduct){
+                        merchantProductList.add(merchantProduct);
+                    }else{
+                        log.error("not found MerchantProduct by pid, pid={}", pid);
+                    }
+                });
+
+                userTag.setProductList(merchantProductList);
+            }
+            return APIResult.ok(userTag);
+        }else{
+            log.error("not found UserTag by id, id={}", id);
+            return APIResult.error(APICode.NOT_EXISTS);
+        }
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public APIResult<UserTag> create(@RequestBody UserTagDTO dto) {
+        UserTag userTag = userTagService.create(dto);
+        if (userTag != null) {
+            return APIResult.ok(userTag);
+        }else{
+            return APIResult.error(APICode.NOT_EXISTS);
+        }
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public APIResult<UserTag> update(@RequestBody UserTagDTO dto) {
+        if(StringUtils.isBlank(dto.getId())){
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        UserTag userTag = userTagService.update(dto);
+        if (userTag != null) {
+            log.error("update UserTag is error, id={}", dto.getId());
+            return APIResult.ok(userTag);
+        }else{
+            return APIResult.error(APICode.NOT_EXISTS);
+        }
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public APIResult delete(@PathVariable("id") String id) {
+        if(StringUtils.isBlank(id)){
+            return APIResult.error(APICode.PARAMETER_ERROR);
+        }
+        boolean flag = userTagService.delete(id);
+        if(flag){
+            return APIResult.ok();
+        }else{
+            log.error("delete UserTag is error, id={}", id);
+            return APIResult.error(APICode.OPERATE_ERROR);
+        }
+    }
+}

+ 7 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/product/MerchantProductService.java

@@ -31,4 +31,11 @@ public interface MerchantProductService {
 
     @RequestMapping(value = "/merchant/product/list", method = RequestMethod.POST)
     APIResult<List<MerchantProductVo>> getList(@RequestBody List<String> productIdList, @RequestParam("merchantId") String merchantId);
+
+    @RequestMapping(value = "/merchant/product/pids", method = RequestMethod.POST)
+    List<MerchantProduct> findMerchantProductList(@RequestBody List<String> productIdList, @RequestParam("merchantId") String merchantId);
+
+    @RequestMapping(value = "/merchant/product/pid", method = RequestMethod.GET)
+    MerchantProduct findMerchantProductByPid(@RequestParam("pid") String pid);
+
 }

+ 10 - 1
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/product/PosterServiceInterface.java

@@ -8,12 +8,14 @@ import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
 
 @FeignClient(name = "${service.product.name}")
 public interface PosterServiceInterface {
 
     @RequestMapping(value = "/poster/list", method = RequestMethod.GET)
-    APIResult<Page<Poster>> search(@Valid @RequestBody  PosterDTO searchDTO);
+    APIResult<List<Poster>> search(@RequestParam Map<String, Object> searchDTO);
 
     @RequestMapping(value = "/poster/{id}", method = RequestMethod.GET)
     APIResult<Poster> getPoster(@PathVariable("id") String id);
@@ -26,4 +28,11 @@ public interface PosterServiceInterface {
 
     @RequestMapping(value = "/poster/{id}", method = RequestMethod.DELETE)
     APIResult delete(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/poster/updatePosters/{merchantId}", method = RequestMethod.PUT)
+    APIResult<List<Poster>> updatePosters(@RequestParam("merchantId") String merchantId,
+                                         @RequestBody List<String> posterIdList);
+
+    @RequestMapping(value = "/poster/getPosters/{merchantId}", method = RequestMethod.GET)
+    APIResult<List<Poster>> getPosters(@RequestParam("merchantId") String merchantId);
 }

+ 12 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/product/ProductService.java

@@ -2,11 +2,13 @@ package cn.rankin.cmsweb.service.product;
 
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.app.vo.ItemVo;
 import cn.rankin.data.api.product.dto.CourseDTO;
 import cn.rankin.data.api.product.dto.PackageDTO;
 import cn.rankin.data.api.product.dto.SupportDTO;
 import cn.rankin.data.api.product.dto.TrainingDTO;
 import cn.rankin.data.api.product.vo.*;
+import cn.rankin.data.api.user.entity.UserRecommend;
 import org.springframework.cloud.netflix.feign.FeignClient;
 import org.springframework.web.bind.annotation.*;
 
@@ -51,4 +53,14 @@ public interface ProductService {
 
     @RequestMapping(value = "/product/ids", method = RequestMethod.GET)
     APIResult<List<ProductVo>> findProductByIds(@RequestParam("id") List<String> ids);
+
+    @RequestMapping(value = "/product/pid/{pid}", method = RequestMethod.GET)
+    ProductVo findProductByPid(@PathVariable("pid") String pid);
+
+    @RequestMapping(value = "/product/ids/info", method = RequestMethod.PUT)
+    List<UserRecommend> setProductInfo(List<UserRecommend> userRecommendList);
+
+    @RequestMapping(value = "/item/pids", method = RequestMethod.POST)
+    List<ItemVo> findItemByPids(@RequestBody List<String> productIdList,
+                                @RequestParam("merchantId") String merchantId );
 }

+ 21 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserRecommendService.java

@@ -0,0 +1,21 @@
+package cn.rankin.cmsweb.service.user;
+
+import cn.rankin.data.api.product.entity.MerchantProduct;
+import cn.rankin.data.api.user.entity.UserRecommend;
+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.RequestParam;
+
+import java.util.List;
+
+@FeignClient(name = "${service.user.name}")
+public interface UserRecommendService {
+
+    @RequestMapping(value = "/userRecommend/uid", method = RequestMethod.GET)
+    List<UserRecommend> get(@RequestParam("uid") String uid);
+
+    @RequestMapping(value = "/userRecommend/uid", method = RequestMethod.PUT)
+    List<UserRecommend> put(@RequestParam("uid") String uid, @RequestBody List<MerchantProduct> productList);
+}

+ 16 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserTagProductRelationServiceInterface.java

@@ -0,0 +1,16 @@
+package cn.rankin.cmsweb.service.user;
+
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@FeignClient(value = "${service.user.name}")
+public interface UserTagProductRelationServiceInterface {
+
+    @RequestMapping(value = "/userTagProductRelation/{userTagId}", method = RequestMethod.GET)
+    List<UserTagProductRelation> findByUserTagId(@PathVariable("userTagId") String userTagId);
+
+
+}

+ 35 - 0
rankin-cms-web/src/main/java/cn/rankin/cmsweb/service/user/UserTagServiceInterface.java

@@ -0,0 +1,35 @@
+package cn.rankin.cmsweb.service.user;
+
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.data.api.user.dto.UserTagDTO;
+import cn.rankin.data.api.user.entity.UserTag;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@FeignClient(value = "${service.user.name}")
+public interface UserTagServiceInterface {
+
+    @RequestMapping(value = "/userTag/list", method = RequestMethod.GET)
+    Page<UserTag> search(@RequestParam Map<String, Object> searchDTO);
+
+    @RequestMapping(value = "/userTag", method = RequestMethod.POST)
+    UserTag create(@RequestBody UserTagDTO dto);
+
+    @RequestMapping(value = "/userTag", method = RequestMethod.PUT)
+    UserTag update(@RequestBody UserTagDTO dto);
+
+    @RequestMapping(value = "/userTag/{id}", method = RequestMethod.DELETE)
+    boolean delete(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/userTag/{id}", method = RequestMethod.GET)
+    UserTag getUserTag(@PathVariable("id") String id);
+
+    @RequestMapping(value = "/userTag/code/{code}", method = RequestMethod.GET)
+    List<UserTag> findUserTagByCodeUid(@PathVariable("code") String code, @PathVariable("uid") String uid);
+
+    @RequestMapping(value = "/userTag/uid/{uid}", method = RequestMethod.GET)
+    List<UserTag> findUserTagByUid(@PathVariable("uid") String uid);
+}

+ 32 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/product/vo/UserRecommendVo.java

@@ -0,0 +1,32 @@
+package cn.rankin.data.api.product.vo;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.ProductTypeEnum;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class UserRecommendVo implements Serializable {
+
+    private String id;
+
+    private String uid;
+
+    private String pid;
+
+    private BaseStatusEnum status;
+
+    private Integer sort;
+
+    private Date gmtCreated;
+
+    private Date gmtModified;
+
+    private ProductTypeEnum type;
+
+    private String name;
+
+    private String code;
+}

+ 30 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserTagDTO.java

@@ -0,0 +1,30 @@
+package cn.rankin.data.api.user.dto;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+import lombok.ToString;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+@Data
+@ToString
+public class UserTagDTO implements Serializable {
+
+    private String id;
+
+    private String name;
+
+    private String uid;
+
+    private String typeCode;
+
+    private Integer sort;
+
+    private BaseStatusEnum status;
+
+    private List<String> productList;
+
+}

+ 24 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/dto/UserTagSearchDTO.java

@@ -0,0 +1,24 @@
+package cn.rankin.data.api.user.dto;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.io.Serializable;
+
+@Data
+@ToString
+public class UserTagSearchDTO implements Serializable {
+
+    private String name;
+
+    private String uid;
+
+    private String typeCode;
+
+    private String sort;
+
+    private Integer pageNo = 1;
+
+    private Integer pageSize = 10;
+
+}

+ 3 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/TerminalUser.java

@@ -81,4 +81,7 @@ public class TerminalUser implements Serializable {
         return this.provinceName + this.cityName + this.zoneName;
     }
 
+    @Transient
+    private int deviceStatus;
+
 }

+ 74 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/UserRecommend.java

@@ -0,0 +1,74 @@
+package cn.rankin.data.api.user.entity;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.enums.ProductTypeEnum;
+import lombok.Data;
+import lombok.ToString;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * The persistent class for the role database table.
+ * 
+ */
+@Data
+@ToString
+@Entity
+@Table(name="u_user_recommend", uniqueConstraints = {@UniqueConstraint(columnNames = {"uid", "pid"})})
+@DynamicInsert
+@DynamicUpdate
+public class UserRecommend implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	@Id
+	@Column(name = "id")
+	private String id;
+
+	@Column(name = "uid")
+	private String uid;
+
+	@Column(name = "pid")
+	private String pid;
+
+	@Column(name = "sort")
+	private int sort;
+
+	@Enumerated(EnumType.ORDINAL)
+	private ProductTypeEnum type;
+
+	@Enumerated(EnumType.ORDINAL)
+	private BaseStatusEnum status;
+
+	@Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date gmtCreated;
+
+	@Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date gmtModified;
+
+	@Transient
+	private String name;
+
+	@Transient
+	private String code;
+
+	@Transient
+	private String title;
+
+	@Transient
+	private String subTitle;
+
+	@Transient
+	private String breadCrumb;
+
+	@Transient
+	private String coverUrl;
+
+
+}

+ 66 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/UserTag.java

@@ -0,0 +1,66 @@
+package cn.rankin.data.api.user.entity;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.data.api.app.vo.ItemVo;
+import cn.rankin.data.api.product.entity.MerchantProduct;
+import lombok.Data;
+import lombok.ToString;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * The persistent class for the role database table.
+ * 
+ */
+@Data
+@ToString
+@Entity
+@Table(name="u_user_tag")
+@DynamicInsert
+@DynamicUpdate
+public class UserTag implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	@Id
+	private String id;
+
+	@Column(name = "uid")
+	private String uid;
+
+	@Column
+	private String name;
+
+	@Column(name = "type_code", nullable = false)
+	private String typeCode;
+
+	@Column
+	private Integer sort;
+
+	@Column
+	@Enumerated(EnumType.ORDINAL)
+	private BaseStatusEnum status;
+
+	@Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date gmtCreated;
+
+	@Column(name = "gmt_modified", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date gmtModified;
+
+	@Transient
+	private List<MerchantProduct> productList;
+
+	@Transient
+	private List<UserTagProductRelation> relationList;
+
+	@Transient
+	private List<ItemVo> recs;
+
+}

+ 46 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/entity/UserTagProductRelation.java

@@ -0,0 +1,46 @@
+package cn.rankin.data.api.user.entity;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import lombok.Data;
+import lombok.ToString;
+import org.hibernate.annotations.DynamicInsert;
+import org.hibernate.annotations.DynamicUpdate;
+
+import javax.persistence.*;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * The persistent class for the role database table.
+ * 
+ */
+@Data
+@ToString
+@Entity
+@Table(name="u_user_tag_product_relation", uniqueConstraints = {@UniqueConstraint(columnNames = {"pid", "tag_id"})})
+@DynamicInsert
+@DynamicUpdate
+public class UserTagProductRelation implements Serializable {
+
+	private static final long serialVersionUID = 1L;
+	@Id
+	private String id;
+
+	@Column(name = "pid")
+	private String pid;
+
+	@Column(name = "tag_id")
+	private String tagId;
+
+	@Column
+	private Integer sort;
+
+	@Enumerated(EnumType.ORDINAL)
+	private BaseStatusEnum status;
+
+	@Column(name = "gmt_created", updatable = false, insertable = false, columnDefinition = "timestamp NULL DEFAULT CURRENT_TIMESTAMP")
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date gmtCreated;
+
+}

+ 2 - 0
rankin-data-api/src/main/java/cn/rankin/data/api/user/vo/TerminalUserVo.java

@@ -52,4 +52,6 @@ public class TerminalUserVo implements Serializable {
     public String getCampusName() {
         return this.provinceName + this.cityName + this.zoneName;
     }
+
+    private int deviceStatus;
 }

+ 11 - 4
rankin-product-service/src/main/java/cn/rankin/productservice/controller/app/ItemController.java

@@ -1,4 +1,4 @@
-package cn.rankin.productservice.controller.app;
+package cn.rankin.productservice.controller;
 
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
@@ -11,19 +11,19 @@ import org.springframework.web.bind.annotation.*;
 import java.util.List;
 
 @RestController
-@RequestMapping(value = "/app/item")
+@RequestMapping(value = "")
 public class ItemController {
 
     @Autowired
     private ItemService itemService;
 
-    @RequestMapping(value = "/ids", method = RequestMethod.POST)
+    @RequestMapping(value = "/app/item/ids", method = RequestMethod.POST)
     public APIResult<List<ItemVo>> findByIds(@RequestBody List<String> productIdList, @RequestParam("merchantId") String merchantId) {
         List<ItemVo> itemVoList = itemService.findByIds(merchantId, productIdList);
         return APIResult.ok(itemVoList);
     }
 
-    @RequestMapping(value = "/ids/page", method = RequestMethod.POST)
+    @RequestMapping(value = "/app/item/ids/page", method = RequestMethod.POST)
     public APIResult<Page<ItemVo>> findPage(@RequestBody ItemSearchDTO itemSearchDTO) {
         String merchantId = itemSearchDTO.getMerchantId();
         String tagId = itemSearchDTO.getTagId();
@@ -32,4 +32,11 @@ public class ItemController {
         Integer pageSize = itemSearchDTO.getPageSize();
         return itemService.findPageByTagIdAndPids(merchantId, tagId, productIdList, pageNo, pageSize);
     }
+
+    @RequestMapping(value = "/item/pids", method = RequestMethod.POST)
+    public List<ItemVo> findItemByPids(@RequestBody List<String> productIdList, @RequestParam("merchantId") String merchantId) {
+        List<ItemVo> itemVoList = itemService.findByIds(merchantId,productIdList);
+        return itemVoList;
+    }
+
 }

+ 61 - 49
rankin-product-service/src/main/java/cn/rankin/productservice/controller/PosterController.java

@@ -2,7 +2,6 @@ package cn.rankin.productservice.controller;
 
 import cn.rankin.common.utils.api.model.APICode;
 import cn.rankin.common.utils.api.model.APIResult;
-import cn.rankin.common.utils.api.page.Page;
 import cn.rankin.common.utils.enums.BaseOrderEnum;
 import cn.rankin.data.api.product.dto.PosterDTO;
 import cn.rankin.data.api.product.entity.*;
@@ -17,7 +16,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.List;
 
 @Slf4j
 @RestController
@@ -28,40 +27,29 @@ public class PosterController {
     private PosterService posterService;
 
     @Autowired
-    private ProductService productService;
-
-    @Autowired
     private ProductRepository productRepository;
 
     @RequestMapping(value = "/list", method = RequestMethod.GET)
-    public APIResult<Page<Poster>> search(@Valid @RequestBody PosterDTO searchDTO) {
+    public APIResult<List<Poster>> search(PosterDTO searchDTO) {
         Poster poster = new Poster();
 
-/*        String code = searchDTO.getCode();
-        if (!StringUtils.isEmpty(code)) {
-            lesson.setCode("%" + code + "%");
-        }
-
-        String name = searchDTO.getName();
-        if (!StringUtils.isEmpty(name)) {
-            lesson.setTitle("%" + name + "%");
-        }*/
-
         poster.setStatus(searchDTO.getStatus());
-
+        poster.setMerchantId(searchDTO.getMerchantId());
+        poster.setPid(searchDTO.getPid());
         // sort
         LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap() { {
             this.put("gmtModified", BaseOrderEnum.DESC);
         }};
 
-        Page<Poster> posterPage = posterService.search(poster, searchDTO.getPageNo(), searchDTO.getPageSize(), sort);
-
-        return APIResult.ok(posterPage);
+        List<Poster> posters = posterService.search(poster , sort);
+        posters.forEach(entity ->{
+            setProductInfo(entity);
+        } );
+        return APIResult.ok(posters);
     }
 
     @RequestMapping(value = "/{id}", method = RequestMethod.GET)
     public APIResult<Poster> getPoster(@PathVariable("id") String id) {
-
         if (StringUtils.isEmpty(id)) {
             return APIResult.error(APICode.PARAMETER_ERROR);
         }
@@ -71,32 +59,27 @@ public class PosterController {
             return APIResult.error(APICode.NOT_EXISTS);
         }
 
-
-//        Product product = productService.find(result.getPid());
-        Product product = productRepository.findByPid(result.getPid());
-        result.setProduct(product);
-
-
-
+        setProductInfo(result);
         return APIResult.ok(result);
-
     }
 
     @Transactional
     @RequestMapping(method = RequestMethod.POST)
     public APIResult<Poster> create(@Valid @RequestBody PosterDTO posterDTO) {
-        try{
-            // 创建海报
-            Poster result = posterService.create(posterDTO);
-            if (null == result) {
-                return APIResult.error(APICode.OPERATE_ERROR);
-            }
-            return APIResult.ok(result);
-        }catch(Exception e){
-            log.info("poster create error: message={}",e.getMessage());
+        if(isExist(posterDTO)){
+            return APIResult.error(APICode.ALREADY_EXISTS);
+        }
+        // 创建海报
+        Poster result = posterService.create(posterDTO);
+        if (null == result) {
             return APIResult.error(APICode.OPERATE_ERROR);
         }
+        setProductInfo(result);
+        return APIResult.ok(result);
+    }
 
+    private boolean isExist(PosterDTO posterDTO) {
+        return posterService.isExist(posterDTO);
     }
 
     @Transactional
@@ -106,24 +89,18 @@ public class PosterController {
         if (Id == null) {
             return APIResult.error(APICode.error("参数错误: id不能为空"));
         }
-
-/*        List<String> wareIdList = lessonDTO.getWareList();
-        List<CourseWare> courseWareList = new ArrayList<>();
-        if (wareIdList != null) {
-            APIResult<List<CourseWare>> wareResult = updateRelation(Id, wareIdList);
-            if (!wareResult.getSuccess()) {
-                return APIResult.error(new BaseCode(wareResult.getCode(), wareResult.getMessage()));
-            }else {
-                courseWareList = wareResult.getData();
-            }
-        }*/
+        if(isExist(posterDTO)){
+            return APIResult.error(APICode.ALREADY_EXISTS);
+        }
 
         Poster result = posterService.update(posterDTO);
         if (null == result) {
             return APIResult.error(APICode.OPERATE_ERROR);
         }
 
+        setProductInfo(result);
         return APIResult.ok(result);
+
     }
 
     @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
@@ -135,4 +112,39 @@ public class PosterController {
             return APIResult.error(ProductServiceAPICode.error("删除失败"));
         }
     }
+
+    @RequestMapping(value = "/updatePosters/{merchantId}", method = RequestMethod.PUT)
+    public APIResult<List<Poster>> updatePosters(@RequestParam("merchantId") String merchantId,
+                                          @RequestBody List<String> posterIdList){
+        List<Poster> posters = posterService.updatePosters(merchantId, posterIdList);
+
+        posters.forEach(poster ->{
+            setProductInfo(poster);
+        });
+        return APIResult.ok(posters);
+    }
+
+    @RequestMapping(value = "/getPosters/{merchantId}", method = RequestMethod.GET)
+    public APIResult<List<Poster>> getPosters(@RequestParam("merchantId") String merchantId){
+        List<Poster> posters = posterService.getByMerchantId(merchantId);
+
+        posters.forEach(poster ->{
+            setProductInfo(poster);
+        });
+        return APIResult.ok(posters);
+    }
+
+    /**
+     * 组装产品信息
+     * @param poster
+     */
+    private void setProductInfo(Poster poster) {
+        if(null == poster){
+            return ;
+        }
+        Product product = productRepository.findByPid(poster.getPid());
+        poster.setProduct(product);
+    }
+
+
 }

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

@@ -128,6 +128,11 @@ public class ProductController {
         return productService.findByPids(pidList);
     }
 
+    @RequestMapping(value = "/pid/{pid}", method = RequestMethod.GET)
+    public Product findProductsByPid(@PathVariable("pid") String pid) {
+        return productService.findProductByPid(pid);
+    }
+
     /**
      *
      * @param pid

+ 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);
+    }
 }

+ 9 - 2
rankin-product-service/src/main/java/cn/rankin/productservice/controller/app/ItemController.java

@@ -11,8 +11,8 @@ import org.springframework.web.bind.annotation.*;
 import java.util.List;
 
 @RestController
-@RequestMapping(value = "/app/item")
-public class ItemController {
+@RequestMapping(value = "/v0/app/item")
+public class ItemControllerV0 {
 
     @Autowired
     private ItemService itemService;
@@ -32,4 +32,11 @@ public class ItemController {
         Integer pageSize = itemSearchDTO.getPageSize();
         return itemService.findPageByTagIdAndPids(merchantId, tagId, productIdList, pageNo, pageSize);
     }
+
+    @RequestMapping(value = "/pids", method = RequestMethod.POST)
+    public List<ItemVo> findItemByPids(@RequestBody List<String> productIdList, @RequestParam("merchantId") String merchantId) {
+        List<ItemVo> itemVoList = itemService.findByIds(merchantId,productIdList);
+        return itemVoList;
+    }
+
 }

+ 10 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/controller/cms/MerchantProductController.java

@@ -97,6 +97,16 @@ public class MerchantProductController {
         return APIResult.ok(merchantProductList);
     }
 
+    @RequestMapping(value = "/pids", method = RequestMethod.POST)
+    public List<MerchantProduct> findByPidsAndMerchantId(@RequestBody List<String> productIdList, @RequestParam("merchantId") String merchantId){
+        return merchantProductService.findByPidsAndMerchantId(productIdList, merchantId);
+    }
+
+    @RequestMapping(value = "/pid", method = RequestMethod.GET)
+    public MerchantProduct findByPid(@RequestParam("pid") String pid){
+        return merchantProductService.findByPid(pid);
+    }
+
 
 
 }

+ 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")

+ 2 - 1
rankin-product-service/src/main/java/cn/rankin/productservice/repository/MerchantProductRepository.java

@@ -19,7 +19,8 @@ public interface MerchantProductRepository extends BasicJpaRepository<MerchantPr
     @Query(value = "select m from MerchantProduct m where m.pid in (?1) and m.merchantId = ?2 order by m.sort")
     List<MerchantProduct> findByPidsAndMerchantId(List<String> pids, String merchantId);
 
-
+    @Query(value = "select m from MerchantProduct m where m.pid in (?1) order by m.sort")
+    List<MerchantProduct> findByPids(List<String> pids);
 
     @Query(value = "select m from MerchantProduct m where m.pid in (?1) and m.merchantId = ?2 and m.status = ?3 order by m.sort")
     List<MerchantProduct> findByPidsAndMerchantId(List<String> pids, String merchantId, BaseStatusEnum status);

+ 9 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/repository/PosterRepository.java

@@ -22,5 +22,14 @@ public interface PosterRepository extends BasicJpaRepository<Poster, String> {
     @Modifying
     @Query(value = "update Poster p set p.status = 1 where p.id = ?1")
     Integer deleteById(String id);
+
+    @Query(value = "select p from Poster p where p.merchantId = ?1 and p.status = ?2")
+    List<Poster> findByStatus(String merchantId, BaseStatusEnum normal);
+
+    @Query(value = "select p from Poster p where p.merchantId = ?1 ")
+    List<Poster> findByMerchantId(String merchantId);
+
+    @Query(value = "select p from Poster p where p.merchantId = ?1 and p.pid = ?2")
+    Poster findByMerchantIdPid(String merchantId, String pid);
 }
 

+ 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);
+    }
 }

+ 27 - 0
rankin-product-service/src/main/java/cn/rankin/productservice/service/MerchantProductService.java

@@ -6,6 +6,7 @@ import cn.rankin.common.utils.enums.BaseOrderEnum;
 import cn.rankin.common.utils.enums.BaseStatusEnum;
 import cn.rankin.common.utils.enums.ProductTypeEnum;
 import cn.rankin.common.utils.util.JpaSortUtil;
+import cn.rankin.common.utils.util.ListUtil;
 import cn.rankin.data.api.product.entity.*;
 import cn.rankin.data.api.product.vo.PackageProductVo;
 import cn.rankin.productservice.code.ProductServiceAPICode;
@@ -14,6 +15,7 @@ import cn.rankin.productservice.repository.MerchantProductRepository;
 import cn.rankin.productservice.repository.ProductRepository;
 import cn.rankin.productservice.repository.TagRepository;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
@@ -318,4 +320,29 @@ public class MerchantProductService {
 
         return merchantProductList;
     }
+
+
+    public List<MerchantProduct> findByPidsAndMerchantId(List<String> productIdList, String merchantId){
+        List<MerchantProduct> merchantProductList = merchantProductRepository.findByPidsAndMerchantId(productIdList, merchantId);
+
+        Map<String, MerchantProduct> merchantProductMap = ListUtil.convert(merchantProductList, "pid", MerchantProduct.class);
+
+        List<MerchantProduct> sortMerchantProductList = new ArrayList<>();
+        for (String productId : productIdList) {
+            MerchantProduct merchantProduct = merchantProductMap.get(productId);
+            if (merchantProduct != null) {
+                sortMerchantProductList.add(merchantProduct);
+            }
+        }
+        return sortMerchantProductList;
+    }
+
+    public MerchantProduct findByPid(String pid) {
+        List<MerchantProduct> merchantProductList = merchantProductRepository.findByPid(pid);
+        if(null != merchantProductList && merchantProductList.size() > 0 ){
+            return merchantProductList.get(0);
+        }else{
+            return null;
+        }
+    }
 }

+ 41 - 18
rankin-product-service/src/main/java/cn/rankin/productservice/service/PosterService.java

@@ -1,6 +1,5 @@
 package cn.rankin.productservice.service;
 
-import cn.rankin.common.utils.api.page.Page;
 import cn.rankin.common.utils.enums.BaseOrderEnum;
 import cn.rankin.common.utils.enums.BaseStatusEnum;
 import cn.rankin.common.utils.util.JpaSortUtil;
@@ -13,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
 
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
@@ -47,18 +47,15 @@ public class PosterService {
         return sortPosterList;
     }
 
-    public Page<Poster> search(Poster poster, Integer pageNo, Integer pageSize, LinkedHashMap<String, BaseOrderEnum> sort) {
+    public List<Poster> search(Poster poster, LinkedHashMap<String, BaseOrderEnum> sort) {
         Long count = posterRepository.count(poster);
-        Page<Poster> page = new Page(count, pageNo, pageSize);
 
         if (count == 0) {
-            return page;
+            return new ArrayList<>();
         }
 
-        List<Poster> posterList = posterRepository.find(poster, page.getStart(), pageSize, JpaSortUtil.sort(sort));
-        page.setList(posterList);
-
-        return page;
+        List<Poster> posterList = posterRepository.find(poster, JpaSortUtil.sort(sort));
+        return posterList;
     }
 
     public Poster findById(String id) {
@@ -66,18 +63,8 @@ public class PosterService {
         return poster;
     }
 
-/*    public boolean exists(String code) {
-        Long count = posterRepository.countByCode(code);
-        return count > 0L;
-    }*/
-
     @Transactional
     public Poster create(PosterDTO posterDTO) {
-        /*String code = lessonDTO.getCode();
-        if (exists(code)) {
-            return APIResult.error(APICode.ALREADY_EXISTS);
-        }*/
-
         Poster poster = convert(posterDTO);
         Poster result = posterRepository.save(poster);
 
@@ -101,4 +88,40 @@ public class PosterService {
         return false;
     }
 
+    public List<Poster> getByMerchantId(String merchantId) {
+        List<Poster> posterList = posterRepository.findByMerchantId(merchantId);
+        if (CollectionUtils.isEmpty(posterList)) {
+            return new ArrayList<>();
+        }
+
+        return posterList;
+    }
+
+    public List<Poster> updatePosters(String merchantId, List<String> posterIdList) {
+        if (CollectionUtils.isEmpty(posterIdList)) {
+            return null;
+        }
+
+        List<Poster> posterList = posterRepository.findByMerchantId(merchantId);
+
+        // 排序
+        posterList.forEach( poster -> {
+//            String productId = poster.getPid();
+            Integer sort = posterIdList.indexOf(poster.getId());
+            poster.setSort(sort);
+        });
+
+        posterRepository.save(posterList);
+        List<Poster> result = posterRepository.findByStatus(merchantId, BaseStatusEnum.NORMAL);
+        return result;
+    }
+
+    public boolean isExist(PosterDTO posterDTO) {
+        Poster poster =posterRepository.findByMerchantIdPid(posterDTO.getMerchantId(),posterDTO.getPid());
+        if(poster != null && !poster.getId().equals(posterDTO.getId())){
+            return true;
+        }else{
+            return false;
+        }
+    }
 }

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

@@ -312,5 +312,9 @@ public class ProductService {
         List<Product> productList = productRepository.findByPids(pidList);
         return APIResult.ok(productList);
     }
+
+    public Product findProductByPid(String pid) {
+        return productRepository.findByPid(pid);
+    }
 }
 

+ 5 - 0
rankin-resource-service/src/main/java/cn/rankin/resourceservice/controller/ResourceController.java

@@ -24,6 +24,11 @@ public class ResourceController {
     @Autowired
     private ResourceService resourceService;
 
+    public static String HTTP_VIDEO_DOMAIN = "http://efunvideo.ai160.com";
+    public static String LJ_VIDEO_DOMAIN = "http://ljvideo.ai160.com";
+
+    public static String HTTPS_VIDEO_DOMAIN = "https://efunvideo.ai160.com";
+
     @RequestMapping(value = "/list")
     public APIResult<Page<Resource>> search(ResourceSearchDTO resourceSearchDTO) {
         log.info(JSON.toJSONString(resourceSearchDTO));

+ 8 - 1
rankin-resource-service/src/main/java/cn/rankin/resourceservice/dto/ResourceDetail.java

@@ -3,8 +3,10 @@ package cn.rankin.resourceservice.dto;
 import cn.rankin.common.utils.enums.BaseStatusEnum;
 import cn.rankin.data.api.resource.entity.Resource;
 import cn.rankin.common.utils.constant.ResourceType;
+import cn.rankin.resourceservice.controller.ResourceController;
 import lombok.Data;
 import lombok.ToString;
+import org.apache.commons.lang.StringUtils;
 
 import java.io.Serializable;
 import java.util.Date;
@@ -58,7 +60,12 @@ public class ResourceDetail implements Serializable {
         resource.setCode(no);
         resource.setName(title);
         resource.setType(type);
-        resource.setUrl(fullPath);
+        if(StringUtils.isNotBlank(fullPath)){
+            resource.setUrl(fullPath.replace(ResourceController.HTTP_VIDEO_DOMAIN, ResourceController.HTTPS_VIDEO_DOMAIN)
+                                    .replace(ResourceController.LJ_VIDEO_DOMAIN, ResourceController.HTTPS_VIDEO_DOMAIN));
+        }else{
+            resource.setUrl(fullPath);
+        }
         resource.setFormat(format);
         resource.setQuality(quality);
         resource.setSize(size);

+ 10 - 2
rankin-resource-service/src/main/java/cn/rankin/resourceservice/dto/ResourceRemote.java

@@ -7,7 +7,9 @@ import javax.persistence.*;
 import cn.rankin.common.utils.enums.BaseStatusEnum;
 import cn.rankin.data.api.resource.entity.Resource;
 import cn.rankin.common.utils.constant.ResourceType;
+import cn.rankin.resourceservice.controller.ResourceController;
 import lombok.Data;
+import org.apache.commons.lang.StringUtils;
 
 @Data
 public class ResourceRemote implements Serializable {
@@ -59,11 +61,17 @@ public class ResourceRemote implements Serializable {
         List<Resource> resourceList = new ArrayList<>();
         videos.forEach(v -> {
             Resource resource = new Resource();
-            resource.setId(v.getId());
+            resource.setId(v.getRid());
             resource.setCode(no);
             resource.setName(title);
             resource.setType(type);
-            resource.setUrl(v.getFullPath());
+            if(StringUtils.isNotBlank(v.getFullPath())){
+                resource.setUrl(v.getFullPath()
+                                .replace(ResourceController.HTTP_VIDEO_DOMAIN, ResourceController.HTTPS_VIDEO_DOMAIN)
+                                .replace(ResourceController.LJ_VIDEO_DOMAIN, ResourceController.HTTPS_VIDEO_DOMAIN));
+            }else{
+                resource.setUrl(v.getFullPath());
+            }
             resource.setFormat(v.getFormat());
             resource.setQuality(v.getQuality());
             resource.setSize(v.getSize());

+ 1 - 1
rankin-resource-service/src/main/java/cn/rankin/resourceservice/proxy/RemoteResourceProxy.java

@@ -32,6 +32,6 @@ public interface RemoteResourceProxy {
     APIResult<ResourceDetail> saveResources(@RequestBody ResourceRemote resourceRemote);
 
     @RequestMapping(value = "/rcenter/v1/resources/mgt", method = RequestMethod.PUT)
-    APIResult<ResourceDetail> updateResources(@RequestBody ResourceRemote resourceRemote);
+    APIResult updateResources(@RequestBody ResourceRemote resourceRemote);
 
 }

+ 10 - 8
rankin-resource-service/src/main/java/cn/rankin/resourceservice/service/ResourceService.java

@@ -5,18 +5,20 @@ import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.common.utils.api.page.Page;
 import cn.rankin.common.utils.constant.ResourceType;
 import cn.rankin.common.utils.dto.resource.ResourceSearchDTO;
+import cn.rankin.common.utils.enums.BaseOrderEnum;
 import cn.rankin.common.utils.exception.DuplicateValueException;
 import cn.rankin.common.utils.exception.NotFoundException;
 import cn.rankin.common.utils.exception.UnsupportedOperationException;
+import cn.rankin.data.api.resource.entity.Resource;
 import cn.rankin.resourceservice.dto.ResourceDetail;
 import cn.rankin.resourceservice.dto.ResourceRemote;
-import cn.rankin.data.api.resource.entity.Resource;
 import cn.rankin.resourceservice.dto.ResourceVideo;
 import cn.rankin.resourceservice.proxy.RemoteResourceProxy;
 import cn.rankin.resourceservice.repository.ResourceRepository;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Sort;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
 
@@ -56,7 +58,7 @@ public class ResourceService {
             return APIResult.ok(page);
         }
 
-        List<Resource> resourceList = resourceRepository.find(resource, page.getStart(), pageSize, null);
+        List<Resource> resourceList = resourceRepository.find(resource, page.getStart(), pageSize, new Sort(Sort.Direction.DESC, "gmtModified"));
         resourceList.forEach(r -> {
             initResourceUrl(r);
         });
@@ -103,6 +105,7 @@ public class ResourceService {
                 this.put("pageNum", resourceSearchDTO.getPageNo());
                 this.put("pageSize", resourceSearchDTO.getPageSize());
                 this.put("type", resourceSearchDTO.getType());
+                this.put("sort", new LinkedHashMap<String,BaseOrderEnum>().put("createTime",BaseOrderEnum.DESC));
             }
         });
 
@@ -157,7 +160,7 @@ public class ResourceService {
         if (ResourceType.VIDEO == resource.getType()) {
             resource.setUrl(concatUrl(videoDomain, path));
         }else if (ResourceType.IMG == resource.getType()) {
-            resource.setUrl(concatUrl(imgDomain, path));
+            resource.setUrl(concatUrl(imgDomain, path).replace(" ", ""));
         }
     }
 
@@ -287,12 +290,11 @@ public class ResourceService {
 
 
         APIResult<ResourceDetail> apiResult = resourceProxy.saveResources(resourceRemote);
-        log.info("saveResources: "+apiResult);
-        log.info("Remote Server return: code={}, message={}", apiResult.getCode(), apiResult.getMessage());
         if (!apiResult.getSuccess()) {
             return errorResourceAPIResult(apiResult);
         }
 
+        log.info("Remote Server return: code={}, message={}", apiResult.getCode(), apiResult.getMessage());
 //        Resource resourceVO = apiResult.getData().toNativeResource();
         return APIResult.ok();
     }
@@ -310,7 +312,7 @@ public class ResourceService {
 
         Set<ResourceVideo> videos = new HashSet<>();
         ResourceVideo video = new ResourceVideo();
-        video.setId(resource.getId());
+//        video.setId(resource.getId());
         video.setBucket("efunbox");
         video.setPath(resource.getPath());
         video.setQuality(resource.getQuality());
@@ -326,12 +328,12 @@ public class ResourceService {
         resourceRemote.setType(resource.getType());
         resourceRemote.setVideos(videos);
 
-        APIResult<ResourceDetail> apiResult = resourceProxy.updateResources(resourceRemote);
+        APIResult apiResult = resourceProxy.updateResources(resourceRemote);
         if (!apiResult.getSuccess()) {
             return errorResourceAPIResult(apiResult);
         }
 
-        log.info("Remote Server info: code={}, message={},data={}", apiResult.getCode(), apiResult.getMessage(),apiResult.getData());
+        log.info("Remote Server info: code={}, message={}", apiResult.getCode(), apiResult.getMessage());
         return APIResult.ok();
     }
 

+ 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 - 1
rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalDeviceController.java

@@ -3,6 +3,7 @@ package cn.rankin.userservice.controller;
 import cn.rankin.common.utils.api.model.APIResult;
 import cn.rankin.data.api.user.dto.TerminalDeviceDTO;
 import cn.rankin.data.api.user.entity.TerminalDevice;
+import cn.rankin.userservice.code.UserServiceAPICode;
 import cn.rankin.userservice.service.TerminalDeviceService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
@@ -28,7 +29,12 @@ public class TerminalDeviceController {
 
     @RequestMapping(value = "/uid/{userId}", method = RequestMethod.GET)
     public APIResult<TerminalDevice> findByUserId(@PathVariable("userId") String userId) {
-        return terminalDeviceService.findByUserId(userId);
+//        return terminalDeviceService.findByUserId(userId);
+        TerminalDevice terminalDevice = terminalDeviceService.findByUserId(userId);
+        if (terminalDevice == null) {
+            return APIResult.error(UserServiceAPICode.NOT_EXISTS);
+        }
+        return APIResult.ok(terminalDevice);
     }
 
     @RequestMapping(value = "/deviceCode/{deviceCode}", method = RequestMethod.GET)

+ 31 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/TerminalUserController.java

@@ -10,12 +10,14 @@ import cn.rankin.data.api.user.dto.TerminalUserDTO;
 import cn.rankin.data.api.user.dto.TerminalUserSearchDTO;
 import cn.rankin.data.api.user.entity.Campus;
 import cn.rankin.data.api.user.entity.Merchant;
+import cn.rankin.data.api.user.entity.TerminalDevice;
 import cn.rankin.data.api.user.entity.TerminalUser;
 import cn.rankin.userservice.code.UserServiceAPICode;
 import cn.rankin.userservice.dto.RemoteUser;
 import cn.rankin.userservice.proxy.RemoteUserProxy;
 import cn.rankin.userservice.service.CampusService;
 import cn.rankin.userservice.service.MerchantService;
+import cn.rankin.userservice.service.TerminalDeviceService;
 import cn.rankin.userservice.service.TerminalUserService;
 import cn.rankin.userservice.utils.StudentNumberUtil;
 import com.alibaba.fastjson.JSON;
@@ -50,6 +52,9 @@ public class TerminalUserController {
     @Autowired
     private RemoteUserProxy remoteUserProxy;
 
+    @Autowired
+    private TerminalDeviceService terminalDeviceService;
+
     @RequestMapping(value = "/list", method = RequestMethod.GET)
     public APIResult<Page<TerminalUser>> search(TerminalUserSearchDTO terminalUserSearchDTO) {
         TerminalUser terminalUser = new TerminalUser();
@@ -79,11 +84,13 @@ public class TerminalUserController {
         if (result.getSuccess()) {
             List<TerminalUser> terminalUserList = result.getData().getList();
             setUserInfo(terminalUserList);
+            setDeciceInfo(terminalUserList);
         }
 
         return result;
     }
 
+
     @RequestMapping(method = RequestMethod.GET)
     public APIResult<List<TerminalUser>> findByCondition(TerminalUserSearchDTO terminalUserSearchDTO) {
         TerminalUser terminalUser = new TerminalUser();
@@ -319,4 +326,28 @@ public class TerminalUserController {
             }
         }
     }
+
+    /**
+     * 设置绑定设备信息
+     * @param terminalUserList
+     */
+    private void setDeciceInfo(List<TerminalUser> terminalUserList) {
+        if (CollectionUtils.isEmpty(terminalUserList)) {
+            return;
+        }
+
+        terminalUserList.forEach(terminalUser ->{
+            TerminalDevice terminalDevice = terminalDeviceService.findByUserId(terminalUser.getId());
+            if(null != terminalDevice){
+                //1  已绑定设备
+                terminalUser.setDeviceStatus(1);
+            }else{
+                terminalUser.setDeviceStatus(0);
+            }
+        });
+    }
+
+
+
+
 }

+ 32 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserRecommendController.java

@@ -0,0 +1,32 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.data.api.product.entity.MerchantProduct;
+import cn.rankin.data.api.user.entity.UserRecommend;
+import cn.rankin.userservice.service.UserRecommendService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/userRecommend")
+public class UserRecommendController {
+
+    @Autowired
+    private UserRecommendService userRecommendService;
+
+    @RequestMapping(value = "/uid",method = RequestMethod.GET)
+    public List<UserRecommend> get(@RequestParam("uid") String uid) {
+        return userRecommendService.get(uid);
+    }
+
+    @RequestMapping(value = "/uid",method = RequestMethod.PUT)
+    public List<UserRecommend> put(@RequestParam("uid") String uid, @RequestBody List<MerchantProduct> products) {
+        return userRecommendService.put(uid, products);
+    }
+
+    @RequestMapping(value = "/courses/uid/{uid}", method = RequestMethod.GET)
+    public List<UserRecommend> getUserRecommendCourses(@RequestParam("uid") String uid) {
+        return userRecommendService.getUserRecommendCourses(uid);
+    }
+}

+ 124 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserTagController.java

@@ -0,0 +1,124 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.enums.BaseOrderEnum;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.data.api.user.dto.UserTagDTO;
+import cn.rankin.data.api.user.dto.UserTagSearchDTO;
+import cn.rankin.data.api.user.entity.UserTag;
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import cn.rankin.userservice.service.UserTagProductRelationService;
+import cn.rankin.userservice.service.UserTagService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequestMapping(value = "userTag")
+public class UserTagController {
+
+    @Autowired
+    private UserTagService userTagService;
+
+    @Autowired
+    private UserTagProductRelationService userTagProductRelationService;
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
+    public UserTag getUserTag(@PathVariable("id") String id) {
+
+        UserTag userTag = userTagService.getUserTag(id);
+
+ /*       if(null != userTag){
+            String userTagId = userTag.getId();
+            List<UserTagProductRelation> userTagProductRelations = userTagProductRelationService.findByTagId(userTagId);
+            userTag.setRelationList(userTagProductRelations);
+        }*/
+
+        return userTag;
+    }
+
+    @RequestMapping(value = "/code/{code}", method = RequestMethod.GET)
+    public List<UserTag> findUserTagByCodeUid(@PathVariable("code") String code, @RequestParam("uid") String uid) {
+        List<UserTag> userTagList = userTagService.findUserTagByCodeUid(code, uid);
+
+        //标签下   课程数据
+        userTagList.forEach(userTag -> {
+            List<UserTagProductRelation> userTagProductRelations = userTagProductRelationService.findByTagId(userTag.getId(), BaseStatusEnum.NORMAL);
+            userTag.setRelationList(userTagProductRelations);
+        });
+
+        return userTagList;
+    }
+
+    @RequestMapping(value = "/uid/{uid}", method = RequestMethod.GET)
+    public List<UserTag> findUserTagByUid(@PathVariable("uid") String uid) {
+        List<UserTag> userTagList = userTagService.findUserTagByUid(uid);
+
+        //标签下   课程数据
+       /* userTagList.forEach(userTag -> {
+            String userTagId = userTag.getId();
+            List<UserTagProductRelation> userTagProductRelations = userTagProductRelationService.findByTagId(userTagId);
+            userTag.setRelationList(userTagProductRelations);
+        });*/
+
+        return userTagList;
+    }
+
+    @RequestMapping(value = "/list", method = RequestMethod.GET)
+    public Page<UserTag> search(UserTagSearchDTO searchDTO) {
+        UserTag userTag = new UserTag();
+
+        String name = searchDTO.getName();
+        if (name != null) {
+            userTag.setName("%" + name + "%");
+        }
+        // sort
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap<>();
+        sort.put("gmtModified", BaseOrderEnum.DESC);
+        return userTagService.search(userTag, searchDTO.getPageNo(), searchDTO.getPageSize(), sort);
+    }
+
+    @RequestMapping(method = RequestMethod.POST)
+    public UserTag create(@RequestBody UserTagDTO userTagDTO) {
+        UserTag userTag = userTagService.create(userTagDTO);
+        if(null == userTag){
+            return null;
+        }
+
+        String userTagId = userTag.getId();
+        List<String> productIdList = userTagDTO.getProductList();
+        if( !CollectionUtils.isEmpty(productIdList)){
+            userTagProductRelationService.updateByTagId(userTagId,productIdList);
+        }
+
+        return userTag;
+    }
+
+    @RequestMapping(method = RequestMethod.PUT)
+    public UserTag update(@RequestBody UserTagDTO userTagDTO) {
+        UserTag result = userTagService.update(userTagDTO);
+        if(null == result){
+            return null;
+        }
+
+        String userTagId = result.getId();
+        List<String> productIdList = userTagDTO.getProductList();
+        if( null != productIdList){
+            userTagProductRelationService.updateByTagId(userTagId,productIdList);
+        }
+
+        return result;
+    }
+
+    @RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
+    public boolean delete(@PathVariable("id") String id) {
+        return userTagService.delete(id);
+    }
+
+
+}

+ 24 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/controller/UserTagProductRelationController.java

@@ -0,0 +1,24 @@
+package cn.rankin.userservice.controller;
+
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import cn.rankin.userservice.service.UserTagProductRelationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/userTagProductRelation")
+public class UserTagProductRelationController {
+
+    @Autowired
+    private UserTagProductRelationService userTagProductRelationService;
+
+    @RequestMapping(value = "/{userTagId}",method = RequestMethod.GET)
+    public List<UserTagProductRelation> findByUserTagId(@PathVariable("userTagId") String userTagId) {
+        List<UserTagProductRelation> userTagProductRelations = userTagProductRelationService.findByUserTagId(userTagId);
+        return userTagProductRelations;
+    }
+
+
+}

+ 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);
 }

+ 17 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserRecommendRepository.java

@@ -0,0 +1,17 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.UserRecommend;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface UserRecommendRepository extends BasicJpaRepository<UserRecommend, String> {
+
+    @Query(value = "select r from UserRecommend r where r.uid = :uid and r.status = :status order by r.sort")
+    List<UserRecommend> findByStatus(@Param("uid") String uid, @Param("status") BaseStatusEnum status);
+
+    List<UserRecommend> findByUid(String uid);
+}

+ 42 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserTagProductRelationRepository.java

@@ -0,0 +1,42 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.List;
+
+public interface UserTagProductRelationRepository extends BasicJpaRepository<UserTagProductRelation, String> {
+
+    @Query(value = "select r from UserTagProductRelation r where r.tagId = ?1 and r.status = ?2 order by r.sort")
+    List<UserTagProductRelation> findByTagId(String tagId, BaseStatusEnum status);
+
+    List<UserTagProductRelation> findByTagId(String tagId);
+
+    @Modifying
+    @Query(value = "update UserTagProductRelation r set r.status = 1 where r.tagId = :tagId")
+    Integer deleteByTagId(@Param("tagId") String tagId);
+
+/*
+    @Modifying
+    @Query(value = "update UserTagProductRelation r set r.status = 1 where r.pid = :productId and r.tagId = :tagId")
+    Integer deleteByPidAndTagId(@Param("productId") String productId, @Param("tagId") String tagId);
+
+    List<UserTagProductRelation> findByTagIdIn(List<String> tagIds);
+
+    @Query(value = "select r from UserTagProductRelation r where r.pid in (?1) and r.tagId in (?2) and r.status = 0")
+    List<UserTagProductRelation> findByPidsAndTagIds(List<String> pids, List<String> tagIds);
+
+    @Query(value = "select r from UserTagProductRelation r where r.pid = ?1 and r.tagId = ?2 and r.status = ?3")
+    List<UserTagProductRelation> findByPidAndTagId(String pid, String tagId, BaseStatusEnum status);
+
+    List<UserTagProductRelation> findByPidAndTagId(String pid, String merchantId);
+
+    @Query(value = "select r from UserTagProductRelation r where r.tagId = ?1 and r.pid in (?2) and r.status = 0 order by r.sort limit ?3, ?4", nativeQuery = true)
+    List<UserTagProductRelation> findByTagIdAndPids(String tagId, List<String> productIdList, Long start, Integer size);
+*/
+
+}

+ 33 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/repository/UserTagRepository.java

@@ -0,0 +1,33 @@
+package cn.rankin.userservice.repository;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.jpa.BasicJpaRepository;
+import cn.rankin.data.api.user.entity.UserTag;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+public interface UserTagRepository extends BasicJpaRepository<UserTag, String> {
+
+    @Query(value = "select t from UserTag t where t.typeCode = ?1 and t.uid = ?2  and t.status = ?3 order by t.sort")
+    List<UserTag> findByTypeCodeUid(String typeCode, String uid, BaseStatusEnum status);
+
+/*
+    @Query(value = "select t from UserTag t where t.typeCode=?1 and  t.uid = ?2  and t.status = ?3 order by t.sort")
+    List<UserTag> findByCodeUid(String code, String uid, BaseStatusEnum status);
+*/
+
+    @Query(value = "select t from UserTag t where t.typeCode = ?1 order by t.sort")
+    List<UserTag> findByTypeCode(String typeCode);
+
+    @Query(value = "select t from UserTag t where t.id in (?1) and t.status = ?2")
+    List<UserTag> findByIds(List<String> tagIdList, BaseStatusEnum status);
+
+    @Modifying
+    @Query(value = "update UserTag t set t.status = 1 where t.id = ?1")
+    Integer deleteById(String id);
+
+    @Query(value = "select t from UserTag t where t.uid = ?1  order by t.sort")
+    List<UserTag> findUserTagByUid(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);
+    }
 }

+ 5 - 1
rankin-user-service/src/main/java/cn/rankin/userservice/service/TerminalDeviceService.java

@@ -61,12 +61,16 @@ public class TerminalDeviceService {
         return APIResult.ok(Boolean.TRUE);
     }
 
-    public APIResult<TerminalDevice> findByUserId(String userId) {
+/*    public APIResult<TerminalDevice> findByUserId(String userId) {
         TerminalDevice terminalDevice = terminalDeviceRepository.findByUserId(userId);
         if (terminalDevice == null) {
             return APIResult.error(UserServiceAPICode.NOT_EXISTS);
         }
         return APIResult.ok(terminalDevice);
+    }*/
+
+    public TerminalDevice findByUserId(String userId) {
+        return terminalDeviceRepository.findByUserId(userId);
     }
 
     public APIResult<TerminalDevice> findByDeviceCode(String deviceCode) {

+ 88 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/UserRecommendService.java

@@ -0,0 +1,88 @@
+package cn.rankin.userservice.service;
+
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.util.ListUtil;
+
+import cn.rankin.data.api.product.entity.MerchantProduct;
+import cn.rankin.data.api.user.entity.UserRecommend;
+import cn.rankin.userservice.repository.UserRecommendRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class UserRecommendService {
+
+    @Autowired
+    private UserRecommendRepository userRecommendRepository;
+
+    public List<UserRecommend> get(String uid) {
+        List<UserRecommend> recommendList = userRecommendRepository.findByStatus(uid, BaseStatusEnum.NORMAL);
+        if (CollectionUtils.isEmpty(recommendList)) {
+            return new ArrayList<>();
+        }
+
+        return recommendList;
+    }
+
+    public List<UserRecommend> put(String uid, List<MerchantProduct> products) {
+        List<String> productIdList = new ArrayList<>();
+        if (!CollectionUtils.isEmpty(products)) {
+            products.forEach(product -> productIdList.add(product.getPid()) );
+        }
+
+        List<UserRecommend> userRecommendList = userRecommendRepository.findByUid(uid);
+        List<String> existRecommendIdList = new ArrayList<>();
+
+        // 更新现存的
+        userRecommendList.forEach(recommend -> {
+            String pid = recommend.getPid();
+            if (productIdList.contains(pid)) {
+                recommend.setStatus(BaseStatusEnum.NORMAL);
+            }else {
+                recommend.setStatus(BaseStatusEnum.DEL);
+            }
+            existRecommendIdList.add(pid);
+        });
+
+        // 更新新加的
+        List<String> notExistsRecommendIdList = ListUtil.subtract(productIdList, existRecommendIdList);
+        if (notExistsRecommendIdList != null && notExistsRecommendIdList.size() > 0) {
+            Map<String, MerchantProduct> merchantProductMap = ListUtil.convert(products, "pid", MerchantProduct.class);
+            for (String productId : notExistsRecommendIdList) {
+                MerchantProduct merchantProduct = merchantProductMap.get(productId);
+                UserRecommend recommend = new UserRecommend();
+                recommend.setPid(productId);
+                recommend.setUid(uid);
+                recommend.setStatus(BaseStatusEnum.NORMAL);
+                recommend.setType(merchantProduct.getType());
+                userRecommendList.add(recommend);
+            }
+
+        }
+
+        // 排序
+        userRecommendList.forEach( recommend -> {
+            String productId = recommend.getPid();
+            Integer sort = productIdList.indexOf(productId);
+            recommend.setSort(sort);
+        });
+
+        userRecommendRepository.save(userRecommendList);
+        List<UserRecommend> result = userRecommendRepository.findByUid(uid);
+        return result;
+    }
+
+    public List<UserRecommend> getUserRecommendCourses(String uid) {
+        List<UserRecommend> recommendList = userRecommendRepository.findByStatus(uid, BaseStatusEnum.NORMAL);
+        if (CollectionUtils.isEmpty(recommendList)) {
+            return new ArrayList<>();
+        }
+
+        return recommendList;
+    }
+}

+ 87 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/UserTagProductRelationService.java

@@ -0,0 +1,87 @@
+package cn.rankin.userservice.service;
+
+import cn.rankin.common.utils.enums.BaseOrderEnum;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.util.JpaSortUtil;
+import cn.rankin.common.utils.util.ListUtil;
+import cn.rankin.data.api.user.entity.UserTagProductRelation;
+import cn.rankin.userservice.repository.UserTagProductRelationRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+@Slf4j
+@Service
+public class UserTagProductRelationService {
+
+    @Autowired
+    private UserTagProductRelationRepository relationRepository;
+
+    public List<UserTagProductRelation> findByUserTagId(String tagId) {
+        UserTagProductRelation relation = new UserTagProductRelation();
+        relation.setTagId(tagId);
+        relation.setStatus(BaseStatusEnum.NORMAL);
+
+
+        // sort
+        LinkedHashMap<String, BaseOrderEnum> sort = new LinkedHashMap() { {
+            this.put("sort", BaseOrderEnum.ASC);
+        }};
+        List<UserTagProductRelation> relationList = relationRepository.find(relation, JpaSortUtil.sort(sort));
+
+        return relationList;
+    }
+
+    public List<UserTagProductRelation> findByTagId(String tagId, BaseStatusEnum status) {
+        return relationRepository.findByTagId(tagId, status);
+    }
+
+    @Transactional
+    public void updateByTagId(String tagId, List<String> productIdList) {
+        if (productIdList == null) {
+            return;
+        }else if (productIdList.size() == 0) {
+            relationRepository.deleteByTagId(tagId);
+            return;
+        }
+
+        List<UserTagProductRelation> relationList = relationRepository.findByTagId(tagId);
+
+        List<String> currentIdList = new ArrayList<>();
+        relationList.forEach( relation -> {
+            String productId = relation.getPid();
+            if (productIdList.contains(productId)) {
+                relation.setStatus(BaseStatusEnum.NORMAL);
+            }else {
+                relation.setStatus(BaseStatusEnum.DEL);
+            }
+            currentIdList.add(productId);
+        });
+
+        List<String> notExistItemIdList = ListUtil.subtract(productIdList, currentIdList);
+        if (notExistItemIdList != null && notExistItemIdList.size() > 0) {
+            notExistItemIdList.forEach( productId -> {
+                UserTagProductRelation relation = new UserTagProductRelation();
+                relation.setPid(productId);
+                relation.setTagId(tagId);
+                relation.setSort(0);
+                relation.setStatus(BaseStatusEnum.NORMAL);
+                relationList.add(relation);
+            });
+        }
+
+        // 排序
+        relationList.forEach( relation -> {
+            String productId = relation.getPid();
+            Integer index = productIdList.indexOf(productId);
+            relation.setSort(index);
+        });
+
+        relationRepository.save(relationList);
+    }
+}

+ 189 - 0
rankin-user-service/src/main/java/cn/rankin/userservice/service/UserTagService.java

@@ -0,0 +1,189 @@
+package cn.rankin.userservice.service;
+
+import cn.rankin.common.utils.api.page.Page;
+import cn.rankin.common.utils.enums.BaseOrderEnum;
+import cn.rankin.common.utils.enums.BaseStatusEnum;
+import cn.rankin.common.utils.util.JpaSortUtil;
+import cn.rankin.data.api.product.entity.Tag;
+import cn.rankin.data.api.user.dto.UserTagDTO;
+import cn.rankin.data.api.user.entity.UserTag;
+import cn.rankin.userservice.repository.UserTagRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import static cn.rankin.userservice.utils.DTOConverter.convert;
+
+@Slf4j
+@Service
+public class UserTagService {
+
+    @Autowired
+    private UserTagRepository userTagRepository;
+
+/*    @Autowired
+    private TagGroupRepository tagGroupRepository;
+
+    @Autowired
+    private MerchantProductRepository merchantProductRepository;
+
+    @Autowired
+    private MerchantProductTagRelationService merchantProductTagRelationService;
+
+    @Autowired
+    private GoodsService goodsService;*/
+
+    public List<UserTag> findByTypeCode(String typeCode,String uid) {
+        List<UserTag> userTagList = userTagRepository.findByTypeCodeUid(typeCode,uid, BaseStatusEnum.NORMAL);
+        return userTagList;
+    }
+
+    public List<UserTag> findByTypeCode(String typeCode) {
+        List<UserTag> userTagList = userTagRepository.findByTypeCode(typeCode);
+        return userTagList;
+    }
+
+/*    public List<MerchantProduct> getMerchantProductList(String tagId, String merchantId) {
+        List<MerchantProductTagRelation> relationList = merchantProductTagRelationService.findByTagId(tagId, BaseStatusEnum.NORMAL);
+        if (CollectionUtils.isEmpty(relationList)) {
+            return new ArrayList<>();
+        }
+
+        List<String> productIdList = new ArrayList<>();
+        relationList.forEach(relation -> productIdList.add(relation.getPid()));
+        List<MerchantProduct> merchantProductList = merchantProductRepository.findByPidsAndMerchantId(productIdList, merchantId);
+        Map<String, MerchantProduct> merchantProductMap = ListUtil.convert(merchantProductList, "pid", MerchantProduct.class);
+
+        List<MerchantProduct> sortMerchantProductList = new ArrayList<>();
+        for (String productId : productIdList) {
+            MerchantProduct merchantProduct = merchantProductMap.get(productId);
+            if (merchantProduct != null) {
+                sortMerchantProductList.add(merchantProduct);
+            }
+        }
+        return sortMerchantProductList;
+    }*/
+
+    // 搜索用户标签
+    public Page<UserTag> search(UserTag userTag, Integer pageNo, Integer pageSize, LinkedHashMap<String, BaseOrderEnum> sort) {
+        Long count = userTagRepository.count(userTag);
+        Page<UserTag> page = new Page(count, pageNo, pageSize);
+        if (count == 0) {
+            return page;
+        }
+
+        List<UserTag> userTagList = userTagRepository.find(userTag, page.getStart(), page.getPageSize(), JpaSortUtil.sort(sort));
+        page.setList(userTagList);
+
+        return page;
+    }
+
+    // 标签详情
+    public UserTag getUserTag(String id) {
+        UserTag userTag = userTagRepository.find(id);
+        String uid = userTag.getUid();
+
+        /*List<MerchantProduct> merchantProductList = getUserProductList(tagId, uid);
+        userTag.setProductList(merchantProductList);*/
+        return userTag;
+    }
+
+    // 标签详情
+    public List<UserTag> findUserTagByCodeUid(String code,String uid) {
+        List<UserTag> userTagLIst = userTagRepository.findByTypeCodeUid(code,uid, BaseStatusEnum.NORMAL);
+//        String uid = userTag.getUid();
+
+        /*List<MerchantProduct> merchantProductList = getUserProductList(tagId, uid);
+        userTag.setProductList(merchantProductList);*/
+        return userTagLIst;
+    }
+
+    @Transactional
+    public UserTag create(UserTagDTO userTagDTO) {
+        UserTag userTag = convert(userTagDTO);
+
+/*        String merchantId = null;
+
+        String groupId = tagDTO.getGroupId();
+        if(StringUtils.isNotBlank(groupId)){
+            //兼容旧版本   tagGroup
+            TagGroup tagGroup = tagGroupRepository.find(groupId);
+            if (tagGroup == null) {
+                return APIResult.error(ProductServiceAPICode.NOT_EXISTS);
+            }
+
+            merchantId = tagGroup.getMerchantId();
+
+        }else{
+            //新版本
+            merchantId = tagDTO.getMerchantId();
+        }
+
+        tag.setMerchantId(merchantId);*/
+        UserTag result = userTagRepository.save(userTag);
+
+        return result;
+    }
+
+    @Transactional
+    public UserTag update(UserTagDTO userTagDTO) {
+        UserTag userTag = convert(userTagDTO);
+        UserTag result = userTagRepository.update(userTag);
+
+     /*   String tagId = result.getId();
+        String uid = result.getUid();
+        List<String> productIdList = tagDTO.getProductList();
+        merchantProductTagRelationService.updateByTagId(tagId, merchantId, productIdList);
+
+        List<MerchantProduct> merchantProductList = getMerchantProductList(tagId, merchantId);
+        tag.setProductList(merchantProductList);*/
+
+        return result;
+    }
+
+    @Transactional
+    public Boolean delete(String tagId) {
+        Integer count = userTagRepository.deleteById(tagId);
+        if (count > 0) {
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    public List<UserTag> findUserTagByUid(String uid) {
+        return userTagRepository.findUserTagByUid(uid);
+    }
+
+/*    @Transactional
+    public void sortTag(String groupId, List<String> tagIdList) {
+        List<Tag> tagList = tagRepository.findByGroupId(groupId, BaseStatusEnum.NORMAL);
+        sortTag(tagIdList, tagList);
+        tagRepository.update(tagList);
+    }
+
+
+
+    @Transactional
+    public void sortTagByTypeCode(String typeCode, List<String> tagIdList) {
+        List<Tag> tagList = tagRepository.findByTypeCode(typeCode);
+        sortTag(tagIdList, tagList);
+        tagRepository.update(tagList);
+    }*/
+
+/*    private void sortTag(List<String> tagIdList, List<Tag> tagList) {
+        for (Tag tag : tagList) {
+            String tagId = tag.getId();
+            if (!tagIdList.contains(tagId)) {
+                tag.setStatus(BaseStatusEnum.DEL);
+                continue;
+            }
+            Integer index = tagIdList.indexOf(tagId);
+            tag.setSort(index);
+        }
+    }*/
+}

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

@@ -64,4 +64,10 @@ public class DTOConverter {
         BeanUtils.copyProperties(whiteUserDTO, whiteUser);
         return whiteUser;
     }
+
+    public static UserTag convert(UserTagDTO userTagDTO) {
+        UserTag userTag = new UserTag();
+        BeanUtils.copyProperties(userTagDTO, userTag);
+        return userTag;
+    }
 }