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,'<','<'),'>','>') 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();


'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
교육 때 진행한 프로젝트 연결 (0) | 2024.07.31 |
---|---|
쌍용교육 -JSP수업 106일차 ch15SpringPage(17) (0) | 2024.07.17 |
쌍용교육 -JSP수업 104일차 ch15SpringPage(15) (0) | 2024.07.15 |
쌍용교육 -JSP수업 103일차 ch15SpringPage(14) (0) | 2024.07.12 |
쌍용교육 -JSP수업 102일차 ch15SpringPage(13) (0) | 2024.07.11 |
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,'<','<'),'>','>') 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();


'쌍용교육(JAVA) > SpringBoot' 카테고리의 다른 글
교육 때 진행한 프로젝트 연결 (0) | 2024.07.31 |
---|---|
쌍용교육 -JSP수업 106일차 ch15SpringPage(17) (0) | 2024.07.17 |
쌍용교육 -JSP수업 104일차 ch15SpringPage(15) (0) | 2024.07.15 |
쌍용교육 -JSP수업 103일차 ch15SpringPage(14) (0) | 2024.07.12 |
쌍용교육 -JSP수업 102일차 ch15SpringPage(13) (0) | 2024.07.11 |