상품에 댓글, 대댓글 달기

wonny·2022년 9월 26일
0

수업 복습

목록 보기
5/14

제품 상세보기에 댓글을 달고 관리자 계정으로 대댓글을 달아보자.

상품 댓글 추가

mySQL

먼저 제품 댓글 데이터를 담을 shopanswer 테이블을 만들어준다.

create table shopanswer(idx smallint auto_increment primary key,
shopnum smallint,
myid varchar(30),
content varchar(1000),
shopanswer varchar(1000) default 'no',
writeday date,
foreign key(shopnum) references shop(shopnum) on delete cascade);

idx: 시퀀스
shopnum: shop의 외부키
myid: 댓글 단 아이디
content: 댓글 내용
shopanswer: 관리자 대댓글 (insert 할 때 NULL값으로 들어가지 않게 default 값으로 'no'를 줬다.)
writeday: 댓글 단 날짜

이제 Dto를 만들어주고, ShopAnswerDao.java에 insert를 만들어준다.

ShopAnswerDao.java

//insert
	public void insertAnswer(ShopAnswerDto dto) {
		
		Connection conn = db.getConnection();
		PreparedStatement pstmt= null;
		 
		String sql = "insert into shopanswer (shopnum, myid, content, writeday) values (?,?,?,now()) ";
		
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getShopnum());
			pstmt.setString(2, dto.getMyid());
			pstmt.setString(3, dto.getContent());
		
			pstmt.execute();
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			db.dbClose(pstmt, conn);
		}
		
	}

	

detailpage.jsp

<!-- 상품 댓글 -->
<%
if(loginok!=null){%>
	<div id="answer">
		<form id="answerfrm">
		<input type="hidden" name="shopnum" id="shopnum" value=<%=dto.getShopnum()%>>
		<input type="hidden" name="myid" id="myid" value="<%=myid%>">
		<textarea class="form-control" name="content" id="content"></textarea>
		<button type="button" id="addanswer" class="btn btn-success">추가</button>
		
		
		</form>
	
	</div>
<%}
%>

사이트에 로그인한 사람만 댓글 작성 칸을 볼 수 있도록 loginok!=null 조건을 줘야 한다.
그리고 상품 댓글을 작성할 수 있는 form을 만들 때 hidden으로 상품번호(shopnum), 로그인된 아이디(myid)를 넣어줘야 한다.

<input type="hidden" name="shopnum" id="shopnum" value=<%=dto.getShopnum()%>>
<input type="hidden" name="myid" id="myid" value="<%=myid%>">

댓글 추가

detailpage.jsp

이제 댓글창에 댓글을 입력하고 '추가'를 누르면 댓글이 DB에 추가되게 하자.

$("#addanswer").click(function(){
	var myid=$("#myid").val();
	var shopnum = $("#shopnum").val();
	var content = $("#content").val();
	console.log(myid,shopnum,content);

댓글창에서 추가를 눌렀을 때 myid, shopnum, content가 넘어오는지 확인해보자. 넘어오는걸 확인했으면 insert하기 위한 jsp를 만들어준다.

readanswer.jsp

<%

request.setCharacterEncoding("utf-8");

String shopnum = request.getParameter("shopnum");
String myid = request.getParameter("myid");
String content = request.getParameter("content");

ShopAnswerDto dto = new ShopAnswerDto();

dto.setShopnum(shopnum);
dto.setMyid(myid);
dto.setContent(content);

ShopAnswerDao dao = new ShopAnswerDao();

dao.insertAnswer(dto);


%>

shopnum, myid, content를 넘겨서 ShopAnswerDto에 담고 dao로 insertAnswer을 호출한다.

detailpage.jsp

$(function(){
//디테일 페이지 출력시 기존 댓글도 출력
answerlist();

//추가 버튼 누르면 댓글 추가
//ajax 함수로 처리(readanswer.jsp로 myid, shopnum, content 3개 보내서 해당 jsp에서 db에 인서트)

//shopnum,myid 넘어오는지 확인


$("#addanswer").click(function(){
	var myid=$("#myid").val();
	var shopnum = $("#shopnum").val();
	var content = $("#content").val();
	console.log(myid,shopnum,content);
	
	$.ajax({
        type:"post",
        dataType:"html",
        url:"shop/readanswer.jsp",
        data:{"myid":myid,"shopnum":shopnum, "content":content},
        success:function(){

           //기존입력값 지우기
           $("#content").val("");
        
           alert("success");
           answerlist();           
           
        	}, statutsCode:{
           404:function(){
              alert("파일을 찾을 수 없습니다.");
           },500:function(){
              alert("서버오류, 오타");
           }
        }
     });
	
	
});

ajax로 readanswer을 불러오면 DB 추가를 할 수 있다!!


상품 댓글 출력

detailpage.jsp

이제 추가한 댓글들을 상세보기 화면에서 보이게 해보자.

<div id="answerlist">
댓글 목록
</div>

간단하게 목록을 보여줄 div를 만들어준다.
댓글 목록은 뭘 클릭해서 나오는게 아니고 상세보기 눌렀을 때 바로 나오는 거니까 사용자함수를 만들어준 후 위에 스크립트에서 함수를 호출해주면 바로 댓글 목록을 볼 수 있다.

ShopAnswerDao.java에서 list 메서드를 만들어준다.

ShopAnswerDao.java

    
    //list
	public List<ShopAnswerDto> getAllAnswerlist(String shopnum) {
		List<ShopAnswerDto> list = new Vector<>();
		
		Connection conn = db.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		String sql = "select * from shopanswer where shopnum=? order by shopnum desc"; //최신글이 맨 위로 올라오도록 desc로 설정
		
		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, shopnum);
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				ShopAnswerDto dto = new ShopAnswerDto();
				dto.setIdx(rs.getString("idx"));
				dto.setShopnum(rs.getString("shopnum"));
				dto.setMyid(rs.getString("myid"));
				dto.setContent(rs.getString("content"));
				dto.setShopanswer(rs.getString("shopanswer"));
				dto.setWriteday(rs.getTimestamp("writeday"));
				//리스트에 추가
				list.add(dto);
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			db.dbClose(rs, pstmt, conn);
		}
	
		return list;
	}

전체출력 메서드를 만들어줬으니 dao를 처리하는 JSON 파일을 만들어줘야 한다.

answerlist.jsp

<%@page import="org.json.simple.JSONObject"%>
<%@page import="data.dao.MemberDao"%>
<%@page import="org.json.simple.JSONArray"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="data.dto.ShopAnswerDto"%>
<%@page import="java.util.List"%>
<%@page import="data.dao.ShopAnswerDao"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%
String shopnum = request.getParameter("shopnum");

ShopAnswerDao dao = new ShopAnswerDao();

List<ShopAnswerDto> list = dao.getAllAnswerlist(shopnum);

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");

//member에서 id를 통해 이름도 가져오기
MemberDao mdao = new MemberDao();

JSONArray arr = new JSONArray();

for(ShopAnswerDto dto:list){
	JSONObject ob = new JSONObject();

	ob.put("idx",dto.getIdx());
	ob.put("myid", dto.getMyid());
	ob.put("name", mdao.getName(dto.getMyid()));
	ob.put("content", dto.getContent());
	ob.put("shopanswer", dto.getShopanswer());
	ob.put("writeday", sdf.format(dto.getWriteday()));
	
	arr.add(ob);
}
%>
<%=arr.toString()%>

shopnum에 따른 댓글 리스트니까 shopnum을 읽어와야 한다. 그리고 dao를 통해 getAllAnswerList(shopnum)을 불러오고 JSON을 반환하기 위한 JSONArray를 만들어준다.

detailpage.jsp

function answerlist(){
	var loginid = $("#myid").val(); //로그인 한 아이디
	var shopnum = $("#shopnum").val(); //현재 상품 번호
    
    $.ajax({
		type:"get",
		url:"shop/answerlist.jsp",
		data:{"shopnum":shopnum},
		dataType:"json",
		success:function(res){
			//출력할 변수
			var s = "";
			$.each(res,function(i,ele){
				s+="<b>"+ele.name+"</b>";
				//삭제 표시는 본인만 보이게
				var myid = ele.myid;
				if(loginid==myid){
					s+="<span class='adel glyphicon glyphicon-trash' idx='"+ele.idx+"'></span>";
				}
				
				//날짜
				s+="<span class='aday'>"+ele.writeday+"</span>";
				//내용
				s+="<pre class='acontent'>"+ele.content+"</pre>";
				
			});
			
			$("#answerlist").html(s);
			
		}
		
		
	});
	
}
//삭제 표시는 본인만 보이게
				var myid = ele.myid;
				if(loginid==myid){
					s+="<span class='adel glyphicon glyphicon-trash' idx='"+ele.idx+"'></span>";
				}

var loginid는 로그인 세션에 저장된 myid 값이다, 즉 로그인 된 아이디.
var myid=ele.myid는 JSON에서 key 값으로 넘긴 myid 값이다.
loginid와 myid가 일치한다는 것은 현재 로그인 된 아이디와 댓글을 작성했던 아이디가 일치한다는 것으로, 댓글 작성자의 화면에만 쓰레기통 모양이 보이도록 했다.

이제 댓글 list 출력까지 했으니 쓰레기통 모양을 눌렀을 때 삭제가 되도록 해보자


댓글 삭제

ShopAnswerDao.java

//삭제
	public void deleteShopAnswer(String idx) {
		Connection conn = db.getConnection();
		PreparedStatement pstmt = null;
		
		String sql= "delete from shopanswer where idx=?";
		
		try {
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, idx);
			pstmt.execute();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			
			db.dbClose(pstmt, conn);
		}
		
	}

detailpage.jsp

<span class='adel glyphicon glyphicon-trash' idx='"+ele.idx+"'></span>

아까 댓글을 출력할 때 로그인 아이디=댓글 작성 아이디인 경우 쓰레기통 글리파이콘을 보이게 하면서 adel이라는 class를 넣어주고, idx 값을 넣어주었다.

	//삭제
	$(document).on("click","span.adel",function(){
		var idx = $(this).attr("idx");
		console.log(idx);

쓰레기통을 클릭했을 때 idx 값이 잘 넘어오는지 확인을 해주고 delete를 처리할 jsp를 만들어준다.

answerdelete.jsp

<%
String idx = request.getParameter("idx");
ShopAnswerDao sdao = new ShopAnswerDao();
sdao.deleteShopAnswer(idx);
%>

idx 값을 넘겨서 idx에 해당하는 댓글을 삭제시켜준다.

detailpage.jsp

	//삭제
	$(document).on("click","span.adel",function(){
		var idx = $(this).attr("idx");
		console.log(idx);
		
		var a = confirm("삭제하시겠습니까?");
		if(!a){
			return;
		}
		//삭제
		$.ajax({
			type:"get",
			url:"shop/answerdelete.jsp",
			data:{"idx":idx},
			dataType:"html",
			success:function(){
				answerlist();
				
			}
			
		});
		
	});

관리자 댓글 달기

이제 admin으로 들어갔을 때 댓글에 대댓글을 달고, 사용자들이 확인할 수 있게 해보자.

detailpage.jsp

먼저 상품 댓글에 관리자가 대댓글을 달 수 있는 대댓글 창을 만들어줘야 하는데
관리자 계정으로 들어갔을 때 '답글달기'를 눌러서 대댓글 창을 볼 수 있어야 하면서,
관리자 계정이 아닌 경우 '답글달기'가 보이면 안되면서,
이미 관리자가 단 대댓글이 있는 경우 관리자의 대댓글을 함께 출력해줘야 한다.

function answerlist(){
	var loginid = $("#myid").val(); //로그인 한 아이디
	var shopnum = $("#shopnum").val(); //현재 상품 번호
	
	$.ajax({
		type:"get",
		url:"shop/answerlist.jsp",
		data:{"shopnum":shopnum},
		dataType:"json",
		success:function(res){
			//출력할 변수
			var s = "";
			$.each(res,function(i,ele){
				s+="<b>"+ele.name+"</b>";
				//삭제 표시는 본인만 보이게
				var myid = ele.myid;
				if(loginid==myid){
					s+="<span class='adel glyphicon glyphicon-trash' idx='"+ele.idx+"'></span>";
				}
				
				//날짜
				s+="<span class='aday'>"+ele.writeday+"</span>";
				//내용
				s+="<pre class='acontent'>"+ele.content+"</pre>";
				
				//관리자 답글
				var answer = ele.shopanswer;
				//현재는 디폴트값 no만 들어가있음
				
				if(loginid=="admin" && answer=="no"){
					s+="<span class='abtn' idx='"+ele.idx+"'>답글달기</span><br>";
				}else if(loginid!="admin" && answer=="no"){
					s+="";
				}else{
					s+="<pre class='aanswer'>[관리자]<br>"+answer+"</pre>";
				}
				s+="<hr>";
			});
			
			$("#answerlist").html(s);
			
		}
		
		
	});
	
}
				//관리자 답글
				var answer = ele.shopanswer;
				//현재는 디폴트값 no만 들어가있음
				
				if(loginid=="admin" && answer=="no"){
					s+="<span class='abtn' idx='"+ele.idx+"'>답글달기</span><br>";
				}else if(loginid!="admin" && answer=="no"){
					s+="";
				}else{
					s+="<pre class='aanswer'>[관리자]<br>"+answer+"</pre>";
				}
				s+="<hr>";

사용자 함수의 answerlist( )에서 관리자 대댓글이 나오게 해주면 된다.
처음 사용자가 댓글을 작성할 때 관리자 대댓글(shopanswer)은 NULL값이 되지 않도록 default='no'를 넣어줬기 때문에 ele.shopanswer의 값이 'no'라면 관리자 댓글이 달리지 않은 것이다.
따라서 로그인 아이디가 admin이고 answer 값이 no라면 admin이 대댓글을 달 수 있도록 '답글달기' span이 뜬다.
로그인 아이디가 admin이 아니라 다른 아이디, 즉 사용자 아이디면서 answer이 no로 되어있으면(=관리자 대댓글이 아직 없는 상태) 다른 사용자가 댓글창을 보고 있는 것이기 때문에 '답글달기' 표시도, 관리자의 대댓글값(no)도 나오면 안되기 때문에 공백을 준다.
그 외의 경우, 로그인 아이디가 admin이 아니면서 answer이 no도 아닌 경우에는 사용자가 로그인 한 상태에서 관리자의 대댓글을 볼 수 있어야 하기 때문에 [관리자] 이름과 함께 answer 댓글 값이 들어가면 된다.

조건에 따른 코드를 작성해놓았으니, '답글달기'가 떴을 때 입력창이 나오게 하고 작성한 대댓글을 insert 해주자.

//답글 달기
	$(document).on("click","span.abtn",function(){
	
	var idx = $(this).attr("idx");
	console.log("idx");
	
	var tag = "<div class='shoptag'>";
	tag +="<textarea class='form-control acontent' id='acontent'></textarea>";
	tag +="<button class='shopsave btn btn-danger btn-xs' idx='"+idx+"'>저장</button>";
	$(this).after(tag); //답글 달기 바로 아래에 추가하기
	$(this).hide(); // '답글 달기' 버튼 안보이게
	
});

'답글달기'를 눌렀을 때 사용자가 달아놓은 댓글의 idx값이 잘 넘어오는지 확인한다.
var tag에 div를 주고 textarea와 idx값이 담긴 저장 버튼을 추가한다.
$(this).after(tag);는 $(this), 즉 '답글달기' 바로 아래에 tag를 넣는다는 의미이다.
'답글달기' 바로 아래에 tag가 실행되면(=입력창이 뜨면) $(this).hide()로 '답글달기'를 숨겨준다.

이제 admin이 대댓글을 입력하고 '저장' 버튼을 눌렀을 때 shopanswer 테이블의 shopanswer에 대댓글 내용이 들어가게 해보자.


대댓글 추가(하는 것 같지만 수정하기)

처음에 shopanswer 테이블을 만들 때 댓글은 content로, 관리자 대댓글은 shopanswer로 넣으면서 shopanswer이 null값이 되지 않으려고(사용자가 댓글 입력할 때 관리자 대댓글은 없는 상황이니까) default 값으로 'no'를 넣어놨기 때문에, 대댓글은 insert가 아니라 update를 해줘야 한다.

ShopAnswerDao.java

//샵 관리자 댓글, 이미 answer에 no값이 들어가 있으니까 update
	public void updateShopAnswer(String idx, String answer) {
		Connection conn = db.getConnection();
		PreparedStatement pstmt = null;
		
		String sql = "update shopanswer set shopanswer=? where idx=?";
		
		try {
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, answer);
			pstmt.setString(2, idx);
			
			pstmt.execute();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			db.dbClose(pstmt, conn);
		}
	}

사용자 댓글 idx에 해당하는 shopanswer의 값을 update해주는 sql문을 작성했다.
이제 이걸 처리해줄 jsp를 만들어준다.

answerupdate.jsp

<%
request.setCharacterEncoding("utf-8");

String idx = request.getParameter("idx");
String acontent = request.getParameter("acontent");

ShopAnswerDao sdao = new ShopAnswerDao();
sdao.updateShopAnswer(idx, acontent);

%>

detailpage.jsp

	//관리자 댓글 저장하기
	$(document).on("click","button.shopsave",function(){
		var idx = $(this).attr("idx");
		console.log(idx);
		
		//var acontent = $(this).prev('.acontent').val(); //id='acontent'를 안줬을 때
		var acontent = $("#acontent").val();
		
		if(acontent.legth==0){
			alert("답글을 입력하세요");
			return;
		}else{
			$.ajax({
				type:"post",
				url:"shop/answerupdate.jsp",
				data:{"idx":idx,"acontent":acontent},
				dataType:"html",
				success:function(){
					answerlist();
				}
				
			});
		}
		
	});

대댓글을 작성하고 나면


이렇게 shopanswer 테이블의 shopanswer에 대댓글이 잘 들어간 것을 볼 수 있따!!

profile
하다 보면 되겠지요..!

0개의 댓글