본문 바로가기

JAVA/JAVA-Project

[스프링] 독서실 관리 프로그램- 좌석 변경 21. 05. 27.

개요 ✨

요구사항: 이용자는 현재 이용 중인 좌석을 다른 좌석으로 바꿀 수 있다.
좌석 배치도에서 이용 중인 회원이라면 "좌석 변경하기" 버튼이 노출되고, 이 버튼을 누르면 좌석이용/변경 페이지(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으로 값을 보냈다!