궤도

[백엔드] Node.js + Sequelize + MySQL 시험지 리스트를 만들어보자 본문

💻 현생/📃 VIVA

[백엔드] Node.js + Sequelize + MySQL 시험지 리스트를 만들어보자

영이오 2021. 2. 11. 16:48

지난번에 미니모의고사를 만들었다. 만들었으면 그걸 관리하는 페이지도 있어야 한다. 그러니 이번에는 사용자가 만든 시험지를 볼 수 있는 시험지 리스트를 만들어보자.

 


시험지 리스트

 

routes/test.list.js(시험지 리스트)

//미니모의고사 가져오기
//localhost:3001/api/test/list?stu_id=samdol
router.get('/', async function (req, res, next) {
    let result = await models.student.findOne({
        where: {
            stu_id: req.query.stu_id
        }
    });
    const user = result.dataValues.stu_sn;

    //사용자가 보유한 미니모의고사
    let test_list = await models.test.findAll({
        where: {
            stu_sn: user
        }
    });

    if (test_list.length != 0) {
        try {
            res.send({ //모의고사 정보 넘김
                message: "test list",
                status: 'success',
                data: {
                    test_list
                }
            });
        } catch (err) { //무언가 문제가 생김
            res.send({
                message: "ERROR",
                status: 'fail'
            })
        }
    }
    else{ //미니모의고사 없음
        res.send({
            message: "No data or fail",
            status: 'null'
        })
    }
});

입력받은 stu_id를 stu_sn으로 바꾼 뒤 test 테이블에 가서 해당하는 학생의 시험지를 전부 가져오면 된다.

시험지가 없는 경우도 처리해두자.

 

localhost:3001/api/test/list?stu_id=samdol


문제 상세보기

 

위에 있는 프로토를 보면 알겠지만 우리 앱에는 시험지 다운로드 기능이 있다. 당장 구현할 것은 아니지만 어쨌든 이걸 구현하려면 시험지의 문제(이미지)를 가져와야 한다.

 

 

routes/test.list.js(문제 열람)

//미니모의고사 다운로드에 쓰지 않을까 싶어서...
//localhost:3001/api/test/list/download?test_sn=18&stu_id=samdol
router.get('/download', async function (req, res, next) {
    let result = await models.student.findOne({
        where: {
            stu_id: req.query.stu_id
        }
    });
    const user = result.dataValues.stu_sn;

    models.test_pb_map.belongsTo(models.problem, { foreignKey: "pb_sn"});
    models.problem.hasMany(models.test_pb_map, { foreignKey: "pb_sn"});

    //다운로드 할 모의고사 문제의 이미지
    let pbs_img = await models.problem.findAll({
        attributes: ['pb_sn', 'pb_img'],
        include: [
            {
                model: models.test_pb_map,
                attributes: [],
                where: {
                    test_sn: req.query.test_sn
                }
            }
        ]
    });

    try {
        res.send({ //문제 정보 넘김
            message: "problems",
            status: 'success',
            data: {
                pbs_img
            }
        });
    } catch (err) { //무언가 문제가 생김
        res.send({
            message: "ERROR",
            status: 'fail'
        })
    }
});

시험지의 pk인 test_sn을 입력으로 받고 있으니 이걸 갖고 test_pb_map 테이블에 가서 pb_sn을 찾고 problem 테이블에서 그 이미지를 찾으면 될 것이다.

 

    models.test_pb_map.belongsTo(models.problem, { foreignKey: "pb_sn"});
    models.problem.hasMany(models.test_pb_map, { foreignKey: "pb_sn"});

    //다운로드 할 모의고사 문제의 이미지
    let pbs_img = await models.problem.findAll({
        attributes: ['pb_sn', 'pb_img'],
        include: [
            {
                model: models.test_pb_map,
                attributes: [],
                where: {
                    test_sn: req.query.test_sn
                }
            }
        ]
    });

여전히 왜 이런식으로 밖에 조인을 못하는지 짜증나지만 어쨌든 이렇게 문제의 sn과 img를 가져오고...

 

    try {
        res.send({ //문제 정보 넘김
            message: "problems",
            status: 'success',
            data: {
                pbs_img
            }
        });
    } catch (err) { //무언가 문제가 생김
        res.send({
            message: "ERROR",
            status: 'fail'
        })
    }

넘겨주면?

 

localhost:3001/api/test/list/download?test_sn=18&stu_id=samdol

뭐 언젠가 쓰겠지...


시험지 삭제

 

해당하는 시험지를 test 테이블에서 삭제하면 된다. 테이블 만들 때 on_delete_cascade를 해놨었기 때문에 test_pb_map의 데이터들도 자동으로 삭제될 것이다.

 

routes/test.list.js(시험지 삭제)

// Delete
//localhost:3001/api/test/list/'삭제할 미니모의고사 sn'?stu_id=samdol
router.delete('/:sn', async function (req, res, next) {
    const sn = req.params.sn;

    let result = await models.student.findOne({
        where: {
            stu_id: req.query.stu_id
        }
    });
    const user = result.dataValues.stu_sn;

    models.test.destroy({
        where: {
            stu_sn: user,
            test_sn: sn
        }
    })
        .then(num => {
            if (num == 1) { //성공
                res.send({
                    message: "Delete test",
                    status: 'success'
                });
            } else { //데이터 입력을 잘못한듯
                res.send({
                    message: "Data was not found!",
                    status: 'fail'
                });
            }
        })
        .catch(err => { //에러
            res.send({
                message: "Could not delete test",
                status: 'fail'
            });
        });
});

굳이 설명할 필요는 없을 것 같다.

 

localhost:3001/api/test/list/20?stu_id=samdol

시험지 삭제

Comments