개발일지-41 [✅구독 도메인: 구독 조회, 구독(+취소)]

김성인·2023년 9월 26일
0

구독 도메인 포스팅



1. [POST] /jat/app/subscription

가게 구독/ 구독 취소하기

  • 앱 내에서 존재하는 모든 하트 모양을 누를 시 구독, 구독 취소하기
  • 요청 바디
    • 구독할 가게 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);
        }
    }
  1. 가게를 구독하기 전, 올바른 가게 Idx를 가진 요청인지 확인
  2. 해당 구매자가 이전에 가게를 구독했다 취소한 기록이 있는지 확인
    -> 이미 취소했던 기록이 있으면 해당 행의 상태값만 변경, 새로운 Id를 생성시킬 필요 X
  3. 구독 여부를 확인하고 재구독 or 신규 구독으로 테이블 값 수정
  4. 또는 구독 취소
  • 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);
    }

테스트

1. 가게 검색 (CU편의점 울산 과학대 후문점 ID:20)

2. 가게 구독 요청


2. [GET] /jat/app/subscribe

구독한 가게 목록 조회

  • 구독한 가게 목록을 조회한다.
  • 응답 바디
    • 가게 이름, 가게 사진, 좌표, 거리, 시간, 평점, 구독여부
  • 컨트롤러
  • 서비스
    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;
    }
  1. 사용자의 ID를 통해 구독한 가게 정보 리스트를 조회
  2. 해당 가게들의 사진 URL 생성
  3. 현재 위치로부터 가게까지의 거리 및 시간 구하기
  • 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);
    }

테스트


후기

가게의 구독 정보를 어떻게 유지할지 고민하다가 테이블을 아싸라 하나 더 추가해서 데이터를 유지하였다.
재 구독 같은 경우는 새로운 데이터를 넣지않고 기존에 들어있던 기록을 수정하여 사용하는 방식을 적용

profile
개발자가 꿈인 25살 대학생입니다.

0개의 댓글