hyeonga_code

reProject_26_관리자 상품관리 페이지 본문

Project_WEATHERWEAR

reProject_26_관리자 상품관리 페이지

hyeonga 2024. 1. 23. 06:59
반응형

2024.01.18

사용한 부트스트랩: ADMINLTE3

 

상품 관리 페이지 작업
 -- JAVA
> com.w2.admin.controller
	- ProductController.java

> com.w2.product
	- ProductVO.java
	- ProductPriceVO.java
	- OptionVO.java
	- ProductDAO.java

> com.w2.product.service
	- ProductService.java (interface)
	- ProductServiceImpl.java
    
-- RESOURCE
> src/main/resources
	- mybatis-config.xml

> src/main/resources/mappings
	- product-mapping.xml

 

1. 페이지 호출 작업

1) ProductController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.w2.admin.controller;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
import com.w2.product.service.ProductService;
import com.w2.util.Search;
 
@Controller
public class ProductController {
    @Autowired
    private ProductService productService;
    
    /**
     * 상품 목록 가져오기
     * @param model
     * @return
     */
    @RequestMapping("productList.mdo")
    public String productList(Model model, @RequestParam(required = false, defaultValue = "1"int page,
            @RequestParam(required = false, defaultValue = "1"int range, @RequestParam(required = false, defaultValue = "productName"String searchType,
            @RequestParam(required = falseString keyword, @ModelAttribute("search") Search search) {
        
        // 검색
        model.addAttribute("search", search);
        search.setSearchType(searchType);
        search.setKeyword(keyword);
        
        // 전체 게시글 개수
        int listCnt = productService.getProductListCnt(search);
        
        // 검색 페이지 정보
        search.pageInfo(page, range, listCnt);
        // 페이징
        model.addAttribute("pagination", search);
        // 화면 출력
        model.addAttribute("productList", productService.getProductList(search));
        
        return "product/productList";
    }
 
}
 

 

 

2) ProductVO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.w2.product;
 
import java.util.Date;
 
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
 
@Getter
@Setter
@ToString
public class ProductVO {
    private String productId;          // 상품번호
    private String productCate;      // 카테고리
    private String productName;      // 상품이름
    private String productContent;  // 상세내용
    private int productView;          // 조회수 0
    private int productLike;          // 찜개수 0
    private Date productRegDate;      // 등록일자 CURRENT_TIMESTAMP()
    private String productSell;        // 판매상태 (Y/N)
    private int productCnt;            // 판매누적 0
    
    private String mainImage;        // 메인이미지
    private int productPrice;        // 판매가
}
 

 

 

 

 

3) ProductService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.w2.product.service;
 
import java.util.List;
 
import com.w2.product.ProductVO;
import com.w2.util.Search;
 
public interface ProductService {
 
    List<ProductVO> getProductList(Search search);    // 상품 목록 가져오기
    int getProductListCnt(Search search);            // 상품 목록 개수 가져오기
}
 

 

 

4) ProductServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.w2.product.service;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
 
import com.w2.product.ProductDAO;
import com.w2.product.ProductVO;
import com.w2.util.Search;
 
@Transactional
@Service("ProductService")
public class ProductServiceImpl implements ProductService {
 
    @Autowired
    private ProductDAO productDAO;
    
    @Override
    public List<ProductVO> getProductList(Search search) {
        return productDAO.getProductList(search);
    }
    
    @Override
    public int getProductListCnt(Search search) {
        return productDAO.getProductListCnt(search);
    }
 
}
 

 

 

5) ProductDAO.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.w2.product;
 
import java.util.List;
 
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
import com.w2.util.Search;
 
@Repository
public class ProductDAO {
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;
 
    public List<ProductVO> getProductList(Search search) {
        return sqlSessionTemplate.selectList("ProductDAO.getProductList", search);
    }
 
    public int getProductListCnt(Search search) {
        return sqlSessionTemplate.selectOne("ProductDAO.getProductListCnt", search);
    }
}
 

 

 

6) product-mapping.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?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="ProductDAO">
 
    <select id="getProductList" resultType="product">
        SELECT p.*, CONCAT(pm.imageDir, pm.imageName) as mainImage, pr.productPrice
        FROM product p
        LEFT JOIN product_image pm ON (p.productId = pm.imageBy AND pm.imageStatus = '대표')
        LEFT JOIN product_price pr ON (p.productId = pr.productId)
        <trim prefix="WHERE" prefixOverrides="AND|OR">
            <if test="keyword != null and keyword != ''">
                <if test="searchType == 'productName'">
                    AND productName like CONCAT('%', #{keyword}, '%')
                </if>
                <if test="searchType == 'productId'">
                    AND productId like CONCAT('%', #{keyword}, '%')
                </if>
            </if>
        </trim>
        ORDER BY productRegDate DESC
        LIMIT #{startList}, #{listSize};
    </select>
    
    <select id="getProductListCnt" resultType="int">
        SELECT count(*)
        FROM product
        <trim prefix="WHERE" prefixOverrides="AND|OR">
            <if test="keyword != null and keyword != ''">
                <if test="searchType == 'productName'">
                    AND productName like CONCAT('%', #{keyword}, '%')
                </if>
                <if test="searchType == 'productId'">
                    AND productId like CONCAT('%', #{keyword}, '%')
                </if>
            </if>
        </trim>
    </select>
</mapper>

 

 

7) mybatis-config.xml 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
 
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
                "http://mybatis.org/dtd/mybatis-3-config.dtd">
 
<configuration>
    
    <typeAliases>
        <!-- typeAlias
                - 매핑파일에서 사용하는 type을 지정
                - 애플리케이션에서 SQL 문으로 값을 전달합니다
                - SQL 문 실행 시 반환되는 레코드를 저장하는 용도로 사용하기 위한 빈을 생성합니다.-->
                
        <typeAlias type="com.w2.admin.AdminVO" alias="admin"/>
        <typeAlias type="com.w2.client.ClientVO" alias="client"/>
        <typeAlias type="com.w2.board.NoticeVO" alias="notice"/>
        <typeAlias type="com.w2.product.ProductVO" alias="product"/>
        <typeAlias type="com.w2.product.ProductPriceVO" alias="productPrice"/>
        <typeAlias type="com.w2.product.OptionVO" alias="option"/>
        <typeAlias type="com.w2.image.ImageVO" alias="image"/>
    </typeAliases>
 
    <!-- SQL 작성문을 지정하여 mapper 파일 경로 알려주는 역할입니다. -->
    <mappers>
        <mapper resource="mappings/admin-mapping.xml"/>
        <mapper resource="mappings/notice-mapping.xml"/>
        <mapper resource="mappings/client-mapping.xml"/>
        <mapper resource="mappings/product-mapping.xml"/>
    </mappers>
</configuration>

 

8) productList.jsp 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WeatherWear 관리자</title>
<style>
    a { color:black !important; }
    .click:hover { cursor: pointer;}
    .tdContent {display:flex; justify-content: center; height: 70px; align-items: center;}
    .check {width:20px; height:20px;}
    .productPrice_select{display: none;}
</style>
<!-- Font Awesome -->
<link href="resources/admin/AdminLTE/plugins/fontawesome-free/css/all.min.css" rel="stylesheet">
<!-- Theme style -->
<link href="resources/admin/AdminLTE/dist/css/adminlte.min.css" rel="stylesheet">
</head>
<body class="hold-transition sidebar-collapse layout-top-nav">
    <div class="wrapper">
        <%@ include file="../header.jsp" %>
    
        <div class="content-header">
            <section class="content-header">
                <div class="container">
                    <div class="row mb-2">
                        <div class="col-sm-6">
                            <h1>상품 목록</h1>
                        </div>
                        <div class="col-sm-6">
                            <ol class="breadcrumb float-sm-right">
                                <li class="breadcrumb-item"><a href="main.mdo">메인</a></li>
                                <li class="breadcrumb-item active">상품 목록</li>
                            </ol>
                        </div>
                    </div>
                </div>
            </section>
            
            <section class="content">
                <div class="container">
                    <div class="row">
                        <div class="col-12">
                            <div class="card">
                                <div class="card-header">
                                    <div class="card-title">
                                        <div class="orderby_btn">
                                            <button type="button" class="btn btn-sm btn-outline-light <c:if test="${pagination.getListSize() == 5}">active</c:if>">최신등록순</button>
                                            <button type="button" class="btn btn-sm btn-outline-light <c:if test="${pagination.getListSize() == 10}">active</c:if>">상품명순</button>
                                            <button type="button" class="btn btn-sm btn-outline-light <c:if test="${pagination.getListSize() == 15}">active</c:if>">상품번호순</button>
                                            <button type="button" class="btn btn-sm btn-outline-primary" onclick="location.href='registerProduct.mdo'">+등록</button>
                                        </div>
                                    </div>
                                    <div class="card-tools">
                                        <!-- Search -->
                                        <div class="input-group input-group-sm">
                                            <select id="orderType" class="form-control">
                                                <option value="productId">상품번호</option>
                                                <option value="productName">상품이름</option>
                                            </select>
                                            <input type="text" id="keyword" class="form-control float-right" placeholder="Search">
                                            <div class="input-group-append">
                                                <button type="button" class="btn btn-default" id="btnSearch">
                                                    <i class="fas fa-search"></i>
                                                </button>
                                            </div>
                                        </div>
                                        <!-- End Search -->
                                    </div>
                                </div>
                                <div class="card-header">
                                    <div class="card-title">
                                        <div class="orderby_btn">
                                            <div class="input-group input-group-sm">
                                                <select class="form-control option_select" onchange="change(this)" id="modifyType">
                                                    <option value="productSell">판매상태</option>
                                                    <option value="productPrice">판매가</option>
                                                </select>&nbsp;&nbsp;&nbsp;
                                                <div class="input-group-sm productSell_select">
                                                    <select class="form-control productSell_select" id="productSell_value">
                                                        <option value="Y">판매중</option>
                                                        <option value="N">판매중지</option>
                                                    </select>
                                                </div>
                                                <div class="input-group-sm productPrice_select">
                                                    <input type="text" name="productPrice_value" class="form-control float-right" placeholder="판매가">
                                                </div>
                                                <div class="input-group-append">
                                                    <button id="add-new-event" type="button" class="btn btn-sm btn-outline-primary" onclick="modify()">수정하기</button>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="card-body table-responsive p-0">
                                    <form id="listForm" name="clientForm" method="post">
                                        <table class="table table-hover text-nowrap" style="table-layout: fixed;">
                                            <colgroup>
                                                <col width="10%" /><!-- checkbox -->
                                                <col width="15%" /><!-- 상품번호 -->
                                                <col width="10%" /><!-- 이미지 -->
                                                <col width="30%" /><!-- 상품이름 -->
                                                <col width="10%" /><!-- 판매상태 -->
                                                <col width="10%" /><!-- 판매가 -->
                                                <col width="10%" /><!-- 조회수 -->
                                            </colgroup>
                                            <thead>
                                                <tr>
                                                    <th><button type="button" class="btn btn-sm btn-outline-primary checkAll" id="checkAll">전체선택</button></th>
                                                    <th>상품번호</th>
                                                    <th colspan="2">상품이름</th>
                                                    <th>판매상태</th>
                                                    <th>판매가</th>
                                                    <th>조회수</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <c:forEach var="item" items="${productList}" varStatus="status">
                                                    <tr class="click">
                                                        <td class="checklist"><span class="tdContent"><input type="checkbox" id="${ item.productId }" value="${ item.productId }" class="check"></span></td>
                                                        <td onclick="location.href='productInfo.mdo?productId=${ item.productId }'"><span class="tdContent">${item.productId}</span></td>
                                                        <td onclick="location.href='productInfo.mdo?productId=${ item.productId }'"><img src='${item.mainImage}' style="width:70px; height:70px;"></td>
                                                        <td onclick="location.href='productInfo.mdo?productId=${ item.productId }'"><span class="tdContent">${item.productName}</span></td>
                                                        <td onclick="location.href='productInfo.mdo?productId=${ item.productId }'"><span class="tdContent">${item.productSell}</span></td>
                                                        <td onclick="location.href='productInfo.mdo?productId=${ item.productId }'"><span class="tdContent">${item.productPrice}</span></td>
                                                        <td onclick="location.href='productInfo.mdo?productId=${ item.productId }'"><span class="tdContent">${item.productView}</span></td>
                                                    </tr>
                                                </c:forEach>
                                            </tbody>
                                        </table>
                                    </form>
                                </div>
                                <script>
                                </script>
                                <!-- pagination -->
                                <div class="card-footer">        
                                    <div class="card-title input-group-sm">
                                        <select name="searchType" class="form-control" id="listSize" onchange="page(1)">
                                            <option value="5" <c:if test="${pagination.getListSize() == 5}">selected="selected"</c:if>>5개</option>
                                            <option value="10" <c:if test="${pagination.getListSize() == 10}">selected="selected"</c:if>>10개</option>
                                            <option value="15" <c:if test="${pagination.getListSize() == 15}">selected="selected"</c:if>>15개</option>
                                            <option value="30" <c:if test="${pagination.getListSize() == 30}">selected="selected"</c:if>>30개</option>
                                        </select>
                                    </div>
                                    
                                    <ul class="pagination pagination-sm m-0 float-right">
                                        <c:if test="${pagination.prev}">
                                            <li class="page-item">
                                                <a class="page-link" href="#" onclick="fn_prev('${pagination.page}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}', '${search.searchType}', '${search.keyword}')">&laquo;</a>
                                            </li>
                                        </c:if>
                                        <c:forEach begin="${pagination.startPage}" end="${pagination.endPage}" var="pageId">
                                            <li class="page-item <c:out value="${pagination.page == pageId ? 'active':''}"/>">
                                                <a class="page-link" href="#" onclick="fn_pagination('${pageId}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}', '${search.searchType}', '${search.keyword}')">${pageId}</a>
                                            </li>
                                        </c:forEach>                                        
                                        <c:if test="${pagination.next}">
                                            <li class="page-item">
                                                <a class="page-link" href="#" onclick="fn_next('${pagination.page}', '${pagination.range}', '${pagination.rangeSize}', '${pagination.listSize}', '${search.searchType}', '${search.keyword}')">&raquo;</a>
                                            </li>
                                        </c:if>
                                    </ul>
                                </div>
                                
                            </div>
                        </div>
                    </div>
                    
                </div>
            </section>
        </div>        
        
        <%@ include file="../footer.jsp" %>
    </div>
 
<!-- jQuery -->
<script src="resources/admin/AdminLTE/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="resources/admin/AdminLTE/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
 
<script src="resources/util/js/paging.js"></script>
<script src="resources/util/js/checkbox.js"></script>
<script src="resources/admin/js/modify_productList.js"></script>
</body>
</html>
cs

 

 

>>> 실행

 

>>> 현재 orderby 기능은 작업되어있지 않다. 추후 추가할 예정

 

reProject_27_체크박스 전체선택/전체해제 버튼으로 처리하기

2024.01.18 체크박스 기능을 버튼을 사용하여 작업하려고함. 전체선택으로 보여지고 전체선택한 경우 전체해제로 보여지도록 작업 checkbox.js 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 2

hyeonga493.tistory.com

 

반응형