源代码链接:https://pan.baidu.com/s/1QBytlPhuPdCAFOoMd72WDA
提取码:a757
后端文件目录
app.js
项目的入口文件src
目录:存储项目开发中用到的文件,换言之就是存储我们开发者编写的文件
controller
目录:控制器。业务逻辑代码放进来
blog.js
文件:博客列表db
目录:存放数据库
mysql.js
:数据库文件model
目录:模型
resModel.js
文件router
目录:存储路由文件
blog.js
文件:路由文件前端文件目录:
index.html
文件创建package.json
文件,敲下面命令
npm init -y
安装mysql
模块,敲下面命名。并在mysql文件中调用
cnpm i mysql
blog.js
文件const {
exec } = require("../db/mysql");
const {
SuccessModel } = require("../model/resModel");
const moment =require('moment')
// 博客列表
const getList = () => {
/*let result= exec("select * from blogs");
return result.then(data=>{
data.forEach(item=>{
item.createtime=moment(item.createtime).format('YYYY-MM-DD HH:mm:ss')
})
return data
})*/
return exec("select * from blogs");
};
// 博客详情
const getDetail = (id) => {
return exec("select * from blogs where id=" + id);
};
// 新增数据
const newBlog = function (blogData) {
console.log(blogData);
let sql = `insert into blogs values(null,'${
blogData.title}','${
blogData.content
}',${
Date.now()},'${
blogData.author}')`;
console.log(sql);
let result = exec(sql);
return result.then((data) => {
return data.insertId;
});
};
/**
* 更新博客
* id:要更新的博客的id
* postData:结构如下:{title:'更改后的title',content:'更改后的content'}
*/
const updateBlog = (id, postData) => {
let sql = `update blogs set title='${
postData.title}',content='${
postData.content}' where id=${
id}`;
let result = exec(sql);
return result.then((data) => {
return data.affectedRows == 1 ? true : false;
});
};
// 删除博客
const deleteBlog = (id) => {
let sql = `delete from blogs where id=${
id}`;
let result = exec(sql);
return result.then((data) => {
return data.affectedRows == 1 ? true : false;
});
};
module.exports = {
getList,
getDetail,
newBlog,
updateBlog,
deleteBlog,
};
mysql.js
文件const mysql = require("mysql");
// 创建链接
const con = mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
port: 3306,
database: "new",
});
// 打开链接
con.connect();
const exec = (sql) => {
return new Promise((resolve, reject) => {
con.query(sql, (err, result) => {
if (err) {
reject("执行sql语句失败");
return;
}
resolve(result);
});
});
};
module.exports={
exec
}
resModel.js
文件class BaseModel {
constructor(msg, data) {
this.msg = msg;
this.data = data;
}
}
class SuccessModel extends BaseModel {
constructor(msg, data) {
super(msg, data);
this.errno = 0;
}
}
class ErrorModel extends BaseModel {
constructor(msg, data) {
super(msg, data);
this.errno = -1;
}
}
module.exports = {
SuccessModel,
ErrorModel,
};
blog.js
文件/**
* 路由文件:接受用户的请求,并进行返回数据
*/
// 引入blog 控制器
const {
getList,
getDetail,
newBlog,
updateBlog,
deleteBlog,
} = require("../controller/blog");
const {
SuccessModel, ErrorModel } = require("../model/resModel");
const handlerBlog = (req) => {
// 使用 URL 模块对 req.url 进行封装
let myUrl = new URL(req.url, "http://127.0.0.1:3000/");
let method = req.method;
let pathname = myUrl.pathname;
// console.log(pathname);
let msgResult = null;
if (pathname == "/api/blog/list" && method == "GET") {
msgResult = getList();
// then 方法的返回值也是一个 promise
return msgResult.then((data) => {
return new SuccessModel("", data);
});
} else if (pathname == "/api/blog/detail" && method == "GET") {
let id = myUrl.searchParams.get("id");
msgResult = getDetail(id);
return msgResult.then((data) => {
return new SuccessModel("", data);
});
} else if (pathname == "/api/blog/new" && method == "POST") {
msgResult = newBlog(req.body);
return msgResult.then((data) => {
return new SuccessModel("", data);
});
} else if (pathname == "/api/blog/update" && method == "POST") {
let id = myUrl.searchParams.get("id");
let postData = req.body;
msgResult = updateBlog(id, postData);
return msgResult.then((data) => {
return new SuccessModel("", data);
});
} else if (pathname == "/api/blog/del" && method == "GET") {
let id = myUrl.searchParams.get("id");
msgResult = deleteBlog(id);
return msgResult.then((data) => {
return new SuccessModel("", data);
});
}
return msgResult;
};
// 暴漏 handlerBlog 方法
module.exports = {
handlerBlog,
};
app.js
文件// 项目入口文件
const url = require("url");
const http = require("http");
// 引入 blog.js 模块
const blog_module = require("./src/router/blog");
const fs = require("fs");
// 创建 http 服务
const app = http.createServer((req, res) => {
// 设置返回格式:JSON
res.setHeader("content-type", "application/json");
// 设置允许跨域请求
res.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8080"); // 允许所有路径跨域
res.setHeader("Access-Control-Allow-Credentials", true); //允许带 cookie
res.setHeader("Access-Control-Allow-Headers", "Content-Type,Content-Length, Authorization, Accept,X-Requested-With,xToken");
res.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.setHeader("X-Powered-By",' 3.2.1');
// 向客户端写入 cookie 因为跨域问题,下面代码不能实现。
res.setHeader("Set-cookie", "username=onlifes;path=/");
// 演示cookie 默认不能跨域写入
// if (req.url == "/index.html") {
// let result=fs.readFileSync("./index.html")
// res.end(result)
// return
// }
getPostData(req).then((data) => {
req.body = data; // 至此,已经能够完全获取到以post 方式提交的数据了
let msgResult = blog_module.handlerBlog(req);
if (msgResult) {
msgResult.then((data) => {
res.end(JSON.stringify(data));
// return return 不能放在这里
});
return; // 中断当前函数
}
msgResult = {
msg: "请求的接口不存在",
};
res.end(JSON.stringify(msgResult));
});
});
// 处理所有网络请求
// app.on('reques',(req, res) => {});
// 启动服务
app.listen(3000, () => {
console.log("Server is running at http://127.0.0.1:3000");
});
const getPostData = (req) => {
/**
* 处理以 post 方式提交的数据
*/
// 获取以 post 方式提交的数据
return new Promise((resolve, reject) => {
if (req.method == "POST") {
let postData = "";
req.on("data", (params) => {
postData += params;
});
req.on("end", () => {
resolve(JSON.parse(postData));
});
} else {
resolve({
});
}
});
};
下载layui包
只需要把里面的layui
文件夹提出来就行
index.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="/layui/css/layui.css" />
<style>
.form-hidden {
display: none;
}
.form-show {
display: block;
}
#form-add {
padding-top: 20px;
}
style>
head>
<body>
<div class="layui-container" style="padding-top: 50px">
<button type="button" class="layui-btn" id="btn-add">发表文章button>
<div class="layui-row">
<div class="layui-col-md12">
<table class="layui-table">
<colgroup>
<col width="150" />
<col width="200" />
<col />
<col />
<col />
<col />
colgroup>
<thead>
<tr>
<th>编号th>
<th>标题th>
<th>内容th>
<th>创建时间th>
<th>作者th>
<th>操作th>
tr>
thead>
<tbody>
tbody>
table>
div>
div>
div>
<form class="layui-form form-hidden" action="" id="form-add">
<div class="layui-form-item">
<label class="layui-form-label">博客标题label>
<div class="layui-input-block">
<input type="text" name="title" id="title" required lay-verify="required" placeholder="请输入标题" autocomplete="off"
class="layui-input" />
div>
div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">博客内容label>
<div class="layui-input-block">
<textarea name="content" id="content" placeholder="请输入内容" class="layui-textarea">textarea>
div>
div>
<div class="layui-form-item">
<label class="layui-form-label">作者label>
<div class="layui-input-block">
<input type="text" name="author" id="author" required lay-verify="required" placeholder="请输入姓名" autocomplete="off"
class="layui-input" />
div>
div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">
立即发表
button>
<button type="reset" class="layui-btn layui-btn-primary">重置button>
div>
div>
form>
<form class="layui-form form-hidden" action="" id="form-edite">
<input type="hidden" name="" id="blog_id" />
<div class="layui-form-item">
<label class="layui-form-label">博客标题label>
<div class="layui-input-block">
<input type="text" name="title" id="edite_title" required lay-verify="required" placeholder="请输入标题"
autocomplete="off" class="layui-input" />
div>
div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">博客内容label>
<div class="layui-input-block">
<textarea name="content" id="edite_content" placeholder="请输入内容" class="layui-textarea">textarea>
div>
div>
<div class="layui-form-item">
<label class="layui-form-label">作者label>
<div class="layui-input-block">
<input type="text" name="author" id="edite_author" required lay-verify="required" placeholder="请输入姓名"
autocomplete="off" class="layui-input" />
div>
div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formEdite">
立即发表
button>
<button type="reset" class="layui-btn layui-btn-primary">重置button>
div>
div>
form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js">script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js">script>
<script src="/layui/layui.js">script>
<script>
// 声明变量,存储ajax请求的基准地址
let baseUrl = 'http://127.0.0.1:3000/'
// 展示博客数据
var loadBlog = () => {
fetch(baseUrl + "api/blog/list", {
credentials: "omit",
})
.then((response) => {
return response.json();
})
.then((data) => {
document.querySelector('tbody').innerHTML=''
console.log();
data.data.forEach((item) => {
let tr = `
${
item.id}
${
item.title}
${
item.content}
${
moment(item.createtime).format("YYYY年M月D号 H时m分s秒")}
${
item.author}
`;
document
.querySelector("tbody")
.insertAdjacentHTML("afterbegin", tr);
});
});
};
loadBlog();
// 声明全局变量, 存储layer.open方法的返回值,用于将来关闭此弹出层
var index = -1;
// 点击发表文章按钮弹出用于添加文章的层
document.querySelector("#btn-add").addEventListener("click", () => {
layui.use("layer", function () {
var layer = layui.layer;
index = layer.open({
content: $("#form-add"),
title: "添加博客",
type: 1,
area: ["800px", "400px"],
});
$("#form-add").css("display", "form-show");
});
});
layui.use("form", function () {
var form = layui.form;
//监听添加
form.on("submit(formDemo)", function (data) {
// 发送 ajax 请求,新增数据
var url = baseUrl + "api/blog/new";
var data = {
title: $("#title").val(),
content: $("#content").val(),
author: $("#author").val()
};
fetch(url, {
method: "POST", // or 'PUT'
body: JSON.stringify(data), // data can be `string` or {object}!
headers: new Headers({
"Content-Type": "application/json",
}),
})
.then((res) => res.json())
.then((response) => {
if (response.errno == 0) {
layer.close(index);
layer.msg("博客发表成功");
// 重新加载数据
loadBlog();
// location.reload();
} else {
layer.msg(response.msg);
}
});
return false;
});
// 监听编辑
form.on("submit(formEdite)", function (data) {
let id = document.querySelector("#blog_id").value;
var data = {
title: $("#edite_title").val(),
content: $("#edite_content").val(),
content: $("#edite_content").val(),
author: $("#edite_author").val(),
};
fetch(baseUrl + "api/blog/update?id=" + id, {
method: "post",
body: JSON.stringify(data),
headers: new Headers({
"Content-Type": "application/json",
}),
})
.then((response) => {
return response.json();
})
.then((data) => {
if (data.data == true) {
layer.close(index);
layer.msg("博客发表成功");
// 重新加载数据
loadBlog();
// location.reload();
}
});
return false;
});
});
// 鼠标悬浮到编辑按钮上,显示提示文字
// document
// .querySelector("tbody")
// .addEventListener("mouseover", function (e) {
// let reg1 = /edite/;
// let reg2 = /delete/;
// if (reg1.test(e.target.className)) {
// layer.tips("编辑文章", e.target, {
// tips: 1,
// }); //在元素的事件回调体中,follow直接赋予this即可
// } else if (reg2.test(e.target.className)) {
// layer.tips("删除文章", e.target, {
// tips: 1,
// }); //在元素的事件回调体中,follow直接赋予this即可
// }
// });
// 点击编辑按钮,弹出用于编辑文章的层
document.querySelector("tbody").addEventListener("click", function (e) {
let reg1 = /edite/;
let reg2 = /delete/;
if (reg1.test(e.target.className)) {
// 获取待编辑的博客的id
let id = e.target.dataset.id;
// 发送ajax请求
fetch(baseUrl + "api/blog/detail?id=" + id)
.then((response) => {
return response.json();
})
.then((res) => {
if (res.errno == 0) {
document.querySelector("#blog_id").value = res.data[0].id;
document.querySelector("#edite_title").value =
res.data[0].title;
document.querySelector("#edite_content").value =
res.data[0].content;
document.querySelector("#edite_author").value =
res.data[0].author;
}
});
layui.use("layer", function () {
var layer = layui.layer;
index = layer.open({
content: $("#form-edite"),
title: "编辑博客",
type: 1,
area: ["800px", "400px"],
});
$("#form-edite").css("display", "form-show");
});
} else if (reg2.test(e.target.className)) {
// 获取待编删除的博客的id
let id = e.target.dataset.id;
fetch(baseUrl + "api/blog/del?id=" + id)
.then((response) => {
return response.json();
})
.then((data) => {
if (data.data == true) {
layer.msg('删除成功')
loadBlog()
// location.reload();
}
});
}
});
script>
body>
html>