nodejs操作数据库

  • 服务器server
    • server.js
  • router文件
    • index.js
    • goods.js
    • user.js
    • reg.js
    • login.js
    • vcode.js
    • upload.js
  • utils文件
    • mongo.js
    • mysql.js
    • tools.js
    • token.js
  • public文件
    • index.html
    • login.html
    • reg.html
    • manage文件夹
      • goods.html
      • index.html
      • order.html
      • user.html
      • user文件下edit.html
    • upload文件放上传的头像
  • assets文件
  • package
    • package.json
    • config.json
  • 文件目录
  • 功能说明:

以代码说明操作过程;

服务器server

server.js

const express = require('express');
const {PORT
} = require('./config.json');
const rootRouter = require('./router');
const path = require('path')//创建一个服务器
const app = express();//  ./ 是当前目录
//   / 是根目录
// 启用静态资源服务器
app.use(express.static(path.join(__dirname, './public'), {// maxAge:60*60*1000*24
}));// 数据接口
app.use('/api', rootRouter);app.listen(PORT, () => {console.log('server is running on port ' + PORT)

router文件

index.js

// const express = require('express')
// const router = express.Router()// const user = require('./use')
// const goods = require('./goods')
// // 格式化参数
// router.use(express.urlencoded(), express.json());// 或者直接解构上面代码
const {Router,urlencoded,json
} = require('express');
// express.json===bodyParse.json, ....
const session = require('express-session')
const token = require('../utils/token');const router = Router();const userRouter = require('./user');
const goodsRouter = require('./goods');
const regRouter = require('./reg');
const loginRouter = require('./login');
const vcodeRouter = require('./vcode');
const uploadRouter = require('./upload');
const {formatData
} = require('../utils/tools');// 数据格式化中间件
router.use(urlencoded({extended: false
}), json())// 使用session会话
// 通过req.session获取存入会话的数据
router.use(session({// 密钥一致secret: 'fqniu',resave: false,saveUninitialized: true,cookie: {// 设置cookie有效期maxAge: 1000 * 60 * 60 * 2}
}))// /api/user
router.use('/user', userRouter);// /api/goods
router.use('/goods', goodsRouter);// 注册
router.use('/reg', regRouter);// 登录
router.use('/login', loginRouter);// 上传
router.use('/upload', uploadRouter);// 校验token
router.get('/jwtverify', (req, res) => {const {authorization} = req.query;console.log('test', authorization)// verify方法校验成功:得到一个对象// verify方法校验不通过:直接抛出错误// try{//     var decoded = jwt.verify(authorization, 'laoxie');//     res.send(formatData())// }catch(err){//     res.send(formatData({code:0}))// }if (token.verify(authorization)) {res.send(formatData())} else {res.send(formatData({code: 0}))}
});// 验证码
router.use('/vcode', vcodeRouter);
module.exports = router;

goods.js

const express = require('express')
const router = express.Router()const mongo = require('../utils/mongo')const {ObjectId
} = require('mongodb')// console.log(mongo)
/*
{insert: [AsyncFunction: insert],remove: [AsyncFunction: remove],update: [AsyncFunction: update],find: [AsyncFunction: find]
}
*/// 1、get 查询所有商品数据   /api/goods
router.get('/', async (req, res) => {let {page = 1, size = 2, sort = 'price'} = req.queryconst skip = (page - 1) * sizeconst limit = size * 1 //这里*1 是为了转为数值型// 处理排序参数sort = sort.split(',') //["price"],["price",'-1]// 查询所有的商品const result = await mongo.find('goods', {}, {skip,limit,sort})res.send(result)
})// 2、delete 删除数据 单
router.delete('/:id', async (req, res) => {const {id} = req.params// console.log(id)try {const result = await mongo.remove('goods', {_id: id})res.send('success')} catch (err) {res.send('fail')}})// 3、post 增加数据 单或多
router.post('/', async (req, res) => {const good = req.body// console.log(good)try {const result = await mongo.insert('goods', good)res.send('success')} catch (err) {res.send('fail')}})// 4、put 修改数据 单
router.put('/:id', async (req, res) => {const {id} = req.params// console.log(req.params)try {const result = await mongo.update('goods', {// 匹配id_id: ObjectId(id)}, {$set: {price: 200}})res.send('success')} catch (err) {res.send('fail')}})module.exports = router

user.js

const express = require('express');
const router = express.Router();
// const query = require('../utils/mysql');
const mongo = require('../utils/mongo');
const {formatData,md5} = require('../utils/tools')// const mysql = require('mysql');// 配置数据库
// 第一种:使用连接对象
// var connection = mysql.createConnection({//     host     : 'localhost',
//     user     : 'root',
//     password : '',
//     database : 'jiaoxue'
// });// 第二种:使用连接池(推荐)
//创建连接池:默认创建10个连接对象放到连接池中
// var pool  = mysql.createPool({//     host     : 'localhost',
//     user     : 'root',
//     password : '',
//     database: 'jiaoxue',
//     multipleStatements: true
// });router.get('/',async (req,res)=>{// 读取数据库,获取所有用户// let sql = `select * from user`;// 1. 连接mySQL数据库// connection.connect();// // 2. 查询所有用户// connection.query(sql, (error, results, fields) => {//     if (error) throw error;//     console.log('results=', results);//     console.log('fields=', fields);//     res.send(results)//     // 关闭连接,释放资源//     connection.end();// })// pool.query(sql, (error, results, fields) => {//     if (error) throw error;//     console.log('results=', results);//     console.log('fields=', fields);//     res.send(results)// })// query(sql,function(result){//     res.send(reusult)// })// const result = await query(sql); // 等效于query(sql).then(result=>{})// mongoconst result = await mongo.find('user')res.send(formatData({data:result}));
})router.delete('/:id',async (req,res)=>{const {id} = req.params;// let sql = `delete from user where id=${id}`;// connection.connect();// connection.query(sql, (error, results, fields) => {//     if (error) throw error;//     res.send('删除成功')//     connection.end()// })// pool.query(sql, (error, results, fields) => {//     if (error) throw error;//     res.send('删除成功')// })// try{//     // 尝试执行这里的代码//     const result = await query(sql);//     res.send(result)// }catch(err){//     // 如果上面的代码有报错,则执行这里的代码//     res.send('删除失败')// }try{await mongo.remove('user',{_id:id});res.send(formatData())}catch(err){res.send(formatData({code:0}))}})// 获取单个用户信息
router.get('/:id',async(req,res)=>{const {id} = req.params;console.log('id=',id)const result = await mongo.find('user',{_id:id});console.log(result)res.send(formatData({data:result[0]}));
})// 修改单个用户信息
router.put('/:id',async (req,res)=>{const {id} = req.params;let {password,age,gender} = req.body;console.log()let newData = {age,gender}if(password){password = md5(password);newData.password = password}try{await mongo.update('user',{_id:id},{$set:newData});res.send(formatData({data:{_id:id,...newData}}))}catch(err){// console.log('err=',err);res.send(formatData({code:0}))}})
module.exports = router;

reg.js

const express = require('express');
const router = express.Router();const {formatData,md5} = require('../utils/tools');
const mongo = require('../utils/mongo');// RESTful api规范
// 注册
router.post('/',async (req,res)=>{let {username,password} = req.body;console.log('password1=',password)// 引用模块里面的函数password = md5(password)let resulttry{result = await mongo.insert('user',{username,password});res.send(formatData());}catch(err){res.send(forMatData({code:0}))}
})// 检查是否用户名重复
router.get('/check',async (req,res)=>{const {username} = req.query;const result = await mongo.find('user',{username});if(result.length>0){res.send(formatData({code:0}))}else{res.send(formatData())}
})module.exports = router;

login.js

const express = require('express');
const router = express.Router();// 引入 封装的 token 模块
const token = require('../utils/token');const { formatData,md5 } = require('../utils/tools');
const mongo = require('../utils/mongo');// 登录
router.get('/', async (req, res) => {let { username, password, vcode, mdl } = req.query;// 其中vcode是前端输入的验证码// 从会话中获取验证码// 校验验证码 这里的req.session 是已经存有vcode的 Session 对象console.log('login.session=', req.session)// vcode 是前端输入验证码之后,传过来的参数 // 而 req.session.vcode 是Session中的存的 vcodeif (vcode !== req.session.vcode) {res.send(formatData({ code: 10 }))return;}// 加密后进行查询password = md5(password)let result = await mongo.find('user', { username, password }); //[{}]// 判断如果 find 找到 有result, 则返回这个数组数据// 如果find 找不到 ,则result为 空数组if (result.length > 0) {// 用户名、密码、验证码都校验通过后,判断是否有免登陆选项console.log('req.query=', req.query);let authorization;if (mdl === 'true') {// token的操作// 1. 生成token// const token = jwt.sign({ username }, 'laoxie' ,{//     // token有效期//     expiresIn: 20//1000 * 60 * 60 * 24 * 7// });authorization = token.create({ username }, '7d')}else{authorization = token.create({ username })}console.log('token=', authorization);result = result[0];result.authorization = authorizationres.send(formatData({ data: result }));} else {res.send(formatData({ code: 0 }))}
})module.exports = router;

vcode.js

验证码制作模块

const express = require('express')
const router = express.Router()// 导入验证码制作模块
const svgCaptcha = require('svg-captcha')const {formatData
} = require('../utils/tools')// 生成验证码
router.get('/', async (req, res) => {// 生成图像验证码:svg-captcha 参数const options = {noise: 3,ignoreChars: '0o1il',background: '#58BC58',color: true,fontSize: 50,height: 38}// 验证码生成 createconst captcha = svgCaptcha.create(options)// console.log(captcha)// captcha 生成的返回值是 : {text:'abcd',data: '<svg />'}// console.log(captcha.text)// 页面刷新就生成一个验证码// 先打印 查看是否有 session , 打印值:Session { cookie:{} }// console.log('login.session=', req.session) // 把验证码存入会话 Session 对象中req.session.vcode = captcha.text.toLocaleLowerCase()// 再打印查看是否存入验证码 , 打印值:Session { cookie:{}, vcode:'xxxx' }// console.log('vcode.session=', req.session)// 把data 中的 svg 传给前端 渲染 验证码 结构样式res.send(formatData({data: captcha.data}))})module.exports = router

upload.js

const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require('path');const mongo = require('../utils/mongo');
const { formatData, md5 } = require('../utils/tools')// 配置上传参数
let storage = multer.diskStorage({// destination: function (req, file, cb) {//   cb(null, './uploads/');// },// 上传文件保存目录,无则自动创建destination: path.join(__dirname, '../public/uploads/'),// 格式化文件名:字段名+时间戳+扩展名// avatar-1597202347355.jpgfilename: function (req, file, cb) {// 获取文件后缀名let ext = path.extname(file.originalname);cb(null, file.fieldname + '-' + Date.now() + ext);}
})// 设置中间件
const uploadMiddleware = multer({ storage });// post /api/upload/avatar
router.post('/avatar', uploadMiddleware.single('avatar'), (req, res) => {// 中间件会把图片信息格式化到req.file,req.filesconsole.log('file=', req.file, req.body);const { _id } = req.body;// 更新用户信息const avatarUrl = '/uploads/' + req.file.filenamemongo.update('user', { _id }, { $set: { avatarUrl } })res.send(formatData({ data: { _id, avatarUrl } }));
})// 一次性最多传5张图片
router.post('/goods', uploadMiddleware.array('goods', 5), (req, res) => {})module.exports = router;

utils文件

mongo.js

/*** * mongodb 操作封装* *///  官网写法如下:
// const MongoClient = require('mongodb').MongoClient;
// // Connection URL
// const url = 'mongodb://localhost:27017';
// // Database Name
// const dbName = 'user';
// // Use connect method to connect to the server
// MongoClient.connect(url, function (err, client) {//   console.log("Connected successfully to server");
//   const db = client.db(dbName);
//   client.close();
// });// 引入mongodb模块 并结构需要用到的方法,源码中在lib/bulk/common.js
const {MongoClient,ObjectId
} = require('mongodb')//  mongodb 数据库地址
const url = 'mongodb://localhost:27017'// 数据库名称
const dbName = 'user'async function connect(){// return new Promise((resolve,reject)=>{//     MongoClient.connect(url, function (err, client) {//         // client: mongo客户端//         if(err){//             reject(err);//         }//         // 匹配数据库//         const db = client.db(dbName);//         // 导出db和client//         resolve({db,client})//         // 数据库操作//         // 数据库操作完成后关闭连接,释放资源//         // client.close();//     });// })const client = await MongoClient.connect(url);const db = client.db(dbName);return {client,db}
}// 增
async function insert(colName,data){// 1. 连接数据库const {db,client} = await connect();// 2. 添加数据// 根据传入的集合名称获取数据库中的某个集合const collection = db.collection(colName);// if(Array.isArray(data)){//     collection.insertMany(data); // collection['inserMany']// }else{//     collection.insertOne(data)// }const result = await collection[Array.isArray(data) ? 'insertMany':'insertOne'](data)// 3. 关闭连接client.close()return result;
}// 删
async function remove(colName,query){ // query{_id:'5c128cdbd1233ce12c878a32'}const {db,client} = await connect();if(query._id && typeof query._id === 'string'){query._id = ObjectId(query._id);}const collection = db.collection(colName);const result = await collection.deleteMany(query);client.close();return result;
}// 改
async function update(colName,query,newData){ // newData{$set:{price:200,qty:2},$inc:{view:1}}const {db,client} = await connect();const collection = db.collection(colName);if(query._id && typeof query._id === 'string'){query._id = ObjectId(query._id);}const result = await collection.updateMany(query,newData);return result;
}// 查
async function find(colName,query={},options={}){ // options={litmit:10,skip:0}const {client,db} = await connect();const collection = db.collection(colName);if(query._id && typeof query._id === 'string'){query._id = ObjectId(query._id);}// 查询到数据集合let result = collection.find(query); // 50->10// 判断是否要跳过记录if(options.skip){result = result.skip(options.skip)}if(options.limit){result = result.limit(options.limit);}// 排序console.log('sort',options.sort);if(options.sort){ //['price'],['price','1']let key,val;key = options.sort[0];if(options.sort.length>1){val = options.sort[1]*1;}else{val = -1;}result = result.sort({[key]:val})}result = await result.toArray();client.close();return result
}module.exports = {insert,remove,update,find
}

mysql.js

/*** * 封装mysql数据库操作的方法* */const mysql = require('mysql')var pool = mysql.createPool({host: 'localhost',user: 'root',password: 'nfq123456',database: 'udata',multipleStatements: true
})// // 第一种:回调函数 实现数据传递
// function query(sql, callback) {//   pool.query(sql, (err, results, fields) => {//     if (err) throw err
//     callback(results)
//   })
// }// 第二种:promise
function query(sql) {return new Promise((resolve, reject) => {pool.query(sql, (err, results, fields) => {if (err) {reject(err)}resolve(results)})})
}module.exports = query

tools.js


const crypto = require('crypto');
// 参数有三个 code 判断输入结果 默认是 success
function formatData({code=1,data=[],msg='success'}={}){if(code === 0){msg = 'fail';}return {code,data,msg}
}// 封装的加密函数
function md5(data,privateKey='laoxie'){const hash = crypto.createHash('md5');hash.update(data+privateKey); // 加盐 盐值const result = hash.digest('hex');return result;
}module.exports = {formatData,md5
}

token.js

const jwt = require('jsonwebtoken');const privateKey = 'fqniu';function create(data = {}, expiresIn = '2h') {const token = jwt.sign({...data}, privateKey, {// token有效期expiresIn});return token;
}function verify(token) {let result;try {jwt.verify(token, privateKey);result = true;} catch (err) {result = false}return result;
}module.exports = {create,verify
}

public文件

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台管理系统</title>
</head><body><h1>后台管理系统</h1><script>(async () => {// 获取 localStorage 的值 const authorization = localStorage.getItem('authorization')// console.log('auth=', authorization)if (authorization) {// 校验 token 的有效性const result = await fetch(`http://localhost:3000/api/jwtverify?authorization=${authorization}`).then(res => res.json())// console.log(result)if (result.code === 0) {localStorage.removeItem('authorization')location.href = "../login.html"}}})()</script>
</body></html>

login.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录</title><link rel="stylesheet" href="./assets/bootstrap/css/bootstrap.css">
</head><body><div class="reg container-fluid"><h1>登录获取更多...</h1><div class="form-group"><label for="username">用户名:</label><input type="text" class="form-control" id="username" aria-describedby="emailHelp"><div class="invalid-feedback">用户或密码错误</div></div><div class="form-group"><label for="password">密码</label><input type="password" class="form-control" id="password"><div class="invalid-feedback">用户或密码错误</div></div><div class="form-group"><label for="vcode">验证码</label><div class="input-group"><input type="text" class="form-control" id="vcode"><div class="input-group-append"><span class="input-group-text" id="svgVcode" style="padding:0">Ad2b</span></div><div class="invalid-feedback">验证码错误</div></div></div><div class="form-group"><label for="freeLogin"><input type="checkbox" id="freeLogin" checked>7天免登陆</label></div><button type="submit" class="btn btn-primary btnLogin">登录</button></div><script>const username = document.querySelector('#username');const password = document.querySelector('#password');const btnLogin = document.querySelector('.btnLogin');const svgVcode = document.querySelector('#svgVcode')const vcode = document.querySelector('#vcode')// 判断用户是否已经登录const authorization = localStorage.getItem('authorization')// 如果存在这个authorization 则处于当前页面,否则返回登录页面 超时也一样if (authorization) {location.href = 'manage/index.html'}// 获取图形验证码async function getVcode() {const result = await fetch(`http://localhost:3000/api/vcode?`).then(res => res.json())// if (result.code === 1) {svgVcode.innerHTML = result.data}}getVcode()// 点击刷新验证码svgVcode.onclick = getVcode// 点击发送 登录 请求btnLogin.onclick = async () => {const _username = username.valueconst _password = password.valueconst _vcode = vcode.valueconst _freeLogin = freeLogin.checked// console.log(_vcode)const result = await fetch(`http://localhost:3000/api/login?username=${_username}&password=${_password}&vcode=${_vcode}&freeLogin=${_freeLogin}`,{// 这里的是get请求,可以不用写 fetch请求默认是 get 请求method: 'get'// 这里用res.json() 是为了前后端统一传递接口数据格式}).then(res => res.json())console.log(result)if (result.code === 0) {username.className = password.className = 'form-control is-invalid'} else if (result.code === 10) {// 验证码错误的判定vcode.className = 'form-control is-invalid';} else {// 登录成功// alert('登录成功')location.href = './manage/index.html'localStorage.setItem('authorization', result.data)}}</script>
</body></html>

reg.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>注册</title><link rel="stylesheet" href="./assets/bootstrap/css/bootstrap.css">
</head><body><div class="reg container-fluid"><h1>免费注册</h1><div class="form-group"><label for="username">用户名:</label><input type="text" class="form-control" id="username" aria-describedby="emailHelp"><div class="invalid-feedback">用户名已存在</div></div><div class="form-group"><label for="password">密码</label><input type="password" class="form-control" id="password"></div><button type="submit" class="btn btn-primary btnReg">注册</button></div><script>const username = document.querySelector('#username');const password = document.querySelector('#password');const btnReg = document.querySelector('.btnReg');let canReg = true;btnReg.onclick = async (e) => {if (!canReg) return;const result = await fetch(`http://localhost:3000/api/reg`, {method: 'post',body: JSON.stringify({username: username.value,password: password.value}),headers: {'Content-Type': 'application/json'}// 这里用res.json() 是为了前后端统一传递接口数据格式}).then(res => res.json());console.log('result=', result);if (result.code === 1) {location.href = 'login.html'}}// 查询用户是否被占用username.onblur = async () => {// 判断如果为空 则不发送请求 const _username = username.value.trim()if (!_username) returnconst result = await fetch(`http://localhost:3000/api/reg/check?username=${username.value}`, {headers: {'Content-Type': 'application/json'}// 这里用res.json() 是为了前后端统一传递接口数据格式}).then(res => res.json());console.log('result=', result);if (result.code === 0) {username.className = 'form-control is-invalid'canReg = false;} else if (result.code === 1) {username.className = 'form-control is-valid'canReg = true;}}</script>
</body></html>

manage文件夹

goods.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台管理系统</title><link rel="stylesheet" href="../assets/bootstrap/css/bootstrap.css">
</head>
<body><div class="container-xl"><nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="index.html">后台管理系统</a><!-- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button> --><div class="collapse navbar-collapse" id="navbarSupportedContent"><!-- <ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="#">Link</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item" href="#">Action</a><a class="dropdown-item" href="#">Another action</a><div class="dropdown-divider"></div><a class="dropdown-item" href="#">Something else here</a></div></li><li class="nav-item"><a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a></li></ul> --></div><div class="navbar-text ml-5"><span id="userInfo" class="mr-2"></span><button class="btn btn-success btn-sm" id="btnLogout">退出</button></div></nav><nav aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="#">首页</a></li><li class="breadcrumb-item"><a href="#">商品管理</a></li><li class="breadcrumb-item active" aria-current="page">添加</li></ol></nav><div class="row"><!-- <div class="col col-xs-12 col-sm-4 col-lg-3"> --><div style="width:200px"><ul class="list-group list-group-flush"><li class="list-group-item list-group-item-action"><a href="user.html">用户管理</a></li><li class="list-group-item list-group-item-action"><a href="goods.html">商品管理</a></li><li class="list-group-item list-group-item-action"><a href="order.html">订单管理</a></li></ul></div><!-- <div class="col col-xs-12 col-sm-8 col-lg-9"> --><div class="col col-auto">商品管理</div></div></div><script src="../js/common.js"></script>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台管理系统</title><link rel="stylesheet" href="../assets/bootstrap/css/bootstrap.css">
</head>
<body><div class="container-xl"><nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="index.html">后台管理系统</a><!-- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button> --><div class="collapse navbar-collapse" id="navbarSupportedContent"><!-- <ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="#">Link</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item" href="#">Action</a><a class="dropdown-item" href="#">Another action</a><div class="dropdown-divider"></div><a class="dropdown-item" href="#">Something else here</a></div></li><li class="nav-item"><a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a></li></ul> --></div><div class="navbar-text ml-5"><span id="userInfo" class="mr-2"></span><button class="btn btn-success btn-sm" id="btnLogout">退出</button></div></nav><nav aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="#">首页</a></li><li class="breadcrumb-item"><a href="#">商品管理</a></li><li class="breadcrumb-item active" aria-current="page">添加</li></ol></nav><div class="row"><!-- <div class="col col-xs-12 col-sm-4 col-lg-3"> --><div style="width:200px"><ul class="list-group list-group-flush"><li class="list-group-item list-group-item-action"><a href="user.html">用户管理</a></li><li class="list-group-item list-group-item-action"><a href="goods.html">商品管理</a></li><li class="list-group-item list-group-item-action"><a href="order.html">订单管理</a></li></ul></div><!-- <div class="col col-xs-12 col-sm-8 col-lg-9"> --><div class="col col-auto">One of three columns</div></div></div><script src="../js/common.js"></script><script></script>
</body>
</html>

order.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台管理系统</title><link rel="stylesheet" href="../assets/bootstrap/css/bootstrap.css">
</head>
<body><div class="container-xl"><nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="#">后台管理系统</a><!-- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button> --><div class="collapse navbar-collapse" id="navbarSupportedContent"><!-- <ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="#">Link</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item" href="#">Action</a><a class="dropdown-item" href="#">Another action</a><div class="dropdown-divider"></div><a class="dropdown-item" href="#">Something else here</a></div></li><li class="nav-item"><a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a></li></ul> --></div><div class="navbar-text ml-5"><span id="userInfo" class="mr-2"></span><button class="btn btn-success btn-sm" id="btnLogout">退出</button></div></nav><nav aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="#">首页</a></li><li class="breadcrumb-item"><a href="#">商品管理</a></li><li class="breadcrumb-item active" aria-current="page">添加</li></ol></nav><div class="row"><!-- <div class="col col-xs-12 col-sm-4 col-lg-3"> --><div style="width:200px"><ul class="list-group list-group-flush"><li class="list-group-item list-group-item-action"><a href="user.html">用户管理</a></li><li class="list-group-item list-group-item-action"><a href="goods.html">商品管理</a></li><li class="list-group-item list-group-item-action"><a href="order.html">订单管理</a></li></ul></div><!-- <div class="col col-xs-12 col-sm-8 col-lg-9"> --><div class="col col-auto">订单管理</div></div></div><script src="../js/common.js"></script>
</body>
</html>

user.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台管理系统</title><link rel="stylesheet" href="../assets/bootstrap/css/bootstrap.css">
</head><body><div class="container-xl"><nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="index.html">后台管理系统</a><!-- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button> --><div class="collapse navbar-collapse" id="navbarSupportedContent"><!-- <ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="#">Link</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item" href="#">Action</a><a class="dropdown-item" href="#">Another action</a><div class="dropdown-divider"></div><a class="dropdown-item" href="#">Something else here</a></div></li><li class="nav-item"><a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a></li></ul> --></div><div class="navbar-text ml-5"><span id="userInfo" class="mr-2"></span><button class="btn btn-success btn-sm" id="btnLogout">退出</button></div></nav><nav aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="#">首页</a></li><li class="breadcrumb-item"><a href="#">商品管理</a></li><li class="breadcrumb-item active" aria-current="page">添加</li></ol></nav><div class="row"><!-- <div class="col col-xs-12 col-sm-4 col-lg-3"> --><div class="col-sm-3" style="min-width:200px"><ul class="list-group list-group-flush"><li class="list-group-item list-group-item-action"><a href="user.html">用户管理</a></li><li class="list-group-item list-group-item-action"><a href="goods.html">商品管理</a></li><li class="list-group-item list-group-item-action"><a href="order.html">订单管理</a></li></ul></div><!-- <div class="col col-xs-12 col-sm-8 col-lg-9"> --><div class="col col-sm-9"><table class="table table-striped table-hover" style="width:100%"><thead><tr><th scope="col">#</th><th scope="col">用户名</th><th scope="col">年龄</th><th scope="col">性别</th><th scope="col">操作</th></tr></thead><tbody id="userlist"></tbody></table></div></div></div><script src="../js/common.js"></script><script src="../js/tools.js"></script><script>(async () => {const userlist = document.querySelector("#userlist");let datalist = await request('/user');datalist = datalist.data;render();function render(){userlist.innerHTML = datalist.map((item, idx) => {return `<tr><td>${idx + 1}</td><td>${item.username}</td><td>${item.age===undefined ? 18:item.age}</td><td>${item.gender ? item.gender : '未知'}</td><td><div class="btn-group btn-group-sm"><button class="btn btn-success btnEdit" data-id="${item._id}">编辑</button>  <button class="btn btn-danger btnDel" data-id="${item._id}">删除</button></div></td></tr>`}).join('')}// 删除功能userlist.onclick = async (e)=>{const target = e.target;const {id} = target.datasetif(target.classList.contains('btnDel')){if(confirm('are you 确定')){// 删除// const result = await request('/user/'+id,{},{method:'delete'});const result = await request.delete('/user/'+id)if(result.code === 1){// [{id:1},{id:2},{id:3}] , 2 => [{id:2},{id:3}]datalist = datalist.filter(item=>item._id !== id);render();}}}else if(target.classList.contains('btnEdit')){// 编辑// const result = await request('/user/'+id,{age:28,gender:'男'},{method:'put'});location.href="./user/edit.html?id="+id}}})();</script>
</body></html>

user文件下edit.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>后台管理系统</title><link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.css"><style>#avatar {width: 100%;}</style>
</head><body><div class="container-xl"><nav class="navbar navbar-expand-lg navbar-dark bg-dark"><a class="navbar-brand" href="../index.html">后台管理系统</a><!-- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button> --><div class="collapse navbar-collapse" id="navbarSupportedContent"><!-- <ul class="navbar-nav mr-auto"><li class="nav-item active"><a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a></li><li class="nav-item"><a class="nav-link" href="#">Link</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</a><div class="dropdown-menu" aria-labelledby="navbarDropdown"><a class="dropdown-item" href="#">Action</a><a class="dropdown-item" href="#">Another action</a><div class="dropdown-divider"></div><a class="dropdown-item" href="#">Something else here</a></div></li><li class="nav-item"><a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a></li></ul> --></div><div class="navbar-text ml-5"><span id="userInfo" class="mr-2"></span><button class="btn btn-success btn-sm" id="btnLogout">退出</button></div></nav><nav aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="#">首页</a></li><li class="breadcrumb-item"><a href="#">商品管理</a></li><li class="breadcrumb-item active" aria-current="page">添加</li></ol></nav><div class="row"><!-- <div class="col col-xs-12 col-sm-4 col-lg-3"> --><div class="col-sm-3" style="min-width:200px"><ul class="list-group list-group-flush"><li class="list-group-item list-group-item-action"><a href="../user.html">用户管理</a></li><li class="list-group-item list-group-item-action"><a href="../goods.html">商品管理</a></li><li class="list-group-item list-group-item-action"><a href="../order.html">订单管理</a></li></ul></div><!-- <div class="col col-xs-12 col-sm-8 col-lg-9"> --><div class="col col-sm-9"><div class="row"><div class="col col-sm-9"><div class="form-group"><label for="username">用户名:</label><input type="text" class="form-control" id="username" disabled></div><div class="form-group"><label for="password">密码:</label><input type="password" class="form-control" id="password"></div><div class="form-group"><label for="gender">性别</label><select class="form-control" id="gender"><option>男</option><option>女</option><option>其他</option></select></div><div class="form-group"><label for="age">年龄</label><input type="number" id="age" class="form-control"></div><button type="submit" class="btn btn-success btn-lg mb-2" id="btnSubmit">提交</button></div><div class="col col-sm-3"><img src="/img/g3.jpg" id="avatar" /><!-- <from enctype="multipart/form-data" method="post" action="http://localhost:2003/api/upload/avatar"> --><input type="file" class="form-control-file" id="uploadAvatar"><!-- </from> --></div></div></div></div></div><script src="/js/common.js"></script><script src="/js/tools.js"></script><script>(async () => {const username = document.querySelector('#username')const password = document.querySelector('#password')const gender = document.querySelector('#gender')const age = document.querySelector('#age')const btnSubmit = document.querySelector('#btnSubmit')const uploadAvatar = document.querySelector('#uploadAvatar')// 获取当前用户信息let currentUser = localStorage.getItem('currentUser');currentUser = JSON.parse(currentUser);// 通过用户id获取用户信息// let _id;// let params = location.search.slice(1);// params = params.split('&');// params.forEach(item=>{//     const arr = item.split('=')//     if(item[0] === 'id'){//         _id = arr[1];//     }// });let _id = location.search.match(/id=([\da-z]{24})/)[1];console.log(_id);const { data } = await request.get('/user/' + _id);// 把数据写入表单username.value = data.username// password.value = data.passwordgender.value = data.genderage.value = data.ageavatar.src = data.avatarUrl || '/uploads/avatar.jpg'btnSubmit.onclick = async () => {const result = await request.put('/user/' + data._id, {password: password.value,gender: gender.value,age: age.value});if (result.code === 1) {alert('更新成功')// 如果修改的用为为自己if (_id === currentUser._id) {Object.assign(currentUser, result.data);localStorage.setItem('currentUser', JSON.stringify(currentUser));}} else {alert('更新失败')}}//  上传头像uploadAvatar.onchange = async (e) => {// html5新特性:FormDataconsole.log(e);// 创建一个用户存放数据的容器const data = new FormData();data.set('_id', _id);data.set('avatar', e.target.files[0]);// 一次性上传多张图片时// for(let i=0;i<e.target.files.length;i++){//     data.append('goods',e.target.files[i]);// }const result = await request.post('/upload/avatar', data, {contentType: false, // 告诉fetch,不需要自定义content-type// headers:{//     'Content-Type':'multipart/form-data'// }});// 更新页面avatar.src = result.data.avatarUrl;// 更新本地存储数据if (_id === currentUser._id) {currentUser.avatarUrl = result.data.avatarUrl;localStorage.setItem('currentUser', JSON.stringify(currentUser));}}})();</script>
</body></html>

upload文件放上传的头像

assets文件

bootstrap文件的 css 和 js 文件

package

package.json

{"name": "mymongodb","version": "1.0.0","description": "","main": "index.js","directories": {"doc": "doc"},"scripts": {"test": "echo \"Error: no test specified\" && exit 1","server": "supervisor src/server.js","start": "npm run server"},"keywords": [],"author": "","license": "ISC","dependencies": {"bootstrap": "^4.5.2","express": "^4.17.1","express-session": "^1.17.1","jsonwebtoken": "^8.5.1","mongodb": "^3.6.0","multer": "^1.4.2","mysql": "^2.18.1","svg-captcha": "^1.4.0"}
}

config.json

{"PORT":3000
}

文件目录


功能说明:

1、登录注册

  • 注册 如果勾选7天免登陆,实现7天不用登录用户名和密码
  • 注册如果不勾选7天免登陆,默认是2小时内

2、进入后台管理系统,显示登录用户名
3、点击用户管理 ,可以对里面的用户修改密码、年龄、性别、上传头像
4、实现不同管理的跳转页面
5、退出登录




nodejs操作数据库代码相关推荐

  1. NodeJS操作数据库

    一.前奏 本文说明:介绍如何使用NodeJS操作mysql数据库 需要准备:需要安装MySQL数据库.Node环境.数据库图形界面工具SQLyog.VSCode开发工具 安装包下载:https://w ...

  2. nodeJs 操作数据库

    首先在node中下载mysql包 npm install mysql 连接数据库 var mysql = require('mysql'); var con = mysql.createConnect ...

  3. nodejs操作mysql创建库和表_Nodejs操作MySQL数据库

    如何用nodejs操作MySql数据呢,其实写法还是简单的, 1.开始在你的node项目中 npm install mysql --save 2.在你的新建项目中 引入代码 //引入数据库 var m ...

  4. Nodejs 操作 MongoDb 数据库

    一.在 Nodejs 中使用 Mongodb 在前面的博文我们给大家讲了如何使用命令操作 Mongodb,这篇博文开始我们给大家讲解一 下如何使用 Nodejs 来操作 Mongodb 数据库 Nod ...

  5. 记录nodejs使用express搭建一个api服务器程序(5)-nodejs操作SQL数据库,Sequelize和Knex

    此文章是我自己用来记录如何搭建一个以express为基础的api服务器框架的过程,并不是什么新手教程,并不会每一步都写得非常详细,如果您要阅读此文,需要一点nodejs和编写代码的基础知识 文接上篇 ...

  6. nodejs操作mongodb数据库(mongoose)

    准备 在上一篇的基础上,通过npm安装mongoose. 关于mongoose Mongoose是MongoDB的一个对象模型工具,是基于node-mongodb-native开发的MongoDB n ...

  7. 怎么用php操作mysql删除数据库代码_如何使用php操作mysql的增删改查?

    php操作mysql的增删改查方法:1.插入语句[insert into 数据表名(字段1,字段2,....) values("值1","值2",..)]:2. ...

  8. php django mysql配置文件_Mysql学习Django+mysql配置与简单操作数据库实例代码

    <Mysql学习Django+mysql配置与简单操作数据库实例代码>要点: 本文介绍了Mysql学习Django+mysql配置与简单操作数据库实例代码,希望对您有用.如果有疑问,可以联 ...

  9. python数据库教程_Python连接mysql数据库及简单增删改查操作示例代码

    1.安装pymysql 进入cmd,输入 pip install pymysql: 2.数据库建表 在数据库中,建立一个简单的表,如图: 3.简单操作 3.1查询操作 #coding=utf-8 #连 ...

最新文章

  1. keras和tensorflow 报错解决:UserWarning: Method on_batch_end() is slow compared to the batch update Check
  2. iOS 设置所有UIButton的ExclusiveTouch属性为YES
  3. 白话Elasticsearch13-深度探秘搜索技术之基于multi_match+most fields策略进行multi-field搜索
  4. java/javaee基础面试问题
  5. Drupal 7中 page.tpl.php 的可用变量
  6. loadrunner脚本设计:检查点(断言)及web_submit_data函数使用示例
  7. 机器学习-Logistic回归原理及实战
  8. QT c++ 中使用PostMessage/SendMessage实例
  9. python二分法编程_python基础18——二分法面向过程匿名函数
  10. 怎么向小学生解释欧拉公式 e^(πi)+1=0?
  11. 前端学习(3270):js中this的使用call bind
  12. 库克“一语成谶”:又有 30 万台安卓设备被“感染”了!| 文末福利
  13. 测试用例编号_怎样编写测试用例更完整,更能提升工作效率?来试试这套方法!...
  14. Linux中断(interrupt)子系统之一:中断系统基本原理
  15. 暗黑战神项目详细总结
  16. GB2312转换为Unicode编码表
  17. Win7+vmware+xpsp3+vs2010驱动开发环境搭建及调试方法
  18. 干货:8266在3d打印机上的使用
  19. Android中MVC,MVP和MVVM的区别
  20. 世界上最有名的十大思想实验

热门文章

  1. 直击|百度发布小度电视伴侣 售价599元
  2. 华为智能摄像头pro鸿蒙系统,内置鸿蒙系统,华为生态产品海雀智能摄像头Pro体验...
  3. js 日期加减操作(日、月、年)
  4. 全面创新:酷我音乐2013年5月14日正式版全面上线,抢先试用
  5. java递归删除空文件夹_Java 删除空文件夹和文件夹及其下面的文件
  6. HarmonyOS连接新体验,半入耳舒适降噪耳机华为FreeBuds 4E全新亮相
  7. ios网页点击出现灰色背景
  8. CTFSHOW-信息收集
  9. 【网页设计基础课】第十周文档流实验作业第三题
  10. java excel异步导出_如何实现前端异步调用导出Excel?