오늘 한 일
Frontend
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>게시판</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
<!-- JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<!-- 구글폰트 -->
<link href="https://fonts.googleapis.com/css?family=Stylish&display=swap" rel="stylesheet">
</head>
<style type="text/css">
* {
font-family: "Stylish", sans-serif;
}
.wrap {
width: 900px;
margin: auto;
}
#post-box {
width: 500px;
margin: 20px auto;
padding: 50px;
border: black solid;
border-radius: 5px;
}
</style>
<script>
let g_perPage = 10;
$(document).ready(function () {
getList(1);
});
function openClose() {
if ($("#post-box").css("display") == "block") {
$("#post-box").hide();
$("#btn-post-box").text("포스팅 박스 열기");
} else {
$("#post-box").show();
$("#btn-post-box").text("포스팅 박스 닫기");
}
}
let url = 'https://b8b8ft0d3l.execute-api.ap-northeast-2.amazonaws.com/default/myFirstLambda';
function getList(currPage) {
let word = $("#word").val();
$.ajax({
url: `${url}?type=list&page=${currPage}&perPage=${g_perPage}&word=${word}`,
method: "GET",
success: function (result) {
clear()
let titleList = result['data']['contents'];
let totalCount = result['data']['pageOptions']['totalCount'];
let currPage = result['data']['pageOptions']['currPage'];
let start = totalCount - ((currPage - 1) * g_perPage);
for (let i = 0; i < titleList.length; i++) {
let data = titleList[i]
$('#list').append(`<tr>
<th scope="row">${start - i}</th>
<td><input class="form-check-input" type="checkbox" name="idxs" value="${data['idx']}"></td>
<td><a href="#"token interpolation">${data['idx']})">${data['title']}</td>
<td>${data['regDate']}</td>
</tr>`);
}
setPage(currPage, result['data']['pageOptions']['totalPage'])
},
})
}
function clear() {
$('#list').empty();
$('#page').empty();
}
function setPerPage(perPage, target) {
g_perPage = perPage;
for (let i = 0; i < $("#select_perPage").find('li').length; i++) {
$("#select_perPage").find('li:eq(' + i + ')').find('a').removeAttr("href");
}
$(target).attr("href", "#");
getList(1, perPage)
}
function setPage(currPage, totalPage) {
for (let i = 0; i < totalPage; i++) {
if(currPage == i + 1) {
$('#page').append(`<li class="page-item"><a class="page-link" href="#"token interpolation">${i + 1}, ${g_perPage})">${i + 1}</a></li>`);
} else {
$('#page').append(`<li class="page-item"><a class="page-link"token interpolation">${i + 1}, ${g_perPage})">${i + 1}</a></li>`);
}
}
}
function writeContent() {
let title = $("#title").val();
let content = $("#content").val();
$.ajax({
url: `${url}?type=write`,
method: "POST",
contentType: "application/json",
data: JSON.stringify({title: title, content: content}),
success: function (result) {
alert("저장되었습니다!!");
location.reload();
},
})
}
function getContent(idx) {
g_idx = idx;
$.ajax({
url: `${url}?type=read&idx=${idx}`,
method: "GET",
success: function (result) {
$("#readTitle").html(result['data']['title'])
$("#readContent").html(result['data']['content'])
$('#exampleModal').modal('toggle')
},
})
}
let g_idx = 0;
function deleteContent() {
$.ajax({
url: `${url}?type=delete&idx=${g_idx}`,
method: "DELETE",
success: function (result) {
$('#exampleModal').modal('toggle');
getList(1);
},
})
}
function deleteAllContent() {
var checkedAry = [];
$.each($("input[name='idxs']:checked"), function () {
checkedAry.push($(this).val());
});
console.log(checkedAry);
$.ajax({
url: `${url}?type=deleteAll&idxs=${checkedAry}`,
method: "DELETE",
success: function (result) {
getList(1);
},
})
}
</script>
<body>
<div class="wrap">
<div class="jumbotron">
<h1 class="display-4">게시판</h1>
<p class="lead"></p>
<hr class="my-4">
<p class="lead">
<button onclick="openClose()" id="btn-post-box" type="button" class="btn btn-primary">포스팅 박스 열기
</button>
</p>
</div>
<div id="post-box" class="form-post" style="display:none">
<div>
<div class="form-group">
<label for="title">제목</label>
<input id="title" class="form-control" placeholder="">
</div>
<div class="form-group">
<label for="content">내용</label>
<textarea id="content" class="form-control" rows="2"></textarea>
</div>
<button type="button" class="btn btn-primary" onclick="writeContent()">기사저장</button>
</div>
</div>
<nav aria-label="Page navigation example">
<div class="form-inline md-form mr-auto mb-4">
<input class="form-control mr-sm-2" type="text" id="word" placeholder="Search" aria-label="Search">
<button class="btn aqua-gradient btn-rounded btn-sm my-0" onclick="getList(1)">Search</button>
</div>
<ul class="pagination justify-content-end" id="select_perPage">
<li class="page-item"><a class="page-link" onclick="setPerPage(5,this)">5</a></li>
<li class="page-item"><a class="page-link" onclick="setPerPage(10,this)">10</a></li>
<li class="page-item"><a class="page-link" onclick="setPerPage(20,this)">20</a></li>
</ul>
</nav>
<div id="cards-box">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col"></th>
<th scope="col">타이틀</th>
<th scope="col">등록일자</th>
</tr>
</thead>
<tbody id="list">
</tbody>
</table>
</div>
<div>
<nav aria-label="Page navigation example">
<div class="form-inline md-form mr-auto mb-4">
<button class="btn aqua-gradient btn-danger btn-sm my-0" onclick="deleteAllContent()">삭제</button>
</div>
<ul class="pagination justify-content-center" id="page">
<li class="page-item disabled">
</li>
</ul>
</nav>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel"><span id="readTitle"></span></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="readContent">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" onclick="deleteContent()">Delete</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Backend
import json
import boto3
import pymysql
from datetime import date
import math
def get_secret():
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name="ap-northeast-2"
)
get_secret_value_response = client.get_secret_value(
SecretId='rds-secret-01'
)
token = get_secret_value_response['SecretString']
return eval(token)
def db_ops():
secrets = get_secret()
try:
connection = pymysql.connect(
host=secrets['host'],
user=secrets['username'],
password=secrets['password'],
db='mydb',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor
)
except pymysql.MySQLError as e:
print("connection error!!")
return e
print("connection ok!!")
return connection
def lambda_handler(event, context):
paramType = event['queryStringParameters']['type']
conn = db_ops()
cursor = conn.cursor()
try:
if paramType == 'write':
if event['httpMethod'] == 'OPTIONS':
body = json.dumps({
"message": "success",
})
else:
today = date.today()
body = json.loads(event['body'])
cursor.execute("insert into bbs(title, content, regDate) value('" + body['title'] + "', '" + body['content'] + "', '" + today.strftime("%Y%m%d") + "')")
conn.commit()
body = json.dumps({
"message": "success",
})
elif paramType == 'list':
paramWord = event['queryStringParameters']['word']
paramCurrPage = event['queryStringParameters']['page']
paramPerPage = event['queryStringParameters']['perPage']
if paramCurrPage is None:
paramCurrPage = 1
if paramPerPage is None:
paramPerPage = 10
startPage = str((int(paramCurrPage)-1) * int(paramPerPage))
if not paramWord:
cursor.execute("select count(idx) as count from bbs")
count = cursor.fetchone()
totalCount = int(count['count'])
totalPage = math.ceil(totalCount/int(paramPerPage))
cursor.execute("select idx, title, regDate from bbs limit "+ startPage + "," + paramPerPage)
result = cursor.fetchall()
else:
cursor.execute("select count(idx) as count from bbs where title like '%"+paramWord+"%'")
count = cursor.fetchone()
totalCount = int(count['count'])
totalPage = math.ceil(totalCount/int(paramPerPage))
cursor.execute("select idx, title, regDate from bbs where title like '%"+paramWord+"%' limit "+ startPage + "," + paramPerPage)
result = cursor.fetchall()
body = json.dumps({
"result": "success",
"data": {
"contents": result,
"pageOptions": { "perPage": paramPerPage, "totalPage":totalPage, "currPage":paramCurrPage, "totalCount":totalCount }
}
})
elif paramType == 'read':
idx = event['queryStringParameters']['idx']
cursor.execute("select * from bbs where idx="+idx)
bbs = cursor.fetchone()
body = json.dumps({
"result": "success",
"data": bbs
})
elif paramType == 'delete':
idx = event['queryStringParameters']['idx']
cursor.execute("delete from bbs where idx="+idx)
conn.commit()
body = json.dumps({
"message": "success",
})
elif paramType == 'deleteAll':
idxs = event['queryStringParameters']['idxs']
cursor.execute("delete from bbs where idx in("+idxs+")")
conn.commit()
body = json.dumps({
"message": "success",
})
return {
"statusCode": 200,
#Cross Origin처리
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST,GET,DELETE'
},
"body": body,
}
except Exception as e:
print(e)
return {
"statusCode": 500,
#Cross Origin처리
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST,GET,DELETE'
},
"body": json.dumps({
"message": "fail",
}),
}
광진님 홧팅!