day06
 一、数据库
 1.打开软件xampp或者直接启动mysql
 2.进入终端或者继承环境的shell
 mysql -u root -p 如果有密码写在p后面
 3.检查是否有重名数据库,没有就创建数据库
 SET NAMES UTF8;
 DROP DATABASE IF EXISTS mydb;
 CREATE DATABASE mydb CHARSET = UTF8;
 4.创建数据表
 (1)用户信息表userinfo
 create table userinfo(
   u_id int auto_increment primary key,
   u_names varchar(255) not null,
   u_phone varchar(255) not null unique,
   u_member INT not null
 ) ENGINE = InnoDB charset = utf8;(2)管理员登录表admin
 create table admin(
   a_id int auto_increment primary key,
   a_names varchar(255) not null unique,
   a_pwd varchar(255) not null
 ) ENGINE = InnoDB charset = utf8;5.插入数据【需要记住字段名】
 (1)用户信息表userinfo 插入11条
 INSERT INTO
   userinfo(u_names, u_phone, u_member)
 VALUES
 (‘tom’,‘15201076723’,1),
 (‘nancy’,‘15201197440’,0),
 (‘jack’,‘15101075644’,1),
 (‘bob’,‘15910257181’,0),
 (‘lily’,‘13522162834’,1),
 (‘Kate’,‘13661217464’,0),
 (‘emma’,‘13522162843’,0),
 (‘bale’,‘13671357146’,0),
 (‘coy’,‘13522172419’,0),
 (‘ball’,‘15910779501’,1),
 (‘dan’,‘15910780895’,1);
 避免乱码,名字用英文(2)管理员登录admin插入数据3条
 INSERT INTO
   admin(a_names, a_pwd)
 VALUES
   (‘zhangsan’, ‘123’),
   (‘lisi’, ‘123’),
   (‘wangwu’, ‘123’);二、服务器端
 1.创建项目目录结构
 -pro 项目目录名字
 |- node_modules拷贝依赖文件夹
 |- public 公共目录,放静态资源(img、js、css等)
 |- views 放html文件
 |- routes 放路由,各种模块逻辑
 |- admin.js 管理员路由器(所有管理员接口)
 |- user.js 用户路由器(所有用户接口)
 |- module 自己写的模块(如连接池功能)
 |- app.js 项目入口文件2.数据库连接模块(自定义模块,建议放在modul中)
 //引入mysql依赖模块
 const mysql = require(‘mysql’)
 //创建连接池对象
 const pool = mysql.createPool({
   //域名或者ip
   host:‘127.0.0.1’,
   //端口号
   port:‘3306’,
   //用户名
   user:‘root’,
   // 密码
   password:’’,
   //操作的数据库名
   database:‘mydb’,
   //连接池可创建最大连接数
   connectionLimit:15
 })
 //暴露自定义模块
 module.exports = pool3.入口文件
 //引入express模块
 const express = require(‘express’)
 //创建web服务器
 const app = express()
 //监听端口 (::8080端口占用,一般是开了好几个窗口)
 app.listen(8080,()=>{console.log(‘❤ ❤ ❤’)})
 //中间件
 //静态资源托管
 app.use(express.static(’./public’))
 app.use(express.static(’./views’))
 //post/put传参,解析格式
 app.use(express.urlencoded({
   extended:false
 }))//路由器
 //引入管理员路由器
 const adminRouter = require(’./routes/admin.js’)
 //引入用户路由器
 const userRouter= require(’./routes/user.js’)//挂载路由的中间件,分配资源路径,配置特定前缀
 //管理员
 app.use(’/admin’,adminRouter)
 //用户
 app.use(’/user’,userRouter)//错误处理中间件
 app.use((err,req,res,next)=>{
   //查看错误类型信息
   console.log(err)
   res.status(500).send({
     “code”:500,
     “msg”:“服务器端的错误”
   })
 })4.接口(业务逻辑)
 (1)管理员
 准备工作
 //该路由专门用于管理员功能功能的业务逻辑
 //引入express
 const express = require(‘express’)
 //因为要是用数据库,引入自定义模块pool
 const pool = require(’…/pool.js’)
 //创建路由对象
 const router = express.Router()
 //业务逻辑…//在整个路由器的最后一行暴露
 module.exports = router
 //管理员登录接口: /login
 //客户端访问url: /admin/login
 //post 约定传参的属性名:anames apwd
 //访问的数据表:admin a_names a_pwd
 router.post(’/login’,(req,res,next)=>{
   // 检查客户端是否成功连接服务器端
   // console.log(‘15行检查登录接口连接成功’)
   // 接收请求参数
   let obj = req.body
   // 19行检查接收参数正确,查的是传参是否正确
   // console.log(obj)
   //执行SQL命令
   pool.query(‘select * from admin where a_names=? and a_pwd=?’,[obj.anames,obj.apwd],(err,data)=>{
     // 检查数据库拿回来的结果就是sql语句写没写对
     //console.log(data)//[{xxxxx}]、[]
     //错误处理一样的代码
     if(err){next(err);return}
     //判断data长度,1代表找到,0代表没找到
     if(data.length0){
       //失败的
       res.send({
         “code”:0,
         “msg”:“用户名或者密码错误登录失败”
       })
     }else {
       //成功的
       res.send({
         “code”:1,
         “msg”:“正确登录成功”
       })
     }
   })
 })
 //管理员查看用户列表接口: /list
 //客户端访问url: /admin/list
 //get 不需要客户端传参
 //访问的数据表:userinfo
 router.get(’/list’,(req,res,next)=>{
    // 检查客户端是否成功连接服务器端
   // console.log(‘49行检查列表接口连接成功’)
   //执行SQL命令
   pool.query(‘select * from userinfo;’,(err,data)=>{
     //错误处理
     if(err){next(err);return}
     //只要sql语句没错,data数据100%有[{…},{…},{…},…]
     res.send({
       “code”:1,
       “msg”:“返回所有用户数据”,
       “data”:data
     })
   })
 })
 //管理员搜索一个用户接口: /query
 //客户端访问url: /admin/query
 //get 使用?在url里传参 unames 用户名字查询用户,可单可多
 //访问的数据表:userinfo u_names = unames
 router.get(’/query’,(req,res,next)=>{
   // 检查客户端是否成功连接服务器端
   // console.log(‘69行查询某用户接口连接成功’)
   let obj = req.query
   // 检查客户端传参是否正确
   // console.log(obj)
   //执行SQL命令
   pool.query(‘select * from userinfo where u_names=?’,[obj.unames],(err,data)=>{
     //错误处理
     if(err){next(err);return}
     //查询数据库返回的数据data []、[{…}]
     // console.log(data)
     //判断data中是不是空数组
     if(data.length0){
       res.send({
         “code”:0,
         “msg”:“没查到该用户信息”
       })
     }else {
       res.send({
         “code”:1,
         “msg”:“找到用户数据返回”,
         “data”:data
       })
     }
   })
 })
 //管理员删除一个用户接口: /del/:uid
 //客户端访问url: /admin/del
 //delete 使用路由传参用id删除
 //访问的数据表:userinfo u_id = uid
 router.delete(’/del/:uid’,(req,res,next)=>{
   // 检查客户端是否成功连接服务器端
   // console.log(‘101行删除某用户接口连接成功’)
   //接收参数
   let obj = req.params
   // 检查参数是否正确
   // console.log(obj)
   //执行SQL命令
   pool.query(‘delete from userinfo where u_id=?’,[obj.uid],(err,data)=>{
     // 错误处理
     if(err){next(err);return}
     //查看数据库返回数据中,数据库中受到影响的条数
     // console.log(data.affectedRows)
     //判断条数变化
     if(data.affectedRows==0){
       res.send({
         “code”:0,
         “msg”:“删除失败”
       })
     }else {
       res.send({
         “code”:1,
         “msg”:“删除成功”
       })
     }
   })
 })(2)用户
 准备工作
 //该路由专门用于用户功能功能的业务逻辑
 //引入express
 const express = require(‘express’)
 //因为要是用数据库,引入自定义模块pool
 const pool = require(’…/pool.js’)
 //创建路由对象
 const router = express.Router()
 //业务逻辑…//在整个路由器的最后一行暴露
 module.exports = router
 //用户登录接口: /login
 //客户端访问url: /user/login
 //post 约定传参 手机号 uphone
 //访问的数据表:userinfo u_phone = uphone
 router.post(’/login’,(req,res,next)=>{
   // 检查客户端是否成功连接服务器端
   // console.log(‘15行用户登录接口连接成功’)
   //接收参数
   let obj = req.body
   //查看传递的参数是否正确
   // console.log(obj)
   //执行SQL命令
   pool.query(‘select * from userinfo where u_phone=?’,[obj.uphone],(err,data)=>{
     if(err){next(err);return}
     // 查看查询结果data
     // console.log(data)
     // 判断数组长度
     if(data.length==0){
       res.send({
         “code”:0,
         “msg”:“没查到手机号登录失败”
       })
     }else {
       res.send({
         “code”:1,
         “msg”:“登录成功”
       })
     }
   })
 })//用户注册接口: /register
 //客户端访问url: /user/register
 //post 约定传参 名字u_names 手机号u_phone 会员u_member
 //访问的数据表:userinfo
 // insert into userinfo set ? [obj]打包好的不用改的用的是数据库字段的名字 当的参数名
 router.post(’/register’,(req,res,next)=>{
   // 检查客户端是否成功连接服务器端
   // console.log(‘47行用户注册接口连接成功’)
   //接收参数
   let obj = req.body
   //检查参数,注意属性名应该和数据库字段名一样
   // console.log(obj)
   //执行SQL命令
   pool.query(‘insert into userinfo set ?’,[obj],(err,data)=>{
     if(err){next(err);return}
     //检查data是什么
     // console.log(data)
     // 返回插入成功的响应
     res.send({
       “code”:1,
       “msg”:“注册成功”
     })
   })
 })
 //用户修改接口: /edit
 //客户端访问url: /user/edit
 //post 约定传参
 //修改数据需要一个参数的旧值电话号 oldphone
 //可以修改的三个新值 unames、uphone、umember
 //访问的数据表:userinfo
 router.put(’/edit’,(req,res,next)=>{
   // 检查客户端是否成功连接服务器端
   // console.log(‘73行用户修改接口连接成功’)
   //接收参数
   let obj = req.body
   // 检查参数
   // console.log(obj)
   // 执行SQL命令
   let sql = update userinfo set u_names="${obj.unames}",u_phone="${obj.uphone}",u_member=${obj.umember} where u_phone="${obj.oldphone}";   pool.query(sql,(err,data)=>{
     if(err){next(err);return}
     // 检查数据库改动条数
     if(data.affectedRows==0){
       res.send({
         “code”:0,
         “msg”:“修改失败”
       })
     }else {
       res.send({
         “code”:1,
         “msg”:“修改成功”
       })
     }
   })
 })