数据库软件
简单的增删改查接口实现
文件目录
代码实现如下
后端
注意:请依据业务自行修改
// 需要下载的包如下
cnpm i express
cnpm i cors
cnpm i body-parser
新建server文件夹 --- git init (生成package.json)
db/index.js
// 用于配置数据库相关信息
let mysql = require('mysql')
// 创建连接池
let db = mysql.createPool({
host: '127.0.0.1', //数据库IP地址
user: 'root', //数据库登录账号
password: '', //数据库登录密码
database: 'onlinefilm' //要操作的数据库
})
module.exports = db
app.js
// 用于配置服务器相关信息
let express = require('express')
let app = express()
let cors = require('cors')
let bodyParser = require('body-parser')
let router = require('./router')
app.use(bodyParser.json()); //配置解析,用于解析json和urlencoded格式的数据
app.use(bodyParser.urlencoded({extended: false}));
app.use(cors()) //配置跨域,必须在路由之前
app.use('/api', router) //配置路由
app.listen(5500, () => {
console.log('服务器启动成功。 ---> http://127.0.0.1:5500/api');
}) // 5500 是端口号,若被占用,自行修改即可
API/userList.js(存放用户的登陆、注册、注销等接口)
// POST 注册的接口
// 需要传入的参数(必填) =》 用户名:name、密码:password
// id: 自动生成
// token: 自动生成
// headimg:https://img-blog.csdnimg.cn/img_convert/cc72aaf2dbae425a15406f4613a62390.png(默认的)
// type: user
exports.register = (req, res) => {
let id = makeUuid()
let token = makeToken()
const body = req.body
// 查询数据库 *(所有) 表单为 userlist 里 所有name ? 为占位符代表条件
const query = 'SELECT * FROM userlist WHERE name=?'
// () 第一位为sql语句 第二位为占位符的条件
db.query(query, body.name, (err, result) => {
// err 为执行错误信息 result为数据
if (err) return res.cc(err);
// 判断影响行数 能查询到证明数据库表单里存在这个值
if (result.length > 0) {
res.send({
status: 403,
data: '成功',
message: '用户名已存在'
})
} else {
// 插入数据
const sql = 'INSERT INTO userlist SET ?'
db.query(sql,
{
id: id,
token: token,
name: body.name,
password: body.password,
type: 'user',
headimg: 'https://img-blog.csdnimg.cn/img_convert/6e194440c59ec154af1279c8c6414296.jpeg'
}, (err, result) => {
if (err) return res.cc(err)
if (!result.affectedRows) return res.cc('注册失败')
res.send({
status: 200,
data: 'ok',
message: '注册成功'
})
})
}
})
}
// POST 登陆的接口
// 需要传入的参数(必填) =》 用户名:name、密码:password
exports.login = (req, res) => {
let {
name,
password
} = req.body;
// 查询语句
let sql = 'SELECT * FROM userlist WHERE name = ?'
db.query(sql, [name], (err, data) => {
if (err) {
return res.send('错误:' + err.message)
}
if (!data.length) {
return res.send({
status: 101404,
msg: '账号不存在'
})
} else {
if (data[0].password === password) {
return res.send({
status: 200,
msg: '登录成功',
userInfo: data[0]
})
}
return res.send({
status: 101101,
msg: '密码错误'
})
}
})
}
// POST 编辑用户
// 需要传入的参数 =》 用户名:name、密码:password、类型:type(user/admin)、headimg(头像)、token、id
exports.updateUser = (req, res) => {
let sql = 'UPDATE userlist SET token = ?, name = ?, password = ?, type = ?, headimg = ? where id = ?'
db.query(sql, [req.body.token, req.body.name, req.body.password, req.body.type, req.body.headimg, req.body.id], (err, data) => {
if (err) {
return res.send('错误:' + err.message)
}
if (data.changedRows > 0) {
res.send({
status: 200,
message: 'success'
})
} else {
res.send({
status: 500,
message: '服务器错误,请联系管理员。'
})
}
})
}
// GET 删除用户
// 需要传入的参数 =》 id(必填)
exports.deleteUser = (req, res) => {
let sql = `DELETE FROM userlist WHERE id = "${req.query.id}"`
db.query(sql, (err, data) => {
if (err) {
return res.send('错误:' + err.message)
}
res.send({
status: 200,
message: 'success'
})
})
}
// GET 获取单条用户详情接口
// 需要传入的参数 =》 id:id
exports.getUserDetail = (req, res) => {
// 根据条件查询数据库表单的数据
const sql = `SELECT * FROM userlist WHERE id = '${req.query.id}'`
db.query(sql, (err, data, fields) => {
if (err) {
return res.send('错误:' + err.message)
}
res.send({
status: 200,
message: "success",
data
});
})
}
// GET 查询用户
// 需要传入的参数 =》 用户名:name
exports.getUserByName = (req, res) => {
/* 如果 counttype 只有一个 判断是否有 name 搜索条件 */
if (req.query && req.query.name) {
let sql = `SELECT * FROM userlist WHERE name = "${req.query.name}"`
db.query(sql, (err, data, fields) => {
if (err) {
return res.send('错误:' + err.message)
}
res.send({
status: 200,
message: "success",
data
});
})
}
/* 显示全部的数据 */
else {
let sql = 'SELECT * FROM userlist';
db.query(sql, (err, data, fields) => {
if (err) {
return res.send('错误:' + err.message)
}
res.send({
status: 200,
message: "success",
data: data
});
})
}
}
utils/makeToken.js
// 生成随机token
module.exports = function makeToken() {
return 'token-' + Number(Math.random().toString().substr(3, 30) + Date.now()).toString(36);
}
utils/makeUuid.js
// 生成随机 uuid
// 如 4d0edd80-af4d-4737-8276-9c13a6b97a8a
module.exports = function makeUuid() {
let s = [];
let hexDigits = "0123456789abcdef";
for (let i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
let uuid = s.join("");
return uuid;
}
router.js
// 用于配置对应路由
let express = require('express')
let router = express.Router()
let userList = require('./API/userList')
/* userList ---> 用户的接口 */
router.get('/deleteUser', userList.deleteUser) // 删除用户
router.post('/updateUser', userList.updateUser) // 编辑用户
router.get('/getUserByName', userList.getUserByName) // 查询用户
router.get('/getUserDetail', userList.getUserDetail) // 获取单条用户详情接口
router.post('/login', loginList.login)
router.post('/register', loginList.register)
router.get('/getPicCode', loginList.getPicCode) // 生成二维码的接口,代码在最下面,不需要的删除即可
/* userList ---> 用户的接口 */
module.exports = router
前端
// 需要下载的包如下
cnpm i axion
cnpm i qs
src/utils/request.js
// axions封装,根据业务需要自行修改
/**axios封装
* 请求拦截、相应拦截、错误统一处理
*/
import axios from "axios";
import QS from "qs";
import store from "../store"; // 不用的删除即可
// 环境的切换
if (process.env.NODE_ENV === "development") {
// 本地开发环境
axios.defaults.baseURL = "http://127.0.0.1:5500/";
} else if (process.env.NODE_ENV === "debug") {
// 本地测试环境
axios.defaults.baseURL = "";
} else if (process.env.NODE_ENV === "production") {
// todo will fix 线上环境
axios.defaults.baseURL = "";
}
// 请求超时时间
axios.defaults.timeout = 10000;
// post请求头
axios.defaults.headers.post["Content-Type"] =
"application/x-www-form-urlencoded;charset=UTF-8";
// 请求拦截器
axios.interceptors.request.use(
(config) => {
// 如果不是外部接口、登陆、注册、验证码的接口
// if (config.url === 'https://tianqiapi.com/free/day' || config.url === "api/login" || config.url === "api/getPicCode" || config.url === "api/register") {
// return config;
// } else {
// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
// if (localStorage.getItem('Authorization')) {
// config.headers.Authorization = localStorage.getItem('Authorization');
// }
// store.dispatch('loginModule/getUserInfo')
// const token = (store as any).state.loginModule.userInfo.token;
// token && (config.headers.Authorization = token);
return config;
// }
},
(error) => {
return error;
}
);
// 响应拦截器
axios.interceptors.response.use(
(response) => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
},
// todo will fix 服务器状态码不是200的情况
(error) => {
if (error) throw error;
// if (error.response.status) {
// switch (error.response.status) {
// // 401: 未登录
// // 未登录则跳转登录页面,并携带当前页面的路径
// // 在登录成功后返回当前页面,这一步需要在登录页操作。
// case 401:
// (this as any).$router.replace({
// path: '/login',
// query: {redirect: (this as any).$router.currentRoute.fullPath}
// });
// break;
// // 403 token过期
// // 登录过期对用户进行提示
// // 清除本地token和清空vuex中token对象
// // 跳转登录页面
// case 403:
// (this as any).$message.warning('登录过期,请重新登录')
// // 清除token
// localStorage.removeItem('token');
// store.commit('loginSuccess', null);
// // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面
// setTimeout(() => {
// (this as any).$router.replace({
// path: '/login',
// query: {
// redirect: (this as any).$router.currentRoute.fullPath
// }
// });
// }, 1000);
// break;
// // 404请求不存在
// case 404:
// (this as any).$message.warning('网络请求不存在')
// break;
// // 其他错误,直接抛出错误提示
// default:
// (this as any).$message.warning(error.response.data.message)
// }
// return Promise.reject(error.response);
// }
}
);
/**
* get方法,对应get请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export function get(url, params) {
return new Promise((resolve, reject) => {
axios
.get(url, {
params: params,
})
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* post方法,对应post请求
* @param {String} url [请求的url地址]
* @param {Object} params [请求时携带的参数]
*/
export function post(url, params) {
return new Promise((resolve, reject) => {
axios
.post(url, QS.stringify(params))
.then((res) => {
resolve(res.data);
})
.catch((err) => {
reject(err.data);
});
});
}
src/api/userlist.js
// 用户相关的接口
import { get, post } from "../utils/request";
// export const upload = (body) => post('api/upload', body);
export const getUserByName = (obj) => get("api/getUserByName", obj);
export const updateUser = (body) => post("api/updateUser", body);
export const deleteUser = (body) => get("api/deleteUser", body);
vue页面中使用(部分代码)
import {updateUser, deleteUser} from "@/api/userlist";
submitUserInfo() {
updateUser({
// headimg: this.formData.headimg,
name: this.formData.name,
password: this.formData.password,
// token: this.formData.token,
type: this.formData.type,
id: this.formData.id.toString(),
}).then(res => {
console.log(res)
})
},
delUser() {
this.$confirm('此操作将永久注销账号, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteUser({
id: this.formData.id
}).then(res => {
if (res.status === 200 && res.data.status === 200) {
this.$message({
type: 'success',
message: '注销成功!'
});
this.$router.push('/')
localStorage.clear()
this.restUserInfo()
} else {
this.$message.error("网络错误,请稍后再试!")
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消注销'
});
});
},
*********** server/API/loginlist.js 生成图片验证码 ***********
cnpm i svg-captcha
// 用于操作数据库
let db = require('../db/index')
let makeUuid = require("../utils/makeUuid")
let makeToken = require("../utils/makeToken")
// 加载图片验证码模块
// GET 图片验证码接口
exports.getPicCode = (req, res) => {
// 设置字母随机验证码相关属性
let options = {
size: 4, // 验证码长度
noise: 3, // 干扰线2条
color: true, // 文字颜色
background: "#f5f7fa", // 验证码图片背景颜色
ignoreChars: '0o1i', // 验证码字符中排除 0o1i
width: 94, // width of captcha
height: 34, // height of captcha
fontSize: 50, // captcha text size
charPreset: '123456789' // random character preset
}
//这里可以分为字母和数字随机验证码和数字算数随机验证码,
//我就先展示字母和数字随机验证码了,
//如果想尝试数字算数随机验证码可以将下一行取消注释,将数字算数验证码解开注释即可
let captcha = svgCaptcha.create(options) //字母和数字随机验证码
// let captcha = svgCaptcha.createMathExpr(options) //数字算数随机验证码
let {text, data} = captcha
// text是指产生的验证码,data指svg的字节流信息
res.type("svg")
res.send({
img: captcha.data,
str: captcha.text
})
}