개요 ✨
요구사항: 이용자는 현재 이용 중인 좌석을 다른 좌석으로 바꿀 수 있다.
좌석 배치도에서 이용 중인 회원이라면 "좌석 변경하기" 버튼이 노출되고, 이 버튼을 누르면 좌석이용/변경 페이지(changeSeat.jsp)로 이동한다.
빈 좌석 중 원하는 좌석의 변경 버튼을 누르면 해당 좌석으로 이전된다.
🍄 VO
SeatVO, RegInfoVO 사용.
SeatVO.java
@Data
public class SeatVO {
private int sno; // 좌석 번호
private String name; // 좌석 이름(고정석,자유석)
private boolean status; // 좌석 이용 상태
private Long userNo; // 회원 번호
}
RegInfoVO.java
@Data
public class RegInfoVO {
private Long regNo; // 등록번호
private Long userNo; // 회원번호
private String userName; // 회원 이름
private Date startDate; // 시작일
private Date endDate; // 종료일
private int fno; // 요금제 번호
private Integer seatNo; // 좌석번호
private Integer lockerNo; // 사물함번호
private String feeName; // 좌석(사물함) 기간명
private LockerVO locker; // 사물함 정보 불러오기
private SeatVO seat; // 좌석 정보 불러오기
private Integer period; // 기간
}
🥕 Mapper
RegInfoMapper.java 일부
public interface RegInfoMapper {
// 좌석 변경 (이용 등록 정보 수정)
public int updateSeat(RegInfoVO infoVO);
}
RegInfoMapper.xml 일부
<!-- 좌석 변경 (이용 등록 정보 수정) -->
<update id="updateSeat">
UPDATE TBL_REGINFO SET
SEATNO = #{seatNo}
WHERE USERNO = #{userNo}
</update>
RegInfoMapperTests.java 일부
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/security-context.xml"})
@Log4j
public class RegInfoMapperTests {
@Test
public void updateSeatTest() {
RegInfoVO infoVO = new RegInfoVO();
infoVO.setSeatNo(2);
infoVO.setUserNo(156L);
mapper.updateSeat(infoVO);
}
}
🔶 이용 등록 정보 테이블(TBL_REGINFO)의 데이터를 수정하는 것.
🔶 이 테이블뿐만 아니라 좌석 테이블(TBL_SEAT)의 데이터도 함께 수정되어야 하기 때문에 추후 service에서 트랜젝션 처리할 예정이다.
SeatMapper.java 일부
public interface SeatMapper {
//좌석 변경 시 새 좌석 상태 변경(이용중)
void updateNewSeat(SeatVO seatVO);
//좌석 변경 시 기존 좌석 상태 변경(빈좌석)
void updateOldSeat(SeatVO seatVO);
}
SeatMapper.xml 일부
<!-- 좌석 변경 시 새 좌석 상태를 이용중으로 변경 -->
<update id="updateNewSeat">
UPDATE TBL_SEAT SET
STATUS = 1,
USERNO = #{userNo}
WHERE SNO = (
SELECT SEATNO FROM TBL_REGiNFO WHERE USERNO = #{userNo}
)
</update>
<!-- 좌석 변경 시 기존 좌석 상태를 빈좌석으로 변경 -->
<update id="updateOldSeat">
UPDATE TBL_SEAT SET STATUS = 0, USERNO = 0
WHERE SNO = #{sno}
</update>
SeatMapperTests.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/security-context.xml"})
@Log4j
public class SeatMapperTests {
@Test
public void updateNewSeatTest() {
SeatVO seatVO = new SeatVO();
seatVO.setUserNo(156L);
mapper.updateNewSeat(seatVO);
}
@Test
public void updateOldSeatTest() {
SeatVO seatVO = new SeatVO();
seatVO.setSno(6);
mapper.updateOldSeat(seatVO);
}
}
🍏 Service
RegInfoService.java 일부
public interface RegInfoService {
// 좌석 변경 (이용 등록 정보 수정)
void changeSeat(RegInfoVO infoVO, SeatVO seatVO);
}
RegInfoServiceImpl.java 일부
@Service
@Log4j
@AllArgsConstructor
public class RegInfoServiceImpl implements RegInfoService{
private RegInfoMapper regMapper;
private SeatMapper seatMapper;
private LockerMapper lockerMapper;
/**
* 이용자가 좌석을 변경하는 메소드
*/
@Override
@Transactional
public void changeSeat(RegInfoVO infoVO, SeatVO seatVO) {
regMapper.updateSeat(infoVO);
/* 변경할 좌석과 기존 이용 좌석의 상태 값을 바꾸는 작업 */
seatMapper.updateNewSeat(seatVO);
seatMapper.updateOldSeat(seatVO);
}
}
RegInfoServiceTests.java 일부
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/security-context.xml"})
@Log4j
public class RegInfoServiceTests {
@Autowired
private RegInfoService service;
@Test
public void changeSeatTest() {
RegInfoVO infoVO = new RegInfoVO();
infoVO.setSeatNo(6);
infoVO.setUserNo(156L);
SeatVO seatVO = new SeatVO();
seatVO.setUserNo(infoVO.getUserNo());
seatVO.setSno(2);
service.changeSeat(infoVO, seatVO);
}
}
🔶 이 테스트 코드 작성할 때 살짝 헤맸다.
🔶 작성하다 보니 changeSeat()의 파라미터가 하나로는 안 돼서 인터페이스부터 다시 수정했었다.
🍍controller
ItemController.java 일부
@Controller
@Log4j
@RequestMapping("/item/*")
@AllArgsConstructor
public class ItemController {
private SeatService seatService;
private LockerService lockerService;
private RegInfoService regInfoService;
@GetMapping("changeSeat")
public void changeSeat(Model model) {
log.info("좌석 변경 페이지..");
model.addAttribute("seatList", seatService.getAllList());
model.addAttribute("regList", regInfoService.getAllList());
}
@PostMapping("changeSeat")
public String changeSeatP(RegInfoVO infoVO, SeatVO seatVO, RedirectAttributes rttr) {
regInfoService.changeSeat(infoVO, seatVO);
rttr.addFlashAttribute("msg", "좌석 변경이 완료되었습니다.");
return "redirect:/item/seat";
}
ItemControllerTests.java 일부
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml",
"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml",
"file:src/main/webapp/WEB-INF/spring/security-context.xml"})
@Log4j
@WebAppConfiguration
public class ItemControllerTests {
@Autowired
private WebApplicationContext ctx;
public MockMvc mvc;
@Before
public void setup(){
mvc = MockMvcBuilders.webAppContextSetup(ctx).build();
}
@Test
public void changeSeatPTest() throws Exception {
log.info(
mvc.perform(MockMvcRequestBuilders.post("/item/changeSeat")
.param("seatNo", "2") // 변경할 좌석
.param("sno", "6") // 기존 이용 좌석
.param("userNo", "156") // 해당 이용자
)
);
}
}
🍎 jsp (부트스트랩4 이용)
changeSeat.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<jsp:include page="../includes/header_.jsp" />
<!-- Home -->
<div class="home">
<div class="home_background_container prlx_parent">
<div class="home_background prlx" style="background-image:url(${pageContext.request.contextPath}/resources/images/news_background.jpg)"></div>
</div>
<div class="home_content">
<h1>좌석 이용/변경</h1>
</div>
</div>
<!-- News -->
<div class="news">
<form method="post">
<div class="container">
<div class="d-flex justify-content-center mb-3"><h1>고정석</h1></div>
<sec:authorize access="isAuthenticated()">
<sec:authentication property="principal" var="member"/>
<div class="mb-3">
<c:forEach items="${regList}" var="reg">
<c:if test="${reg.userNo == member.vo.userNo}">
<fmt:formatDate var="formatEndDate" value="${reg.endDate}" pattern="yyyy.MM.dd"/>
<span>나의 만료일: ${formatEndDate}, 현재 이용중인 좌석: ${reg.seatNo}</span>
<a href="${pageContext.request.contextPath}/payment/exPayment" class="btn btn-sm btn-outline-warning mx-2">연장하기</a>
<input type="hidden" name="sno" value="${reg.seatNo}"> <!-- 기존 좌석 번호 -->
</c:if>
</c:forEach>
</div>
</sec:authorize>
<div class="row">
<div id="room1" class="border px-5 py-5">
<div class="card-deck">
<c:forEach items="${seatList}" var="seat" begin="0" end="3">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 0${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="0" end="3">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 0${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
<div class="card-deck mt-4">
<c:forEach items="${seatList}" var="seat" begin="4" end="7">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 0${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="4" end="7">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 0${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
<div class="card-deck mt-4">
<c:forEach items="${seatList}" var="seat" begin="8" end="11">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="8" end="11">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
</div>
<!-- <script src="/resources/js/regInfo.js"> /* 등록 ajax 부분 */</script> -->
<div id="room2" class="border px-5 py-5 ml-3">
<div class="card-deck">
<c:forEach items="${seatList}" var="seat" begin="12" end="15">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="12" end="15">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-target="#myModal" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
<div class="card-deck mt-4">
<c:forEach items="${seatList}" var="seat" begin="16" end="19">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="16" end="19">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
</div> <!-- end room2 -->
</div> <!-- end row -->
<!-- 자유석 -->
<div class="d-flex justify-content-center mt-5"><h1>자유석</h1></div>
<div id="room3" class="border px-5 py-5 mr-3 mt-3">
<div class="card-deck">
<c:forEach items="${seatList}" var="seat" begin="20" end="27">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="20" end="27">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-target="#myModal" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
<!-- -->
<div class="card-deck mt-4">
<c:forEach items="${seatList}" var="seat" begin="28" end="35">
<c:if test="${seat.status == true}">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<p class="card-text">이용중</p>
</div>
</div>
</c:if>
</c:forEach>
<c:forEach items="${seatList}" var="seat" begin="28" end="35">
<c:if test="${seat.status == false}">
<div class="card bg-muted">
<div class="card-body text-center">
<p class="card-text">좌석 ${seat.sno}</p>
<p class="card-text">${seat.name}</p>
<button type="button" class="sRegBtn btn btn-sm btn-light" data-target="#myModal" data-sno="${seat.sno}" value="${seat.sno}">변경</button>
</div>
</div>
</c:if>
</c:forEach>
</div>
</div> <!-- end room3 -->
<sec:authorize access="isAuthenticated()">
<sec:authentication property="principal" var="member"/>
<input type="hidden" name="userNo" value="${member.vo.userNo}"> <!-- 유저번호 -->
</sec:authorize>
</div>
</form>
</div> <!-- news 끝 -->
<script>
$(function() { //ready
/* 각 좌석의 변경 버튼을 눌렀을 때 */
$(".sRegBtn").click(function() {
var result = confirm($(this).attr('value') + "번 좌석으로 변경하시겠습니까?");
var sno = $(this).data("sno"); /* 등록 버튼에 해당하는 좌석 번호 */
var user = '${member.vo.userNo}';
var str = '<input type="hidden" name="seatNo" value="'+ sno +'">'; // 변경할 좌석
if(user =='') {
alert("로그인 후 이용하실 수 있습니다.");
return false;
} else { // 로그인 된 상태
if(result) {
$(this).closest("form").append(str).submit();
var msg = '${msg}';
if(msg === '좌석 변경이 완료되었습니다.') {
alert("좌석 변경이 완료되었습니다.");
}
}
}
});
})
</script>
<jsp:include page="../includes/footer.jsp" />
🔶 해당 jsp에서 보내야 할 값은 현재 이용 중인 좌석 번호와 변경할 좌석 번호, 그리고 회원 번호이다. 이용 중인 좌석 번호는 상단에서, 회원 번호는 <script>
직전에서, 그리고 변경할 좌석 번호는 스크립트로 hidden으로 값을 보냈다!
'JAVA > JAVA-Project' 카테고리의 다른 글
[스프링] 독서실 관리 프로그램- 관리자 페이지에서의 좌석 등록 1 21. 05. 31. (0) | 2021.05.31 |
---|---|
테이블 3개 조인하기. (관리자-좌석관리에서 좌석 배치도에 정보 입력 하기 위함) 21. 05. 29. (0) | 2021.05.29 |
[스프링] 독서실 관리 프로그램- 이용 기간 연장하기 21. 06. 02. 수정 (0) | 2021.05.26 |
[스프링] 독서실 관리 프로그램 1인 1좌석 자바스크립트 21. 05. 26. (0) | 2021.05.26 |
[스프링] 좌석 만료일이 지났을 때 처리 21. 05. 24. (0) | 2021.05.24 |