스프링부트+jsp로 배달사이트 만들기-15 리뷰작성

2021. 12. 8. 19:26스프링부트

리뷰 작성을 위해 StoreController에 추가합니다

// 리뷰 작성
@PostMapping("/store/review")
public String review(Review review, MultipartFile file, @AuthenticationPrincipal LoginService user) throws IOException {

    if (file.isEmpty()) {
        String img = "/img/none.gif";
        review.setReviewImg(img);
    } else {
        
    }
    long userId = user.getUser().getId();
    review.setUserId(userId);

    storeService.reviewWrite(review);

    return "redirect:/orderList";
}

리뷰 작성 시에 이미지를 첨부 할 수 있기 때문에 MultipartFile을 사용합니다

 

리뷰 정보를 담을 Review클래스와 service, dao에 reviewWrite를 추가합니다

@Getter
@Setter
@ToString
public class Review {
	private String orderNum; 
	private long storeId;
	private String storeName;
	private String reviewContent;
	private String bossComment;
	private Date regiDate;
	private float score;
	private String reviewImg;
	
	private long userId;
	private String username;
	private String nickname;
}

 

StoreService

void reviewWrite(Review review);

 

StoreServiceImp

@Override
public void reviewWrite(Review review) {
	storeDAO.reviewWrite(review);
}

 

StoreDAO

void reviewWrite(Review review);

 

StoreDAOImp

@Override
public void reviewWrite(Review review) {
	sql.insert("store.reviewWrite", review);
}

 

storeMapper

<insert id="reviewWrite">
		INSERT INTO BM_REVIEW (
		    ORDER_NUM
		    ,STORE_ID
		    ,REVIEW_CONTENT
		    ,USER_ID
		    ,SCORE
		    ,REVIEW_IMG 
		) VALUES (
			${orderNum }
			,#{storeId }
			,#{reviewContent }
			,#{userId}
			,#{score}
			,#{reviewImg }
		)		
	</insert>

 

 

 

리뷰작성 버튼을 누르면 db에 값이 입력되고 리뷰 수정하기 버튼으로 변경됩니다

 

 

매장에서 댓글을 확인 할 수 있도록 다음 코드들을 수정합니다

StoreDetail클래스의 reviewList 주석을 해제합니다

@NoArgsConstructor
@AllArgsConstructor
@ToString
@Getter
@Setter
public class StoreDetail {
	private Store storeInfo;
	private List<Food> foodList;
	private List<Review> reviewList;
}

 

StoreServiceImp 주석처리되어 있던 reviewList를 주석 해제 하고 생성자에 댓글목록도 추가합니다

	@Override
	public StoreDetail storeDetail(long storeId) {
		Store storeInfo = storeDAO.storeDetail(storeId); 
		List<Food> foodList = storeDAO.foodList(storeId);
		List<Review> reviewList = storeDAO.reviewList(storeId);
		
		System.out.println("가게 정보 = " + storeInfo);
		System.out.println("메뉴목록 = " + foodList);
		System.out.println("댓글목록 = " + reviewList);
		 
		return new StoreDetail(storeInfo, foodList, reviewList);
	}

 

dao에 reviewList를 추가합니다

StoreDAO

List<Review> reviewList(long id);

 

StoreDAOImp

@Override
public List<Review> reviewList(long id) {
	return sql.selectList("store.reviewList", id);
}

 

Storemapper

<select id="reviewList" resultType="Review">
		SELECT
		    r.order_num,
		    r.store_id,
		    r.review_content,
		    r.boss_comment,
		    r.regi_date,
		    r.score,
		    r.review_img,
		    r.user_id,
		    u.nickname
		FROM
		    bm_review r
		LEFT JOIN
		    bm_user u
		ON
		    r.user_id = u.id
		WHERE
		    r.store_id = #{id}
		ORDER BY    
			regi_date DESC
	</select>

 

매장상세페이지로 가면 콘솔에 목록들을 확인할 수 있습니다

 

이제 매장상세 페이지에서 주문횟수, 리뷰 수, 별점들을 보여줄 수 있게 쿼리를 쿼리를 수정합니다

<select id="storeDetail" resultType="Store">
SELECT	RESULT.*
        ,CASE WHEN TO_CHAR(SYSDATE,'HH24') BETWEEN OPENING_TIME AND OPENING_TIME + BS_TIME THEN 'true' ELSE 'false' END IS_OPEN
FROM	(SELECT S.*,
                C.*,
                CASE WHEN MOD(24 - S.OPENING_TIME + S.CLOSING_TIME, 24) != 0 THEN MOD(24 - S.OPENING_TIME + S.CLOSING_TIME, 24) ELSE 24 END BS_TIME
        FROM 	BM_STORE S
                ,(SELECT * FROM  
                        (SELECT	ROUND(AVG(SCORE),1) SCORE
                        ,COUNT(REVIEW_CONTENT) REVIEW_COUNT
                        ,COUNT(BOSS_COMMENT) BOSS_COMMENT_COUNT
                        ,COUNT(CASE WHEN SCORE=1 THEN 1 END) SCORE1
                        ,COUNT(CASE WHEN SCORE=2 THEN 1 END) SCORE2
                        ,COUNT(CASE WHEN SCORE=3 THEN 1 END) SCORE3
                        ,COUNT(CASE WHEN SCORE=4 THEN 1 END) SCORE4
                        ,COUNT(CASE WHEN SCORE=5 THEN 1 END) SCORE5
                FROM 	BM_REVIEW WHERE STORE_ID = #{id } ) 
                ,(SELECT SUM(ORDER_COUNT) ORDER_COUNT FROM (
                    SELECT COUNT(*) ORDER_COUNT FROM BM_ORDER_USER WHERE STORE_ID = #{id }
                        UNION ALL
                    SELECT COUNT(*) ORDER_COUNT FROM BM_ORDER_NON_USER WHERE STORE_ID = #{id } ))
                ) C
        WHERE 	ID = #{id }
        ) RESULT
</select>

가게, 리뷰, 주문 테이블을 조인 후 리뷰의 각 별점 수, 총점의 평균, 주문횟수를 출력합니다

CASE WHEN MOD(24 - S.OPENING_TIME + S.CLOSING_TIME, 24) != 0 THEN MOD(24 - S.OPENING_TIME + S.CLOSING_TIME, 24) ELSE 24 END BS_TIME부분은 현재시간이 영업시작 시간과 영업종료 시간 사이에 있을 경우 'true'를 반환하고 아닐경우 'false'를 반환하게 했습니다

이 데이터를 받을 수 있게 Store클래스 아래에 추가합니다

	private float score;
	private int orderCount;
	private int reviewCount;
	private int bossCommentCount;
	private int likesCount;
	
	private int score1; // 리뷰 1점
	private int score2; // 리뷰 2점
	private int score3; // 리뷰 3점
	private int score4; // 리뷰 4점
	private int score5; // 리뷰 5점	
	
	//오픈중?
	private String isOpen;

 

 

매장 상세페이지로 가서 주석처리 되어있던 부분을 해제하고 구현하지 않았던 댓글탭을 추가합니다

 

 

<li>
    <div class="score_info">
        <div>
            <div class="score">${info.score }</div>
                   
            <div>
                <c:forEach begin="0" end="4" var="i">
                     <c:choose>
                           <c:when test="${Math.round(info.score) > i }">
                               <i class="far fas fa-star"></i>
                           </c:when>
                           <c:otherwise>
                               <i class="far fa-star"></i>
                           </c:otherwise>
                     </c:choose>
                </c:forEach>
            </div>
        </div>
            
        <div class="score_count">
            <div> 
                <div>5점</div>
                
                <div class="graph_box">
                    <div class="graph_background"></div>
                    <div class="graph score5" data-score5="${info.score5 }"></div>
                </div>
                
                <div class="review_count">${info.score5 }</div>
            </div>
            
            <div> 
                <div>4점</div>
                <div class="graph_box">
                    <div class="graph_background"></div>
                    <div class="graph score4" data-score4="${info.score4 }"></div>
                </div>
                <div class="review_count">${info.score4 }</div>
            </div>
                
            <div> 
                <div>3점</div>
                <div class="graph_box">
                    <div class="graph_background"></div>
                    <div class="graph score3" data-score3="${info.score3 }"></div>
                </div>
                <div class="review_count">${info.score3 }</div>
            </div>
            
            <div> 
                <div>2점</div>
                <div class="graph_box">
                    <div class="graph_background"></div>
                    <div class="graph score2" data-score2="${info.score2 }"></div>
                </div>
                <div class="review_count">${info.score2 }</div>
            </div>
            
            <div> 
                <div>1점</div>
                <div class="graph_box">
                    <div class="graph_background"></div>
                    <div class="graph score1" data-score1="${info.score1 }"></div>
                </div>
                <div class="review_count">${info.score1 }</div>
            </div>
        </div>
    
    </div>
</li>



<c:forEach items="${store.reviewList }" var="reviewList">
<li>
    <div class="client">
        
        <div class="review_header">
            <div>
                <div class="nickname">${reviewList.nickname }</div>
                <div>
                    
                    <c:forEach begin="0" end="4" var="i">
                        <c:choose>
                               <c:when test="${Math.round(reviewList.score) > i }">
                                   <i class="far fas fa-star"></i>
                               </c:when>
                               <c:otherwise>
                                   <i class="far fa-star"></i>
                               </c:otherwise>
                         </c:choose>
                    </c:forEach>
                    
                    <span><fm:formatDate value="${reviewList.regiDate }" pattern="yyyy-MM-dd" /> </span>
                </div>
            </div>
        </div> 
            
        <div>
            <c:if test="${!empty reviewList.reviewImg }">
                <div><img src="${reviewList.reviewImg }" alt="이미지" class="review_img"></div>
            </c:if>
            <div>${reviewList.reviewContent } </div>
        </div>
    </div>
    
    
    <div class="boss">
        <c:if test="${!empty reviewList.bossComment }">	
            <div class="boss_comment_box">
                <div class="nickname">사장님</div>
                <div class="boss_comment">${reviewList.bossComment }</div>
            </div>
        </c:if>
    </div>
    
    
     <div class="boss input">
            <div class="boss_comment_box">
             <div class="nickname">사장님</div>
            <div class="boss_comment">
                <textarea class="comment_area" spellcheck="false"></textarea>
            </div>
            
            <div>
                <button class="boss_comment_btn reply" >댓글 달기</button>
                <input type="hidden" value="${reviewList.orderNum }" class="order_num">
            </div>
        </div>
       </div>
</li>
</c:forEach>

 

 

 

이제 내가 쓴 리뷰를 수정 할 수 있게 StroeController에 추가합니다

// 리뷰 수정
@PostMapping("/store/reviewModify")
public String reviewModify(Review review, MultipartFile file, @AuthenticationPrincipal LoginService user) throws IOException {

    if(!file.isEmpty()){
//			String img = uploadFile.fildUpload(file);
//			review.setReviewImg(img);
    }
    long userId = user.getUser().getId();
    review.setUserId(userId);

    System.out.println(review);
    storeService.reviewModify(review);

    return "redirect:/orderList";
}

 

StoreService

void reviewModify(Review review);

 

StoreServiceImp

@Override
public void reviewModify(Review review) {
    storeDAO.reviewModify(review);
}

 

StoreDAO

void reviewModify(Review review);

 

StoreDAOImp

@Override
public void reviewModify(Review review) {
	sql.update("store.reviewModify", review);
}

StoreMapper

<update id="reviewModify">
    UPDATE BM_REVIEW SET
        REVIEW_CONTENT = #{reviewContent }
        ,SCORE = #{score}
        
        <if test="reviewImg != null">
        ,REVIEW_IMG = #{reviewImg }
        </if>
        
    WHERE
        ORDER_NUM = ${orderNum }    
</update>

 

 

 

사진 첨부가 되지 않았을땐 이미지 박스를 보이지 않게 수정합니다