前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >3. 许愿墙后台管理系统(后端接口)

3. 许愿墙后台管理系统(后端接口)

作者头像
爱学习的程序媛
发布2022-04-07 16:05:28
发布2022-04-07 16:05:28
1.7K00
代码可运行
举报
文章被收录于专栏:学习/读书笔记学习/读书笔记
运行总次数:0
代码可运行

许愿墙的后台管理系统主要有4个模块:登录模块、首页模块、许愿管理模块和管理员管理模块。使用前后端分离方式,后端接口使用Express框架,前端使用Vue框架,页面使用Element组件。这节先实现后端接口。

3.1 实现接口

1)登录验证:如果正确,返回登录成功信息和当前登录的管理员信息;如果错误,则返回提示信息;

2)许愿列表:分页返回许愿信息,可通过姓名、创建时间筛选;

3)单条许愿信息:获取某一条许愿信息;

4)新增许愿:添加一条新的许愿信息;

5)修改许愿:修改某一条许愿信息;

6)删除许愿:删除某一条许愿信息;

7)管理员列表:分页返回管理员信息,可通过用户名、姓名、角色筛选;

8)单条管理员信息:获取某一条管理员信息;

9)新增管理员:添加一个新的管理员信息(同一用户名只能添加一次);

10)修改管理员:修改某一条管理员信息;

11)删除管理员:删除某一条管理员信息;

12)除登录外,所有接口须验证是否登录

3.2 创建MySQL数据库表

本节仍然使用上节创建的数据库wish和数据表wish,另外再创建一张数据表admin,用来存放管理员信息。

admin表各字段及其作用:

可以添加一些模拟数据:

3.3 创建后端项目

3.3.1 生成项目目录wish-admin-api

3.3.2 安装依赖包

3.3.3 更改默认端口

默认端口为 3000,为了方便演示以及避免与其他项目冲突,将端口号改为 3002。

3.3.4 增加配置信息

代码语言:javascript
代码运行次数:0
复制
//config.js

const config = {
    DEBUG: true,
    MYSQL: {
        host: 'localhost',
        database: 'wish',
        username: 'root',
        password: '123456'
    }
};

module.exports = config;

3.3.5 增加数据库配置信息

代码语言:javascript
代码运行次数:0
复制
//db.js

const Sequelize = require('sequelize');
const config = require('./config');

const sequelize = new Sequelize(
    config.MYSQL.database,
    config.MYSQL.username,
    config.MYSQL.password, {
        host: config.MYSQL.host,
        dialect: 'mysql',
        logging: config.DEBUG ? console.log : false,//是否打印日志
        pool: {//配置数据库连接池
            max: 5,
            min: 0,
            idle: 10000
        },
        timezone: '+08:00'//时区设置
    }
);

module.exports = sequelize;

3.3.6 增加常量信息

代码语言:javascript
代码运行次数:0
复制
//constant/constant.js

const constantObj = {
    //请求成功
    DEFAULT_SUCCESS: {
        code: '00',
        msg: '操作成功'
    },
    // 请求失败
    DEFAULT_ERROR: {
        code: '01',
        msg: '操作失败'
    },
    //缺少必要参数
    LACK: {
        code: '02',
        msg: '缺少必要参数'
    },
    // Token验证失败
    TOKEN_ERROR: {
        code: '03',
        msg: 'Token验证失败'
    },
    // 用户名或密码错误
    LOGIN_ERROR: {
        code: '04',
        msg: '用户名或密码错误'
    },
    // 管理员信息不存在
    ADMIN_NOT_EXSIT: {
        code: '05',
        msg: '管理员信息不存在'
    },
    // 许愿信息不存在
    WISH_NOT_EXSIT: {
        code: '06',
        msg: '许愿信息不存在'
    },
    //数据已存在
    DATA_EXSIT: {
        code: '07',
        msg: '数据已存在'
    }
};

module.exports = constantObj;

3.3.7 增加数据库映射信息

代码语言:javascript
代码运行次数:0
复制
//models/wish.js

const Sequelize = require('sequelize');
const db = require('../db');

const Wish = db.define('Wish', {
    id: {type: Sequelize.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true},
    name: {type: Sequelize.STRING(20), allowNull: false},
    content: {type: Sequelize.STRING, allowNull: false}
}, {
    underscored: true,
    tableName: 'wish'
});

module.exports = Wish;
代码语言:javascript
代码运行次数:0
复制
//models/admin.js

const Sequelize = require('sequelize');
const db = require('../db');

const Admin = db.define('Admin', {
    id: {type: Sequelize.INTEGER, primaryKey: true, allowNull: false, autoIncrement: true},
    username: {type: Sequelize.STRING(20), allowNull: false},
    password: {type: Sequelize.STRING(36), allowNull: false},
    name: {type: Sequelize.STRING(20), allowNull: false},
    role: {type: Sequelize.INTEGER, allowNull: false},
    lastLoginAt: {type: Sequelize.DATE}
}, {
    underscored: true,
    tableName: 'admin'
});

module.exports = Admin;

3.3.8 增加公共方法

代码语言:javascript
代码运行次数:0
复制
//controllers/common.js

const async = require('async');
const Constant = require('../constant/constant');

const exportObj = {
    clone,
    checkParams,
    autoFn
};

module.exports = exportObj;

/**
* 克隆方法,克隆一个对象
* @param obj
* @returns {any}
*/
function clone(obj){
    return JSON.parse(JSON.stringify(obj));
}

/**
* 校验参数方法
* @param params 请求的参数集
* @param checkArr 需要验证的参数
* @param cb 回调
*/
function checkParams(params, checkArr, cb){
    let flag = true;
    checkArr.forEach(val => {
        if(!params[val]){
            flag = false;
        }
    });
    if(flag){
        cb(null);
    }else {
        cb(Constant.LACK);
    }
}

/**
* 返回JSON格式数据
* @param tasks 当前controller执行的tasks
* @param res Response对象
* @param resObj 当前controller返回json对象
*/
function autoFn(tasks, res, resObj){
    async.auto(tasks, err => {
        if(err){
            console.log(JSON.stringify(err));
            res.json({
                code: err.code || Constant.DEFAULT_ERROR.code,
                msg: err.msg || JSON.stringify(err)
            })
        }else {
            res.json(resObj)
        }
    });
}

3.3.9 增加Token处理方法

代码语言:javascript
代码运行次数:0
复制
//controllers/token.js

const jwt = require('jsonwebtoken');

// 设置一个密钥,用来加密和解密token
const tokenKey = 'XfZEpWEn? ARD7rHBN';

const Token = {
    /**
     * 加密
     * param data 需要加密在Token中的数据
     * param time Token的过期时间,单位为s
     * returns {*} 返回一个Token
     */
    encrypt(data, time){
        return jwt.sign(data, tokenKey, {expiresIn: time});
    },
    /**
     * 解密
     * param token 加密之后的Token
     * returns 返回对象
     * {
     *      token: boolean, //(true表示Token合法,false则表示不合法)
     *      data: * //(解密出来的数据或错误信息)
     *  }
     */
    decrypt(token){
        try {
            let data = jwt.verify(token, tokenKey);
            return {
                token: true,
                data: data
            }
        }catch(err){
            return {
                token: false,
                data: err
            }
        }
    }
};

module.exports = Token;

3.3.10 增加路由处理方法

代码语言:javascript
代码运行次数:0
复制
//controllers/index.js

const dateFormat = require('dateformat');
const Common = require('./common');
const AdminModel = require('../models/admin');
const Constant = require('../constant/constant');
const Token = require('./token');

// 设置默认Token过期时间,单位为s
const TOKEN_EXPIRE_SENCOND = 36000;

let exportObj = {
    login
};

module.exports = exportObj;

//登录
function login(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['username', 'password'], cb);
        },
        query: ['checkParams', (results, cb) => {
            AdminModel.findOne({
                where: {
                    username: req.body.username,
                    password: req.body.password
                }
            }).then(result => {
                if(result){
                    resObj.data = {
                        id: result.id,
                        username: result.username,
                        name: result.name,
                        role: result.role,
                        lastLoginAt: dateFormat(result.lastLoginAt, 'yyyy-mm-dd HH:MM:ss'),
                        createdAt: dateFormat(result.createdAt, 'yyyy-mm-dd HH:MM:ss')
                    };
                    const adminInfo = {
                        id: result.id
                    };
                    // 生成Token
                    let token = Token.encrypt(adminInfo, TOKEN_EXPIRE_SENCOND);
                    resObj.data.token = token;
                    cb(null, result.id);
                }else {
                    cb(Constant.LOGIN_ERROR);
                }
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }],
        writeLastLoginAt: ['query', (results, cb) => {
            let adminId = results['query'];
            AdminModel.update({
                lastLoginAt: new Date()
            },{
                where: {
                    id: adminId
                }
            }).then(result => {
                if(result){
                    cb(null);
                }else {
                    cb(Constant.DEFAULT_ERROR);
                }
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}
代码语言:javascript
代码运行次数:0
复制
//controllers/wish.js

const dateFormat = require('dateformat');
const Common = require('./common');
const WishModel = require('../models/wish');
const Constant = require('../constant/constant');

let exportObj = {
    getWishList,
    getWishInfo,
    addWish,
    updateWish,
    removeWish
};

module.exports = exportObj;

// 获取许愿列表
function getWishList(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.query, ['page', 'rows'], cb);
        },
        query: ['checkParams', (results, cb) => {
            let offset = req.query.rows * (req.query.page - 1) || 0;
            let limit = parseInt(req.query.rows) || 10;
            let whereCondition = {};
            if(req.query.name){
                whereCondition.name = req.query.name;
            }
            if(req.query.createdAt){
                whereCondition.createdAt = req.query.createdAt;
            }
            WishModel.findAndCountAll({
                where: whereCondition,
                offset: offset,
                limit: limit,
                order: [['created_at', 'DESC']]
            }).then(result => {
                let list = [];
                result.rows.forEach(val => {
                    let obj = {
                        id: val.id,
                        name: val.name,
                        content: val.content,
                        createdAt: dateFormat(val.createdAt, 'yyyy-mm-dd HH:MM:ss')
                    };
                    list.push(obj);
                });
                resObj.data = list;
                resObj.count = result.count;
                cb(null);
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}

//获取单条许愿信息
function getWishInfo(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.params, ['id'], cb);
        },
        query: ['checkParams', (results, cb) => {
            WishModel.findByPk(req.params.id)
                    .then(result => {
                        if(result){
                            resObj.data = {
                                id: result.id,
                                name: result.name,
                                content: result.content,
                                createdAt: dateFormat(result.createdAt, 'yyyy-mm-dd HH:MM:ss')
                            };
                            cb(null);
                        }else {
                            cb(Counstant.WISH_NOT_EXSIT);
                        }
                    }).catch(err => {
                        console.log(err);
                        cb(Constant.DEFAULT_ERROR);
                    })

        }]
    };
    Common.autoFn(tasks, res, resObj);
}

// 添加许愿
function addWish(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['name', 'content'], cb);
        },
        add: ['checkParams', (results, cb) => {
            WishModel.create({
                name: req.body.name,
                content: req.body.content
            }).then(result => {
                cb(null);
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}

//修改许愿
function updateWish(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['id', 'name', 'content'], cb);
        },
        update: ['checkParams', (result, cb) => {
            WishModel.update({
                name: req.body.name,
                content: req.body.content
            }, {
                where: {
                    id: req.body.id
                }
            }).then(result => {
                if(result[0]){
                    cb(null)
                }else {
                    cb(Constant.WISH_NOT_EXSIT);
                }
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]

    };
    Common.autoFn(tasks, res, resObj);
}

//删除许愿
function removeWish(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['id'], cb);
        },
        remove: ['checkParams', (result, cb) => {
            WishModel.destroy({
                where: {
                    id: req.body.id
                }
            }).then(result => {
                if(result){
                    cb(null);
                }else {
                    cb(Constant.WISH_NOT_EXSIT);
                }

            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}
代码语言:javascript
代码运行次数:0
复制
//controllers/admin.js

const dateFormat = require('dateformat');
const Common = require('./common');
const AdminModel = require('../models/admin');
const Constant = require('../constant/constant');

let exportObj = {
    getAdminList,
    getAdminInfo,
    addAdmin,
    updateAdmin,
    removeAdmin
};

module.exports = exportObj;

// 获取管理员列表
function getAdminList(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.query, ['page', 'rows'], cb);
        },
        query: ['checkParams', (results, cb) => {
            let offset = req.query.rows * (req.query.page - 1) || 0;
            let limit = parseInt(req.query.rows) || 10;
            let whereCondition = {};
            if(req.query.username){
                whereCondition.username = req.query.username;
            }
            if(req.query.name){
                whereCondition.name = req.query.name;
            }
            if(req.query.role){
                whereCondition.role = req.query.role;
            }
            if(req.query.createdAt){
                whereCondition.createdAt = req.query.createdAt;
            }
            AdminModel.findAndCountAll({
                where: whereCondition,
                offset: offset,
                limit: limit,
                order: [['created_at', 'DESC']]
            }).then(result => {
                let list = [];
                result.rows.forEach(val => {
                    let obj = {
                        id: val.id,
                        username: val.username,
                        name: val.name,
                        role: val.role,
                        createdAt: dateFormat(val.createdAt, 'yyyy-mm-dd HH:MM:ss'),
                        lastLoginAt: dateFormat(val.lastLoginAt, 'yyyy-mm-dd HH:MM:ss'),
                    };
                    list.push(obj);
                });
                resObj.data = list;
                resObj.count = result.count;
                cb(null);
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}

//获取单条管理员信息
function getAdminInfo(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.params, ['id'], cb);
        },
        query: ['checkParams', (results, cb) => {
            AdminModel.findByPk(req.params.id)
                    .then(result => {
                        if(result){
                            resObj.data = {
                                id: result.id,
                                username: result.username,
                                name: result.name,
                                role: result.role,
                                createdAt: dateFormat(result.createdAt, 'yyyy-mm-dd HH:MM:ss'),
                                lastLoginAt: dateFormat(result.lastLoginAt, 'yyyy-mm-dd HH:MM:ss'),
                            };
                            cb(null);
                        }else {
                            cb(Counstant.ADMIN_NOT_EXSIT);
                        }
                    }).catch(err => {
                        console.log(err);
                        cb(Constant.DEFAULT_ERROR);
                    })

        }]
    };
    Common.autoFn(tasks, res, resObj);
}

// 添加管理员
function addAdmin(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['username', 'password', 'name', 'role'], cb);
        },
        query: ['checkParams', (results, cb) => {
            AdminModel.findOne({
                where: {
                    username: req.body.username,
                }
            }).then(result => {
                if(result && result.username === req.body.username){
                    cb(Constant.DATA_EXSIT);
                }else {
                    cb(null);
                }
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }],
        add: ['query', (results, cb) => {
            AdminModel.create({
                username: req.body.username,
                password: req.body.password,
                name: req.body.name,
                role: req.body.role
            }).then(result => {
                cb(null);
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}

//修改管理员
function updateAdmin(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['id', 'username', 'password', 'name', 'role'], cb);
        },
        update: ['checkParams', (result, cb) => {
            AdminModel.update({
                username: req.body.username,
                password: req.body.password,
                name: req.body.name,
                role: req.body.role
            }, {
                where: {
                    id: req.body.id
                }
            }).then(result => {
                if(result[0]){
                    cb(null)
                }else {
                    cb(Constant.ADMIN_NOT_EXSIT);
                }
            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]

    };
    Common.autoFn(tasks, res, resObj);
}

//删除管理员
function removeAdmin(req, res){
    const resObj = Common.clone(Constant.DEFAULT_SUCCESS);
    let tasks = {
        checkParams(cb){
            Common.checkParams(req.body, ['id'], cb);
        },
        remove: ['checkParams', (result, cb) => {
            AdminModel.destroy({
                where: {
                    id: req.body.id
                }
            }).then(result => {
                if(result){
                    cb(null);
                }else {
                    cb(Constant.ADMIN_NOT_EXSIT);
                }

            }).catch(err => {
                console.log(err);
                cb(Constant.DEFAULT_ERROR);
            })
        }]
    };
    Common.autoFn(tasks, res, resObj);
}

3.3.11 增加token验证方法

代码语言:javascript
代码运行次数:0
复制
routes/middelware/verify.js

const Token = require('../../controllers/token');
const Constant = require('../../constant/constant');

const exportObj = {
    verifyToken,
};

module.exports = exportObj;

//验证Token中间件
function verifyToken(req, res, next){
    //如果请求路径是/login,即登录页,则跳过,继续下一步
    if(req.path === '/login') return next();
    let token = req.headers.token;
    //解密
    let tokenVerifyObj = Token.decrypt(token);
    if(tokenVerifyObj.token){
        next();
    }else {
        res.json(Constant.TOKEN_ERROR);
    }
}

3.3.12 增加路由

代码语言:javascript
代码运行次数:0
复制
//routes/index.js

const express = require('express');
const router = express.Router();
const IndexController = require('../controllers/index');

router.post('/login', IndexController.login);

module.exports = router;
代码语言:javascript
代码运行次数:0
复制
//routes/wish.js

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

const WishController = require('../controllers/wish');

router.get('/', WishController.getWishList);

router.get('/:id', WishController.getWishInfo);

router.post('/', WishController.addWish);

router.put('/', WishController.updateWish);

router.delete('/', WishController.removeWish);

module.exports = router;
代码语言:javascript
代码运行次数:0
复制
//routes/admin.js

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

const AdminController = require('../controllers/admin');

router.get('/', AdminController.getAdminList);

router.get('/:id', AdminController.getAdminInfo);

router.post('/', AdminController.addAdmin);

router.put('/', AdminController.updateAdmin);

router.delete('/', AdminController.removeAdmin);

module.exports = router;

3.3.13 修改app.js文件

代码语言:javascript
代码运行次数:0
复制
...
const verifyMiddleware = require('./routes/middleware/verify');

const indexRouter = require('./routes/index');
const wishRouter = require('./routes/wish');
const adminRouter = require('./routes/admin');
...
app.use('/', indexRouter);
app.use('/wish', verifyMiddleware.verifyToken, wishRouter);
app.use('/admin', verifyMiddleware.verifyToken, adminRouter);
...
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱学习的程序媛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档