文件结构如下:
|----heroManage
|----node_modules --> 这是用命令自动生成的 npm i express body-parser multer
|----uploads --> 这是用代码自动生成的 var upload = multer({ dest: “uploads/” });
|----utils --> 这是复制的工具包
|----www --> 这是主要的前端代码包
|----app.js --> 这是主要的后端代码文件
|----package.json --> 这是用命令自动生成的 npm init -y
|----package-lock.json --> 这是和上面的node_modules文件夹一起生成的
这是后端主要逻辑代码:
// 导包
const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const multer = require("multer");
// 用包,帮我们创建一个uploads文件夹
var upload = multer({ dest: "uploads/" });
// 导入我们自己写的模块,需要拼接一个绝对路径
const db = require(path.join(__dirname, "utils", "db.js"));
// 创建服务器
const app = express();
// 例如,通过如下代码就可以将 www 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
app.use(express.static("www"));
// 如果要使用多个静态资源目录,请多次调用 express.static 中间件函数:
app.use(express.static("uploads"));
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// 写接口(注册路由)
// 1. 用户登录
app.post("/login", (req, res) => {
// 1.1 接收用户传递过来的用户名和密码
let { username, password } = req.body; // 对象解构语法
// 1.2 判断账号和密码是否正确
// 实际开放的时候判断流程:把账号和密码发到数据库中去验证
if (username == "admin" && password == "123456") {
res.send({
code: 200,
msg: "登录成功!",
});
} else {
res.send({
code: 400,
msg: "账号或者密码不正确!",
});
}
});
// 2. 获取所有英雄
app.get("/getAllHero", (req, res) => {
// 调用我们自己写的db.js模块,调用它里面的方法获取所有的英雄
let list = db.getHeros();
res.send({
code: 200,
data: list,
});
});
// 3. 新增英雄
app.post("/add", upload.single("icon"), (req, res) => {
// req.file is the `avatar` file // 传过来的文件,参数名用icon
// req.body will hold the text fields, if there were any // 一起传过来的文本保存在req.body中
console.log(req.file); // 文件的参数就在这里 { filename: 'ee7c4b63db36fd8acd85f24eaf55eb6d', }
console.log(req.body); // 文本参数就在这里 { name: '千里', skill: '飘起来' }
// 用变量保存一下
let { name, skill } = req.body;
let icon = req.file.filename;
// 把这个新增的英雄的数据,用我们自己写的插件db.js 存起来
let result = db.addHero({
name,
skill,
icon: "http://127.0.0.1:4399/" + icon,
});
// 判断
if (result == true) {
res.send({
code: 200,
msg: "新增成功",
});
} else {
res.send({
code: 400,
msg: "新增失败",
});
}
});
// 4. 删除英雄
app.get("/delete", (req, res) => {
// 接收前端传递过来的要删除的英雄的id
let { id } = req.query;
// console.log(id);
// 用我们自己写的db.js这个文件去删除 英雄
let result = db.deleteHeroById(id);
// 判断
if (result == true) {
res.send({
code: 200,
msg: "删除成功!",
});
} else {
res.send({
code: 400,
msg: "删除失败!",
});
}
});
// 5. 根据id获取英雄(编辑的第一步)
app.get("/getHeroById", (req, res) => {
// 获取前端传递过来需要编辑的这个英雄的id
let { id } = req.query; // 解构赋值
// 用db.js来获取id下的英雄信息
let result = db.getHeroById(id);
if (result != false) {
res.send({
code: 200,
mag: "获取成功",
data: result,
});
} else {
res.send({
code: 400,
mag: "获取失败",
});
}
res.send("根据id获取英雄");
});
// 6. 编辑英雄
app.post("/edit", upload.single("icon"), (req, res) => {
// 用模块multer来接收用户编辑之后的(英雄名,英雄技能,,英雄头像)
// 文件(英雄头像)req.file.filename;
// 非文件参数 req.body
// console.log(req.file.filename); // 387d6f59e71fd30002b039dd05f6062c
// console.log(req.body); // { id: '3', name: '千里里', skill: '飘起来了' }
// 存进变量里
let icon = req.file.filename;
let { id, name, skill } = req.body;
// 用db.js来处理
let result = db.editHero({
id,
name,
skill,
icon: "http://127.0.0.1:4399/" + icon,
});
if (result == true) {
res.send({
code: 200,
msg: "修改成功!",
});
} else {
res.send({
code: 400,
msg: "修改失败!",
});
}
res.send("编辑英雄");
});
// 开启服务器
app.listen(4399, () => {
console.log("服务器开启了...");
});
这是前端登录页代码:
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bootstrap 101 Templatetitle>
<link href="./lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<style>
.login-panel {
margin-top: 100px;
}
.vCode {
height: 36px;
cursor: pointer;
}
.wrap {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url("images/bg03.jpg") center bottom no-repeat;
overflow: auto;
}
.navbar-brand {
padding: 10px 15px;
}
.form-horizontal {
margin-top: 10px;
}
.form-horizontal .form-group {
margin-bottom: 20px;
}
style>
head>
<body>
<div class="wrap">
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button
type="button"
class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#mymenu"
>
<span class="sr-only">Toggle navigationspan>
<span class="icon-bar">span>
<span class="icon-bar">span>
<span class="icon-bar">span>
button>
<a class="navbar-brand" href="#"><img src="images/logo.png" />a>
div>
div>
nav>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-default login-panel">
<div class="panel-heading">
<h3 class="panel-title"><b>用户登录b>h3>
div>
<div class="panel-body">
<form action="#" method="post" class="form-horizontal">
<div class="form-group">
<label for="userName" class="col-sm-2 control-label"
>用户名label
>
<div class="col-sm-10">
<input
type="text"
name="username"
value="叶良辰"
class="form-control"
id="username"
placeholder="请输入用户名"
/>
div>
div>
<div class="form-group">
<label for="userPass" class="col-sm-2 control-label"
>密码label
>
<div class="col-sm-10">
<input
type="password"
name="password"
value="1234"
class="form-control"
id="password"
placeholder="请输入密码"
/>
div>
div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-success login">
登陆
button>
<a href="./register.html" class="btn btn-default">注册a>
div>
div>
form>
div>
div>
div>
div>
div>
div>
body>
html>
<script src="./lib/bootstrap/js/jquery-1.12.4.js">script>
<script src="./lib/bootstrap/js/bootstrap.min.js">script>
<script>
// 入口函数
$(function () {
// 一:登录功能
// 1. 给登录按钮设置一个点击事件
$(".login").on("click", function (e) {
// 去掉默认的提交行为
e.preventDefault();
// 2. 获取用户输入的账号和密码
let username = $("#username").val().trim();
let password = $("#password").val().trim();
// 3. 发送ajax请求,获取返回的数据
$.ajax({
type: "post",
url: "http://127.0.0.1:4399/login",
// 对象解构语法
data: {
username,
password,
},
success: function (backData) {
// backData: 接收到的后端返回的json数据
// console.log(backData);
if (backData.code == 200) {
// 如果成功,就跳转到首页
alert("登录成功");
window.location.href = "index.html";
} else {
alert(backData.msg);
}
},
});
});
});
script>
这是前端的主页代码:
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Bootstrap 101 Templatetitle>
<link href="./lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<style>
.wrap {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url("images/bg03.jpg") center bottom no-repeat;
overflow: auto;
}
.navbar-brand {
padding: 10px 15px;
}
.logout {
font-weight: 900;
font-size: 20px;
color: #ff0000;
text-decoration: none;
}
.logout:hover {
text-decoration: none;
color: yellowgreen;
}
#my-table th {
text-align: center;
}
#my-table td {
text-align: center;
line-height: 80px;
padding: 0;
padding: 10px;
}
td img {
width: 80px;
height: 80px;
}
.username {
font-weight: 900;
color: hotpink;
background-color: yellowgreen;
}
.pagination {
margin: 0px;
padding: 0px;
font-size: 0;
line-height: 1;
}
.pagination li {
display: inline-block;
font-size: 14px;
}
.mp15 {
margin-top: 15px;
}
.table {
margin-bottom: 0;
}
.table-bordered > thead > tr > td,
.table-bordered > thead > tr > th {
border-bottom-width: 1px;
}
.page-title {
font-size: 16px;
font-weight: bold;
}
style>
head>
<body>
<div class="wrap">
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button
type="button"
class="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#mymenu"
>
<span class="sr-only">Toggle navigationspan>
<span class="icon-bar">span>
<span class="icon-bar">span>
<span class="icon-bar">span>
button>
<a class="navbar-brand" href="#"><img src="images/logo.png" />a>
div>
div>
nav>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading clearfix">
<div class="row">
<div class="col-md-6 page-title">英雄列表div>
<div class="col-md-6 text-right">当前位置:首页div>
div>
div>
<div class="panel-body">
<div class="row">
<div class="col-md-9">
div>
<div class="col-md-3">
<a href="./add.html" class="btn btn-success pull-right"
>新增a
>
div>
div>
<table id="my-table" class="table table-bordered mp15">
<thead>
<tr>
<th width="25%">头像th>
<th width="25%">姓名th>
<th width="25%">技能th>
<th width="25%">操作th>
tr>
thead>
<tbody>
<tr>
<td><img src="./lib/img/盖伦.png" alt="" />td>
<td>盖伦td>
<td>躲草丛td>
<td>
<button
onclick="location.href='./edit.html'"
class="btn btn-primary"
>
编辑
button>
<button
onclick="alert('你真狠')"
class="btn btn-danger"
>
删除
button>
td>
tr>
<tr>
<td><img src="./lib/img/盖伦.png" alt="" />td>
<td>盖伦td>
<td>躲草丛td>
<td>
<button
onclick="location.href='./edit.html'"
class="btn btn-primary"
>
编辑
button>
<button
onclick="alert('你真狠')"
class="btn btn-danger"
>
删除
button>
td>
tr>
tbody>
table>
div>
div>
div>
div>
div>
div>
body>
html>
<script src="./lib/bootstrap/js/jquery-1.12.4.js">script>
<script src="./lib/bootstrap/js/bootstrap.min.js">script>
<script src="./lib/js/template-web.js">script>
<script type="text/html" id="cq">
{{each data v}}
<tr>
<td><img src="{{v.icon}}"></td>
<td>{{v.name}}</td>
<td>{{v.skill}}</td>
<td>
<button onclick="location.href='./edit.html?id={{v.id}}'" class="btn btn-primary">编辑</button>
<button data-id='{{v.id}}' class="btn btn-danger delete">删除</button>
</td>
</tr>
{{/each}}
script>
<script>
// 入口函数
$(function () {
// 一:一进到首页,就要发送ajax请求,获取所有的英雄数据
$.ajax({
type: "get",
url: "http://127.0.0.1:4399/getAllHero",
success: function (res) {
console.log(res);
// var temp = template('cq', res);
// $('tbody').html(temp)
if (res.code == 200) {
// 通过模板引擎渲染
var resHtml = template("cq", res);
console.log(resHtml);
$("tbody").html(resHtml);
}
},
});
});
// 删除数据
$("tbody").on("click", ".delete", function () {
var that = this;
// console.log(this)
var id = $(this).attr("data-id").trim();
if (confirm("你要删除吗??")) {
$.ajax({
type: "get",
url: "http://127.0.0.1:4399/delete",
data: {
id: id,
},
success: function (res) {
// console.log(res)
if (res.code == 200) {
$(that).parent().parent().remove();
}
},
});
}
});
script>