쌍용교육(JAVA)/SpringBoot

쌍용교육 -JSP수업 105일차 ch15SpringPage(16)

구 승 2024. 7. 16. 11:06

TalkMapper.java

	//채팅 메시지 번호 생성
	@Select("SELECT sptalk_seq.nextval FROM dual")
	public Integer selectTalkNum();
	//채팅 메시지 등록
	@Insert("INSERT INTO sptalk (talk_num,talkroom_num,mem_num,message)VALUES (#{talk_num},#{talkroom_num},#{mem_num},#{message})")
	public void insertTalk(TalkVO talkVO);
	//읽지않은 채팅 기록 저장
	@Insert("INSERT INTO sptalk_read (talkroom_num,talk_num,mem_num) VALUES (#{talkroom_num},#{talk_num},#{mem_num})")
	public void insertTalkRead(@Param(value="talkroom_num")Long talkroom_num,@Param(value="talk_num")Long talk_num,@Param(value="mem_num")Long mem_num);

TalkServiceImpl

	@Override
	public void insertTalk(TalkVO talkVO) {
		talkVO.setTalk_num(talkMapper.selectTalkNum());
		talkMapper.insertTalk(talkVO);
		//채팅방 멤버가 읽지 않은 채팅 정보 저장
		for(TalkMemberVO vo : talkMapper.selectTalkMember(talkVO.getTalkroom_num())) {
			//읽지 않은 정보를 저장
			talkMapper.insertTalkRead(talkVO.getTalkroom_num(), talkVO.getTalk_num(), vo.getMem_num());
		}
		
	}

TalkController.java

//채팅 메시지 전송
	@PostMapping("/talk/writeTalk")
	@ResponseBody
	public Map<String, String> writeTalkAjax(TalkVO vo, HttpSession session){
		
		log.debug("<<채팅 메시지 전송>>"+vo);
		
		Map<String,String> mapAjax = new HashMap<String, String>();
		
		MemberVO user = (MemberVO)session.getAttribute("user");
		
		if(user==null) {
			//로그인이 되지 않는 경우
			mapAjax.put("result","logout");
			
		}else {
			//로그인 된 경우
			vo.setMem_num(user.getMem_num());
			//메시지 등록
			talkService.insertTalk(vo);
			mapAjax.put("result","success");
		}
		return mapAjax;//mapAjax 는 map<String.String> mapJson은 map<String.Object>
	}

message.talk.js

	/*--------------------
	 * 채팅하기
	 *--------------------*/
	function selectMsg(){
		
	}
	//메시지 입력후 enter 이벤트 처리
	$('#message').keydown(function(event){
		if(event.keyCode == 13 && !event.shiftKey){
			$('#detail_form').trigger('submit');
		}
	});
	//채팅 메시지 등록
	$('#detail_form').submit(function(event){
		if($('#message').val().trim()==''){
			alert('메시지를 입력하세요');
			$('#message').val('').focus(); //공백을 제거하고 포커스를 맞추기
			return false;
		}
		if($('#message').val().length>1333){
			alert('메시지를 1333자 까지만 입력가능합니다.');
			return false;
		}
		//입력한 데이터를 읽어오기
		let form_data = $(this).serialize();
		//서버와 통신
		$.ajax({
			url:'../talk/writeTalk',
			type:'post',
			data:form_data,
			dataType:'json',
			success:function(param){
				if(param.result == 'logout'){
					alert('로그인 해야 작성 할 수 있습니다.');
				}else if(param.result=='success'){
					//폼 초기화
					$('#message').val('').focus();
					selectMsg(); //추후에 웹소켓으로 변경
				}else{
					alert('채팅 메시지 등록 오류 발생');
				}
			},
			error:function(){
				alert('네트워크 오류 발생');
			}
		});//end of ajax
		//기본 이벤트 제거
		event.preventDefault();
	});

전송버튼 또는 엔터를 누르면 값이 들어간다.

TalkMapper.java

	//읽은 채팅 기록 삭제
	@Delete("DELETE FROM sptalk_read WHERE talkroom_num=#{talkroom_num} AND mem_num=#{mem_num}")
	public void deleteTalkRead(Map<String,Long> map);

TalkMapper.xml

	<!-- 채팅 메시지 읽기 -->
	<select id="selectTalkDetail" parameterType="long" resultType="talkVO">
		SELECT
			<![CDATA[
			REPLACE(REPLACE(message,'<','&lt;'),'>','&gt;') message,
			]]>
			chat_date,
			read_count,
			mem_num,
			id
		FROM sptalk
		LEFT OUTER JOIN(SELECT
							talk_num,
							COUNT(*) read_count
							FROM sptalk_read
							GROUP BY talk_num)
		USING(talk_num)
		JOIN spmember
		USING(mem_num)
		WHERE talkroom_num=#{talkroom_num} 
		AND chat_date >=(SELECT
							member_date
						 FROM sptalk_member
						 WHERE talkroom_num =#{talkroom_num}
						 AND mem_num=#{mem_num}) <!-- 멤버 등록일 이후의 정보만 읽어옴 -->
		ORDER BY chat_date ASC
	</select>

talkServiceImpl

@Override
	public List<TalkVO> selectTalkDetail(Map<String, Long> map) {
		// 읽은 채팅 기록 삭제
		talkMapper.deleteTalkRead(map);
		return talkMapper.selectTalkDetail(map);
	}

TalkController

	//채팅 메시지 읽기
	@GetMapping("/talk/talkDetailAjax")
	@ResponseBody
	public Map<String,Object> talkDetailAjax(
								long talkroom_num,
								HttpSession session){
		Map<String,Object> mapJson =
				new HashMap<String, Object>();
		MemberVO user = (MemberVO)session.getAttribute("user");
		
		if(user==null) {
			//로그인이 되지 않는 경우
			mapJson.put("result","logout");
			
		}else {
			//로그인 된 경우
			Map<String,Long> map = new HashMap<String, Long>();
			map.put("talkroom_num",talkroom_num);
			map.put("mem_num",user.getMem_num());
			List<TalkVO> list = talkService.selectTalkDetail(map);
			
			mapJson.put("result","success");
			mapJson.put("list",list);
			mapJson.put("user_num",user.getMem_num());
		}
		return mapJson;
	}

기존 값을 삭제한다.


기존에 있던 초대문구 설정 작업을 하기위해 

//채팅 멤버 초대 문구 설정

vo.setTalkVO(new TalkVO());

vo.getTalkVO().setMem_num(user.getMem_num());

vo.getTalkVO().setMessage(user.getId()+"님이 "+findMemberId(vo, user)+"님을 초대했습니다.@{member}@");

 

TalkServiceImpl

		//입장 메시지 처리
		talkRoomVO.getTalkVO().setTalk_num(talkMapper.selectTalkNum()); //시퀀스를 생성해줘야된다.
		talkRoomVO.getTalkVO().setTalkroom_num(talkRoomVO.getTalkroom_num());
		insertTalk(talkRoomVO.getTalkVO());

insertTalk(talkRoomVO.getTalkVO()); 부분은 원래
talkMapper. insertTalk(talkRoomVO.getTalkVO()); 라고 되어있었는데
impl페이지에 override되어있는 insertTalk를 호출 할 수 없고, 그에 따라서 sptalk_read에 값이 들어가지 않기 때문에 

talkMapper. 은 지웠다.

채팅방을 다시 새로 만들어주면 누구누구님을 초대했습니다. 라고 뜬다.

message.talk.js

//채팅 데이터 읽기	
	function selectMsg(){
		$.ajax({
			url:'../talk/talkDetailAjax',
			type:'get',
			data:{talkroom_num:$('#talkroom_num').val()},
			dataType:'json',
			success:function(param){
				if(param.result == 'logout'){
					alert('로그인 후 사용하세요!');
					message_socket.close();
				}else if(param.result == 'success'){
						
					//메시지 표시 UI 초기화	
					$('#chatting_message').empty();
					
					let chat_date='';	
					$(param.list).each(function(index,item){
						let output = '';
						//날짜 추출
						if(chat_date != item.chat_date.split(' ')[0]){
							chat_date = item.chat_date.split(' ')[0];
							output += '<div class="date-position"><span>'+chat_date+'</span></div>';
						}
						
						if(item.message.indexOf('@{member}@')>=0){//멤버등록/탈퇴 메시지 처리
							//신규, 탈퇴 회원 메시지
							output += '<div class="member-message">';
							output += item.message.substring(0,item.message.indexOf('@{member}@'));
							output += '</div>';
						}else{
							//멤버등록/탈퇴 메시지가 아닌 일반 메시지
							if(item.mem_num == param.user_num){
								output += '<div class="from-position">'+item.id;
								output += '<div>';
							}else{	
								output += '<div class="to-position">';
								output += '<div class="space-photo">';
								output += '<img src="../member/viewProfile?mem_num='+ item.mem_num +'" width="40" height="40" class="my-photo">';
								output += '</div><div class="space-message">';
								output += item.id;
							}
							output += '<div class="item">';
							output += item.read_count + ' <span>' + item.message.replace(/\r\n/g,'<br>').replace(/\r/g,'<br>').replace(/\n/g,'<br>') + '</span>';
							//시간 추출
							output += '<div class="align-right">' + item.chat_date.split(' ')[1] + '</div>';
							output += '</div>';
							output += '</div><div class="space-clear"></div>';
							output += '</div>';
						}
						
						//문서 객체에 추가
						$('#chatting_message').append(output);
						//스크롤을 하단에 위치시킴
						$('#chatting_message').scrollTop($("#chatting_message")[0].scrollHeight);
					});	
				}else{
					alert('채팅 메시지 읽기 오류 발생');	
					message_socket.close();
				}
			},
			error:function(){
				alert('네트워크 오류 발생');
				/*message_socket.close();*/
			}
		});	
	}
    selectMsg();

읽지않으면 숫자가 2라고 된다.3명이 있기 떄문에
브라우저가 달라야 다른 사용자로 인식함. 크롬으로 창을 2개 띄우면 같은 사용자로 인식하기 떄문에 읽은숫자가 안사라짐