Project/Semi (20.07.08-20.08.11)
[Academy Semi Project] 부트페이 API
myspace
2020. 8. 28. 11:55
무료 결제 연동 API 서비스
개발자를 위한 PG 연동 서비스로, 빠른 결제 연동, 더 높은 결제성공율, 무료 통계 서비스를 제공합니다.
www.bootpay.co.kr
1. 부트페이에 가입한 뒤, 프로젝트 설정에 프로젝트명/판매자 노출명 등 필요한 정보 기입.
2. [결제수단 활성화] 탭에서 PG사, 결제수단 선택.
3. AGENDA 사이트에 로그인한 후 후원 버튼을 누르면 결제창이 뜨고, 결제 완료 후에는 개인후원내역 페이지로 넘어가는 기능. 로그인하지 않으면 후원할 수 없도록 함.
main.jsp
// main.jsp
<%@page import="com.agenda.login.LoginDto"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% request.setCharacterEncoding("UTF-8"); %>
<% response.setContentType("text/html; charset=UTF-8"); %>
// jstl을 사용하여 AGENDA 홈페이지에 로그인하지 않으면 후원이 불가능한 기능 구현
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Agenda</title>
// 부트페이 홈페이지에서 제공하는 CDN
// CDN : html이나 jsp 파일에서 결제창(js) 띄울 수 있도록 웹에 연동하는 것
<script src="https://cdn.bootpay.co.kr/js/bootpay-3.2.6.min.js" type="application/javascript"></script>
<script src="http://code.jquery.com/jquery-3.5.1.js"></script>
// body 태그 안에 들어가는 후원 박스(부트페이 결제 API)
// JSTL의 c:choose문에서 후원 버튼을 눌렀을 때
// logindto가 null이 ne(아닐)일 때 결제창이 실행되고(c:when),
// null이라면 '로그인해주세요'라는 alert창이 뜸(c:otherwise)
<section class="section third area">
<div class="donation-wrapper">
<span></span><span></span><span></span>
<div class="donation-content-wrapper">
<p>A Cup of Coffee </p>
<c:choose>
<c:when test="${logindto ne null }">
<div class="donation-content" onclick="pay01()" id="donaClick01" title="${logindto.member_id }">donate</div>
</c:when>
<c:otherwise>
<div class="donation-content" onclick="alert('로그인해주세요')" id="donaClick01">donate</div>
</c:otherwise>
</c:choose>
</div>
<span></span><span></span><span></span>
</div>
<div class="donation-wrapper">
<span></span><span></span><span></span>
<div class="donation-content-wrapper">
<p>A piece of cake</p>
<c:choose>
<c:when test="${logindto ne null }">
<div class="donation-content" onclick="pay02()" id="donaClick02" title="${logindto.member_id }">donate</div>
</c:when>
<c:otherwise>
<div class="donation-content" onclick="alert('로그인해주세요')" id="donaClick02">donate</div>
</c:otherwise>
</c:choose>
</div>
</div>
<div class="donation-wrapper">
<span></span><span></span><span></span>
<div class="donation-content-wrapper">
<p>Coffee</p> <p>with a Piece of Cake</p>
<c:choose>
<c:when test="${logindto ne null }">
<div class="donation-content" onclick="pay03()" id="donaClick03" title="${logindto.member_id }">donate</div>
</c:when>
<c:otherwise>
<div class="donation-content" onclick="alert('로그인해주세요')" id="donaClick03">donate</div>
</c:otherwise>
</c:choose>
</div>
</div>
<div class="donation-wrapper">
<span></span><span></span><span></span>
<div class="donation-content-wrapper">
<p>Whole Cake set</p>
<c:choose>
<c:when test="${logindto ne null }">
<div class="donation-content" onclick="pay04()" id="donaClick04" title="${logindto.member_id }">donate</div>
</c:when>
<c:otherwise>
<div class="donation-content" onclick="alert('로그인해주세요')" id="donaClick04">donate</div>
</c:otherwise>
</c:choose>
</div>
</div>
</section>
// body 끝나기 직전에 js(javascript) 호출 코드
<script type="text/javascript" src="${pageContext.request.contextPath}/main/mainpay.js"></script>
mainpay.js
// mainpay.js
// main.jsp의 onclick="pay01()","pay02()","pay03()","pay04()"가 작동하도록 함
/* function pay01~04(){} 안에 있는 코드는
* 부트페이 공식홈페이지에서 제공.
*
* main.jsp에서 온클릭 버튼을 눌렀을 때 결제창이 띄워지고
* 결제한 결과값(이하 '결제값')이 JSON 형태로 {key:value} 나타남.
*
* .error(function (data) {})에는 결제값이 error가 날 경우
* .cancel에는 결제를 취소할 경우 등등 처리할 코드를 써주면 되는데,
* 우리는 결제가 끝났을 경우(done)만 사용하면 됨.
*
* */
function pay01() {
BootPay.request({
price: '1000',
application_id: "5f17cf9f8f0751002136c6b9",
name: '커피 한 잔을 후원하시겠습니까?',
pg: '',
method: 'card',
show_agree_window: 0,
items: [
{
item_name:'A Cup of Coffee',
qty: 1,
unique: '123',
price: 1000,
}
],
user_info: {
username: '사용자 이름',
email: '사용자 이메일',
addr: '사용자 주소',
phone: '010-1234-4567'
},
order_id: '고유order_id_1234',
params: {callback1: '그대로 콜백받을 변수 1', callback2: '그대로 콜백받을 변수 2', customvar1234: '변수명도 마음대로'},
account_expire_at: '2018-05-25',
extra: {
start_at: '2019-05-10',
end_at: '2022-05-10',
vbank_result: 1,
quota: '0,2,3',
theme: 'purple',
custom_background: '#00a086',
custom_font_color: '#ffffff'
}
}).error(function (data) {
console.log(data);
}).cancel(function (data) {
console.log(data);
}).ready(function (data) {
console.log(data);
/* .confirm 코드는 기본제공.
* 결제값이 Bootpay 공식홈페이지의 결제내역으로 넘어가도록 함.*/
}).confirm(function (data) {
console.log(data);
var enable = true;
if (enable) {
BootPay.transactionConfirm(data);
} else {
BootPay.removePaymentWindow();
}
}).close(function (data) {
console.log(data);
/* 결제가 완료(done) 되면 실행될 함수*/
}).done(function (data) {
console.log(data);
/* main.jsp 후원 부분의 c:when 하위 div에 id와 title이 있음.
* var(변수) member_id는 #donaClick01이라는 id를 가진 div에서 title 값을 attr(잘라서 가져오기)한 것 */
var member_id = $("#donaClick01").attr("title");
console.log("컨트롤러 넘어가기전 아이디" + member_id)
console.log("끝 : "+data);
/* ajax를 통해서 url에 json형태의 결과값인 data를 string형태로 바꾼 obj와, 위에서 만든 변수인 member_id를 같이 보냄
* (여기까지 읽고 dnController의 donation으로 가세요)
* dnController의 "donation"으로 간 json 형태의 값은 다시 이곳으로 돌아와서
* success니까 member_id와 같이 dnController의 "dnlist"로 이동함.
* */
$.ajax({
url: "./dnController?command=donation",
method: "post",
data: {"obj" : JSON.stringify(data), member_id : member_id},
success: function(msg){
location.href="./dnController?command=dnlist&member_id="+member_id;
},
error:function(){
alert("통신 실패");
}
});
});
}
function pay02(){
BootPay.request({
price: '5000',
application_id: "5f17cf9f8f0751002136c6b9",
name: '케이크 한 조각을 후원하시겠습니까?',
pg: '',
method: 'card',
show_agree_window: 0,
items: [
{
item_name: 'A Piece of Cake',
qty: 1,
unique: '123',
price: 5000,
}
],
user_info: {
username: '사용자 이름',
email: '사용자 이메일',
addr: '사용자 주소',
phone: '010-1234-4567'
},
order_id: '고유order_id_1234',
params: {callback1: '그대로 콜백받을 변수 1', callback2: '그대로 콜백받을 변수 2', customvar1234: '변수명도 마음대로'},
account_expire_at: '2018-05-25',
extra: {
start_at: '2019-05-10',
end_at: '2022-05-10',
vbank_result: 1,
quota: '0,2,3',
theme: 'purple',
custom_background: '#00a086',
custom_font_color: '#ffffff'
}
}).error(function (data) {
console.log("에러 : " + data);
}).cancel(function (data) {
console.log("취소 : " + data);
}).ready(function (data) {
console.log("준비 : " + data);
}).confirm(function (data) {
console.log("확인 : " + data);
var enable = true;
if (enable) {
BootPay.transactionConfirm(data);
} else {
BootPay.removePaymentWindow();
}
}).close(function (data) {
console.log(data);
}).done(function (data) {
console.log(data);
var member_id = $("#donaClick02").attr("title");
console.log("컨트롤러 넘어가기전 아이디" + member_id)
console.log("끝 : "+data);
$.ajax({
url: "./dnController?command=donation",
method: "post",
data: {"obj" : JSON.stringify(data), member_id : member_id},
success: function(msg){
location.href="./dnController?command=dnlist&member_id="+member_id;
},
error:function(){
alert("통신 실패");
}
});
});
}
function pay03(){
BootPay.request({
price: '10000',
application_id: "5f17cf9f8f0751002136c6b9",
name: '커피와 조각케이크를 후원하시겠습니까?',
pg: '',
method: 'card',
show_agree_window: 0,
items: [
{
item_name: 'Coffee With a Piece of Cake',
qty: 1,
unique: '123',
price: 10000,
}
],
user_info: {
username: '사용자 이름',
email: '사용자 이메일',
addr: '사용자 주소',
phone: '010-1234-4567'
},
order_id: '고유order_id_1234',
params: {callback1: '그대로 콜백받을 변수 1', callback2: '그대로 콜백받을 변수 2', customvar1234: '변수명도 마음대로'},
account_expire_at: '2018-05-25',
extra: {
start_at: '2019-05-10',
end_at: '2022-05-10',
vbank_result: 1,
quota: '0,2,3',
theme: 'purple',
custom_background: '#00a086',
custom_font_color: '#ffffff'
}
}).error(function (data) {
console.log(data);
}).cancel(function (data) {
console.log(data);
}).ready(function (data) {
console.log(data);
}).confirm(function (data) {
console.log(data);
var enable = true;
if (enable) {
BootPay.transactionConfirm(data);
} else {
BootPay.removePaymentWindow();
}
}).close(function (data) {
console.log(data);
}).done(function (data) {
console.log(data);
var member_id = $("#donaClick03").attr("title");
console.log("컨트롤러 넘어가기전 아이디" + member_id)
console.log("끝 : "+data);
console.log(data);
$.ajax({
url: "./dnController?command=donation",
method: "post",
data: {"obj" : JSON.stringify(data), member_id : member_id},
success: function(msg){
location.href="./dnController?command=dnlist&member_id="+member_id;
},
error:function(){
alert("통신 실패");
}
});
});
}
function pay04(){
BootPay.request({
price: '50000',
application_id: "5f17cf9f8f0751002136c6b9",
name: '케이크 세트를 후원하시겠습니까?',
pg: '',
method: 'card',
show_agree_window: 0,
items: [
{
item_name: 'Whole Cake Set',
qty: 1,
unique: '123',
price: 50000,
}
],
user_info: {
username: '사용자 이름',
email: '사용자 이메일',
addr: '사용자 주소',
phone: '010-1234-4567'
},
order_id: '고유order_id_1234',
params: {callback1: '그대로 콜백받을 변수 1', callback2: '그대로 콜백받을 변수 2', customvar1234: '변수명도 마음대로'},
account_expire_at: '2018-05-25',
extra: {
start_at: '2019-05-10',
end_at: '2022-05-10',
vbank_result: 1,
quota: '0,2,3',
theme: 'purple',
custom_background: '#00a086',
custom_font_color: '#ffffff'
}
}).error(function (data) {
console.log(data);
}).cancel(function (data) {
console.log(data);
}).ready(function (data) {
console.log(data);
}).confirm(function (data) {
console.log(data);
var enable = true;
if (enable) {
BootPay.transactionConfirm(data);
} else {
BootPay.removePaymentWindow();
}
}).close(function (data) {
console.log(data);
}).done(function (data) {
console.log(data);
var member_id = $("#donaClick04").attr("title");
console.log("컨트롤러 넘어가기전 아이디" + member_id)
console.log("끝 : "+data);
$.ajax({
url: "./dnController?command=donation",
method: "post",
data: {"obj" : JSON.stringify(data), member_id : member_id},
success: function(msg){
location.href="./dnController?command=dnlist&member_id="+member_id;
},
error:function(){
alert("통신 실패");
}
});
});
}
dnController.java (서블릿)
package com.agenda.donation;
import java.io.IOException;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.agenda.login.LoginDto;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@WebServlet("/dnController")
public class dnController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
// 결제 통지 받기
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
dnDao dao = new dnDao();
String command = request.getParameter("command");
System.out.println(command);
if (command.equals("donation")) {
// mainpay.js에서 보낸 member_id를 받음
String member_id = request.getParameter("member_id");
System.out.println("도네이션 컨트롤러 : " + member_id);
// mainpay.js에서 보낸 obj(JSON문자열)를 받아서 string 변수에 담음
String obj = request.getParameter("obj");
System.out.println(obj);
// mainpay.js의 JSON형태의 결제 결과값들을 파싱
JsonElement element = JsonParser.parseString(obj);
// JSON element 값을 JSON object 형태로 바꿔서 꺼냄
JsonObject tmp = element.getAsJsonObject();
// json 형태인 {"key":"value"}에서 key("price", "pruchased_at")를 호출한 뒤 변수에 담아줌
int dona_bill = tmp.get("price").getAsInt();
String dona_date2 = tmp.get("purchased_at").getAsString();
// String형태의 dano_date2라는 변수를 Date로 형변환
SimpleDateFormat transFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dona_date = null;
try {
dona_date = (Date) transFormat.parse(dona_date2);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(dona_bill);
System.out.println(dona_date);
// dto에 세팅
dnDto dto = new dnDto();
dto.setDona_bill(dona_bill);
dto.setDona_date(dona_date);
dto.setMember_id(member_id);
// db에 넣기
int dona_db = dao.insert(dto);
System.out.println(dona_db); //dona_db:1 즉, db에 저장 성공
// db에 있는 값 꺼내서 후원내역 테이블에서 보여주려면
// db에 저장된 값(dona_db>0)을 mainpay.js의 msg에 응답 시키기
// 아래 코드를 통해서 다시 mainpay.js ajax의 success로 돌아감
response.getWriter().print(dona_db);
}
// 개인 후원내역조회 - 메인페이지에서 후원하고 나면 결제창 꺼지면서 자동으로 바로 넘어감
else if (command.equals("dnlist")) {
String member_id = request.getParameter("member_id");
System.out.println("리스트 아이디 : " + member_id);
List<dnDto> list = dao.selectOne(member_id);
request.setAttribute("donationList", list);
System.out.println(list);
RequestDispatcher dispatch = request.getRequestDispatcher("myinfo/myreceipt.jsp");
dispatch.forward(request, response);
}
// 전체 후원내역 조회 - 관리자 계정으로 로그인해서 관리자페이지에서만 볼 수 있음
else if (command.equals("alldnlist")) {
List <dnDto> list = dao.selectList();
request.setAttribute("list", list);
RequestDispatcher dispatch = request.getRequestDispatcher("admin/adreceipt.jsp");
dispatch.forward(request, response);
}
}
public void dispatch(String url, HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
RequestDispatcher dispatch = request.getRequestDispatcher(url);
dispatch.forward(request, response);
}
}
dnDao.java
package com.agenda.donation;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
public class dnDao extends dnSqlMapConfig {
private String namespace="com.agenda.donation.dnMapper.";
public List<dnDto> selectList() {
SqlSession session = null;
List<dnDto> list = null;
try {
session = getSqlSessionFactory().openSession(false);
list = session.selectList("com.agenda.donation.dnMapper.selectList");
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return list;
}
public List<dnDto> selectOne(String member_id) {
SqlSession session = null;
List<dnDto> list = null;
try {
session = getSqlSessionFactory().openSession(false);
list = session.selectList(namespace+"selectOne", member_id);
System.out.println("dao>>" + list);
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return list;
}
public int insert(dnDto dto) {
SqlSession session = null;
int res = 0;
try {
session = getSqlSessionFactory().openSession(false);
res = session.insert(namespace+"insert", dto);
if(res>0) {
session.commit();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return res;
}
}
dnDto.java
package com.agenda.donation;
import java.util.Date;
public class dnDto {
private int dona_no;
private int dona_bill;
private Date dona_date;
private String member_id;
public dnDto() {
}
public dnDto(int dona_no, int dona_bill, Date dona_date, String member_id) {
this.dona_no = dona_no;
this.dona_bill = dona_bill;
this.dona_date = dona_date;
this.member_id = member_id;
}
public int getDona_no() {
return dona_no;
}
public void setDona_no(int dona_no) {
this.dona_no = dona_no;
}
public int getDona_bill() {
return dona_bill;
}
public void setDona_bill(int dona_bill) {
this.dona_bill = dona_bill;
}
public Date getDona_date() {
return dona_date;
}
public void setDona_date(Date dona_date) {
this.dona_date = dona_date;
}
public String getMember_id() {
return member_id;
}
public void setMember_id(String member_id) {
this.member_id = member_id;
}
}
dnMapper.sql
<?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.agenda.donation.dnMapper">
<resultMap type="dnDto" id="dnResultMap">
<result property="dona_no" column="DONA_NO"/>
<result property="dona_bill" column="DONA_BILL"/>
<result property="dona_date" column="DONA_DATE"/>
<result property="member_id" column="MEMBER_ID"/>
</resultMap>
<select id="selectList" resultMap="dnResultMap">
SELECT DONA_NO, DONA_BILL, DONA_DATE, MEMBER_ID
FROM AG_DONATION
ORDER BY DONA_NO
</select>
<select id="selectOne" resultMap="dnResultMap">
SELECT DONA_NO, MEMBER_ID, DONA_BILL, DONA_DATE
FROM AG_DONATION
WHERE MEMBER_ID = #{member_id}
</select>
<insert id="insert" parameterType="dnDto">
INSERT INTO AG_DONATION
(DONA_NO, MEMBER_ID, DONA_BILL, DONA_DATE)
VALUES
(AG_DONATIONSEQ.NEXTVAL, #{member_id}, #{dona_bill}, #{dona_date})
</insert>
</mapper>
dnConfig.java
<?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>
<properties resource="com/agenda/common/db.Properties"/>
<typeAliases>
<typeAlias type="com.agenda.donation.dnDto" alias="dnDto"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/agenda/donation/dnMapper.xml" />
</mappers>
</configuration>
dnSqlMapConfig.java
package com.agenda.donation;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class dnSqlMapConfig {
private SqlSessionFactory sqlSessionFactory;
public SqlSessionFactory getSqlSessionFactory() {
String resource = "com/agenda/donation/dnConfig.xml";
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
} finally {
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactory;
}
}
dnDB.sql
CREATE TABLE AG_DONATION(
DONA_NO NUMBER PRIMARY KEY,
DONA_BILL NUMBER NOT NULL,
DONA_DATE DATE NOT NULL,
MEMBER_ID VARCHAR2(50),
CONSTRAINT DONA_FK FOREIGN KEY(MEMBER_ID) REFERENCES AG_MEMBER(MEMBER_ID)
);
SELECT * FROM AG_DONATION;
SELECT AG_DONATIONSEQ.CURRVAL FROM AG_DONATION;
SELECT AG_DONATIONSEQ.NEXTVAL FROM DUAL;
DELETE * FROM AG_DONATION ORDER BY DONA_NO;
SELECT DONA_NO, MEMBER_ID, DONA_BILL, DONA_DATE
FROM AG_DONATION
WHERE MEMBER_ID = 'test2';
4. AGENDA 사이트에 관리자 계정으로 로그인 했을 때, 전체후원내역조회 하는 기능.
adlayout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Admin Page</title>
<script src="http://code.jquery.com/jquery-3.5.1.js"></script>
<style type="text/css">
@charset "UTF-8";
@font-face{font-family:'Nanum Gothic'; src:url('../font/NanumBarunGothic.ttf')}
@font-face{font-family:'Nanum Gothic Light'; src:url('../font/NanumBarunGothicLight.ttf')}
@font-face{font-family:'Nanum Gothic Bold'; src:url('../font/NanumBarunGothicBold.ttf')}
@font-face{font-family:'Nanum Gothic Ultra Light'; src:url('../font/NanumBarunGothicUltraLight.ttf')}
body {
margin: 0 0;
padding: 0 0;
}
#admin {
display: flex;
flex-direction: column;
align-items: center;
width: 100vw;
height: 100vh;
}
#ad_top {
display: flex;
justify-content: center;
width: 100vw;
height: 150px;
}
#ad_title {
display: flex;
justify-content: center;
align-items: center;
font-family:'Nanum Gothic Bold';
font-size: 44px;
line-height: 72px;
color: #000000;
}
#ad_bottom {
width: 100vw;
top: 100vh;
display: flex;
align-items: center;
justify-content: space-around;
font-family:'Nanum Gothic';
}
.ad_box {
width: 240px;
height: 400px;
top: 373px;
bottom: 40px;
background: #FAFAFA;
cursor: pointer;
text-align: center;
font-size: 16pt;
line-height: 200px;
margin-top: 150px;
margin-bottom: 150px;
}
#ad_box span {
display: teble-cell;
}
.icon {
width: 100px;
height: 100px;
display: block;
position: relative;
margin: 0px auto;
}
.btn {
position: absolute;
background-color: #CED8F6;
top: 200px;
}
#ad_footer {
position: relative;
width: 100vw;
height: 300px;
bottom: 0;
background: #E5E5E5;
}
</style>
</head>
<body>
<div id="admin">
<c:choose>
<c:when test="${empty logindto }">
<jsp:include page="../header/header.jsp" />
</c:when>
<c:otherwise>
<jsp:include page="../header/loginMain.jsp" />
</c:otherwise>
</c:choose>
<div id="ad_top">
<div id="ad_title">관리자 페이지</div>
</div>
<div id="ad_bottom">
<div class="ad_box" onclick="location.href='${pageContext.request.contextPath}/adController?command=admyinfo&member_id=${logindto.member_id }'">
<span>내 정보 수정</span>
<img class="icon" src="image/info.png" />
</div>
<div class="ad_box" onclick="location.href='${pageContext.request.contextPath}/adController?command=allMember'">
<span>회원 정보 관리</span>
<img class="icon" src="image/search.png" />
</div>
<div class="ad_box" onclick="location.href='${pageContext.request.contextPath}/dnController?command=alldnlist'">
<span>전체 후원기록</span>
<img class="icon" src="image/qr.png" />
</div>
</div>
<footer id="ad_footer">
<jsp:include page="../footer/mainFooter.jsp"></jsp:include>
</footer>
</div>
</body>
</html>
adreceipt.jsp
<%@page import="java.util.Date"%>
<%@page import="com.agenda.donation.dnDto"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>전체 후원내역 조회</title>
<style type="text/css">
* {
margin: 0px;
padding: 0px;
}
#allreceipt {
width: 100vw;
height: 100vh;
background-color: whitesmoke;
display: flex;
justify-content: center;
align-items: center;
}
#allreceipt table{
width: 1000px;
heigth: 100%;
padding: 30px;
margin: 80px auto;
font-family: 'Nanum Gothic Light';
}
#title {
font-family: 'Nanum Gothic Bold';
}
table{
border-collapse: collapse;
width: 100%;
}
tr,td{
padding : 5px;
text-align: center;
}
td {
border-top: 1px solid black;
border-bottom: 1px solid black;
padding: 8px;
font-size : 1em;
}
thead tr td {
font-family: 'Nanum Gothic Bold';
}
/* 컬럼크기 */
td:first-child {
width: 30px;
}
td:nth-child(2) {
width: 300px;
}
td:nth-child(3) {
width: 30px;
}
td:nth-child(4) {
width: 100px;
}
td:nth-child(5) {
width: 30px;
}
/* 컬럼크기 끝 */
#title {
font-size : 1.5em;
padding: 8px
}
#back {
background-color: black;
color: white;
cursor: pointer;
}
#back {
padding : 5px 5px;
border : none;
cursor: pointer;
background-color: gray;
color : white;
}
</style>
</head>
<body>
<c:choose>
<c:when test="${empty logindto }">
<jsp:include page="../header/header.jsp" />
</c:when>
<c:otherwise>
<jsp:include page="../header/loginMain.jsp" />
</c:otherwise>
</c:choose>
<div id="allreceipt">
<table border="0">
<caption id="title">전체 후원내역</caption>
<thead>
<tr>
<td>후원 번호</td>
<td>후원 아이디</td>
<td>금액</td>
<td>후원 날짜</td>
</tr>
</thead>
<tbody>
<c:choose>
<c:when test="${empty list }">
<div>후원내역이 없습니다.</div>
</c:when>
<c:otherwise>
<c:forEach items="${list }" var="dto">
<tr>
<td>${dto.dona_no }</td>
<td>${dto.member_id }</td>
<td>${dto.dona_bill }</td>
<td>${dto.dona_date }</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</tbody>
<tfoot>
<tr>
<td colspan="10"><input id="back" type="button" onclick="location.href='admin/adlayout.jsp'" value="돌아가기"></td>
</tr>
</tfoot>
</table>
</div>
<!-- 풋터-->
<jsp:include page="../footer/mainFooter.jsp" />
</body>
이외에도 위의 dnController 등 사용.