EigeneaiApi.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. package com.style24.front.biz.thirdparty;
  2. import java.io.UnsupportedEncodingException;
  3. import java.net.URI;
  4. import java.net.URLEncoder;
  5. import java.util.ArrayList;
  6. import java.util.Collection;
  7. import javax.annotation.PostConstruct;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.http.HttpStatus;
  10. import org.springframework.http.ResponseEntity;
  11. import org.springframework.stereotype.Component;
  12. import org.springframework.web.client.RestTemplate;
  13. import com.google.gson.Gson;
  14. import com.style24.front.biz.dao.TsfGoodsDao;
  15. import com.style24.front.support.security.session.TsfSession;
  16. import com.style24.persistence.domain.Cart;
  17. import com.style24.persistence.domain.Goods;
  18. import com.style24.persistence.domain.eigene.Eigeneai;
  19. import com.style24.persistence.domain.eigene.Eigeneai.Result;
  20. import com.style24.persistence.domain.eigene.Item;
  21. import lombok.extern.slf4j.Slf4j;
  22. /**
  23. * 추천솔루션 - Eigene.ai
  24. *
  25. * @author gagamel
  26. * @since 2021. 5. 14
  27. */
  28. @Component
  29. @Slf4j
  30. public class EigeneaiApi {
  31. private String apiUrl = "https://api.eigene.io/rec";
  32. private String rtsApiUrl = "https://rts-api.eigene.io/api";
  33. private String cuid = "1252aed4-78dc-46e8-b784-94ac42e86dd4";
  34. @Autowired
  35. private RestTemplate restTemplate;
  36. @Autowired
  37. private TsfGoodsDao goodsDao;
  38. @PostConstruct
  39. public void init() {
  40. log.debug("\n\n---- Eigene.ai initialization started ----");
  41. log.debug("apiUrl: [{}]", apiUrl);
  42. log.debug("cuid: [{}]", cuid);
  43. log.debug("\n--- Eigene.ai initialization completed ----\n");
  44. }
  45. /**
  46. * 카테고리별 주간판매베스트추천상품 목록
  47. * 사용되는 화면 영역)
  48. * 메인 > 베스트 영역
  49. * 카테고리메인 > 베스트 상품
  50. * 베스트 > 카테고리별 베스트
  51. * @param size - 결과에 포함할 상품수
  52. * @param cate1No - 카테고리번호1
  53. * @return
  54. * @author gagamel
  55. * @since 2021. 5. 14
  56. */
  57. public Collection<Result> getCategoryWeeklySellBestGoodsList(int size, Integer cate1No) {
  58. String requestUrl = apiUrl + "/m060?cuid=" + cuid + "&size=" + size + "&incids=" + cate1No;
  59. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  60. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  61. return eigeneai.getResults();
  62. }
  63. return new ArrayList<Result>();
  64. }
  65. // /**
  66. // * 매출급상승 카테고리 목록
  67. // * 사용되는 화면 영역)
  68. // * 메인 > MD추천상품
  69. // * @return
  70. // * @author gagamel
  71. // * @since 2021. 6. 30
  72. // */
  73. // public Collection<Result> getSoaringSalesCategoryList() {
  74. // String requestUrl = apiUrl + "/m063?cuid=" + cuid;
  75. //
  76. // Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  77. // if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  78. // return eigeneai.getResults();
  79. // }
  80. //
  81. // return new ArrayList<Result>();
  82. // }
  83. //
  84. // /**
  85. // * MD추천상품 목록. 매출급상승 카테고리별 상품 목록
  86. // * 사용되는 화면 영역)
  87. // * 메인 > MD추천상품
  88. // * @param size - 결과에 포함할 상품수
  89. // * @param cateId - 카테고리ID
  90. // * @return
  91. // * @author gagamel
  92. // * @since 2021. 6. 30
  93. // */
  94. // public Collection<GagaMap> getMdRecommendGoodsList(int size, String cateId) {
  95. // // 1.매출급상승 카테고리 목록
  96. // String requestUrl = apiUrl + "/m063?cuid=" + cuid;
  97. // Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  98. // if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  99. // Collection<Result> cateList = eigeneai.getResults();
  100. //
  101. // if (cateList != null && !cateList.isEmpty()) {
  102. // for (Result cateInfo : cateList) {
  103. // if (StringUtils.isNotBlank(cateInfo.getCategoryId())) {
  104. // GagaMap dataMap = new GagaMap();
  105. // dataMap.setString("styleNm", cateInfo.getCategoryId());
  106. //
  107. // // 2.카테고리별 상품 목록
  108. // requestUrl = apiUrl + "/c001?cuid=" + cuid + "&size=" + size + "&cids=" + cateInfo.getCategoryId();
  109. // eigeneai = this.getEigeneaiInfo(requestUrl);
  110. // if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  111. // dataMap.set("", eigeneai.getResults());
  112. // }
  113. // }
  114. // }
  115. // }
  116. // }
  117. //
  118. // return new ArrayList<GagaMap>();
  119. // }
  120. /**
  121. * 주간판매베스트추천상품 목록
  122. * 사용되는 화면 영역)
  123. * 베스트 > 전체 베스트
  124. * @param size - 결과에 포함할 상품수
  125. * @return
  126. * @author gagamel
  127. * @since 2021. 5. 14
  128. */
  129. public Collection<Result> getWeeklySellBestGoodsList(int size) {
  130. String requestUrl = apiUrl + "/m061?cuid=" + cuid + "&size=" + size;
  131. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  132. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  133. return eigeneai.getResults();
  134. }
  135. return new ArrayList<Result>();
  136. }
  137. /**
  138. * 브랜드 주간판매베스트추천상품 목록
  139. * 사용되는 화면 영역)
  140. * 브랜드메인 > 베스트 상품
  141. * @param size - 결과에 포함할 상품수
  142. * @param brandGroupNo - 브랜드그룹번호
  143. * @return
  144. * @author gagamel
  145. * @since 2021. 6. 30
  146. */
  147. public Collection<Result> getBrandWeeklySellBestGoodsList(int size, Integer brandGroupNo) {
  148. String requestUrl = apiUrl + "/m061?cuid=" + cuid + "&size=" + size + "&inbids=" + brandGroupNo;
  149. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  150. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  151. return eigeneai.getResults();
  152. }
  153. return new ArrayList<Result>();
  154. }
  155. /**
  156. * 아울렛 주간판매베스트추천상품 목록
  157. * 사용되는 화면 영역)
  158. * 아울렛메인 > 베스트
  159. * @param size - 결과에 포함할 상품수
  160. * @return
  161. * @author gagamel
  162. * @since 2021. 6. 30
  163. */
  164. public Collection<Result> getOutletWeeklySellBestGoodsList(int size) {
  165. String requestUrl = apiUrl + "/m064?cuid=" + cuid + "&size=" + size;
  166. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  167. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  168. return eigeneai.getResults();
  169. }
  170. return new ArrayList<Result>();
  171. }
  172. /**
  173. * 브랜드 월간클릭베스트추천상품 목록
  174. * 사용되는 화면 영역)
  175. * 브랜드메인 > MD Pick
  176. * @param size - 결과에 포함할 상품수
  177. * @param brandGroupNo - 브랜드그룹번호
  178. * @return
  179. * @author gagamel
  180. * @since 2021. 6. 30
  181. */
  182. public Collection<Result> getBrandMonthlyClickBestGoodsList(int size, Integer brandGroupNo) {
  183. String requestUrl = apiUrl + "/m062?cuid=" + cuid + "&size=" + size + "&inbids=" + brandGroupNo;
  184. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  185. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  186. return eigeneai.getResults();
  187. }
  188. return new ArrayList<Result>();
  189. }
  190. /**
  191. * 아울렛 월간클릭베스트추천상품 목록
  192. * 사용되는 화면 영역)
  193. * 아울렛메인 > MD Pick
  194. * @param size - 결과에 포함할 상품수
  195. * @return
  196. * @author gagamel
  197. * @since 2021. 6. 30
  198. */
  199. public Collection<Result> getOutletMonthlyClickBestGoodsList(int size) {
  200. String requestUrl = apiUrl + "/m065?cuid=" + cuid + "&cids=" + "" + "&size=" + size;
  201. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  202. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  203. return eigeneai.getResults();
  204. }
  205. return new ArrayList<Result>();
  206. }
  207. /**
  208. * 실시간 많이 조회되고 있는 상품 목록
  209. * 사용되는 화면 영역)
  210. * 퀵메뉴 > 쇼핑백 (담은 상품 없는 경우)
  211. * 쇼핑백 > 추천상품 (담은 상품 없는 경우)
  212. * 검색 > 검색 시작화면
  213. * @param size - 결과에 포함할 상품수
  214. * @return
  215. * @author gagamel
  216. * @since 2021. 6. 30
  217. */
  218. public Collection<Item> getRealtimeViewGoodsList(int size) {
  219. Collection<Item> dataList = new ArrayList<Item>();
  220. String requestUrl = rtsApiUrl + "/stream?cuid=" + cuid + "&size=" + size + "&type=view";
  221. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  222. if (eigeneai.getItems() != null && !eigeneai.getItems().isEmpty()) {
  223. Collection<Item> items = eigeneai.getItems();
  224. StringBuilder sql = new StringBuilder();
  225. int idx = 1;
  226. for (Item item : items) {
  227. if (idx++ > 1) {
  228. sql.append("UNION ALL");
  229. }
  230. sql.append(" SELECT ").append(item.getCount()).append(" AS COUNT");
  231. sql.append(" , '").append(item.getItemId()).append("' AS ITEM_ID");
  232. sql.append(" , '").append(item.getImageUrl()).append("' AS IMAGE_URL");
  233. sql.append(" , '").append(item.getItemName()).append("' AS ITEM_NAME");
  234. sql.append(" , '").append(item.getItemUrl()).append("' AS ITEM_URL");
  235. sql.append(" , '").append(item.getCategoryId()).append("' AS CATEGORY_ID");
  236. sql.append(" , '").append(item.getBrandId()).append("' AS BRAND_ID");
  237. sql.append(" , ").append(idx).append(" AS RK FROM DUAL\n");
  238. }
  239. Goods goods = new Goods();
  240. goods.setSql(sql.toString());
  241. if (TsfSession.isLogin()) {
  242. goods.setCustNo(TsfSession.getInfo().getCustNo());
  243. }
  244. goods.setFrontGb(TsfSession.getFrontGb());
  245. goods.setCustGb(TsfSession.getCustGb());
  246. dataList.addAll(goodsDao.getGoodsAddInfoList(goods));
  247. }
  248. return dataList;
  249. }
  250. /**
  251. * 실시간 많이 조회되고 있는 베스트 상품 목록
  252. * 사용되는 화면 영역)
  253. * 베스트 > 베스트상품_실시간 베스트
  254. * @param size - 결과에 포함할 상품수
  255. * @return
  256. * @author gagamel
  257. * @since 2021. 6. 30
  258. */
  259. public Collection<Item> getRealtimeViewBestGoodsList(int size , String cate1No) {
  260. String requestUrl = "";
  261. if(cate1No.equals(null) || "null".equals(cate1No) || "".equals(cate1No)){
  262. requestUrl = rtsApiUrl + "/stats-transition?cuid=" + cuid + "&size=" + size + "&type=view&interval=30&span=30&offset=0&categoryid1=";
  263. }else{
  264. requestUrl = rtsApiUrl + "/stats-transition?cuid=" + cuid + "&size=" + size + "&type=view&interval=30&span=30&offset=0&categoryid1="+cate1No;
  265. }
  266. //&type=view&interval=5&span=10
  267. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  268. if (eigeneai.getItems() != null && !eigeneai.getItems().isEmpty()) {
  269. return eigeneai.getItems();
  270. }
  271. return new ArrayList<Item>();
  272. }
  273. /**
  274. * 매출급상승 카테고리별 상품 목록
  275. * @param size - 결과에 포함할 상품수
  276. * @return
  277. * @author gagamel
  278. * @since 2021. 5. 14
  279. */
  280. public Eigeneai getSalesSoaringGoodsList() {
  281. // TODO: 매출급상승 카테고리 5개 조회 후 카테고리별 상품 7개 조회
  282. String requestUrl = apiUrl + "/m010?cuid=" + cuid + "&size=5";
  283. return this.getEigeneaiInfo(requestUrl);
  284. }
  285. /**
  286. * 고객의 최근검색어별 상품 목록
  287. * 사용되는 화면 영역)
  288. * 검색 > 검색결과 추천상품
  289. * 메인 > 당신을 위한 제안 > 검색어 연관상품 추천
  290. * @param size - 결과에 포함할 상품수
  291. * @return
  292. * @author gagamel
  293. * @since 2021. 5. 14
  294. */
  295. public Collection<Eigeneai> getCustomerKeywordGoodsList() {
  296. Collection<Eigeneai> dataList = new ArrayList<>();
  297. // 고객별 최근검색어 목록. TODO: 아이겐에서 미개발
  298. String requestUrl = apiUrl + "/m010?cuid=" + cuid + "&size=5";
  299. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  300. Collection<Eigeneai.Result> resultList = eigeneai.getResults();
  301. if (resultList == null || resultList.isEmpty()) {
  302. return dataList;
  303. }
  304. try {
  305. // 고객별 최근검색어 기준 검색어연관상품 목록 조회
  306. for (Eigeneai.Result result : resultList) {
  307. dataList.add(this.getKeywordGoodsList(10, result.getCategoryId()));
  308. }
  309. } catch (UnsupportedEncodingException e) {
  310. // Do nothing
  311. }
  312. return dataList;
  313. }
  314. /**
  315. * 검색어 연관상품 목록
  316. * 사용되는 화면 영역)
  317. * 검색 > 검색결과 추천상품
  318. * @param size - 결과에 포함할 상품수
  319. * @param keyword - 키워드
  320. * @exception UnsupportedEncodingException
  321. * @return
  322. * @author gagamel
  323. * @since 2021. 5. 14
  324. */
  325. private Eigeneai getKeywordGoodsList(int size, String keyword) throws UnsupportedEncodingException {
  326. String requestUrl = apiUrl + "/s003?cuid=" + cuid + "&size=" + size + "&st=" + URLEncoder.encode(keyword, "UTF-8") + "&cps=true&cpt=m004";
  327. return this.getEigeneaiInfo(requestUrl);
  328. }
  329. /**
  330. * 연관상품 목록
  331. * 사용되는 화면 영역)
  332. * 상품상세 > 함께 본 상품
  333. * @param goodsCd - 상품코드
  334. * @param size - 결과에 포함할 상품수
  335. * @return
  336. * @author gagamel
  337. * @since 2021. 5. 14
  338. */
  339. public Collection<Result> getRelatedGoodsList(String goodsCd, int size) {
  340. String requestUrl = apiUrl + "/a037?cuid=" + cuid + "&size=" + size + "&iids=" + goodsCd + "&cps=true&cpt=m001";
  341. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  342. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  343. return eigeneai.getResults();
  344. }
  345. return new ArrayList<Result>();
  346. }
  347. /**
  348. * 연관상품 목록
  349. * 사용되는 화면 영역)
  350. * 쇼핑백 > 추천상품 (담은 상품이 있는 경우)
  351. * @param cartList - 장바구니목록
  352. * @param size - 결과에 포함할 상품수
  353. * @return
  354. * @author gagamel
  355. * @since 2021. 5. 14
  356. */
  357. public Collection<Result> getRelatedGoodsList(Collection<Cart> cartList, int size) {
  358. if (cartList != null && !cartList.isEmpty()) {
  359. StringBuilder sb = new StringBuilder();
  360. int idx = 0;
  361. for (Cart cart : cartList) {
  362. if (idx++ > 0) {
  363. sb.append(",");
  364. }
  365. sb.append(cart.getGoodsCd());
  366. }
  367. String requestUrl = apiUrl + "/a037?cuid=" + cuid + "&size=" + size + "&iids=" + sb.toString() + "&cps=true&cpt=m001";
  368. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  369. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  370. return eigeneai.getResults();
  371. }
  372. }
  373. return new ArrayList<Result>();
  374. }
  375. /**
  376. * 브랜드 연관상품 목록
  377. * 사용되는 화면 영역)
  378. * 상품상세 > 브랜드연관상품
  379. * @param size - 결과에 포함할 상품수
  380. * @param goodsCd - 상품코드
  381. * @param brandGroupNo - 브랜드그룹번호
  382. * @return
  383. * @author gagamel
  384. * @since 2021. 5. 14
  385. */
  386. public Collection<Result> getBrandRelatedGoodsList(int size, String goodsCd, Integer brandGroupNo) {
  387. String requestUrl = apiUrl + "/a038?cuid=" + cuid + "&size=" + size + "&iids=" + goodsCd + "&cps=true&cpt=b004&bids=" + brandGroupNo;
  388. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  389. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  390. return eigeneai.getResults();
  391. }
  392. return new ArrayList<Result>();
  393. }
  394. /**
  395. * 동일 카테고리 연관상품 목록
  396. * 사용되는 화면 영역)
  397. * 상품상세 > 비슷한 상품
  398. * @param size - 결과에 포함할 상품수
  399. * @param goodsCd - 상품코드
  400. * @return
  401. * @author gagamel
  402. * @since 2021. 5. 14
  403. */
  404. public Collection<Result> getSameCategoryRelatedGoodsList(int size, String goodsCd) {
  405. String requestUrl = apiUrl + "/a039?cuid=" + cuid + "&size=" + size + "&iids=" + goodsCd + "&cps=true&cpt=m002";
  406. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  407. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  408. return eigeneai.getResults();
  409. }
  410. return new ArrayList<Result>();
  411. }
  412. /**
  413. * 상품의 실시간 조회수
  414. * 사용되는 화면 영역)
  415. * 상품상세 > 실시간 뷰
  416. * @param goodsCd - 상품코드
  417. * @return
  418. * @author gagamel
  419. * @since 2021. 5. 14
  420. */
  421. public int getRealtimeViewCount(String goodsCd) {
  422. String requestUrl = rtsApiUrl + "/stat?cuid=" + cuid + "&itemid=" + goodsCd + "&type=view";
  423. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  424. if (eigeneai.getItem() != null) {
  425. return eigeneai.getItem().getCount();
  426. }
  427. return 0;
  428. }
  429. /**
  430. * 아이겐 정보 조회
  431. * @param requestUrl - Reqeust URL
  432. * @return
  433. * @author gagamel
  434. * @since 2021. 5. 14
  435. */
  436. private Eigeneai getEigeneaiInfo(String requestUrl) {
  437. log.info("requestUrl: {}", requestUrl);
  438. URI url = URI.create(requestUrl);
  439. // GET방식으로 호출
  440. ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
  441. log.info("responseEntity.getStatusCode(): {} ", responseEntity.getStatusCode());
  442. String responseJson = responseEntity.getBody();
  443. log.info("responseEntity.getBody(): {}", responseJson);
  444. if (!responseEntity.getStatusCode().equals(HttpStatus.OK)) {
  445. return null;
  446. }
  447. Gson gson = new Gson();
  448. return gson.fromJson(responseJson, Eigeneai.class);
  449. }
  450. /**
  451. * 검색어 연관 상품 추천 목록
  452. * @return
  453. * @author bin2107
  454. * @since 2021. 7. 26
  455. */
  456. public Collection<Result> getRecommendItemList(int size, String keyword) {
  457. String requestUrl = "";
  458. // 2021.09.02 공백처리
  459. try {
  460. keyword = URLEncoder.encode(keyword, "UTF-8");
  461. requestUrl = apiUrl + "/s003?size="+size+"&cuid=" + cuid + "&st=" + keyword + "&cps=true&cpt=m004";
  462. } catch (UnsupportedEncodingException e) {
  463. // TODO Auto-generated catch block
  464. e.printStackTrace();
  465. }
  466. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  467. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  468. return eigeneai.getResults();
  469. }
  470. return new ArrayList<Result>();
  471. }
  472. /**
  473. * 당신을 위한 제안
  474. * 사용되는 화면 영역)
  475. * 메인 > 당신을 위한 제안
  476. * @param goodsCd - 상품코드
  477. * @param size - 결과에 포함할 상품수
  478. * @return
  479. * @author bin2107
  480. * @since 2021. 9. 23
  481. */
  482. public Collection<Result> getRecommendForYouList(String goodsCd, int size) {
  483. String requestUrl = apiUrl + "/a037?cuid=" + cuid + "&size=" + size + "&iids=" + goodsCd + "&cps=true&cpt=m001";
  484. Eigeneai eigeneai = this.getEigeneaiInfo(requestUrl);
  485. if (eigeneai.getResults() != null && !eigeneai.getResults().isEmpty()) {
  486. return eigeneai.getResults();
  487. }
  488. return new ArrayList<Result>();
  489. }
  490. }