nodejs操作数据库代码

以代码说明操作过程;

服务器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.query

  const skip = (page - 1) * size
  const 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=>{})


    // mongo
    const 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 result
    try{
        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中的存的 vcode
    if (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 = authorization
        res.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
  }

  // 验证码生成 create
  const 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.jpg
    filename: 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.files
    console.log('file=', req.file, req.body);
    const { _id } = req.body;

    // 更新用户信息
    const avatarUrl = '/uploads/' + req.file.filename
    mongo.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.value
      const _password = password.value
      const _vcode = vcode.value
      const _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) return

      const 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.dataset
        if(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.password
      gender.value = data.gender
      age.value = data.age
      avatar.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新特性:FormData
        console.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、退出登录

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值