이승윤

feat: categori detail 쿼리 추가 기능

1 var express = require('express'); 1 var express = require('express');
2 var router = express.Router(); 2 var router = express.Router();
3 var CategoriModel = require('../models/CategoriModel'); 3 var CategoriModel = require('../models/CategoriModel');
4 -//var csrf = require('csurf'); 4 +var VideoModel = require('../models/VideoModel');
5 -//var csrfProtection = csrf({ cookie: true }); 5 +var Youtube = require('youtube-node');
6 -var loginRequired = require('../libs/loginRequired'); 6 +var youtube = new Youtube();
7 -
8 -var path = require('path');
9 -var uploadDir = path.join(__dirname, '../uploads'); // 루트의 uploads위치에 저장한다.
10 -var fs = require('fs');
11 7
12 -//multer 셋팅 8 +var loginRequired = require('../libs/loginRequired');
13 -var multer = require('multer');
14 -var storage = multer.diskStorage({
15 - destination: function (req, file, callback) {
16 - //이미지가 저장되는 도착지 지정
17 - callback(null, uploadDir);
18 - },
19 - filename: function (req, file, callback) {
20 - // products-날짜.jpg(png) 저장
21 - callback(
22 - null,
23 - 'products-' + Date.now() + '.' + file.mimetype.split('/')[1]
24 - );
25 - },
26 -});
27 9
28 -var upload = multer({ storage: storage }); 10 +var limit = 10; // 출력 갯수
11 +youtube.setKey('AIzaSyCAaeW1qMSInEdN1OzU20FZlToIZYkb1bc'); // API 키 입력
29 12
30 router.get('/', function (req, res) { 13 router.get('/', function (req, res) {
31 res.send('categori main page'); 14 res.send('categori main page');
...@@ -43,7 +26,6 @@ router.get('/products', function (req, res) { ...@@ -43,7 +26,6 @@ router.get('/products', function (req, res) {
43 }); 26 });
44 27
45 router.get('/categories/write', loginRequired, function (req, res) { 28 router.get('/categories/write', loginRequired, function (req, res) {
46 - //edit에서도 같은 form을 사용하므로 빈 변수( product )를 넣어서 에러를 피해준다
47 res.render('category/form', { categories: '' }); 29 res.render('category/form', { categories: '' });
48 }); 30 });
49 31
...@@ -67,17 +49,85 @@ router.post('/categories/write', loginRequired, function (req, res) { ...@@ -67,17 +49,85 @@ router.post('/categories/write', loginRequired, function (req, res) {
67 49
68 router.get('/products/detail/:id', function (req, res) { 50 router.get('/products/detail/:id', function (req, res) {
69 //url 에서 변수 값을 받아올떈 req.params.id 로 받아온다 51 //url 에서 변수 값을 받아올떈 req.params.id 로 받아온다
52 + var word = req.query.keyword;
70 CategoriModel.findOne({ _id: req.params.id }, function (err, product) { 53 CategoriModel.findOne({ _id: req.params.id }, function (err, product) {
54 + var video = [];
71 //제품정보를 받고 그안에서 댓글을 받아온다. 55 //제품정보를 받고 그안에서 댓글을 받아온다.
72 CategoriModel.find({ product_id: req.params.id }, function (err, comments) { 56 CategoriModel.find({ product_id: req.params.id }, function (err, comments) {
73 - res.render('category/productsDetail', { 57 + if (word != null) {
74 - product: product, 58 + var count = 0;
75 - comments: comments, 59 + youtube.addParam('order', 'rating'); // 평점 순으로 정렬
76 - }); 60 + youtube.addParam('type', 'video'); // 타입 지정
61 + youtube.addParam('videoLicense', 'creativeCommon'); // 크리에이티브 커먼즈 아이템만 불러옴
62 + youtube.search(word, limit, function (err, result) {
63 + // 검색 실행
64 + console.log(word);
65 + if (err) {
66 + console.log(err);
67 + } // 에러일 경우 에러공지하고 빠져나감
68 + //console.log(JSON.stringify(result, null, 2)); // 받아온 전체 리스트 출력
69 + var items = result['items']; // 결과 중 items 항목만 가져옴
70 + for (var i in items) {
71 + var it = items[i];
72 + for (var j in it) {
73 + if (it[j]['title'] != null) {
74 + var title = it[j]['title'];
75 + }
76 + if (it[j]['videoId'] != null) {
77 + var video_id = it[j]['videoId'];
78 + }
79 + var urls = 'https://www.youtube.com/watch?v=' + video_id;
80 + }
81 + var item = {
82 + id: count,
83 + title: title,
84 + video_id: video_id,
85 + urls: urls,
86 + categori: product.title,
87 + };
88 + count++;
89 + video.push(item);
90 + }
91 + res.render('category/productsDetail', {
92 + product: product,
93 + comments: comments,
94 + videos: video,
95 + });
96 + });
97 + } else {
98 + res.render('category/productsDetail', {
99 + product: product,
100 + comments: comments,
101 + videos: video,
102 + });
103 + }
77 }); 104 });
78 }); 105 });
79 }); 106 });
80 107
108 +router.post('/products/detail/:id', loginRequired, function (req, res) {
109 + var item = [];
110 + var count = 1;
111 + for (var i in req.body.videoNum) {
112 + item.push(req.body.videoNum[i].split('///'));
113 + var video = new VideoModel({
114 + categori: item[i][2],
115 + id: count,
116 + title: item[i][1],
117 + video_id: item[i][3],
118 + urls: item[i][4],
119 + });
120 + var validationError = video.validateSync();
121 + if (validationError) {
122 + res.send(validationError);
123 + } else {
124 + video.save(function (err) {});
125 + }
126 + count++;
127 + }
128 + res.redirect('/categori/products');
129 +});
130 +
81 router.get('/products/edit/:id', loginRequired, function (req, res) { 131 router.get('/products/edit/:id', loginRequired, function (req, res) {
82 //기존에 폼에 value안에 값을 셋팅하기 위해 만든다. 132 //기존에 폼에 value안에 값을 셋팅하기 위해 만든다.
83 CategoriModel.findOne({ _id: req.params.id }, function (err, product) { 133 CategoriModel.findOne({ _id: req.params.id }, function (err, product) {
...@@ -87,37 +137,24 @@ router.get('/products/edit/:id', loginRequired, function (req, res) { ...@@ -87,37 +137,24 @@ router.get('/products/edit/:id', loginRequired, function (req, res) {
87 }); 137 });
88 }); 138 });
89 139
90 -router.post( 140 +router.post('/products/edit/:id', loginRequired, function (req, res) {
91 - '/products/edit/:id', 141 + //그전에 지정되 있는 파일명을 받아온다
92 - loginRequired, 142 + CategoriModel.findOne({ _id: req.params.id }, function (err, product) {
93 - upload.single('thumbnail'), 143 + var query = {
94 - // csrfProtection, 144 + name: req.body.name,
95 - function (req, res) { 145 + thumbnail: req.file ? req.file.filename : product.thumbnail,
96 - //그전에 지정되 있는 파일명을 받아온다 146 + price: req.body.price,
97 - CategoriModel.findOne({ _id: req.params.id }, function (err, product) { 147 + description: req.body.description,
98 - //아래의 코드만 추가되면 된다. 148 + };
99 - if (req.file && product.thumbnail) { 149 + CategoriModel.update(
100 - //요청중에 파일이 존재 할시 이전이미지 지운다. 150 + { id: req.params.id },
101 - fs.unlinkSync(uploadDir + '/' + product.thumbnail); 151 + { $set: query },
152 + function (err) {
153 + res.redirect('/categori/products/detail/' + req.params.id);
102 } 154 }
103 - //위의 코드만 추가되면 된다. 155 + );
104 - //넣을 변수 값을 셋팅한다 156 + });
105 - var query = { 157 +});
106 - name: req.body.name,
107 - thumbnail: req.file ? req.file.filename : product.thumbnail,
108 - price: req.body.price,
109 - description: req.body.description,
110 - };
111 - CategoriModel.update(
112 - { id: req.params.id },
113 - { $set: query },
114 - function (err) {
115 - res.redirect('/category/products/detail/' + req.params.id);
116 - }
117 - );
118 - });
119 - }
120 -);
121 158
122 router.get('/products/delete/:id', function (req, res) { 159 router.get('/products/delete/:id', function (req, res) {
123 CategoriModel.deleteMany({ _id: req.params.id }, function (err) { 160 CategoriModel.deleteMany({ _id: req.params.id }, function (err) {
......
...@@ -10,6 +10,6 @@ ...@@ -10,6 +10,6 @@
10 <td><input type="text" name="description" class="form-control" value="<%=categories.description%>"/></td> 10 <td><input type="text" name="description" class="form-control" value="<%=categories.description%>"/></td>
11 </tr> 11 </tr>
12 </table> 12 </table>
13 - <input type="submit" name="submit" value="submit" class="btn btn-primary"> 13 + <input type="submit" name="submit" value="완료" class="btn btn-primary">
14 </form> 14 </form>
15 <% include ../includes/footer.ejs %> 15 <% include ../includes/footer.ejs %>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -3,6 +3,32 @@ ...@@ -3,6 +3,32 @@
3 <div class="panel-heading"> 3 <div class="panel-heading">
4 <%=product.title%> 4 <%=product.title%>
5 </div> 5 </div>
6 + <form method="get" action="">
7 + <div class="input-group">
8 + <input type="text" class="form-control" placeholder="검색 키워드를 입력하세요!" name="keyword" autocomplete='off'>
9 + <span class="input-group-btn">
10 + <button class="btn btn-secondary" type="submit">찾기</button>
11 + </span>
12 + </div>
13 + </form>
14 + <form method="post" action="">
15 + <% for (var i in videos) { %>
16 + <div style="float:left;
17 + padding: 15px;
18 + ">
19 + <input type="checkbox" name="videoNum" style="
20 + position: absolute;
21 + margin-top: 5px;
22 + margin-left: 5px;
23 + z-index: 4;
24 + zoom:3.0;
25 + " value="<%=videos[i].id + '///' + videos[i].title +'///'+ videos[i].categori +'///'+ videos[i].video_id +'///'+ videos[i].urls%>"/>
26 + <div id="<%=videos[i].id%>" vid="<%=videos[i].video_id%>">
27 + </div>
28 + </div>
29 + <%};%>
30 + <button class="btn btn-primary" style="margin-top: 10px; margin-left: 15px;" >영상담기</button>
31 + </form>
6 <div class="panel-body"> 32 <div class="panel-body">
7 <div style="padding-bottom: 10px"> 33 <div style="padding-bottom: 10px">
8 작성일 : 34 작성일 :
...@@ -20,9 +46,9 @@ ...@@ -20,9 +46,9 @@
20 <div> 46 <div>
21 댓글작성하기 47 댓글작성하기
22 <form id="commentForm" action="" method="post"> 48 <form id="commentForm" action="" method="post">
23 - <input type="hidden" name="product_id" value="<%=product._id%>" /> 49 + <input type="hidden" name="product_id" value="<%=product.id%>" />
24 <textarea class="form-control" name="content"></textarea> 50 <textarea class="form-control" name="content"></textarea>
25 - <button class="btn btn-primary" style="margin-top: 10px">댓글작성</button> 51 + <button class="btn btn-primary" style="margin-top: 10px" type="submit">댓글작성</button>
26 </form> 52 </form>
27 </div> 53 </div>
28 <!-- 댓글영역 --> 54 <!-- 댓글영역 -->
...@@ -90,4 +116,45 @@ $(document).on('click' , '.comment_delete' , function(){ ...@@ -90,4 +116,45 @@ $(document).on('click' , '.comment_delete' , function(){
90 }); 116 });
91 } 117 }
92 }); 118 });
119 +</script>
120 +<script src="https://unpkg.com/masonry-layout@4/dist/masonry.pkgd.min.js"></script>
121 +<script type="text/javascript"
122 + src="https://cdnjs.cloudflare.com/ajax/libs/jquery.imagesloaded/4.1.1/imagesloaded.pkgd.min.js"></script>
123 +<script type="text/javascript">
124 + var $masonry_container = $('#masonry_container');
125 + $masonry_container.imagesLoaded(function () {
126 + $masonry_container.masonry({
127 + itemSelector: '.masonry-grid',
128 + columnWidth: 270
129 + });
130 + });
131 +</script>
132 +<script>
133 + var tag = document.createElement('script');
134 +
135 + tag.src = "https://www.youtube.com/iframe_api";
136 + var firstScriptTag = document.getElementsByTagName('script')[0];
137 + firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
138 +
139 + var player;
140 + var players = [];
141 + var videoIds = [];
142 + for (var i = 0; i < 10; i++) {
143 + players.push(String(i));
144 + videoIds.push($('#' + i).attr('vid'));
145 + }
146 +
147 + function onYouTubeIframeAPIReady() {
148 + for (var i = 0; i < videoIds.length; i++) {
149 + player = new YT.Player(players[i], {
150 + height: '300',
151 + width: '500',
152 + videoId: videoIds[i],
153 + events: {
154 + // 'onReady': onPlayerReady,
155 + // 'onStateChange': onPlayerStateChange
156 + }
157 + });
158 + }
159 + }
93 </script> 160 </script>
...\ No newline at end of file ...\ No newline at end of file
......