9:15경 학원 도착
<9:30 1교시>
댓글 작성 Dto, Dao,
package test.post.dto;
public class CommentDto {
private long num;
private String writer;
private String content;
private String targetWriter;
private long postNum;
private long parentNum;
private String deleted;
private String createdAt;
private String profileImage;
//페이징 처리 위한 필드
private int startRowNum;
private int endRowNum;
public long getNum() {
return num;
}
public void setNum(long num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTargetWriter() {
return targetWriter;
}
public void setTargetWriter(String targetWriter) {
this.targetWriter = targetWriter;
}
public long getPostNum() {
return postNum;
}
public void setPostNum(long postNum) {
this.postNum = postNum;
}
public long getParentNum() {
return parentNum;
}
public void setParentNum(long parentNum) {
this.parentNum = parentNum;
}
public String getDeleted() {
return deleted;
}
public void setDeleted(String deleted) {
this.deleted = deleted;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getProfileImage() {
return profileImage;
}
public void setProfileImage(String profileImage) {
this.profileImage = profileImage;
}
public int getStartRowNum() {
return startRowNum;
}
public void setStartRowNum(int startRowNum) {
this.startRowNum = startRowNum;
}
public int getEndRowNum() {
return endRowNum;
}
public void setEndRowNum(int endRowNum) {
this.endRowNum = endRowNum;
}
}
jsp가 ${}를 해석하지 않게 \${}로 HTML로 출력되게
<%@page import="test.user.dto.SessionDto"%>
<%@page import="test.post.dao.PostDao"%>
<%@page import="test.post.dto.PostDto"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
//검색조건이 있는지 읽어와 본다.
String condition=request.getParameter("condition");
String keyword=request.getParameter("keyword");
String findQuery=null;
//있다면 dto 에 해당 정보를 담는다.
PostDto findDto=new PostDto();
if(condition != null){
//findDto=new PostDto();
findDto.setCondition(condition);
findDto.setKeyword(keyword);
findQuery="&condition="+condition+"&keyword="+keyword;
}
//자세히 보여줄 글의 번호를 읽어온다.
int num=Integer.parseInt(request.getParameter("num"));
findDto.setNum(num);
//DB 에서 해당 글의 정보를 얻어와서
PostDto dto=PostDao.getInstance().getData(findDto);
//세션 아이디를 읽어와서
String sessionId=session.getId();
//이미 읽었는지 여부를 얻어낸다
boolean isReaded=PostDao.getInstance().isReaded(num, sessionId);
if(!isReaded){
//글 조회수도 1 증가 시킨다
PostDao.getInstance().addViewCount(num);
//이미 읽었다고 표시한다.
PostDao.getInstance().insertReaded(num, sessionId);
}
request.setAttribute("dto", dto);
request.setAttribute("findDto", findDto);
request.setAttribute("findQuery", findQuery);
//응답한다
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/post/view.jsp</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
#contents {
margin-top: 20px;
padding: 20px;
background-color: #fefefe;
border-radius: 10px;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
border: 1px solid #ddd;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
#contents:hover {
transform: translateY(-5px);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
}
#content{
width: 100%;
height: 300px;
}
/* 댓글 프로필 이미지를 작은 원형으로 만든다. */
.profile-image{
width: 50px;
height: 50px;
border: 1px solid #cecece;
border-radius: 50%;
}
/* ul 요소의 기본 스타일 제거 */
.comments ul{
padding: 0;
margin: 0;
list-style-type: none;
}
/* .reply_icon 을 li 요소를 기준으로 배치 하기 */
.comments li{
position: relative;
}
.comments .reply-icon{
position: absolute;
top: 1rem;
left: 1rem;
color: red;
}
/* 대댓글을 들여 쓰기 위한 클래스 */
.indent{
padding-left: 50px;
}
/* 답글 아이콘은 일단 보이지 않게 */
.reply-icon{
display: none;
}
.comment-form, .re-insert-form, .update-form{
display: flex;
}
.comment-form textarea, .re-insert-form textarea, .update-form textarea{
height: 100px;
flex-grow: 1;
}
.comment-form button, .re-insert-form button, .update-form button{
flex-basis: 100px;
}
/* 대댓글폼은 일단 숨겨 놓는다 */
.re-insert-form, .update-form{
display: none;
}
/* 댓글 출력 디자인 */
.comments pre {
display: block;
padding: 9.5px;
margin: 5px 0;
font-size: 13px;
line-height: 1.42857143;
color: #333333;
word-break: break-all;
word-wrap: break-word;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
}
.loader{
/* 로딩 이미지를 가운데 정렬하기 위해 */
text-align: center;
/* 일단 숨겨 놓기 */
display: none;
}
/* 회전하는 키프레임 정의 */
@keyframes rotateAni{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
/* 회전하는 키프레임을 로더 이미지에 무한 반복 시키기 */
.loader svg{
animation: rotateAni 1s ease-out infinite;
}
body{
padding-bottom: 200px;
}
</style>
</head>
<body>
<div class="container">
<c:if test="${dto.prevNum ne 0}">
<a href="view.jsp?num=${dto.prevNum}${findQuery}">이전글</a>
</c:if>
<c:if test="${dto.nextNum ne 0}">
<a href="view.jsp?num=${dto.nextNum}${findQuery}">다음글</a>
</c:if>
<c:if test="${not empty findDto.condition}">
<p>
<strong>${findDto.condition }</strong> 조건
<strong>${findDto.keyword }</strong>검색어로 검색된 내용 자세히보기
</p>
</c:if>
<h3>글 상세 보기</h3>
<table class="table table-bordered">
<tr>
<th>글번호</th>
<td>${dto.num }</td>
</tr>
<tr>
<th>작성자</th>
<td>${dto.writer }</td>
</tr>
<tr>
<th>제목</th>
<td>${dto.title }</td>
</tr>
<tr>
<th>조회수</th>
<td>${dto.viewCount }</td>
</tr>
<tr>
<th>작성일</th>
<td>${dto.createdAt }</td>
</tr>
<tr>
<th>수정일</th>
<td>${dto.updatedAt }</td>
</tr>
<tr>
<td colspan="2">
<div id="contents">${dto.content }</div>
</td>
</tr>
</table>
<%-- 만일 글 작성자가 로그인된 아이디와 같다면 수정, 삭제 링크를 제공한다. --%>
<c:if test="${dto.writer eq sessionDto.userName }">
<a class="btn btn-outline-success btn-sm" href="${pageContext.request.contextPath }/post/protected/edit.jsp?num=${dto.num }">수정</a>
<a class="btn btn-outline-danger btn-sm" href="javascript:" onclick="deleteConfirm()">삭제</a>
<script>
function deleteConfirm(){
const isDelete=confirm("이 글을 삭제 하겠습니까?");
if(isDelete){
//javascript 를 이용해서 페이지 이동 시키기
location.href="${pageContext.request.contextPath }/post/protected/delete.jsp?num=${dto.num}";
}
}
</script>
</c:if>
<h4>댓글을 입력해 주세요</h4>
<!-- 원글에 댓글을 작성할 폼 -->
<form class="comment-form" action="protected/comment-insert.jsp" method="post">
<!-- 원글의 글번호가 댓글의 ref_group 번호가 된다. -->
<input type="hidden" name="postNum" value="${dto.num}"/>
<!-- 원글의 작성자가 댓글의 대상자가 된다. -->
<input type="hidden" name="targetWriter" value="${dto.writer}"/>
<textarea name="content">${empty sessionDto ? '댓글 작성을 위해 로그인이 필요합니다' : ''}</textarea>
<button type="submit">등록</button>
</form>
<!-- 댓글 목록 -->
<div class="comments">
<ul>
</ul>
</div>
</div>
<script>
//로그인된 사용자의 이름
const userName="${sessionDto.userName}";
document.querySelector(".comment-form").addEventListener("submit", (e)=>{
//폼 제출 막기
e.preventDefault();
//폼에 작성된 내용을 이용해서 query 문자열을 얻어낸다
const formData=new FormData(e.target);
const queryString = new URLSearchParams(formData).toString();
//fetch 함수를 이용해서 댓글 정보를 페이지 전환없이 서버에 전송함.
fetch("protected/comment-insert.jsp",{
method:"POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body:queryString
})
.then(res=>res.json())
.then(comment=>{
//저장된 댓글 정보가 응답됨
console.log(comment);
//li 요소를 만들어서
const li = document.createElement("li");
li.classList.add(comment.num !== comment.parentNum ? "indent" : "not");
// 프로필 이미지 처리
const profileImage = comment.profileImage
? `<img class="profile-image" src="/upload/${comment.profileImage}" alt="Profile Image">`
: `<svg class="profile-image" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M11 6a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
<path fill-rule="evenodd" d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm8-7a7 7 0 0 0-5.468 11.37C3.242 11.226 4.805 10 8 10s4.757 1.225 5.468 2.37A7 7 0 0 0 8 1z"/>
</svg>`;
//li 요소 안에 dl을 출력
li.innerHTML=`
<dl>
<dt>
\${profileImage}
<!-- 댓글 작성자 -->
<span>\${comment.writer}</span>
<!-- 댓글 대상자를 조건부로 출력 (대댓글에만 출력) -->
\${comment.num != comment.parentNum ? '@'+comment.targetWriter : ''}
<!-- 댓글 작성일자 -->
<small>\${comment.createdAt}</small>
<!-- 답글 링크 -->
<a data-num="\${comment.num}" class="reply-link" href="javascript:">답글</a>
<!-- 로그인된 유저가 쓴 댓글일 경우 수정, 삭제 링크를 제공한다 -->
</dt>
<dd>
<pre id="content\${comment.num}">\${comment.content}</pre>
</dd>
</dl>
`;
document.querySelector(".comments ul").append(li);
});
});
</script>
</body>
</html>
<10:30 2교시>
<%@page import="test.user.dto.SessionDto"%>
<%@page import="com.google.gson.Gson"%>
<%@page import="test.post.dto.CommentDto"%>
<%@page import="test.post.dao.CommentDao"%>
<%@ page language="java" contentType="application/json; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//세션에 저장된 정보를 이용해서
SessionDto sessionDto=(SessionDto)session.getAttribute("sessionDto");
//댓글 작성자의 username을 얻어냄
String writer=sessionDto.getUserName();
//fetch를 이용해서 전송되는 정보를 추출한다
long postNum = Long.parseLong(request.getParameter("postNum"));
String targetWriter = request.getParameter("targetWriter");
String content = request.getParameter("content");
//원글의 댓글일 경우 parentNum 이 넘어 오지 않아서 null 이다.
String strParentNum = request.getParameter("parentNum");
long parentNum = 0;
CommentDao dao=CommentDao.getInstance();
//저장할 댓글의 글번호를 미리 얻어낸다.
long num=dao.getSequence();
//만일 parentNum 이 넘어오지 않으면
if(strParentNum == null){
parentNum=num; // 댓글의 글번호가 parentNum 이 된다.
}else{
//넘어 온다면 넘어오는 값을 parentNum 으로 설정한다.
parentNum=Long.parseLong(strParentNum);
}
//저장할 댓글 정보
CommentDto dto=new CommentDto();
dto.setNum(num);
dto.setWriter(writer);
dto.setPostNum(postNum);
dto.setTargetWriter(targetWriter);
dto.setContent(content);
dto.setParentNum(parentNum);
boolean isSuccess=dao.insert(dto);
if(!isSuccess){
response.sendError(500, "댓글 추가 실패!");
return;
}
//DB 에 저장된 정보를 다시 읽어오기
dto=dao.getData(num);
//Gson 객체를 이용해서 CommentDto에 저장된 정보를 json 문자열로 변환해서 응답함
Gson gson=new Gson();
%>
<%=gson.toJson(dto) %>
10:47 오전 진도 끝
프로젝트 시작
if (year==-1&& month==-1 && storenum==-1&&listall != null && !listall.isEmpty())
else if(year!=-1&&month=-1&&storenum==-1&&listyear!=null&&!listall.isEmpty)
하ㅏ......
<%@page import="java.util.ArrayList"%>
<%@page import="test.dao.Com1SaleDao"%>
<%@page import="test.dto.Com1SaleDto"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//현재 페이지 위치를 세션 영역에 저장 (관리자 전용 네비바에 활성 상태 표시 위함)
session.setAttribute("current_page", "salemanage");
//로그인 상태 표시 : 세션 영역에서 접속 계정 정보 가져오기
String comname = (String)session.getAttribute("comname");
String ename = (String)session.getAttribute("ename");
Com1SaleDao saledao = Com1SaleDao.getInstance();
Com1SaleDao.
int year=-1;
int month=-1;
/*
1. 아무것도 안넘어오는 경우
2. year 만 넘어오는 경우
3. year , month 만 넘어오는 경우
*/
String strYear=request.getParameter("year");
String strMonth=request.getParameter("month");
/*
if(!strYear.isEmpty() && strMonth.isEmpty() ){ //년 만 넘어오는 경우
System.out.println(strYear);
year = Integer.parseInt(strYear);
list=saledao.getListStoreYearlySales(year);
}else(!strYear.isEmpty() && !strMonth.isEmpty()){//년, 월 만 넘어오는 경우
year = Integer.parseInt(strYear);
month = Integer.parseInt(strMonth);
list=saledao.getListStoreMonthlySales(year, month);
}
*/
//Com1SaleDto dtomonth = saledao.getStoreMonth(storenum, year, month);
//Com1SaleDto dtoyear = saledao.getStoreYear(storenum, year);
//Com1Dao com1Dao = Com1Dao.getInstance();
//String storenumParam = request.getParameter("storenum");
//int storenum = -1;
//List<Com1SaleDto> storeList = null;
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<jsp:include page="/include/resource.jsp"></jsp:include>
<style>
.tab-button {
padding: 10px 20px;
cursor: pointer;
font-weight: bold;
background-color: #f1f1f1;
border: 1px solid #ddd;
transition: background-color 0.3s ease;
display: inline-block;
}
.active-tab {
background-color: #dcdcdc;
border-bottom: 2px solid #999;
}
.tab-content {
padding: 20px;
background-color: #fff;
border-top: 1px solid #ddd;
display: none;
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
table-layout: fixed;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: center;
background-color: #fff;
font-size: 16px;
white-space: normal;
overflow-wrap: break-word;
text-overflow: ellipsis;
word-wrap: break-word;
}
th {
background-color: #f5f5f5;
font-weight: bold;
color: #333;
border-bottom: 2px solid #bbb;
}
tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
tbody tr:hover {
background-color: #eef;
}
label {
margin-right: 10px; /* 라벨과 입력란 사이의 간격 */
}
input {
margin-bottom: 20px; /* 입력란 사이의 간격 */
padding: 8px; /* 입력란에 여백 추가 */
}
</style>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container">
<p>
<%--> 회사코드 :
<%=comid %>
회사번호 :
<%=comname %>
사원번호 :
<%=empno %>
역할 :
<%=role %>
이름 :
<%=ename %> --%>
</p>
</div>
<div class="container flex-fill" style="width: 100%; margin-top: 50px;">
<form action="saleview.jsp" method="get">
<label for="year">연도 입력: </label>
<input type="number" id="year" name="year" placeholder="연도를 입력하세요">
<label for="month">월 입력: </label> <input type="number" id="month" name="month" placeholder="월을 입력하세요">
<label for="storenum">지점 입력: </label> <input type="number" id="storenum" name="storenum" placeholder="지점을 입력하세요">
<button type="submit" id="submitbtn">조회</button>
</form>
<%= %>
<div class="tab-content"
style="padding: 20px; background-color: #fff; border-top: 1px solid #ddd; display: block;">
<table>
<thead>
<tr>
<th>호점</th>
<th>날짜</th>
<th>매출</th>
</tr>
</thead>
<tbody>
<%for (Com1SaleDto tmp : list) { %>
<tr>
<td><%=tmp.getStoreNum() %></td>
<td><%=tmp.getSalesDate() %></td>
<td><%=tmp.getDailySales()%></td>
</tr>
<%}%>
<tr>
<td>총합</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
<%@ include file="/include/footer.jsp"%>
<script>
</script>
</body>
</html>
<%@page import="test.dao.Com1SaleDao"%>
<%@page import="test.dao.Com1Dao"%>
<%@page import="test.dto.Com1Dto"%>
<%@page import="test.dto.Com1SaleDto"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//현재 페이지 위치를 세션 영역에 저장 (관리자 전용 네비바에 활성 상태 표시 위함)
session.setAttribute("current_page", "salemanage");
//로그인 상태 표시 : 세션 영역에서 접속 계정 정보 가져오기
String comname = (String)session.getAttribute("comname");
String ename = (String)session.getAttribute("ename");
Com1SaleDao saledao = Com1SaleDao.getInstance();
int year=-1;
int month=-1;
int storenum=-1;
/*
1. 아무것도 안넘어오는 경우
2. year 만 넘어오는 경우
3. year , month 만 넘어오는 경우
*/
String strYear=request.getParameter("year");
String strMonth=request.getParameter("month");
String strStorenum=request.getParameter("storenum");
List<Integer> storenums = Com1Dao.getInstance().getStoreNumList();
List<Com1SaleDto> list=null;
if(strYear != null &&strMonth == null && strStorenum == null){ //년 만 넘어오는 경우
year = Integer.parseInt(strYear);
list=saledao.getListStoreYearlySales(year);
}else if(strYear != null &&strMonth != null && strStorenum == null){//년, 월 만 넘어오는 경우
year = Integer.parseInt(strYear);
month = Integer.parseInt(strMonth);
list=saledao.getListStoreMonthlySales(year, month);
}else{//아무것도 안넘어오는 경우
list=saledao.getListAll();
}
//Com1SaleDto dtomonth = saledao.getStoreMonth(storenum, year, month);
//Com1SaleDto dtoyear = saledao.getStoreYear(storenum, year);
//Com1Dao com1Dao = Com1Dao.getInstance();
//String storenumParam = request.getParameter("storenum");
//int storenum = -1;
//List<Com1SaleDto> storeList = null;
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
<jsp:include page="/include/resource.jsp"></jsp:include>
<style>
.tab-button {
padding: 10px 20px;
cursor: pointer;
font-weight: bold;
background-color: #f1f1f1;
border: 1px solid #ddd;
transition: background-color 0.3s ease;
display: inline-block;
}
.active-tab {
background-color: #dcdcdc;
border-bottom: 2px solid #999;
}
.tab-content {
padding: 20px;
background-color: #fff;
border-top: 1px solid #ddd;
display: none;
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
table-layout: fixed;
}
th, td {
border: 1px solid #ddd;
padding: 12px;
text-align: center;
background-color: #fff;
font-size: 16px;
white-space: normal;
overflow-wrap: break-word;
text-overflow: ellipsis;
word-wrap: break-word;
}
th {
background-color: #f5f5f5;
font-weight: bold;
color: #333;
border-bottom: 2px solid #bbb;
}
tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
tbody tr:hover {
background-color: #eef;
}
label {
margin-right: 10px; /* 라벨과 입력란 사이의 간격 */
}
input {
margin-bottom: 20px; /* 입력란 사이의 간격 */
padding: 8px; /* 입력란에 여백 추가 */
}
</style>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="container">
<p>
<%--> 회사코드 :
<%=comid %>
회사번호 :
<%=comname %>
사원번호 :
<%=empno %>
역할 :
<%=role %>
이름 :
<%=ename %> --%>
</p>
</div>
<div class="container flex-fill" style="width: 100%; margin-top: 50px;">
<form action="saleview.jsp">
<label for="year">연도 입력: </label> <input type="number" id="year"
name="year" placeholder="연도를 입력하세요"> <label for="year">월
입력: </label> <input type="number" id="month" name="month"
placeholder="월을 입력하세요"> <label for="storenum">지점 입력: </label> <input
type="number" id="storenum" name="storenum" placeholder="지점을 입력하세요">
<button type="submit" id="submitbtn">조회</button>
</form>
<div class="tab-content"
style="padding: 20px; background-color: #fff; border-top: 1px solid #ddd; display: block;">
<table>
<%
int totalSales = 0; // 총합을 저장할 변수 선언
%>
<thead>
<tr>
<th>호점</th>
<th>날짜</th>
<th>매출</th>
</tr>
</thead>
<tbody>
<% if(list != null && !list.isEmpty()) {
for (Com1SaleDto tmp : list) { %>
<tr>
<td><%=tmp.getStoreNum()%></td>
<td><%=tmp.getSaleDate()%></td>
<td><%=tmp.getDailySales()%></td>
</tr>
<%
totalSales += tmp.getDailySales(); // 매출을 합산
}
%>
<tr>
<td>총합</td>
<td><%=totalSales%></td>
<!-- 총합 출력 -->
</tr>
<%} %>
</tbody>
</table>
</div>
</div>
<%@ include file="/include/footer.jsp"%>
<script>
</script>
</body>
</html>
'자바풀스택 과정 > 자바 풀 스택 : 수업내용정리' 카테고리의 다른 글
자바 풀 스택 2/11 하루 기록 052 (0) | 2025.02.11 |
---|---|
자바 풀 스택 2/10 하루 기록 051 (0) | 2025.02.10 |
자바 풀 스택 2/6 하루 기록 049 (0) | 2025.02.06 |
자바 풀 스택 2/5 하루 기록 048 (1) | 2025.02.05 |
자바 풀 스택 2/4 하루 기록 047 (1) | 2025.02.04 |