[게시판 프로젝트] 게시글 상세보기

J_Eddy·2021년 12월 24일
0

📌 게시글 상세보기

🏁 Contetnts

게시글 작성 후 해당 게시글을 눌렀을 때 보이는 상세 화면이다. 처음 부딪힌 문제는 위지윅을 이용해서 해당 글을 DB에 저장할 때 아래와 같이 태그도 함께 저장이 된다.

이를 화면단에 보여줄 때 Dto를 넘겨 보여주는 방식으로 진행하였는데 HTML에서 아래와 같이 단순 text를 사용하면 해당 p태그도 화면에 같이 노출되게 된다.

 <div class="mx-10 mt-2" id="contentMain" th:text="${boardForm.content}"></div>

따라서 Thymeleaf의 utext문법을 사용해서 DB에 있는 글을 화면에 보여주도록 하였다.
utext 문법은 태그 escape 하지 않고 나타내는 것이다. 예를 들어 <p>태그를 &lt;p&gt; 로 표시하여 html에서 인식하게 하는 것이다.

 <div class="mx-10 mt-2" id="contentMain" th:utext="${boardForm.content}"></div>

🏁 이미지

위 DB 테이블을 보면 제일 아랫줄에 이미지 역시 <img>태그로 저장되어 있다. 이 역시 utext로 처리하면 되지만 만약 여러장의 사진이 첨부되어 있다면 정리가 되지않고 아래와 같이 주르륵(?) 나오게 된다.

이 부분이 일반 게시판에 비해 너무 지저분해 보여서 이미지 슬라이더를 이용하여 이미지를 정리했다.

이미지 슬라이더는 스크립트 형식으로 추가해서 사용하였다.

전체적인 사용로직은 DB에서 utext로 내용을 로드시키고 js를 이용해 img태그를 추출한다.
이후 해당 이미지 태그의 개수가 1개 이상이라면 이미지 슬라이더를 이용해 contentImg클래스에 담아넣는다.

/*이미지 태그 추출*/
$(function getImageByTagName(){
    const dbValue = document.getElementById('contentMain');
    const tag = dbValue.getElementsByTagName('img');
    const tagLength = tag.length;
    if(tag.length>=1){
        for(let i=0; i<tagLength; i++){
            $(".contentImg").append(tag[0]);
        }
    }else if(tag.length==0){
        $(".contentImg").append('<img src="/images/no_image.png">');
    }
});
/*이미지 슬라이더 화살표*/
$(function(){
    $('.contentImg').slick({
        prevArrow:'.arrow_prev',
        nextArrow:'.arrow_next'
    });
});

결과

🏁 거래장소

거래장소 버튼 클릭 시 DB에 저장되어있는 위도경도를 팝업으로 넘겨 카카오지도에 마커로 표시되도록 하였다.

/*거래장소 보기*/
$("#showLocation").on('click',function (){
    window.open("/board/map_content","map","width=910,height=485,left="+popX+",top=120");
});

추가적으로 해당 마커 클릭 시 url을 통해 카카오지도로 이동하여 큰지도로보기, 길찾기를 구현하였다.

/*인포윈도우에 있는 url*/
var openMapUrl = "https://map.kakao.com/link/map/거래 장소," + myLat + "," + myLng;
var openToMapUrl = "https://map.kakao.com/link/to/거래 장소," + myLat + "," + myLng;

var iwContent = '<div style="padding:5px;">거래 장소</br><a href="'+ openMapUrl +'" style="color:blue" target="_blank">큰지도보기</a><a href="'+ openToMapUrl +'" style="color:blue" target="_blank"> 길찾기</a></div>';

// 인포윈도우를 생성합니다
var infowindow = new kakao.maps.InfoWindow({
    content : iwContent
});

거래장소 클릭

큰지도보기 클릭

길찾기 클릭

🏁 판매완료 버튼

현재 세션에 저장되어있는 회원의 정보(로그인한 username)와 해당 게시물의 작성자가 동일하다면 수정버튼이 활성화 되고, 추가로 게시물의 status판매중 일 경우 판매완료버튼을 활성화 시킨다.

<a class="btn btn-primary btn-sm" id="modify" th:if="${boardForm.writer.equals(session.memberNickname)}" th:href="@{/board/modify(id=${boardForm.id})}">수정</a>
        <button type="button" class="btn btn-success btn-sm" id="soldOutBtn" th:if="${boardForm.writer.equals(session.memberNickname) && !#strings.equals(boardForm.status.value,'soldOut')}">판매완료</button>

로그인 한 사람과 글 작성자가 동일해서 수정과 판매완료 버튼이 활성화

이때 판매완료 버튼을 클릭 시 ajax를 이용해 api통신을 하게 되고 서비스측에서 해당 게시물의 id를 통해 statussoldOut으로 변경하게 된다. status를 바꾸는 작업은 queryDsl을 이용하여 수행하였다.

$("#soldOutBtn").on('click',function (){
    if(confirm("판매완료로 변경하시겠습니까?")) {
        $.ajax({
            type: "get",
            url: "/api/board/soldOut",
            data: {"id": $("#bid").val()},
            success: function (result) {
                if (result == "success") {
                    alert("변경되었습니다.");
                    location.reload();
                } else alert("잠시 후 다시 시도해주세요");
            },
            error: function (request, status, error) {
                alert("code : " + request.status + "\n" + "error : " + error);
            }
        });
    }
});
/*판매완료 버튼*/
    @Transactional
    public void boardStatusUpdate(Long id){
        queryFactory.update(QBoardEntity.boardEntity)
                .set(QBoardEntity.boardEntity.status, Status.soldOut)
                .where(QBoardEntity.boardEntity.id.eq(id))
                .execute();
    }

🏁 게시글 수정 버튼

해당 게시글의 수정버튼 클릭 시 html창이 열리고 boardForm과 같은 형식으로 동작된다. 이때 service단에서 createdDate는 그대로 두고 updateDate를 현재시간으로 update처리 한다.

/*보드 수정 후 전송*/
    public BoardDto boardModifySave(BoardDto boardDto, String username, HttpServletRequest request) {
        Optional<BoardCategoryEntity> boardCategoryEntity = boardCategoryRepository.findByName(boardDto.getCategoryName());
        Optional<MemberEntity> memberEntity = memberRepository.findByUsername(username);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
        boardDto.setUpdatedDate(LocalDateTime.now().format(formatter));

        /*ip찾는 로직*/
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null) {
            ip = request.getRemoteAddr();
        }
        boardDto.setWriteIp(ip);

        BoardEntity boardEntity = boardDto.toEntity();

        boardEntity.setCategory(boardCategoryEntity.get());
        boardEntity.setWriter(memberEntity.get());

        return boardRepository.save(boardEntity).toDto();
    }
profile
논리적으로 사고하고 해결하는 것을 좋아하는 개발자입니다.

1개의 댓글

comment-user-thumbnail
2022년 7월 9일

안녕하세요~ 판매중인 상품에 대한 html코드를 좀 보고싶은데 혹시 방법이 있을까요 ?!

답글 달기