📁exp_20220711/models/food/foodmodel.js 생성
//nodejs mongodb ORM기반 모듈
var mongoose = require("mongoose");
// 자동 번호생성 = 시퀀스
const AutoIncrement = require("mongoose-sequence")(mongoose);
var Schema = mongoose.Schema;
var foodSchema = new Schema({
    _id        :  Number, // 기본키, (SEQ)음식코드
    name       : { type: String, default: "" },  // 음식이름
    price      : { type: Number, default: 0 },  // 음식가격
    content    : { type: String, default: "" },  // 내용
    regdate    : { type: Date, default: Date.now }, // 등록일, 디폴트값 : 현재시간 
    
    imagedata  : { type: Buffer, default: null }, // 이미지 데이터
    imagename  : { type: String, default: "" }, // 이미지 이름
    imagetype  : { type: String, default: "" }, // 이미지의 종류, jpeg, png등
    imagesize  : { type: Number, default: 0 }, // 이미지의 크기 용량
    // 삭제여부 확인용(1 = 삭제안됨,0 = 삭제됨)
    chk        : { type: Number, default: 1 },
    restaurantcode : { type: String, default: "" },  // 식당코드(외래키)
});
//시퀀스 설정
foodSchema.plugin(AutoIncrement, { 
    id: "SEQ_FD_FOOD_CODE", 
    inc_field: "_id",  
    start_seq : 1001 
  }); 
//몽고 DB에 컬렉션 생성
module.exports = mongoose.model("fd_food", foodSchema); 
📁exp_20220711/routes/food/fd_food.js 생성
➡️app.js에 라우트 등록
var fd_foodRouter = require('./routes/food/fd_food');  
app.use('/api/fd_food', fd_foodRouter);
📁routes / food / fd_restaurant.js 에서
식당 로그인 서버 생성시 FID, ROLE 지정했으니// 토큰에 포함할 내용 (아이디와 권한정보(식당인지 고객인지)) const data = { "FID":result._id, "ROLE": "RESTAURANT" }➡️fd_auth.js 에도 FID와 ROLE 지정해준다
req.body.FID = data.FID; req.body.ROLE = data.ROLE;💡로그인시 생성했던 토큰 정보를 복원해준다
127.0.0.1:3000/api/fd_food/insert.json
POST > body > form-data > key(image) value(파일첨부)
headers > token 
router.post("/insert.json", upload.single("image"),
    auth.checkToken, async function (req, res, next) {
    try {  
        const fid = req.body.FID;
        const role = req.body.ROLE;
        console.log(fid);
        console.log(role);
        console.log(req.file);
        //  권한 확인
        if(role === 'RESTAURANT'){
            // 추가할 빈 객체 생성
            const obj = new Food();
            // 항목추가 obj.모델변수명 = req.body.전송변수명
            obj.name           = req.body.name;
            obj.content        = req.body.content;
            obj.price          = Number(req.body.price);
            // 복원했던 fid에 restaurantcode의 정보가 있다
            obj.restaurantcode = fid;
    
            obj.imagedata = req.file.buffer;
            obj.imagename = req.file.originalname;
            obj.imagetype = req.file.mimetype;
            obj.imagesize = req.file.size;
        // 출력해서 내가 원하는대로 되어있는지 확인!
        // console.log('obj=>',obj);
            const result = await obj.save();
            if(result !== null) {
            return res.send({ status: 200, result:result });
            }
            return res.send({ status: 0 });
        }
       } 
    catch (e) {
        console.error(e);
        return res.send({ status: -1, result: e });
      }
    });
✏️메뉴 등록시
obj.restaurantcode = fid.restaurantcode; 로 잘못 작성하여 다음단계를 계속 진행하니 값이 아예 안들어가거나 꼬여버렸다😥
obj.restaurantcode = fid;
한줄 고치니까 다 잘 작동된다...
혼자 할때는 console.log 찍어 확인하며 코드를 작성해야겠다
- 데이터를 완전히 지우는게 아니라 빈 데이터로 업데이트
 
➡️ 주문내역이 남아있을 수 있기때문에 지울 수 없다- token (아무나 삭제하면 안되니 인증필요 ) + body {"_id" : "삭제할 번호" }
 - 삭제여부가 표시될 항목이 필요
 
➡️ exp_20220711/fd_foodmodel.js 에 chk 항목 추가// 삭제유무 확인용(1 = 삭제안됨,0 = 삭제됨) chk : { type: Number, default: 1 },
📁 exp_20220711/routes/food/fd_food.js
메뉴 삭제 서버 생성
router.delete("/delete.json", auth.checkToken, async function (req, res, next) {
    try {  
        const fid = req.body.FID;
        const role = req.body.ROLE;
        console.log(fid);
        console.log(role);
        //  권한 정보가 식당이 맞다면
        if(role === 'RESTAURANT'){
            // query =>and 
            // 1)사용하여 로그인 한 사용자의 데이터 이면서 
            // 2)지우고 싶은 데이터 찾기
            const query = { 
                _id: Number(req.body._id),
                restaurantcode : fid,
            };
            
            const obj = await Food.findOne(query);
            console.log(obj);
            //  _id, name, restaurantcode 는 order 테이블이 참조하므로 변경제외
            // 숫자는 0으로 데이터는 ''(공백)으로 바꿔준다
            if( obj !== null ){
            obj.content        = '';
            obj.price          = 0;
            obj.imagedata = null;
            obj.imagename = '';
            obj.imagetype = '';
            obj.imagesize = 0;
            obj.chk = 0;
            const result = await obj.save();
            if(result !== null) {
            return res.send({ status: 200});
            }
        }
            return res.send({ status: 0 });
        }
       } 
    catch (e) {
        console.error(e);
        return res.send({ status: -1, result: e });
      }
    });
- 이미지를 첨부하였을때(첨부이미지로 변경)
 
/ 이미지를 첨부하지 않았을때(기본이미지 설정)- 토큰(아무나 삭제 시킬 수 없으니) + body > { "_id" : "변경할 번호", 메뉴이름, 내용, 가격, 이미지}
 - 이미지 포함될땐 POSTMAN > formdata 사용하여 보낸다
 
📁 exp_20220711/routes/food/fd_food.js
메뉴 수정 서버 생성
// 127.0.0.1:3000/api/fd_food/update.json
router.put("/update.json", upload.single("image"), auth.checkToken, async function (req, res, next) {
    try {  
        const fid = req.body.FID;
        const role = req.body.ROLE;
        console.log(fid);
        console.log(role);
        console.log(req.file);  //이미지 첨부 하지 않고 데이터전송시 cmd창 => undefined
         
         if(role === 'RESTAURANT'){//  권한 정보가 식당이 맞다면
            // query => and 
            // 1)사용하여 로그인 한 사용자의 데이터 이면서 
            // 2)바꾸고 싶은 데이터 찾기
            const query = { 
                _id: Number(req.body._id),
                restaurantcode : fid,
            };
            const obj = await Food.findOne(query);
            obj.name = req.body.name;
            obj.price = Number(req.body.price);
            obj.content = req.body.content;
            if(typeof req.file !== 'undefined'){  // 파일을 첨부한 상태
            obj.imagedata = req.file.buffer;
            obj.imagename = req.file.originalname;
            obj.imagetype = req.file.mimetype;
            obj.imagesize = Number(req.file.size);
            const result = await obj.save();
            if(result !== null) {
            return res.send({ status: 200, result:result });
            }
            }
            return res.send({ status: 0 });
         }    
       
        
       } 
    catch (e) {
        console.error(e);
        return res.send({ status: -1, result: e });
      }
    });
- 식당(관리자 입장)에서 조회하는 상황
 - token 확인 필요
 - 삭제된 항목 포함하여 조회
 - 페이지네이션기능 + 검색기능
 
 📁 exp_20220711/routes/food/fd_food.js
메뉴 삭제 서버 생성
// 127.0.0.1:3000/api/fd_food/selectlist.json?page=1&text=
router.get("/selectlist.json", upload.single("image"),
    auth.checkToken, async function (req, res, next) {
    try {  
        const fid = req.body.FID;
        const role = req.body.ROLE;
        console.log(fid);
        console.log(role);
         
         if(role === 'RESTAURANT'){
       //  ? page=1 & text =a
       const page = Number(req.query.page);
       const text = req.query.text;
       console.log(page);
       console.log(text);
       // 조회조건
       const query = { 
        name    : new RegExp(text, 'i'),
        restaurantcode : fid,
    } ;
        const project = {imagedata:0, imagesize:0, imagename:0, imagetype: 0}
       const result = await Food.find(query).select(project)
       .sort({name : 1}).skip( (page-1)*10 ).limit(10); 
         console.log(result);
       
     if(result !== null){
        let arr = [] // 빈 객체 만들기;
        for(let tmp of result) { //result값을 반복
            // toObject = 일종의 데이터 가공! 반복문 돌리고 내가 원하는 형태로 가져감
            // tmp의 모델 객체를 일반 object로 변환 후 obj에 저장
            let obj = tmp.toObject();
            // obj에 새로운 key값 추가
            obj.imageurl = `/api/fd_food/image?_id=${obj._id}`;
            // obj에 새로운 key값 추가 ( 1000 = 1초, 1000 * 60  * 60 *9 )
            obj.regdate1 = new Date(obj.regdate) + 1000 * 60 * 60 *9;
            // arr에 일반 obj값을 추가
            arr.push(obj);
        }
       // 전체개수 구하기
     const total = await Food.countDocuments(query);
     return res.send({ status: 200, result : arr, total : total }); 
     }
    } 
    return res.send({ status: 0 }); 
    }
    catch (e) {
        console.error(e);
        return res.send({ status: -1, result: e });
      }
    });
- 식당용 이미지 url로 사용할 것
 - token 확인 필요
 
router.get("/image", async function (req, res, next) {
    try {  
        const query = { _id   : Number(req.query._id)} ;
        const project = {imagedata:1, imagesize:1, imagename:1, imagetype: 1}
        const result = await Food.findOne(query).select(project);
        res.contentType(result.imagetype) // contentType 변경
        return res.send(result.imagedata); // 파일데이터
     
    }
    catch (e) {
        console.error(e);
        return res.send({ status: -1, result: e });
      }
    });