- 앱 내에서 존재하는 모든 하트 모양을 누를 시 구독, 구독 취소하기
- 요청 바디
- 구독할 가게 Idx, 구독/취소 여부
- 컨트롤러
- 서비스
@Transactional(rollbackFor = BaseException.class) public AppSubscriptionRes subscription(int customerIdx, AppSubscriptionReq appSubscriptionReq) throws BaseException { // 1. 가게존재 여부확인 int existStoreCheck; try { existStoreCheck = appSubscribeDao.existStore(appSubscriptionReq.getStoreIdx()); }catch (Exception e) { throw new BaseException(DATABASE_ERROR); } if (existStoreCheck ==0){ throw new BaseException(POST_STORES_NOT_REGISTERD); //없는가게입니다 } // 2. 구독 기록 확인 int subIdx; try { subIdx = appSubscribeDao.sudIdxByCustomerIdxStoreIdx(customerIdx, appSubscriptionReq.getStoreIdx()); } catch (IncorrectResultSizeDataAccessException error) { subIdx = 0; } catch (Exception e) { throw new BaseException(DATABASE_ERROR); } // 3. 구독 상태 처리 try{ if(appSubscriptionReq.getYn() == 1){ // 구독 if (subIdx != 0) {// 재 구독 appSubscribeDao.reSubscribe(customerIdx, appSubscriptionReq.getStoreIdx()); }else{ // 신규 구독 subIdx = appSubscribeDao.firstSubscribe(customerIdx, appSubscriptionReq.getStoreIdx()); } }else{ // 구독 취소 if (subIdx != 0) { appSubscribeDao.cancelSubscription(customerIdx, appSubscriptionReq.getStoreIdx()); }else{ throw new BaseException(DATABASE_ERROR); } } }catch (Exception e) { throw new BaseException(DATABASE_ERROR); } // 4. 구독 상태값 확인 후 결과 응답 try{ String status = appSubscribeDao.checkSubscribeStatus(customerIdx, appSubscriptionReq.getStoreIdx()); return new AppSubscriptionRes(subIdx, status); }catch (Exception e) { throw new BaseException(DATABASE_ERROR); } }
- 가게를 구독하기 전, 올바른 가게 Idx를 가진 요청인지 확인
- 해당 구매자가 이전에 가게를 구독했다 취소한 기록이 있는지 확인
-> 이미 취소했던 기록이 있으면 해당 행의 상태값만 변경, 새로운 Id를 생성시킬 필요 X- 구독 여부를 확인하고 재구독 or 신규 구독으로 테이블 값 수정
- 또는 구독 취소
- Dao
// 가게 존재 여부 확인 public int existStore(int storeIdx){ String query ="SELECT EXISTS(SELECT storeIdx FROM Stores WHERE storeIdx =?);"; return jdbcTemplate.queryForObject(query, Integer.class,storeIdx); }
// 가게 구독 기록 확인 public int sudIdxByCustomerIdxStoreIdx(int customerIdx, int storeIdx) { String query = "SELECT subIdx FROM Subscribe WHERE customerIdx = ? AND storeIdx=?;"; return this.jdbcTemplate.queryForObject(query, (rs, rowNum) -> rs.getInt("subIdx"), customerIdx, storeIdx); }
//첫구독 public int firstSubscribe(int customerIdx, int storeIdx) { String query = "INSERT INTO Subscribe(customerIdx,storeIdx,status) VALUE (?,?,'A');"; Object[] params = new Object[]{customerIdx, storeIdx}; this.jdbcTemplate.update(query, params); String lastInsertIdQuery = "select last_insert_id()"; return this.jdbcTemplate.queryForObject(lastInsertIdQuery,int.class); }
//다시 구독 public int reSubscribe(int customerIdx, int storeIdx) { String query = "UPDATE Subscribe SET status = 'A' WHERE customerIdx =? AND storeIdx =?;"; return jdbcTemplate.update(query, customerIdx, storeIdx); }
//구독취소 public int cancelSubscription(int customerIdx, int storeIdx) { String query = "UPDATE Subscribe SET status = 'D' WHERE customerIdx =? AND storeIdx =?;"; return jdbcTemplate.update(query, customerIdx, storeIdx); }
- 구독한 가게 목록을 조회한다.
- 응답 바디
- 가게 이름, 가게 사진, 좌표, 거리, 시간, 평점, 구독여부
- 컨트롤러
- 서비스
public List<GetAppSubscriptionRes> getSubscriptionList(int customerIdx, Double longitude, Double latitude) throws BaseException { List<GetAppSubscriptionRes> getAppSubscriptionRes; try { getAppSubscriptionRes = appSubscribeDao.getSubscriptionList(customerIdx); } catch (Exception e) { throw new BaseException(DATABASE_ERROR); } for (GetAppSubscriptionRes subscription : getAppSubscriptionRes) { if (subscription.getStoreLogoUrl() != null && subscription.getStoreLogoUrl().length() != 0) { subscription.setStoreLogoUrl("" + s3Client.getUrl(bucketName, subscription.getStoreLogoUrl())); } if (subscription.getStoreSignUrl() != null && subscription.getStoreSignUrl().length() != 0) { subscription.setStoreSignUrl("" + s3Client.getUrl(bucketName, subscription.getStoreSignUrl())); } int distance = (int) locationValue.getDistance(latitude, longitude, subscription.getY(), subscription.getX()); int duration = locationValue.getDuration(distance); subscription.setDistance(distance); subscription.setDuration(duration); } return getAppSubscriptionRes; }
- 사용자의 ID를 통해 구독한 가게 정보 리스트를 조회
- 해당 가게들의 사진 URL 생성
- 현재 위치로부터 가게까지의 거리 및 시간 구하기
- Dao
// 가게 정보 조회 public List<GetAppSubscriptionRes> getSubscriptionList(int customerIdx) { String query = "SELECT\n" + " S.storeIdx,\n" + " S.store_name,\n" + " S.store_logo_url,\n" + " S.sign_url,\n" + " S.x, S.y,\n" + " ROUND(AVG(R.star), 1) AS star_average\n" + "FROM Subscribe SUB\n" + "LEFT JOIN Stores S on SUB.storeIdx = S.storeIdx\n" + "LEFT JOIN Review R on S.storeIdx = R.storeIdx AND R.status != 'D'\n" + "WHERE SUB.customerIdx = ?\n" + "AND SUB.status = 'A'\n" + "GROUP BY SUB.storeIdx"; return this.jdbcTemplate.query(query, (rs, rowNum) -> new GetAppSubscriptionRes( rs.getInt("storeIdx"), rs.getString("store_name"), rs.getString("store_logo_url"), rs.getString("sign_url"), rs.getDouble("x"), rs.getDouble("y"), 0, 0, rs.getDouble("star_average"), 1 ), customerIdx); }
가게의 구독 정보를 어떻게 유지할지 고민하다가 테이블을 아싸라 하나 더 추가해서 데이터를 유지하였다.
재 구독 같은 경우는 새로운 데이터를 넣지않고 기존에 들어있던 기록을 수정하여 사용하는 방식을 적용