英雄管理系統
文件結構如下:
|----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("服務器開啓了...");
});
這是前端登錄頁代碼:
<!DOCTYPE html>
<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 Template</title>
<!-- Bootstrap -->
<link href="./lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<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 navigation</span>
<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">
<label for="vCode" class="col-sm-2 control-label">驗證碼</label>
<div class="col-sm-6">
<input type="text" name="vcode" class="form-control" id="vcode" placeholder="請輸入驗證碼" />
</div>
<div class="col-sm-4">
<img class="vCode" src="/captcha" alt="" />
</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>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="./lib/bootstrap/js/jquery-1.12.4.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<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>
這是前端的主頁代碼:
<!DOCTYPE html>
<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 Template</title>
<!-- Bootstrap -->
<link href="./lib/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<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 navigation</span>
<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">
<!-- action 不寫 就是當前頁面 method 不寫 就是 get -->
<div class="row">
<div class="col-md-9">
<!--<form class="form-inline">
<div class="form-group">
<label class="sr-only" for="exampleInputAmount"
>Amount (in dollars)</label
>
<div class="input-group">
<div class="input-group-addon">英雄姓名</div>
<input
type="text"
value=""
class="form-control"
name="search"
placeholder="請輸入查詢內容"
/>
</div>
</div>
<button type="submit" class="btn btn-default">查找</button>
</form>-->
</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>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="./lib/bootstrap/js/jquery-1.12.4.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="./lib/bootstrap/js/bootstrap.min.js"></script>
<!-- 引入模板引擎js文件 -->
<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>