Board.js 게시판 백엔드

팡태(❁´◡`❁)·2022년 2월 14일
1

3rd_20220124

목록 보기
27/29
var express = require('express');
var router = express.Router();

// 참고 : https://github.com/mongodb/node-mongodb-native
// CMD> npm i mongodb --save
const db     = require('mongodb').MongoClient;
const dburl  = require('../config/mongodb').URL;
const dbname = require('../config/mongodb').DB;

// 참고 : https://github.com/expressjs/multer
// CMD> npm i multer --save
const multer = require('multer');
const upload = multer({ storage:multer.memoryStorage() });

// localhost:3000/board/insert
// 전송되는 값 : title, content, writer, image
// 자동으로 생성되어야 하는 값 : _id, regdate
router.post('/insert', upload.single("image"), 
            async function(req, res, next) {
  try {
    console.log(req.body);
    console.log(req.file);

    // 1. DB접속
    const dbconn = await db.connect(dburl);
    // 2. DB선택 및 컬렉션 선택
    const collection = dbconn.db(dbname).collection('sequence');
    // 3. 시퀀스에서 값을 가져오고, 그 다음을 위해서 증가
    const result = await collection.findOneAndUpdate(
      { _id : 'SEQ_BOARD1_NO' }, // 가지고 오기 위한 조건
      { $inc : {seq : 1 } }      // seq값을 1증가씨킴
    );

    console.log('------------------------');
    // 4. 정상동작 유무 결과 확인
    console.log(result.value.seq);
    console.log('------------------------');

    // 추가하고자 하는 항목 설정
    const obj = {
      _id       : result.value.seq,
      title     : req.body.title,
      content   : req.body.content,
      writer    : req.body.writer,
      hit       : 1,
      filename  : req.file.originalname,
      filedata  : req.file.buffer,
      filetype  : req.file.mimetype,
      filesize  : req.file.size,
      regdate   : new Date()
    };

    // 추가할 컬렉션 선택
    const collection1 = dbconn.db(dbname).collection('board1');
    // 추가하기
    const result1     = await collection1.insertOne(obj);
    // 결과확인
    if(result1.insertedId === result.value.seq) {
      return res.send({ status: 200 });
    }
    return res.send({ status: 0 });
  } 
  catch(e) {
    console.error(e);
    res.send({ status: -1, message: e });
  }
});


// localhost:3000/board/image?_id=115
// 출력하고자하는 이미지의 게시물번호를 전달
router.get('/image', async function(req, res, next) {
  try {
    const no = Number(req.query['_id']);
    // const no = req.query._id

    // db연결, db선택, 컬렉션선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('board1');

    // 이미지 정보 가져오기
    const result = await collection.findOne(
      { _id: no },  //조건
      { projection: { filedata: 1, filetype: 1 } },  //필요한 항목만 projection   
    );  

    // console.log(result);
    // application/json => image/png
    res.contentType(result.filetype);
    return res.send(result.filedata.buffer); 
  } 
  catch(e) {
    console.error(e);
    res.send({status : -1, message:e});
  }
});

// localhost:3000/board/select?page=1&text=
router.get('/select', async function(req, res, next) {
  try {
    const page = Number(req.query.page); // 페이지번호
    const text = req.query.text; // 검색어

    // db연결, db선택, 컬렉션선택
    const dbconn     = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('board1');

    // find(조건).sort(정렬).toArray()
    // abc  => a, b, c
    const result = await collection.find(
      { title: new RegExp(text, 'i') },
      { projection: { _id: 1, title: 1, writer: 1, hit: 1, regdate: 1 } }
    )
    .sort({ _id: -1}).skip((page-1) * 10).limit(10).toArray(); 
    // 오라클(o), mysql SQL문 => SELECT * FROM ORDER BY _ID DESC ...

    // 결과확인
    console.log(result);

    // 검색어가 포함된 전체 개시물 개수 => 페이지네이션 번호 생성시 필요
    const result1 = await collection.countDocuments(
      { title : new RegExp(text, 'i') },
    );

    return res.send({ status: 200, rows: result, total: result1 });
  } 
  catch(e) {
    console.error(e);
    res.send({ status: -1, message: e });
  }
});

// 게시판 상세내용 
// localhost:3000/board/selectone?no=13
router.get('/selectone', async function(req, res, next) {
  try {
    // 1. 전송되는 값 받기(형변환에 주의)
    const no = Number(req.query.no);

    // 2. db연결, db선택, 컬렉션선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('board1');

    // 3. db에서 원하는 값 가져오기( findOne(1개) or find(n개) )
    const result = await collection.findOne(
      { _id: no }, //조건
      { projection: { filedata: 0, filename: 0, filesize: 0, filetype: 0 } }, //필요한 컬럼만
    );

    // 4. 가져온 정보에서 이미지 정보를 추가함
    // 이미지 URL, 이전글번호, 다음글번호
    result['imageurl'] = '/board/image?_id=' + no;

    // 108
    // 109  이전글
    // 113  <= 현재요청되는 글번호 위치
    // 120  다음글
    // 129
    // 130

    // { _id : {$lt : 113} }    // 113미만
    // { _id : {$lte : 113} }   // 113이하
    // { _id : {$gt : 113} }   // 113초과
    // { _id : {$gte : 113} }   // 113이상

    const prev = await collection.find(
      { _id: { $lt: no } }, //조건
      { projection: { _id : 1 } } //필요한 컬럼만
    ).sort({ _id: -1 }).limit(1).toArray();
   
    console.log(prev);  // [ { _id: 116 } ]   OR   []
    console.log(result); // 개발자 확인 용도

    if( prev.length > 0) { // 이전글이 존재한다면
      result['prev'] = prev[0]._id;
    }
    else { // 이전글이 없다면
      result['prev'] = 0;
    }

    const next = await collection.find(
      { _id: { $gt: no } }, //조건
      { projection: { _id: 1 } } //필요한 컬럼만
    ).sort({ _id: 1 }).limit(1).toArray();

    if( next.length === 1) { // 이전글이 존재한다면
      result['next'] = next[0]._id;
    }
    else { // 이전글이 없다면
      result['next'] = 0;
    }

    // 같은것   : find( {_id : 113} )   find( {_id: {$eq : 113}} )
    // 같지않음 : find( { _id : {$ne : 113 } })
    // 포함    : find( {_id : {$in : [113, 114, 115]} } )

    // 조건2개일치 and 
    // find( { _id : 113, hit : 34} )   
    // find( { $and : [ {_id:113},{hit:77} ] } )

    // 조건2개중 1개만 or
    // find ( { $or : [ {_id:113}, {hit:34} ] } )

    return res.send({status : 200, result: result}); // 프론트로 전달함. 
  }
  catch(e) {
    console.error(e); // 개발자 확인 용도
    res.send({status : -1, message:e}); // 프론트로 전달함.
  }  
});

// 조회수 1씩 증가
// localhost:3000/board/updatehit?no=113
router.put('/updatehit', async function(req, res, next) {
  try {
    // 1. 전달되는 값 받기
    const no = Number(req.query.no);

    // 2. db연결, db선택, 컬렉션선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('board1');

    // 3. 조회수 증가
    const result = await collection.updateOne(
      { _id: no }, // 조건
      { $inc: { hit: 1 }  }  // ex) hit를 1씩 증가시킴
    );

    // 4. DB 수행 후 반환되는 결과 값에 따라 적절한 값을 전달
    if(result.modifiedCount === 1){
      return res.send({ status: 200 });
    }
    
    return res.send({ status: 0 });
  }
  catch(e) {
    console.error(e); // 개발자 확인 용도
    return res.send({ status: -1, message: e }); // 프론트로 전달함.
  }  
});

// 글삭제
// localhost:3000/board/delete?no=105
router.delete('/delete', async function(req, res, next) {
  try {
    // 1. 전달되는 값 받기
    const no = Number(req.query.no);

    // 2. db연결, db선택, 컬렉션선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('board1');

    // 3. 삭제 수행
    const result = await collection.deleteOne(
      { _id : no }
    );

    // 4. 결과 반환
    if(result.deletedCount === 1){
      return res.send({status : 200});
    }
    return res.send({ status: 0 });
  }
  catch(e) {
    console.error(e); // 개발자 확인 용도
    return res.send({status : -1, message:e}); // 프론트로 전달함.
  }  
});

// 글수정 : 글번호(조건), 제목, 내용, 작성자
// localhost:3000/board/update?no=105
router.put('/update', async function(req, res, next) {
  try {
    // 1. 전달되는 값 받기
    const no = Number(req.query.no);  // query
    const title = req.body.title;     // body
    const content = req.body.content; // body
    const writer = req.body.writer;   // body

    // 2. db연결, db선택, 컬렉션선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('board1');

    // 3. 변경 수행
    const result = await collection.updateOne(
      { _id : no },
      { $set : {title :title, content: content, writer: writer } }
    );

    // 4. 결과 반환
    if(result.modifiedCount === 1){
      return res.send({ status : 200 });
    }
    return res.send({ status : 0 });
  }
  catch(e) {
    console.error(e); // 개발자 확인 용도
    return res.send({ status : -1, message: e }); // 프론트로 전달함.
  }  
});

// 댓글쓰기 
// 기본키 : 답글번호(X) - 줄별 데이터를 구분하는 고유한 값 
// 내용, 작성자         - 데이터 
// 외래키 : 원본글번호  - 다른곳(board1의 글번호) 로만 사용 가능
// 등록일(X))           - 데이터
// localhost:3000/board/insertreply
router.post('/insertreply', async function(req, res, next) {
  try {
    // 1. DB접속, DB선택 및 컬렉션 선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('sequence');

    const result = await collection.findOneAndUpdate(
      { _id : 'SEQ_BOARDREPLY1_NO' }, // 가지고 오는 조건
      { $inc : {seq : 1 } }      // 다음 값을 위해 seq값 1증가
    );

    const obj = {
      _id     : result.value.seq,           // 기본키(PK) - 답글번호
      content : req.body.content,           // 답글 내용
      writer  : req.body.writer,            // 답글작성자
      boardno : Number(req.body.boardno),   // 외래키(FK) - 원본글번호
      regdate : new Date()                  // 답글 작성일자
    }

    const collection1 = dbconn.db(dbname).collection('boardreply1');
    const result1 = await collection1.insertOne(obj);

    // 결과확인
    if(result1.insertedId === result.value.seq) {
      return res.send({status : 200});
    }
    return res.send({status : 0});
  } 
  catch(e) {
    console.error(e);
    res.send({status : -1, message:e});
  }
});

// 댓글조회
// localhost:3000/board/selectreply?no=105
router.get('/selectreply', async function(req, res, next) {
  try {
    // 1. 전송되는 값 받기(형변환에 주의)
    const no = Number(req.query.no);

    // 2. db연결, db선택, 컬렉션선택
    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('boardreply1');

    // 3. db에서 원하는 값 가져오기( findOne(1개) or find(n개) )
    const result = await collection.find(
      { boardno : no }
    ).toArray();

    //4. 전달하기
    return res.send({status : 200, result: result});
  }
  catch(e) {
    console.error(e); // 개발자 확인 용도
    res.send({status : -1, message:e}); // 프론트로 전달함.
  }  
});

// 댓글삭제
// localhost:3000/board/deletereply?no=105
router.delete('/deletereply', async function(req, res, next) {
  try {
    const no = Number(req.query.no)

    const dbconn = await db.connect(dburl);
    const collection = dbconn.db(dbname).collection('boardreply1');

    const result = await collection.find(
      { boardno: no }
    ).toArray();

      return res.send({ status : 200, result: result });
  }
  catch(e) {
    console.error(e); // 개발자 확인 용도
    return res.send({ status: -1, message: e }); // 프론트로 전달함.
  }  
});


module.exports = router;

0개의 댓글