본문 바로가기
ICIA 수업일지/<최종본>

2021.08.10 수업_웹 구현물 최종본

by 주성씨 2021. 8. 10.

- node.js

C:\data\node\ex06\public\stylesheets\style.css

@font-face {
  font-family: 'GmarketSansMedium';
  src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/GmarketSansMedium.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

body {
  font-family: 'GmarketSansMedium';
}

#container {
  border: 1px solid rgb(233, 124, 233);
  padding: 20px;
  width: 960px;
  margin: 0px auto;
}

#header {
  border: 1px solid rgb(233, 124, 233);
  padding: 10px;
  margin-bottom: 10px;
}

h2, h3 {
  text-align: center;
  color: rgb(86, 16, 86);
}

#menu {
  border: 1px solid rgb(233, 124, 233);
  padding: 20px;
  margin-bottom: 10px;
  overflow: hidden;
}

#menu .item {
  float: left;
  width: 100px;
  background-color: purple;
  color: white;
  padding: 5px;
  margin-left: 10px;
  text-align: center;
  cursor: pointer;
  border-radius: 10px;
}

#menu .item:hover{
  background-color: white;
  color: purple;
}

#content {
  border: 1px solid rgb(233, 124, 233);
  padding: 20px;
  margin-bottom: 10px;
}

#footer {
  border: 1px solid rgb(233, 124, 233);
  padding: 20px;
}

 

C:\data\node\ex06\routes\bbs.js

var express = require('express');
var router = express.Router();

/* GET 공지사항. */
router.get('/', function(req, res, next) {
  res.render('index',{title:'게시판관리', pageName:'bbs.ejs'});
});

module.exports = router;

 

C:\data\node\ex06\routes\index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Lalla Roola', pageName: 'info.ejs' }); //index.ejs를 render
});

module.exports = router;

 

C:\data\node\ex06\routes\member.js

var express = require('express');
var router = express.Router();

/* GET 공지사항. */
router.get('/', function(req, res, next) {
  res.render('index',{title:'회원관리', pageName:'member.ejs'});
});

module.exports = router;

 

C:\data\node\ex06\routes\notice.js

var express = require('express');
var router = express.Router();
var db = require('../db.js');

/* GET 공지사항 title, pageName. */
router.get('/', function (req, res, next) {
  res.render('index', {
    title: '공지사항',
    pageName: 'notice.ejs'
  });
});

/* GET 공지사항목록*/
router.get('/notice.json', function (req, res) {
  var page = parseInt(req.query.page);
  var start = (page - 1) * 4;
  var sql = 'select *,date_format(wdate,"%Y-%m-%d %h:%i:%s") fdate from notice order by no desc limit ?,4;';
  db.get().query(sql, [start], function (err, rows) {
    // res.send(rows);
    var data = rows;
    sql = 'select count(*) cnt from notice;';
    db.get().query(sql,[],function(err,rows){
      var count = rows[0].cnt;
      res.send({'rows':data,'count':count})
    });
  });
});

/* GET 공지사항 입력 */
router.get('/insert', function (req, res) {
  res.render('index', {
    title: '공지사항입력',
    pageName: 'notice_insert.ejs'
  });
});

/* POST 공지사항 입력*/
router.post('/insert', function (req, res) {
  //post로 넘어오는 데이터는 body에 저장된다.
  var title = req.body.title;
  var content = req.body.content;

  var sql = 'insert into notice(title, content) values(?,?);';
  db.get().query(sql, [title, content], function (err, rows) {
    res.sendStatus(200);
  });
});

/*GET 공지사항 Read*/
router.get('/read', function (req, res) {
  var no = req.query.no;
  var sql = 'select * from notice where no=?';
  db.get().query(sql, [no], function (err, rows) {
    res.render('index', {
      title: '공지사항 정보',
      pageName: 'notice_read.ejs',
      notice: rows[0]
    });
  });
});

/*GET 공지사항 delete*/
router.get('/delete', function (req, res) {
  var no = req.query.no;
  var sql = 'delete from notice where no=?;';
  db.get().query(sql, [no], function (err, rows) {
    res.sendStatus(200);
  });
});

/*post 공지사항 update*/
router.post('/update', function (req, res) {
  var no = req.body.no;
  var title = req.body.title;
  var content = req.body.content;
  var sql = 'update notice set title=?, content=? where no=?;';
  db.get().query(sql, [title, content, no], function (err, rows) {
    res.sendStatus(200);
  });
});

module.exports = router;

 

C:\data\node\ex06\routes\product.js

var express = require('express');
var router = express.Router();

/* GET 공지사항. */
router.get('/', function(req, res, next) {
  res.render('index',{title:'상품관리', pageName:'product.ejs'});
});

module.exports = router;

 

C:\data\node\ex06\views\bbs.ejs

<h3>게시판관리</h3>

 

C:\data\node\ex06\views\index.ejs

<!DOCTYPE html>
<html>

<head>
  <title><%= title %></title>
  <link rel='stylesheet' href='/stylesheets/style.css' />
  <script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>

<body>
  <div id="container">
    <div id="header"><a href="/">
      <h2>쇼핑몰 관리자 화면</h2></a>
    </div>
    <div id="menu">
      <a href="/notice"><div class="item">공지사항</div></a>
      <a href="/bbs"><div class="item">게시판관리</div></a>
      <a href="/product"><div class="item">상품관리</div></a>
      <a href="/member"><div class="item">회원관리</div></a>
    </div>
    <div id="content">
      <%-include(pageName)%>
    </div>
    <div id="footer">
      <h3>Copyright. Lalla Roola. All rights reserved.</h3>
    </div>
  </div>
</body>

</html>

 

C:\data\node\ex06\views\info.ejs

<h3>쇼핑몰 소개</h3>
<p>돋고, 날카로우나 커다란 사랑의 바로 것이다. 안고, 투명하되 생의 위하여서 더운지라 것이다. 주는 그들의 얼마나 그것을 심장의 같이, 그들의 만천하의 봄바람이다. 있을 희망의 부패를 눈이 사람은 힘있다.
    커다란 끝까지 뭇 없으면 귀는 어디 구하지 굳세게 이상 보라. 거친 청춘의 그것을 갑 살 청춘은 미묘한 위하여 없으면 아니다. 그들의 기관과 피에 칼이다. 남는 생명을 천하를 것은 소담스러운 그리하였는가?
    설산에서 하는 어디 튼튼하며, 황금시대를 끓는 있음으로써 거선의 봄바람이다. 발휘하기 같이, 얼음 사랑의 인생을 품에 튼튼하며, 것이다.</p>
<p>많이 대중을 생생하며, 그와 가진 기관과 청춘의 끓는 미인을 철환하였는가? 구하지 오직 그들의 피가 천자만홍이 생명을 운다. 풀이 사랑의 불어 구하지 과실이 것이 석가는 약동하다. 내는 곧 현저하게 칼이다.
    평화스러운 인간이 모래뿐일 듣는다. 끓는 뜨고, 피어나기 것이다. 기쁘며, 창공에 몸이 열매를 교향악이다. 있는 스며들어 품으며, 그림자는 인도하겠다는 보는 사는가 가치를 힘있다. 긴지라 방황하여도, 피어나기
    풀이 옷을 품었기 가슴에 이것이다. 얼음에 물방아 원대하고, 가치를 맺어, 때문이다.</p>
<p>황금시대를 있으며, 튼튼하며, 눈이 커다란 청춘의 천자만홍이 이상이 힘있다. 많이 앞이 일월과 힘차게 살 웅대한 용감하고 이상의 사막이다. 수 새가 얼음에 굳세게 없으면 천지는 곳으로 일월과 끓는 이것이다.
    열락의 따뜻한 수 노년에게서 사막이다. 우리는 우리의 그들은 것이다.보라, 그들의 방황하였으며, 피부가 아니다. 있으며, 남는 구하지 피는 피에 우리는 곳으로 사막이다. 창공에 군영과 따뜻한 밝은 영락과
    가치를 갑 두손을 듣는다. 우는 트고, 기관과 찾아 시들어 같으며, 품었기 생의 운다. 불어 황금시대를 풀이 그것을 그러므로 그들의 가슴에 바이며, 그들은 것이다. 생의 우리의 우리 맺어, 길지 얼마나
    말이다. 남는 끓는 굳세게 가는 갑 어디 힘차게 없으면 그들의 그리하였는가?</p>

 

C:\data\node\ex06\views\member.ejs

<h3>회원관리</h3>

 

C:\data\node\ex06\views\notice_insert.ejs

<style>
    table {
        width: 700px;
        margin: 0px auto;
        padding: 10px;
        background-color: rgb(247, 212, 247);
    }

    #groupButton {
        width: 920px;
        text-align: center;
        margin-top: 15px;
    }

    input,
    textarea {
        font-size: 15px;
    }
</style>
<h3>공지사항입력</h3>
<!-- 양식 테그는 form -->
<form name="frm">
    <table>
        <tr>
            <td><input type="text" name="title" placeholder="제목을 입력하세요." size="100" style="padding: 5px;"></td>
        </tr>
        <tr>
            <td><textarea name="content" placeholder="내용을 입력하세요." rows="15" cols="102" style="padding: 5px;"></textarea>
            </td>
        </tr>
    </table>
    <div id="groupButton">
        <input type="submit" value="등록" />
        <input type="reset" value="취소" />
    </div>
</form>
<script>
    // submit은 무조건 되므로 e를 넣는다.
    // name은 .이나 #을 안붙여도 된다.
    $(frm).on('submit',function(e){
        e.preventDefault(); // submit을 박는다.
        var title=$(frm.title).val();
        if(title===''){
            alert("제목을 입력하세요.");
            $(frm.title).focus();
            return;
        };
        var content=$(frm.content).val();
        if(content===''){
            alert("내용을 입력하세요.");
            $(frm.content).focus();
            return;
        };

        // !가 붙었으니 false면 return이 된다.
        if(!confirm('내용을 등록하시겠습니까?')) return;

        // 내용을 insert 하는 작업
        $.ajax({
            type:'post',
            url:'/notice/insert',
            data:{'title':title,'content':content},
            success: function(arg){ // data 받을게 없으니
                alert('저장되었습니다.');
            }
        });
    });

</script>

 

C:\data\node\ex06\views\notice_read.ejs

<style>
    table {
        width: 700px;
        margin: 0px auto;
        padding: 10px;
        background-color: rgb(247, 212, 247);
    }

    #groupButton {
        width: 920px;
        text-align: center;
        margin-top: 15px;
    }

    input,
    textarea {
        font-size: 15px;
    }
</style>
<h3>공지사항정보</h3>
<!-- 양식 테그는 form -->
<form name="frm">
    <table>
        <tr>
            <td><input type="text" name="title" value="<%=notice.title%>" size="100" style="padding: 5px;"></td>
        </tr>
        <tr>
            <td><textarea name="content" rows="15" cols="102" style="padding: 5px;"><%=notice.content%></textarea>
            </td>
        </tr>
    </table>
    <div id="groupButton">
        <input type="submit" value="수정" />
        <input type="reset" value="취소" />
        <input type="button" value="삭제" id="btnDelete" />
    </div>
</form>
<script>
    // 전역변수로
    var no = "<%=notice.no%>"

    // 삭제 버튼을 눌렀을때
    $('#btnDelete').on('click', function () {
        if (!confirm(no + ' 을(를) 삭제하시겠습니까?')) return;
        $.ajax({
            type: 'get',
            url: '/notice/delete',
            data: {
                'no': no
            },
            success: function (data) {
                alert('삭제되었습니다.');
                location.href = '/notice';
            }
        });
    });

    // 수정 submit
    $(frm).on('submit', function (e) {
        e.preventDefault(); // submit을 박는다.
        var title = $(frm.title).val();
        if (title === '') {
            alert("제목을 입력하세요.");
            $(frm.title).focus();
            return;
        };
        var content = $(frm.content).val();
        if (content === '') {
            alert("내용을 입력하세요.");
            $(frm.content).focus();
            return;
        };

        // !가 붙었으니 false면 return이 된다.
        if (!confirm('글을 수정하시겠습니까?')) return;

        // 내용을 update 하는 작업
        $.ajax({
            type: 'post',
            url: '/notice/update',
            data: {'no':no, 'title':title, 'content':content},
            success:function(){
                alert('수정이 완료되었습니다!');
                location.href='/notice';
            }
        });
    });
</script>

 

C:\data\node\ex06\views\notice.ejs

<h3>공지사항</h3>
<a href="/notice/insert" style="margin-left: 25px;">글쓰기</a>
<style>
    #tbl .row {
        border-bottom: 1px solid rgb(194, 36, 194);
        margin-bottom: 10px;
        cursor: pointer;
        padding: 10px;
    }

    #tbl .row:hover {
        background-color: rgb(247, 212, 247);
    }

    #tbl .title {
        display: inline-block;
        width: 690px;
    }

    #tbl .content {
        margin: 20px 0px 20px 0px;
        background-color: rgb(251, 233, 251);
        padding: 20px;
    }

    #more {
        display: inline-block;
        cursor: pointer;
        text-decoration: underline;
        color: rgb(194, 36, 194);
        margin-top: 10px;
    }
</style>
<table id="tbl"></table>
<!-- <span id="more">더보기</span> -->
<div style="width: 900px; text-align: center; margin: 10px;">
    <button id="prev" disabled="true">&lt;</button>
    <span id="page">1</span>
    <button id="next">&gt;</button>
</div>

<script>
    // 변수 선언
    var page = 1;

    getList();

    // #more click
    // $('#more').on('click',function(){
    //     nPage++;
    //     getList();
    // });

    // #prev click
    $('#prev').on('click', function () {
        page--;
        getList();
    });

    // #next click
    $('#next').on('click', function () {
        page++;
        getList();
    });

    // 공지사항 출력
    function getList() {
        $.ajax({
            type: 'get',
            url: '/notice/notice.json',
            dataType: 'json',
            data: {
                'page': page
            },
            success: function (data) {
                var str = '';
                $(data.rows).each(function () {
                    var no = this.no;
                    var title = this.title;
                    var date = this.fdate;
                    str += `<tr class="row" onClick="location.href='/notice/read?no=${no}'">`;
                    str += `<td class="no">[${no}]</td>`;
                    str += `<td><div class="title">${title}</div></td>`;
                    str += `<td class="date">${date}</td>`;
                    str += `</tr>`;
                });
                $('#tbl').html(str);
                var count = data.count; // 상품수
                var lastPage = Math.ceil(count/4);
                $('#page').html(`${page}/${lastPage}`);
                // 첫번째 페이지 마지막 페이지 버튼 비활성화
                if (page == 1) $('#prev').attr('disabled', true);
                else $('#prev').attr('disabled', false);

                if (page == lastPage) $('#next').attr('disabled', true);
                else $('#next').attr('disabled', false);
            }
        });
    };
</script>

 

C:\data\node\ex06\views\product.ejs

<h3>상품관리</h3>

 

C:\data\node\ex06\app.js

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');


var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 2021.08.10
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var noticeRouter = require('./routes/notice');
var bbsRouter = require('./routes/bbs');
var productRouter = require('./routes/product');
var memberRouter = require('./routes/member');
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/notice', noticeRouter);
app.use('/bbs', bbsRouter);
app.use('/product', productRouter);
app.use('/member', memberRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

//2021.08.10
//데이타베이스 연결
var db = require('./db');
db.connect(function(err){
  if(err){
    console.log('DB error.......');
    process.exit(1);
  }else{
    console.log('DB Success......');
  }
});

module.exports = app;

 

C:\data\node\ex06\db.js

var mysql = require('mysql');
var conn;
exports.connect = function () {
    conn = mysql.createPool({
        connectionLimit: 100,
        host: 'localhost',
        user: 'shopping',
        password: 'pass',
        database: 'shoppingdb'
    });
}
exports.get = function () {
    return conn;
};

 

- MySQL

- root

#2021.08.10
#데이터 베이스 생성
create database shoppingdb;
#유저 생성
create user 'shopping'@'localhost' identified by 'pass';
#유저에게 데이터베이스 권한 부여
grant all privileges on shoppingdb.* to 'shopping'@'localhost';

 

- shoppingdb

-- table create
create table notice(
   no int auto_increment primary key,
    title varchar(200) not null,
    content varchar(2000),
    wdate datetime default now()
);

-- 테이블 튜블 insert 
insert into notice(title, content)
values('안녕하세요 카카오입니다.','카카오 서비스를 이용해 주시는 회원 여러분께 감사드립니다.위치정보관리책임자 변경에 대해 안내드리기 위하여, 카카오 서비스 약관의 내용이 2021년 8월 9일자로 변경될 예정임을 안내드립니다.');
insert into notice(title, content)
values('위치기반서비스 이용약관 변경 안내','안녕하세요.카카오의 서비스를 이용해주시는 회원 여러분께 감사드리며, 위치기반서비스 이용약관 변경에 관한 안내 말씀 드립니다.');
insert into notice(title, content)
values('카카오 통합서비스약관, 카카오 서비스 약관, 카카오 통합 약관, 카카오 운영정책 변경 안내','안녕하세요 카카오입니다.카카오 서비스를 이용해 주시는 회원 여러분께 감사드립니다.카카오 통합서비스약관, 카카오 서비스 약관, 카카오 통합 약관, 카카오 운영정책의 내용이 2021년 7월 1일자로 변경될 예정임을 안내드립니다.분사로 인하여 카카오톡 채널의 카카오알림 카테고리에서 "멜론" 은 제외될 예정입니다.다만, 분사 이전에 카카오알림 채널 추가 및 광고메시지 수신에 동의하여 "멜론" 채널이 이미 추가된 경우에는 계속 유지됩니다. ');
insert into notice(title, content)
values('개인정보 처리방침 개정안내','안녕하세요. 카카오(이하 ‘회사’)입니다.서비스를 이용해 주시는 이용자 여러분께 감사드리며, 새로운 개인정보 처리방침 적용에 관한 안내 말씀 드립니다회사는 이용자 여러분의 개인정보를 무엇보다 소중하게 처리하고 있으며, 어떤 사안보다도 우선하여 안전하게 관리하고 있습니다.새롭게 변경될 개인정보 처리방침 내용을 확인하시고 서비스 이용에 참고하시기 바랍니다.');
insert into notice(title, content)
values('카카오 전자금융거래 이용약관 변경 사전 안내',' 변경 사전 안내 2019-10-25 안녕하세요. 카카오입니다.카카오 서비스를 이용해주시는 회원 여러분께 감사드립니다.건전한 상거래 환경 조성 및 고객의 안전한 결제서비스 이용을 위해 카카오 전자금융거래 이용약관의 내용이 2019년 12월 1일자로 변경될 예정입니다. ');

-- 더미 데이터 생성 
insert into notice(title, content)
select title, content from notice;