Ex) 수강신청 목록 구현
- AdminTakeCourseController 클래스
- resource의 admin 아래에 takecourse 라는 패키지를 만든다.
- 컨트롤러
- 수강 관련 서비스 TakeCourseService - 매개변수 수정
<hide/>
package com.zerobase.fastlms.course.service;
import com.zerobase.fastlms.course.dto.CourseDto;
import com.zerobase.fastlms.course.model.CourseParam;
import java.util.List;
public interface TakeCourseService {
/**
* 수강 목록
*/
List<CourseDto> list(CourseParam parameter);
}
- TakeCourseParam
- TakeCourseDto
<hide/>
package com.zerobase.fastlms.course.dto;
import java.time.LocalDateTime;
public class TakeCourseDto {
Long id;
long courseId;
String userId;
long payPrice; // 결제 금액
String status; // 상태 (수강 신청, 결제 완료, 수강 신청)
LocalDateTime regDt; // 신청일
// join
String userName;
String phone;
String subject;
}
- TakeCourse 임플
<hide/>
package com.zerobase.fastlms.course.service;
import com.zerobase.fastlms.course.dto.CourseDto;
import com.zerobase.fastlms.course.dto.TakeCourseDto;
import com.zerobase.fastlms.course.mapper.CourseMapper;
import com.zerobase.fastlms.course.mapper.TakeCourseMapper;
import com.zerobase.fastlms.course.model.TakeCourseParam;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
@Service
@RequiredArgsConstructor
public class TakeCourseServiceImpl implements TakeCourseService{
private final TakeCourseMapper takeCourseMapper;
@Override
public List<TakeCourseDto> list(TakeCourseParam parameter) {
long totalCount = takeCourseMapper.selectListCount(parameter);
List<TakeCourseDto> list = takeCourseMapper.selectList(parameter);
if(!CollectionUtils.isEmpty(list)){
int i = 0;
for(TakeCourseDto x : list){
x.setTotalCount(totalCount); // 전체 개수를 하나씩 다 넣어준다.
x.setSeq(totalCount - parameter.getPageStart() - i);
++i;
}
}
return list;
}
}
- 매퍼
<hide/>
package com.zerobase.fastlms.course.mapper;
import com.zerobase.fastlms.course.dto.CourseDto;
import com.zerobase.fastlms.course.dto.TakeCourseDto;
import com.zerobase.fastlms.course.entity.TakeCourse;
import com.zerobase.fastlms.course.model.CourseParam;
import com.zerobase.fastlms.course.model.TakeCourseParam;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface TakeCourseMapper {
long selectListCount(TakeCourseParam parameter);
List<TakeCourseDto> selectList(TakeCourseParam parameter);
}
- 매퍼 xml 파일 만든다.
<hide/>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zerobase.fastlms.course.mapper.TakeCourseMapper">
<sql id="selectListWhere">
</sql>
<select id="selectListCount"
resultType="long">
SELECT COUNT(*)
FROM take_course
WHERE 1 = 1
<include refid="selectListWhere"/>
</select>
<select id="selectList"
resultType="com.zerobase.fastlms.course.dto.TakeCourseDto">
SELECT tc.*
, c.subject
, m.user_name
, m.phone
FROM take_course tc
JOIN course c ON tc.course_id = c.id
JOIN member m ON tc.user_id = m.user_id
WHERE 1 = 1
<include refid="selectListWhere"/>
ORDER BY reg_dt DESC
LIMIT #{pageStart}, #{pageEnd}
</select>
</mapper>
- 수강관리 인덱스
-> colspan: 표에서 3개의 열을 합친다.
<hide/>
<!doctype html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>관리자 화면</title>
<style>
.list table{
width: 100%;
border-collapse: collapse;
}
.list table th, .list table td{
border: solid 1px #000;
}
p.nothing {
text-align: center;
padding: 100px;
}
.list .buttons{
position: relative;
padding: 10px 0;
}
.list .buttons a , .list .buttons button{
border-width: 0;
background-color: transparent;
text-decoration: underline;
font-size: 14px;
line-height: 20px;
height: 20px;
color: #000;
cursor: pointer;
}
.list .buttons .total-count{
text-align: right;
/*position: absolute;*/
/*top: 0;*/
/*right: 0;*/
}
.pager{
margin-top: 10px;
text-align: center;
}
.pager a.on{
font-weight: bold;
color: red;
}
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script>
$(document).ready(function (){
$('#selectAll').on('click', function (){
var checked = $(this).is(':checked');
$('#dataList input[type=checkbox]').each(function (k, v){
$(this).prop('checked', checked);
});
});
$('#deleteButton').on('click', function (){
var $checked = $('#dataList input[type=checkbox]:checked');
if($checked.length < 1){
alert("삭제할 데이터를 선택해주세요.")
return false;
}
if(!confirm('선택한 데이터를 삭제하겠습니까?')){ // 체크 박스를 누르고나서 선택 삭제를 누른 경우에만 실행된다.
return false;
}
var idList = [];
$.each($checked, function (k, v){
idList.push($(this).val());
});
console.log(idList);
console.log(idList.join(','));
var $deleteForm = $('form[name=deleteForm]');
$deleteForm.find('input[name=idList]').val(idList.join(','));
$deleteForm.submit(); // 서버로 보낸다.
});
});
</script>
</head>
<body>
<!--<div th:replace="/fragments/layout.html :: fragment-admin-body-menu" ></div>-->
<h1>수강 관리</h1>
<div class="list">
<div class="buttons">
<p class="total-count">전체 <span th:text="${totalCount}"></span>개</p>
</div>
<table>
<thead>
<tr>
<th>NO</th>
<th>등록일</th>
<th>강좌명</th>
<th colspan="3">신청인</th>
<th>상태</th>
</tr>
</thead>
<tbody id ="dataList">
<tr th:each="x : ${list}">
<td th:text="${x.seq}">1</td>
<td>
<p th:text="${x.regDt}">2022.01.01</p>
</td>
<td>
<p th:text="${x.subject}">강좌명</p>
</td>
<td>
<p th:text="${x.userName}"></p>
</td>
<td>
<p th:text="${x.userId}"></p>
</td>
<td>
<p th:text="${x.phone}"></p>
</td>
<td>
<p th:if="${x.status eq 'REQ'}">수강신청</p>
<p th:if="${x.status eq 'COMPLETE'}">결제완료</p>
<p th:if="${x.status eq 'CANCEL'}">수강취소</p>
</td>
</tr>
</tbody>
</table>
<div class="pager" th:utext="${pager}"></div>
</div>
<form name="deleteForm" method="post" action="/admin/course/delete.do">
<input type="hidden" name="idList"/>
</form>
</body>
</html>
Note) 실행 결과
Ex) 수강 관리 창에서 결제완료 처리
- 리스트 페이지
<hide/>
<!doctype html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>관리자 화면</title>
<style>
.list table{
width: 100%;
border-collapse: collapse;
}
.list table th, .list table td{
border: solid 1px #000;
}
p.nothing {
text-align: center;
padding: 100px;
}
.list .buttons{
position: relative;
padding: 10px 0;
}
.list .buttons a , .list .buttons button{
border-width: 0;
background-color: transparent;
text-decoration: underline;
font-size: 14px;
line-height: 20px;
height: 20px;
color: #000;
cursor: pointer;
}
.list .buttons .total-count{
text-align: right;
/*position: absolute;*/
/*top: 0;*/
/*right: 0;*/
}
.list .row-buttons{
text-align: center;
}
.pager{
margin-top: 10px;
text-align: center;
}
.pager a.on{
font-weight: bold;
color: red;
}
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script>
$(document).ready(function (){
$('.row-buttons button').on('click', function (){
var status = $(this).val();
var id = $(this).closest('div').find('input[name=id]').val();
var msg = status == 'COMPLETE' ? '결제완료 처리하시겠습니까?' : '수강취소 처리하시겠습니까?';
if(!confirm(msg)){
return false;
}
var procFrom = $('#procFrom');
procFrom.find('input[name=id]').val(id);
procFrom.find('input[name=status]').val(status);
procFrom.submit();
});
});
</script>
</head>
<body>
<!--<div th:replace="/fragments/layout.html :: fragment-admin-body-menu" ></div>-->
<h1>수강 관리</h1>
<div class="list">
<div class="buttons">
<p class="total-count">전체 <span th:text="${totalCount}"></span>개</p>
</div>
<table>
<thead>
<tr>
<th>NO</th>
<th>등록일</th>
<th>강좌명</th>
<th colspan="3">신청인</th>
<th>상태</th>
<th>비고</th>
</tr>
</thead>
<tbody id ="dataList">
<tr th:each="x : ${list}">
<td th:text="${x.seq}">1</td>
<td>
<p th:text="${x.regDt}">2022.01.01</p>
</td>
<td>
<p th:text="${x.subject}">강좌명</p>
</td>
<td>
<p th:text="${x.userName}"></p>
</td>
<td>
<p th:text="${x.userId}"></p>
</td>
<td>
<p th:text="${x.phone}"></p>
</td>
<td>
<p th:if="${x.status eq 'REQ'}">수강신청</p>
<p th:if="${x.status eq 'COMPLETE'}">결제완료</p>
<p th:if="${x.status eq 'CANCEL'}">수강취소</p>
</td>
<td>
<div class="row-buttons" th:if="${x.status eq 'REQ'}">
<input type="hidden" name="id" th:value="${x.id}"/>
<button value="COMPLETE" type="button">결제완료 처리</button>
<button value="CANCEL" type="button">수강취소 처리</button>
</div>
</td>
</tr>
</tbody>
</table>
<div class="pager" th:utext="${pager}"></div>
</div>
<form id="procFrom" method="post" action="/admin/takecourse/status.do">
<input type="hidden" name="id"/>
<input type="hidden" name="status"/>
</form>
</body>
</html>
- 서비스
<hide/>
/**
* 수강 내용 변경
*/
ServiceResult updateStatus(Long id, String status);
- 컨트롤러 status()
<hide/>
@PostMapping("/admin/takecourse/status.do")
public String status(Model model, TakeCourseParam parameter) {
ServiceResult result = takeCourseService.updateStatus(parameter.getId(), parameter.getStatus()); // 값이 저장되면 토탈카운트가 존재한다.
if(!result.isResult()){
model.addAttribute("message", result.getMessage());
return "common/error";
}
return "redirect:/admin/takecourse/list.do";
}
- Impl
<hide/>
@Override
public ServiceResult updateStatus(Long id, String status) {
Optional<TakeCourse> optionalTakeCourse = takeCourseRepository.findById(id);
if(!optionalTakeCourse.isPresent()){
return new ServiceResult(false, "수강 정보가 존재하지 않습니다.");
}
TakeCourse takeCourse = optionalTakeCourse.get();
takeCourse.setStatus(status);
takeCourseRepository.save(takeCourse);
return new ServiceResult(true);
}
- 서비스 result
<hide/>
package com.zerobase.fastlms.course.model;
import lombok.Data;
@Data
public class ServiceResult{
boolean result;
String message;
public ServiceResult(boolean result, String message) {
this.result = result;
this.message = message;
}
}
Note) 실행 결과 - 하나는 결제 완료, 하나는 수강 취소 누른 상황
Ex) 수강 관리 페이지 등록일 날짜 포맷
- Dto에 게터 추가
<hide/>
public String getRegDtText(){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm");
return regDt != null ? regDt.format(formatter) : "";
}
- 리스트 페이지
<hide/>
<tr th:each="x : ${list}">
<td th:text="${x.seq}">1</td>
<td>
<p th:text="${x.regDtText}">2022.01.01</p>
</td>
<td>
<p th:text="${x.subject}">강좌명</p>
</td>
<td>
<p th:text="${x.userName}"></p>
</td>
<td>
<p th:text="${x.userId}"></p>
</td>
<td>
<p th:text="${x.phone}"></p>
</td>
<td>
<p th:if="${x.status eq 'REQ'}">수강신청</p>
<p th:if="${x.status eq 'COMPLETE'}">결제완료</p>
<p th:if="${x.status eq 'CANCEL'}">수강취소</p>
</td>
<td>
<div class="row-buttons" th:if="${x.status eq 'REQ'}">
<input type="hidden" name="id" th:value="${x.id}"/>
<button value="COMPLETE" type="button">결제완료 처리</button>
<button value="CANCEL" type="button">수강취소 처리</button>
</div>
</td>
</tr>
Note) 실행 결과
'Spring Projcect > 학습 관리 시스템 & 백오피스 구축' 카테고리의 다른 글
Chapter 17. 강좌 관리 (0) | 2022.08.26 |
---|---|
Chapter 16. 회원 정보 수정 (0) | 2022.08.25 |
Chapter 14. 스프링 부트(Spring Boot) (0) | 2022.08.24 |
Chapter 13. 강좌 목록 (0) | 2022.08.23 |
Chapter 12. 카테고리 화면 (0) | 2022.08.22 |