Skip to content

WinWin‐Message

jung-so-e edited this page Aug 4, 2023 · 5 revisions

📌Message

✔️쪽지

  • 버튼을 누르면 해당 게시글을 작성한 회원 또는 해당 프로필 회원에게 쪽지를 보낼 수 있는 모달창이 뜸
  • 보내거나 받은 쪽지는 마이페이지 > 쪽지함에 등록됨
  • 마이페이지에서 쪽지 박스를 누르면 전체 쪽지가 보여짐 / 답장하기 가능
  • 마이페이지 쪽지함 -> 무한스크롤

🖥️ code

ChattingRestController.java
@RestController
@RequiredArgsConstructor
@RequestMapping("/chattings/*")
public class ChattingRestController {
    private final ChattingService chattingService;
    private final ShareService shareService;
    private final UserService userService;

    /* 쪽지 보내기 */
    @PostMapping("/inputModal")
    public void sendChatting(@RequestBody ChattingDto chattingDto, HttpServletRequest req){
        Long chattingFrom = (Long)req.getSession().getAttribute("userNumber");
        chattingDto.setChattingFrom(chattingFrom);

        chattingService.sendChatting(chattingDto);
    }

    /* 나눔 쪽지 보내기 */
    @PostMapping("/shareModal/{shareNumber}/{wingAmount}")
    public void sendShareChatting(@RequestBody ChattingDto chattingDto, HttpServletRequest req,
                                  @PathVariable(value = "shareNumber", required = false) Long shareNumber, @PathVariable("wingAmount") int wingAmount) {
        Long chattingFrom = (Long) req.getSession().getAttribute("userNumber");
        chattingDto.setChattingFrom(chattingFrom);

        chattingService.sendChatting(chattingDto);
        shareService.modifyShareStatus(shareNumber);
        shareService.wingTrade(wingAmount, chattingDto.getChattingFrom(), chattingDto.getChattingTo());
        UserDto userDto = userService.findUserInfo(chattingFrom);
        req.getSession().setAttribute("userWing", userDto.getUserWing());
    }

    /* 쪽지 확인 (받은 쪽지) */
    @GetMapping("/sendModal")
    public ChattingVo chattingSelectModel(Long chattingNumber) {
        if (chattingNumber == null) {
            return null;
        }
        ChattingVo chattingVo = chattingService.chattingSelectModal(chattingNumber);

        return chattingVo;
    }

    /* 쪽지 확인 (보낸 쪽지) */
    @GetMapping("/sendModal2")
    public ChattingVo chattingSendModel(Long chattingNumber) {
        if (chattingNumber == null) {
            return null;
        }
        ChattingVo chattingVo = chattingService.chattingSendModal(chattingNumber);

        return chattingVo;
    }

    // 받은 메세지 조회
    @GetMapping("/receiveMessage/{page}")
    public Map<String, Object> chattingSelect(HttpServletRequest req, @PathVariable("page") int page) {
        Long userNumber = (Long) req.getSession().getAttribute("userNumber");

        Criteria criteria = new Criteria();
        criteria.setPage(page);
        criteria.setAmount(5);
        PageVo pageVo = new PageVo(criteria, chattingService.chattingReceiveAll(userNumber));
        List<ChattingVo> chattingVoList = chattingService.chattingSelect(userNumber, criteria);

        Map<String, Object> myBoard = new HashMap<>();
        myBoard.put("pageVo", pageVo);
        myBoard.put("chattingVoList", chattingVoList);

        return myBoard;
    }

    // 보낸 메세지 조회
    @GetMapping("/sendMessage/{page}")
    public Map<String, Object> chattingSelectFrom(HttpServletRequest req, @PathVariable("page") int page) {
        Long userNumber = (Long) req.getSession().getAttribute("userNumber");
        Criteria criteria = new Criteria();
        criteria.setPage(page);
        criteria.setAmount(5);
        PageVo pageVo = new PageVo(criteria, chattingService.chattingSendAll(userNumber));
        List<ChattingVo> chattingVoList = chattingService.chattingSelectFrom(userNumber, criteria);

        Map<String, Object> myBoard = new HashMap<>();
        myBoard.put("pageVo", pageVo);
        myBoard.put("chattingVoList", chattingVoList);


        return myBoard;
    }

}
ChattingService.java
   @Service
@RequiredArgsConstructor
public class ChattingService {

    private final ChattingMapper chattingMapper;

    // 쪽지 보내기
    public void sendChatting(ChattingDto chattingDto){
        if(chattingDto == null){throw new IllegalArgumentException("채팅 정보 xxxxxxxxxxx");}
        chattingMapper.sendChatting(chattingDto);
    }

    // 쪽지 조회하기 (받은 쪽지)
    public List<ChattingVo> chattingSelect(Long userNumber, Criteria criteria){
        if(userNumber == null){throw new IllegalArgumentException("존재하지 않는 회원");}

        return Optional.ofNullable(chattingMapper.chattingSelect(userNumber, criteria))
                .orElseThrow(()->{throw new IllegalArgumentException("존재하지 않는 회원 번호");});
    }

    // 쪽지 조회하기 (보낸 쪽지)
    public List<ChattingVo> chattingSelectFrom(Long userNumber, Criteria criteria){
        if(userNumber == null){throw new IllegalArgumentException("존재하지 않는 회원");}

        return Optional.ofNullable(chattingMapper.chattingSelectFrom(userNumber, criteria))
                .orElseThrow(()->{throw new IllegalArgumentException("존재하지 않는 회원 번호");});
    }
    
    // 쪽지 모달창 조회하기
    @Transactional(readOnly = true)
    public ChattingVo chattingSelectModal(Long chattingNumber){
        if(chattingNumber == null){throw new IllegalArgumentException("존재하지 않는 쪽지");}
        
        return chattingMapper.chattingSelectModal(chattingNumber);
    }

    // 쪽지 모달창 조회하기 (보낸 쪽지)
    @Transactional(readOnly = true)
    public ChattingVo chattingSendModal(Long chattingNumber){
        if(chattingNumber == null){throw new IllegalArgumentException("존재하지 않는 쪽지");}

        return chattingMapper.chattingSendModal(chattingNumber);
    }

    // 답장하기 (회원 이름, 닉네임 조회)
    public ChattingVo selectChattingName(Long chattingNumber){
        if(chattingNumber == null){throw new IllegalArgumentException("존재하지 않는 쪽지");}

        return chattingMapper.selectChattingName(chattingNumber);
    }

    // 받은 쪽지 총 갯수
    public int chattingReceiveAll(Long userNumber){
        if(userNumber == null){throw new IllegalArgumentException("?????????");}
        return chattingMapper.chattingReceiveAll(userNumber);
    }

    // 보낸 쪽지 총 갯수
    public int chattingSendAll(Long userNumber){
        if(userNumber == null){throw new IllegalArgumentException("?????????");}
        return chattingMapper.chattingSendAll(userNumber);
    }
}
ChattingMapper.xml
    
<mapper namespace="com.example.winwin.mapper.chatting.ChattingMapper">

    <!-- 쪽지 보내기 -->
    <insert id="sendChatting">
        <selectKey keyProperty="chattingNumber" order="BEFORE" resultType="Long">
            SELECT SEQ_CHATTING.NEXTVAL FROM DUAL
        </selectKey>
        INSERT INTO CHATTING (CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_TO, CHATTING_FROM)
        VALUES (#{chattingNumber}, #{chattingContent}, #{chattingTo}, #{chattingFrom})
    </insert>

    <!-- 쪽지 모달창에 데이터 꽂기 -->
    <select id="chattingSelectModal" resultType="chattingVo">
        SELECT CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, WW_USER.USER_NICKNAME, WW_USER.USER_NAME,
               WW_USER.USER_NUMBER, USER_PFP.PFP_SYSTEM_NAME,
               USER_PFP.PFP_UUID, USER_PFP.PFP_UPLOAD_PATH
        FROM CHATTING JOIN WW_USER
        ON CHATTING.CHATTING_FROM = WW_USER.USER_NUMBER
        LEFT JOIN USER_PFP
        ON USER_PFP.USER_NUMBER = WW_USER.USER_NUMBER
        WHERE CHATTING_NUMBER = #{userNumber}
    </select>

    <!-- 쪽지 모달창에 데이터 꽂기 (보낸 쪽지) -->
    <select id="chattingSendModal" resultType="chattingVo">
        SELECT CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, WW_USER.USER_NICKNAME, WW_USER.USER_NAME,
               WW_USER.USER_NUMBER, USER_PFP.PFP_SYSTEM_NAME,
               USER_PFP.PFP_UUID, USER_PFP.PFP_UPLOAD_PATH
        FROM CHATTING JOIN WW_USER
        ON CHATTING.CHATTING_TO = WW_USER.USER_NUMBER
        LEFT JOIN USER_PFP
        ON USER_PFP.USER_NUMBER = WW_USER.USER_NUMBER
        WHERE CHATTING_NUMBER = #{userNumber}
    </select>

    <!-- 무한 스크롤 (받은 쪽지) -->
    <select id="chattingSelect">
        SELECT CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, CHATTING_FROM,
        USER_NICKNAME, USER_NUMBER, PFP_SYSTEM_NAME,
        PFP_UUID, PFP_UPLOAD_PATH
        FROM(
        select ROWNUM RN, CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, CHATTING_FROM,
        USER_NICKNAME, USER_NUMBER, PFP_SYSTEM_NAME,
        PFP_UUID, PFP_UPLOAD_PATH
        from(
        SELECT CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, CHATTING_FROM,
        U.USER_NICKNAME USER_NICKNAME, U.USER_NUMBER USER_NUMBER, P.PFP_SYSTEM_NAME PFP_SYSTEM_NAME,
        P.PFP_UUID PFP_UUID, P.PFP_UPLOAD_PATH PFP_UPLOAD_PATH
        FROM CHATTING JOIN WW_USER U
        ON CHATTING.CHATTING_FROM = U.USER_NUMBER
        LEFT JOIN USER_PFP P
        ON P.USER_NUMBER = U.USER_NUMBER
        WHERE CHATTING_TO = #{userNumber}
        ORDER BY CHATTING_NUMBER DESC
        )
        <![CDATA[
        WHERE ROWNUM <= #{criteria.page} * #{criteria.amount}
        ]]>
        )
        WHERE RN > ( #{criteria.page} - 1) * #{criteria.amount}
    </select>

    <!-- 무한 스크롤 (보낸 쪽지) -->
    <select id="chattingSelectFrom">
        SELECT CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, CHATTING_FROM,
               USER_NICKNAME, USER_NUMBER, PFP_SYSTEM_NAME,
               PFP_UUID, PFP_UPLOAD_PATH
        FROM(
                select ROWNUM RN, CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, CHATTING_FROM,
                       USER_NICKNAME, USER_NUMBER, PFP_SYSTEM_NAME,
                       PFP_UUID, PFP_UPLOAD_PATH
                from(
                        SELECT CHATTING_NUMBER, CHATTING_CONTENT, CHATTING_DATE, CHATTING_TO, CHATTING_FROM,
                               U.USER_NICKNAME USER_NICKNAME, U.USER_NUMBER USER_NUMBER, P.PFP_SYSTEM_NAME PFP_SYSTEM_NAME,
                               P.PFP_UUID PFP_UUID, P.PFP_UPLOAD_PATH PFP_UPLOAD_PATH
                        FROM CHATTING JOIN WW_USER U
                                           ON CHATTING.CHATTING_TO = U.USER_NUMBER
                                      LEFT JOIN USER_PFP P
                                                ON P.USER_NUMBER = U.USER_NUMBER
                        WHERE CHATTING_FROM = #{userNumber}
                        ORDER BY CHATTING_NUMBER DESC
                    )
        <![CDATA[
                WHERE ROWNUM <= #{criteria.page} * #{criteria.amount}
        ]]>
        )
        WHERE RN > ( #{criteria.page} - 1) * #{criteria.amount}
    </select>

    <!-- 받은 쪽지 총 개수 -->
    <select id="chattingReceiveAll" resultType="int">
        SELECT COUNT(CHATTING_FROM)
        FROM CHATTING
        WHERE CHATTING_TO = #{userNumber}
    </select>

    <!-- 보낸 쪽지 총 개수 -->
    <select id="chattingSendAll" resultType="int">
        SELECT COUNT(CHATTING_TO)
        FROM CHATTING
        WHERE CHATTING_FROM = #{userNumber}
    </select>
</mapper>
message.js
$("#inputMessage").keyup(function (e) {
    let content = $(this).val();

    // 글자수 세기
    if (content.length == 0 || content == "") {
        $(".send-text-count").text("0");
    } else {
        $(".send-text-count").text(content.length);
    }

    // 글자수 제한
    if (content.length > 400) {
        // 400자 부터는 타이핑 되지 않도록
        $(this).val($(this).val().substring(0, 400));
        // 400자 넘으면 알림창 뜨도록
        $('.warning-text').html("글자수는 400자까지 입력 가능합니다.");
    }
});

// 나눔 쪽지 보내기
$('.input-container').on('click','.send-btn', function (){

    let num = $('.chattingTo').data('num');
    let shareNumber = $('.share-num').val();
    let wingAmount = $('.share-wing-count').text();

        $.ajax({
            url: "/chattings/shareModal/" + shareNumber + "/" + wingAmount,
            type: 'post',
            data: JSON.stringify({chattingTo : num, chattingContent : $('#inputMessage').val()}),
            contentType : "application/json; charset=utf-8",
            success: function (){
                alert("전송이 완료되었습니다.");
                $('#inputMessage').val('');
                $('.input-wrap').addClass('none');
                $('body').css('overflow', 'auto');
                $('.form-reset')[0].reset();

                window.location.href = '/share/list';
            }
        });

});

//쪽지 보내기
$('.input-container').on('click','.send-btn', function (){

    let num = $('.chattingTo').data('num');
    let shareNumber = $('.share-num').val();
    let wingAmount = $('.share-wing-count').text();

    if(shareNumber == null || wingAmount == null){
        $.ajax({
            url: "/chattings/inputModal",
            type: 'post',
            data: JSON.stringify({chattingTo : num, chattingContent : $('#inputMessage').val()}),
            contentType : "application/json; charset=utf-8",
            success: function (){
                alert("전송이 완료되었습니다.");
                $('#inputMessage').val('');
                $('.input-wrap').addClass('none');
                $('body').css('overflow', 'auto');
                $('.form-reset')[0].reset();
            }
        })
    }
});

// 모달창
$(function () {
    $(".send-main").on('click', '.message-box', function () {
        $(".send-wrap").css("display", "flex");
        $(".send-wrap").fadeIn();

        let chattingNumber = $(this).closest('.message-box').find('.message-list').data('cnum');

        $.ajax({
            url: "/chattings/sendModal2",
            type: 'get',
            data: {chattingNumber: chattingNumber},
            success: function (result) {
                if (result == null) {
                    alert("삭제된 쪽지입니다.");
                }
                $('.send-sender').text(result.userNickname);
                $('.send-content-chat').text(result.chattingContent);
                $('.send-date-s').text(result.chattingDate);

                if (result.pfpSystemName != null) {
                    $('.send-message-profile-img').css("background-image", "url(/profile/" + result.pfpUuid + "_" + result.pfpSystemName + ")");
                } else {
                    $('.send-message-profile-img').css("background-image", "url(/img/profile-basic.png)");
                }
            }
        })

    });
});

// 모달창이 나타났을 때 스크롤 제거
$(".send-main").on('click', '.message-box', function () {
    $(".send-wrap").removeClass("none");

    $('body').css('overflow', 'hidden');
});

// 검은 화면 누르면 모달창 제거
$(".send-wrap").on("click", function (e) {

    if ($(e.target).hasClass("send-wrap")) {
        $(".send-wrap").css("display", "none");
        $(".send-wrap").addClass("none");
        $('body').css('overflow', 'auto');

        $('.form-reset')[0].reset();
    }
});


// 무한스크롤
let pageNumber = 1;

getListPage({page: pageNumber}, appendList, showError);

$(window).on('scroll', function () {
    if (Math.ceil($(window).scrollTop()) == $(document).height() - $(window).height()
        || Math.floor($(window).scrollTop()) == $(document).height() - $(window).height()) {
        ++pageNumber;
        getListPage({page: pageNumber}, appendList, showError)
    }
});

function getListPage(pageInfo, appendList, error) {
    $.ajax({
        url: `/chattings/sendMessage/${pageInfo.page}`,
        type: 'get',
        dataType: 'json',
        success: function (result) {
            console.log(result);
            if (appendList) {
                appendList(result);
            }
        },
        error: error
    });
}

function appendList(map) {
    let text = '';

    if (map.chattingVoList.length == 0 && pageNumber == 1) {
        text = `
          <div class="community-main-box">
            <span>앗! 보낸 쪽지가 없어요.😿<br/>
            회원들과 활발한 쪽지를 나누어 보아요.</span>
          </div>
        `;

        $('.send-main').html(text);

    } else {

        map.chattingVoList.forEach(chatting => {

            text += `
                <div class="message-box">
                        <span class="message-list" data-cnum="${chatting.chattingNumber}"></span>
                            <div class="message-box-top">
                                <div class="sender-profile">
                                `;
            if (chatting.pfpSystemName == null) {
                text += `<div class="sender-img">
                                  <img class="sender-img" src="/img/profile-basic.png"/>
                              </div>`;
            } else {
                text += `<div class="sender-img"
                              style="${'background-image: url(/profile/' + chatting.pfpUuid + '_' + chatting.pfpSystemName + ')'}">
                              </div>`;
            }
            text += `
                                    <span name="chattingTo" class="sender">${chatting.userNickname}</span>
                                </div>
                                <button class="send-reply" data-uunum="${chatting.userNumber}">✉ 보내기</button>
                            </div>
                            <span class="message-content">${chatting.chattingContent}</span>
                            <div class="message-bottom-box">
                                <span class="message-date">${chatting.chattingDate}</span>
                            </div>
                    </div>
        `;

        });
        $('.send-main').append(text);
    }
}

function showError(a, b, c) {
    console.log(c);
}

// 답장하기 모달창
$(function () {
    $(".chatting-main").on('click', '.send-reply', function (e) {
        // e.stopPropagation();
        $(".send-wrap").css("display", "none");
        $(".input-wrap").fadeIn();

        let userNickname = $(this).closest('.message-box').find('.sender').text();
        let num = $(this).data('uunum');

        $('.chattingTo').text(userNickname);
        $('.chattingTo').data('num', num);
    });


});

📸 view

Image

// 나눔 페이지에서 쪽지 보내기

// 마이페이지 -> 쪽지함

// 쪽지 박스 눌렀을 때

image


Clone this wiki locally