该项目目录如下:
node后端服务入口文件index.js
// node 后端服务器
const userApi = require('./api/user');
const articleApi = require('./api/article');
const fs = require('fs');
const path = require('path');
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
// 后端api路由
app.use('/api/user', userApi);
app.use('/api/article', articleApi)
// 监听端口
app.listen(3001);
console.log('success listen at port:3001......');
连接数据库db.js
// 数据库连接配置
module.exports = {
mysql: {
host: 'localhost',
user: 'root',
password: 'root',
database: 'user',
port: '3306'
}
}
该项目我把所有sql语句单独抽取出来放在sql.js文件里面:
// sql语句
var sql = {
// 用户
user: {
login: 'select * from admin_user where userName = ? and passWord = ?',
queryUserList: 'select * from user',
createUser: 'INSERT INTO user (userId, userName, createDate, nickName, passWord) VALUES (?,?,?,?,?)'
},
article: {
query: 'select * from article',
queryById: 'select * from article where discuss_id = ?',
create: 'INSERT INTO article (title, content, keyword, type_id, type_name) VALUES (?,?,?,?,?)',
delete: 'delete from article where discuss_id = ?',
update: 'update article set title=?,content=?,keyword=? where discuss_id = ?',
queryArticleType: 'select * from article_type',
createArticleType: 'INSERT INTO article_type (typeId, typeName, createDate) VALUES (?,?,?)',
queryArticleTypeById: 'select * from article_type where typeId = ?'
}
}
module.exports = sql;
server目录下api文件夹下的文件是最核心的,服务端增删改查的业务逻辑代码都在这里面,例如 user.js
var models = require('../db');
var express = require('express');
const jwt = require('jsonwebtoken');
var uuid = require('node-uuid');
var router = express.Router();
var mysql = require('mysql');
var $sql = require('../sql');
// 连接数据库
var conn = mysql.createConnection(models.mysql);
conn.connect();
// 登录接口
router.post('/login', (req, res) => {
var sql = $sql.user.login;
var params = req.body;
console.log(params);
conn.query(sql, [params.userName, params.passWord], function (err, result) {
var data = JSON.parse(JSON.stringify(result))
if (data.length === 0) {
return res.send({
status: 1,
msg: "用户名或密码错误"
})
} else {
let content = {
userName: params.userName
}
let secretOrPrivateKey = "_jwt"; // 这是加密的key(密钥)
let token = jwt.sign(content, secretOrPrivateKey, {
expiresIn: 60 * 60 * 1 // 1小时过期
});
return res.send({
status: 1,
msg: "登录成功",
userName: params.userName,
token: token
})
}
})
});
// 创建用户
router.post('/createUser', (req, res) => {
var sql = $sql.user.createUser;
console.log(req);
conn.query(sql, [req.body.userId, req.body.userName, req.body.createDate, req.body.nickName, req.body.passWord], function (err, result) {
var data = req.body;
console.log(result)
return res.send({
status: 1,
msg: "新增成功",
data: data
})
})
});
// 查询用户列表
router.post('/getUserList', (req, res) => {
var sql = $sql.user.queryUserList;
var params = req.body;
// console.log(params);
conn.query(sql, [], function (err, result) {
var data = JSON.parse(JSON.stringify(result))
return res.send({
status: 1,
msg: "查询成功",
list: data
})
})
});
module.exports = router;
下面再看看,前端是怎么调后台接口:
auth.js代码:
import Cookies from 'js-cookie'
const TokenKey = 'id_token'
const name = "userName"
const json = 'tree'
const id = "discussId"
export function getToken () {
return Cookies.get(TokenKey)
}
export function setToken (token) {
return Cookies.set(TokenKey, token)
}
export function setUserName (userName) {
return Cookies.set(name, userName)
}
export function getUserName () {
return Cookies.get(name)
}
export function removeToken () {
return Cookies.remove(TokenKey)
}
export function setJson (data) {
return Cookies.set(json, data)
}
export function setDiscussId (data) {
return Cookies.set(id, data)
}
export function getDiscussId() {
return Cookies.get(id)
}
request.js代码:
import axios from 'axios'
import store from '../store'
import { getToken } from '@/utils/auth'
// 创建axios实例
const service = axios.create({
// baseURL: 'http://localhost:8090',
timeout: 15000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers = {
// 判断是否存在token,如果存在的话,则每个http header都加上token
authorization: 'Bearer ' + getToken(),
'Content-Type': 'application/json;charset=UTF-8',
Accept: 'application/json, */*'
}
} else {
config.headers = {
'Content-Type': 'application/json;charset=UTF-8',
Accept: 'application/json, text/plain, */*'
}
}
return config
},
error => {
console.log(error) // for debug
Promise.reject(error)
}
)
// respone拦截器
service.interceptors.response.use(
response => {
return response.data
},
error => {
console.log('err' + error) // for debug
return Promise.reject(error)
}
)
export default service
页面调用方式这里以登录功能为例:
Login.vue代码:
<template>
<!-- <div class="login-box">
<h1>登录页</h1>
<form>
<input type="text" name="username" v-model="userName"> <br>
<input type="text" name="age" v-model="age"> <br>
<a href="javascript:;" @click="addUser">提交</a>
</form>
</div> -->
<div class="bg-container">
<div class="login-form">
<div style="font-size: 20px; font-weight: 300; color: #fff">程序猿博客后台管理系统</div>
<div>
<el-form label-width="80px" class="login-box">
<el-form-item label="账号" prop="userName">
<el-input type="text" placeholder="请输入账号" v-model="userName" />
</el-form-item>
<el-form-item label="密码" prop="passWord">
<el-input type="password" placeholder="请输入密码" v-model="passWord" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">登录</el-button>
</el-form-item>
</el-form>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Copyright © 2019 程序猿博客股份有限公司</span>
</div>
</div>
</div>
</template>
<script>
import { setToken, setUserName } from "@/utils/auth";
import request from "@/utils/request";
export default {
name: "login",
data() {
return {
userName: "admin",
passWord: "admin"
};
},
methods: {
onSubmit() {
var userName = this.userName;
var passWord = this.passWord;
request({
url: "/api/user/login",
method: "post",
data: {
userName,
passWord
}
}).then(res => {
if (res.msg === "登录成功") {
this.$message({
message: "恭喜你,登录成功",
type: "success"
});
setToken(res.token);
setUserName(res.userName);
this.$router.push("home");
}
});
}
}
};
</script>
<style scoped>
.el-form-item__label{
color: #fff;
}
.bg-container {
width: 100%;
height: 900px;
overflow: hidden;
margin: 0;
/* background-image: url('../../assets/login_bg.jpg'); */
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
margin: 0 auto;
height: 30px;
line-height: 20px;
padding-top: 5px;
padding-bottom: 5px;
}
.footer .copyright {
font-size: 12px;
text-align: center;
width: 100%;
/* color: #fff; */
opacity: 0.5;
}
.login-form {
position: absolute;
left: 50%;
top: 35%;
transform: translate(-50%, -50%);
}
/* h2 {
color: #fff;
} */
.login-box {
border: 1px solid #dcdfe6;
width: 350px;
margin: 80px auto;
padding: 35px 35px 15px 35px;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
box-shadow: 0 0 25px #909399;
}
</style>
表结构如下(具体字段名可以看sql语句):
线上体验地址:点我体验 用户名和密码都是默认的,可以直接登录