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

2021.08.11 수업_웹 구현물 최종본

by 주성씨 2021. 8. 11.

C:\data\node\ex07\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>
  <style>
    .aHeader:visited{
      color: white;
    }
    .aMenu:visited{
      color: black;
    }
  </style>
</head>

<body>
  <div id="container">
    <div id="header"><a href="/" style="text-decoration: none;" class="aHeader">
        <h2>쇼핑몰관리자</h2>
      </a>
    </div>
    <div id="center">
      <div id="menu">
        <ul>
          <a href="/notice" style="text-decoration: none;" class="aMenu">
            <li>공지사항</li>
          </a>
          <a href="/product" style="text-decoration: none;" class="aMenu">
            <li>상품관리</li>
          </a>
          <li>회원관리</li>
        </ul>
      </div>
      <div id="content">
        <%-include(pageName)%>
      </div>
    </div>
    <div id="footer">
      <h3>Copyright. LJS. All rights reserved.</h3>
    </div>
  </div>
</body>

</html>

 

C:\data\node\ex07\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;
};

 

C:\data\node\ex07\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.11 수업
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var noticeRouter = require('./routes/notice');
var productRouter = require('./routes/product');
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/notice', noticeRouter);
app.use('/product', productRouter);

// 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.11
//데이타베이스 연결
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\ex07\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>
  <style>
    .aHeader:visited{
      color: white;
    }
    .aMenu:visited{
      color: black;
    }
  </style>
</head>

<body>
  <div id="container">
    <div id="header"><a href="/" style="text-decoration: none;" class="aHeader">
        <h2>쇼핑몰관리자</h2>
      </a>
    </div>
    <div id="center">
      <div id="menu">
        <ul>
          <a href="/notice" style="text-decoration: none;" class="aMenu">
            <li>공지사항</li>
          </a>
          <a href="/product" style="text-decoration: none;" class="aMenu">
            <li>상품관리</li>
          </a>
          <li>회원관리</li>
        </ul>
      </div>
      <div id="content">
        <%-include(pageName)%>
      </div>
    </div>
    <div id="footer">
      <h3>Copyright. LJS. All rights reserved.</h3>
    </div>
  </div>
</body>

</html>

 

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

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

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: '쇼핑몰 관리', pageName: 'info.ejs' });
});

module.exports = router;

 

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

<h3>회사소개</h3>
<p>가슴에 할지니, 위하여 풍부하게 인생을 것이다. 군영과 오직 피가 열락의 보라. 끝에 크고 트고, 두손을 갑 것이다. 풀밭에 품고 눈에 위하여서. 날카로우나 더운지라 별과 끓는다. 되려니와, 소담스러운 그들의
    청춘 길을 목숨을 기관과 하였으며, 아니다. 같지 물방아 힘차게 끝에 듣는다. 가슴이 영락과 발휘하기 소담스러운 인도하겠다는 사막이다. 품었기 청춘 있음으로써 보이는 원대하고, 얼마나 인생의 교향악이다.
    무엇을 얼마나 평화스러운 물방아 인류의 같이, 있는가?</p>
<p>우리 아니더면, 어디 보이는 싶이 뛰노는 커다란 용기가 있다. 청춘이 그것을 보는 무엇이 위하여서. 그러므로 밝은 우리의 더운지라 방황하여도, 부패뿐이다. 그들은 우리의 있으며, 피어나기 같으며, 칼이다. 온갖
    것이 대중을 날카로우나 너의 있을 사막이다. 황금시대의 위하여서, 속에 청춘이 그들의 이것은 같이, 있다. 이 능히 새가 트고, 철환하였는가? 인생에 부패를 일월과 살았으며, 아름다우냐? 들어 이상 방지하는
    보내는 찬미를 인간의 발휘하기 있는가? 황금시대의 역사를 만천하의 과실이 못할 것은 눈에 산야에 것이다. 같으며, 무엇을 반짝이는 갑 아름다우냐?</p>
<p>오아이스도 현저하게 수 봄바람이다. 속잎나고, 무엇이 공자는 속에 힘있다. 따뜻한 같은 것은 품에 것이다. 긴지라 인간에 피부가 살았으며, 이상을 것은 대고, 끝에 보이는 봄바람이다. 충분히 그들은 꽃이 것은
    이는 말이다. 노년에게서 낙원을 끓는 어디 그들에게 보라. 우리 눈이 때까지 사막이다. 가치를 것이다.보라, 봄바람을 별과 아니다. 이상의 할지라도 그러므로 청춘에서만 이상의 것이다. 창공에 목숨이 찾아
    뜨고, 간에 열매를 심장의 인도하겠다는 그들에게 있다.</p>
<p>보이는 미묘한 크고 있다. 살았으며, 모래뿐일 이것이야말로 할지니, 사막이다. 그들은 때까지 할지니, 소리다.이것은 위하여 위하여 무엇을 이것이다. 어디 같이, 평화스러운 광야에서 그들의 작고 열락의 인간은
    그리하였는가? 굳세게 구하기 돋고, 얼마나 하여도 품었기 뭇 커다란 귀는 있으랴? 긴지라 따뜻한 인간의 그들의 위하여, 천자만홍이 교향악이다. 인간에 얼마나 청춘은 것이다. 그들은 위하여 투명하되 끓는 곳으로
    가치를 힘있다. 지혜는 천자만홍이 든 동산에는 이성은 행복스럽고 청춘의 때문이다.</p>

 

- 공지사항란

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

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

// post 공지사항 delete
router.post('/delete', function(req,res){
    var no = req.body.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);
    });
});

// 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]
        });
    });
});

// post로 공지사항 등록하는 라우터 만들기
router.post('/insert', function (req, res) {
    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);
    });
});

// 공지사항 글쓰기 화면 출력
router.get('/insert', function (req, res) {
    res.render('index', {
        title: '공지사항입력',
        pageName: './notice/insert.ejs'
    })
});

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

// 공지사항 목록데이터
router.get('/list.json', function (req, res) {
    var sql = 'select *,date_format(wdate,"%Y-%m-%d %h:%i:%s") fdate  from notice order by no desc limit 0,5;';
    db.get().query(sql, [], function (err, rows) {
        res.send(rows);
    });
});

module.exports = router;

 

C:\data\node\ex07\views\notice\list.ejs

<h3>공지사항목록</h3>
<a href="/notice/insert" style="display: inline-block; margin-bottom: 10px;">글쓰기</a>
<table id="tbl"></table>
<style>
    #tbl {
        width: 750px;
        border: 1px solid rgb(0, 0, 77);
        padding: 10px;
    }

    #tbl .row {
        border-bottom: 1px solid rgb(0, 0, 77);
        margin-bottom: 10px;
        cursor: pointer;
        padding: 10px;
    }

    #tbl .row:hover {
        background-color: rgb(230, 238, 255);
    }

    #tbl .title {
        width: 500px;
        text-overflow: ellipsis;
        padding: 10px;
    }
</style>

<script>
    getList();

    function getList() {
        $.ajax({
            type: 'get',
            url: '/notice/list.json',
            dataType: 'json',
            success: function (data) {
                var str = '';
                $(data).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><div class="title">[${no}] ${title}</div></td>`;
                    str += `<td><div class="date">${date}</div></td>`;
                    str += `</tr>`;
                });
                $('#tbl').html(str);
            }
        });
    };
</script>

 

C:\data\node\ex07\views\notice\read.ejs

<h3>공지사항정보</h3>
<form name="frm">
    <table style="width: 750px; margin-left: auto;">
        <tr>
            <td><input type="text" name="title" value="<%=notice.title%>" size="70"></td>
        </tr>
        <tr>
            <td><textarea name="content" rows="15" cols="72"><%=notice.content%></textarea>
            </td>
        </tr>
    </table>
    <div style="width: 500px; margin: 0px auto; text-align: center;">
        <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:'post',
            url:'/notice/delete',
            data:{'no':no},
            success:function(){
                alert('삭제가 완료되었습니다.');
                location.href='/notice';
            }
        });
    });

    $(frm).on('submit', function (e) {
        e.preventDefault();
        var title = $(frm.title).val();
        if (title == '') {
            alert('제목을 입력하세요.');
            $(frm.title).focus();
            return;
        };

        var content = $(frm.content).val();
        if (content == '') {
            alert('내용을 입력하세요.');
            $(frm.content).focus();
            return;
        };

        if (!confirm('공지를 수정하시겠습니까?')) {
            return;
        };

        // 공지사항수정
        $.ajax({
            type: 'post',
            url: '/notice/update',
            data: {
                'no':no,
                'title': title,
                'content': content
            },
            success: function () {
                alert('수정완료');
                location.href = '/notice';
            }
        })
    });
</script>

 

C:\data\node\ex07\views\notice\insert.ejs

<h3>공지사항입력</h3>
<form name="frm">
    <table style="width: 750px; margin-left: auto;">
        <tr>
            <td><input type="text" name="title" placeholder="제목을 입력하세요." size="70"></td>
        </tr>
        <tr>
            <td><textarea name="content" placeholder="내용을 입력하세요." rows="15" cols="72"></textarea></td>
        </tr>
    </table>
    <div style="width: 500px; margin: 0px auto; text-align: center;">
        <input type="submit" value="공지사항등록"/>
        <input type="reset" value="공지등록취소">
    </div>
</form>
<script>
    $(frm).on('submit',function(e){
        e.preventDefault();
        var title = $(frm.title).val();
        if(title==''){
            alert('제목을 입력하세요.');
            $(frm.title).focus();
            return;
        };
        
        var content = $(frm.content).val();
        if(content==''){
            alert('내용을 입력하세요.');
            $(frm.content).focus();
            return;
        };

        if(!confirm('공지를 등록하시겠습니까?')){
            return;
        };

        // 공지사항등록
        $.ajax({
            type:'post',
            url:'/notice/insert',
            data:{'title':title, 'content':content},
            success:function(){
                alert('등록완료');
                location.href='/notice';
            }
        })
    });
</script>

 

- 상품관리란

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

const {
  request
} = require('express');
var express = require('express');
var router = express.Router();
var db = require('../db'); // new

// post 상품등록
var multer = require('multer');
var uploadPath = './public/upload';
var path = require('path');

var upload = multer({
  storage: multer.diskStorage({
    destination: (req, file, done) => {
      done(null, uploadPath);
    },
    filename: (req, file, done) => {
      var ext = path.extname(file.originalname);
      done(null, path.basename(file.originalname, ext) + Date.now() + ext);
    },
  })
});

// 상품 이미지 받아서 라우팅하기
// upload 위의 multer 변수명, single은 파일갯수 한개만, filename은 위의 이미지 경로
// upload.single('image') 로 이미지 처리를 위한 미들웨어를 생성
router.post('/insert', upload.single('image'), function (req, res) {
  var title = req.body.title;
  var price = parseInt(req.body.price);
  var image = `/upload/${req.file.filename}`;
  var sql = 'insert into product(title,price,image) values(?,?,?);';
  db.get().query(sql, [title, price, image], function (err, rows) {
    res.sendStatus(200);
  });
});

/* GET 상품등록페이지 출력. */
router.get('/insert', function (req, res, next) {
  res.render('index', {
    title: '상품등록',
    pageName: './product/insert.ejs'
  });
});

/* GET 상품목록페이지 출력. */
router.get('/', function (req, res, next) {
  res.render('index', {
    title: '상품목록',
    pageName: './product/list.ejs'
  });
});

// 상품 목록 get // new
router.get('/list.json', function (req, res) {
  var sql = 'select *,format(price, 0) fprice from product order by id desc limit 0,5;';
  db.get().query(sql, [], function (err, rows) {
    res.send(rows);
  });
});

module.exports = router;

 

C:\data\node\ex07\views\product\list.ejs

<style>
    .item {
        overflow: hidden;
        box-shadow: 10px 10px 10px gray;
        margin-bottom: 20px;
        padding: 10px;
        border-radius: 20px;
    }

    .item img {
        float: left;
    }

    .item .content {
        float: left;
        width: 300px;
        padding: 10px;
    }
</style>

<h3>상품목록</h3>
<a href="/product/insert">상품등록</a>
<div id="product"></div>

<script>
    getList();

    function getList() {
        $.ajax({
            type: 'get',
            url: '/product/list.json',
            dataType: 'json',
            success: function (data) {
                var str = '';
                $(data).each(function () {
                    var id = this.id;
                    var title = this.title;
                    var image = this.image;
                    var price = this.fprice;
                    str += `<div class="item">`;
                    str += `<img src="${image}" width=100px height=100px/>`;
                    str += `<div class="content">`;
                    str += `<div class="id">[${id}]</div>`;
                    str += `<div class="title">${title}</div>`;
                    str += `<div class="price">${price}원</div>`;
                    str += `</div></div>`;
                });
                $('#product').html(str);
            }
        })
    }
</script>

 

C:\data\node\ex07\views\product\insert.ejs

<style>
    input[type=text] {
        border: 2px solid rgb(0, 0, 77);
        height: 25px;
        /* outline-style: none; */
    }
</style>

<h3>상품등록</h3>
<hr>
<form name="frm" enctype="multipart/form-data">
    <table>
        <tr>
            <td>
                <input type="text" name="title" placeholder="상품명입력" size="50">
            </td>
        </tr>
        <tr>
            <td>
                <input type="text" name="price" placeholder="상품가격" size="50">
            </td>
        </tr>
        <tr>
            <td>
                <img src="http://placehold.it/250/250" id="image" width="250" /><br>
                <input type="file" name="image" accept="image/*">
            </td>
        </tr>
    </table>
    <hr>
    <div>
        <input type="submit" value="상품등록">
        <input type="reset" value="등록취소">
    </div>
</form>
<script>
    // submit 등록할때
    $(frm).on('submit', function (e) {
        e.preventDefault();
        var title = $(frm.title).val()
        if (title == '') {
            alert('상품명을 입력하세요.');
            $(frm.title).focus();
            return;
        };

        var price = $(frm.price).val();
        if (price == '') {
            alert('가격을 입력하세요.');
            $(frm.price).focus();
            return;
        };

        var image = $(frm.image).val();
        if (image == '') {
            alert('이미지를 등록하세요.');
            $(frm.image).focus();
            return;
        };

        if (price.replace(/[0-9]/g, '') || price == "") {
            alert('가격은 숫자만 입력하세요.');
            $(frm.price).focus();
            return;
        };

        if (!confirm('상품을 등록하시겠습니까?')) {
            return;
        };

        // 상품등록
        var formData = new FormData();
        formData.append('title', title);
        formData.append('price', price);
        formData.append('image', $(frm.image)[0].files[0]);

        $.ajax({
            type: 'post',
            url: '/product/insert',
            data: formData,
            processData: false,
            contentType: false,
            success: function () {
                alert('상품등록 성공!');
                location.href = "/product";
            }
        });

    });

    // 이미지가 바뀔때 미리보기
    $(frm.image).on('change', function (e) {
        var reader = new FileReader();
        reader.onload = function (e) {
            $('#image').attr('src', e.target.result);
        }
        reader.readAsDataURL(this.files[0]);
    });
</script>

 

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

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

body{
  font-family: 'Cafe24SsurroundAir';
}

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

#header {
  border: 1px solid rgb(0, 0, 77);
  background-color: rgb(0, 0, 77);
  color: white;
  padding: 20px;
  margin-bottom: 10px;
}

#center {
  padding: 20px;
  border: 1px solid rgb(0, 0, 77);
  margin-top: 10px;
  margin-bottom: 10px;
  overflow: hidden;
}

#menu {
  margin-bottom: 10px;
  float: left;
  width: 150px;
}

#content {
  border-left: 1px solid rgb(0, 0, 77);
  padding: 20px;
  width: 700px;
  float: left;
}

h2, h3 {
  text-align: center;
}

li{
  padding: 10px;
  font-size: 20px;
  margin-bottom: 10px;
  text-align: center;
}

li:hover{
  cursor: pointer;
  background-color: rgb(0, 0, 77);
  color: white;
  border-radius: 10px;
}

#footer {
  background-color: rgb(0, 0, 77);
  border: 1px solid rgb(0, 0, 77);
  color: white;
  padding: 20px;
}

a:hover{
  cursor: pointer;
  background-color: rgb(0, 0, 77);
  color: white;
  border-radius: 10px;
}

 

최종 출력본