const express = require("express");
const app = express();
const path = require("node:path");
const fs = require("fs/promises");
let STUDENT_ARR = require("./data/students.json");
// 将ejs设置为默认的模板引擎
app.set("view engine", "ejs");
// 配置模板路径
// app.set('views','views') // 默认设置,前一个表示设置,后一个表示路径
app.set("views", path.resolve(__dirname, "views"));
// 配置静态资源路径
app.use(express.static(path.resolve(__dirname, "public")));
// 配置请求体解析
app.use(express.urlencoded({ extended: true }));
// app.use(express.json())
/*
删除
- 点击删除链接后,删除当前数据
- 流程:
1.点击删除链接
2.向路由发送请求
3.路由怎么写?
- 获取学生的id
- 删除id为n的学生
- 将新的数组写入json文件
- 重定向到学生列表页面
*/
app.get("/delete", (req, res) => {
// 获取要删除的学生id
const id = +req.query.id;
// 根据id删除学生
STUDENT_ARR = STUDENT_ARR.filter(stu => stu.id !== id);
// 将新的数组写入到文件中
fs.writeFile(path.resolve(__dirname, "./data/students.json"), JSON.stringify(STUDENT_ARR))
.then(() => {
// res.redirect() 用来发起请求的重定向
// 重定向的作用是告诉浏览器你向另外一个地址再发起一次请求
res.redirect("/students");
})
.catch(() => {
// 处理异常
console.log("出错了---");
});
});
/*
修改
- 点击修改链接后,应该显示一个表单,表单中应该有要修改的学生的信息
用户对学生信息进行修改,修改以后点击按钮提交表单
- 流程:
1.点击学生修改链接
2.跳转到一个路由
- 这个路由会返回一个页面,页面中有一个表单,表单中应该显示学生的各种信息
3.用户填写表单,电机按钮提交到一个新的路由
- 获取学生信息,并对信息进行修改
*/
app.post("/update-student", (req, res) => {
// 获取学生id
// const id = +req.query.id;// 通过查询字符串获取id
const { id, name, age, gender, address } = req.body;
// 修改学生信息
// 根据学生id来获取学生对象
const student = STUDENT_ARR.find(item => item.id === +id);
student.name = name;
student.age = +age;
student.gender = gender;
student.address = address;
// 将新的数组写入到文件中
fs.writeFile(path.resolve(__dirname, "./data/students.json"), JSON.stringify(STUDENT_ARR))
.then(() => {
// res.redirect() 用来发起请求的重定向
// 重定向的作用是告诉浏览器你向另外一个地址再发起一次请求
res.redirect("/students");
})
.catch(() => {
// 处理异常
console.log("出错了---");
});
});
app.get("/to-update", (req, res) => {
const id = +req.query.id;
// 获取要修改的学生的信息
const student = STUDENT_ARR.find(item => item.id === id);
res.render("update", { student });
});
app.get("hello", (req, res) => {
res.send("hello");
});
app.get("/students", (req, res) => {
res.render("students", { stus: STUDENT_ARR });
});
// 创建一个添加学生信息的路由
app.post("/add-student", (req, res) => {
// 路由里要做什么?
// 生成id
const id = STUDENT_ARR.at(-1) ? STUDENT_ARR.at(-1).id + 1 : 1;
// 1.获取用户填写的信息
const newUser = {
id,
name: req.body.name,
age: +req.body.age,
gender: req.body.gender,
address: req.body.address,
};
// 2.验证用户信息(略)
// 3.将用户信息添加到数组中
STUDENT_ARR.push(newUser);
// 4.返回响应
// res.send('添加成功!')
// 直接在添加路由中渲染ejs,会面临表单重复提交的问题
// res.render('students', { stus: STUDENT_ARR });
// 将新的数据写入到json文件中
fs.writeFile(path.resolve(__dirname, "./data/students.json"), JSON.stringify(STUDENT_ARR))
.then(() => {
// res.redirect() 用来发起请求的重定向
// 重定向的作用是告诉浏览器你向另外一个地址再发起一次请求
res.redirect("/students");
})
.catch(() => {
// 处理异常
console.log("出错了---");
});
});
// 可以在所有路由的后面配置错误路由
app.use((req, res) => {
// 只要这个中间件一执行,说明上边的地址都没有匹配
res.status(404);
res.send("<h1>您访问的地址已被外星人劫持!</h1>");
});
app.listen(3000, () => {
console.log("服务器已启动");
});
student.ejs代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>这是ejs模板</title>
<style>
table {
border-collapse: collapse;
}
th,
td {
border: 1px solid #000;
font-size: 20px;
padding: 10px;
text-align: center;
}
caption {
font-size: 25px;
font-weight: bold;
}
</style>
</head>
<body>
<% for(const stu of stus){ %> <%=stu.name %> - <%=stu.age %> - <%=stu.gender %> - <%=stu.address %>
<br />
<% } %>
<hr />
<% if (stus && stus.length > 0) { %>
<table>
<caption>
学生列表
</caption>
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>地址</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<% for(const stu of stus){ %>
<tr>
<td><%=stu.id %></td>
<td><%=stu.name %></td>
<td><%=stu.age %></td>
<td><%=stu.gender %></td>
<td><%=stu.address %></td>
<td>
<a onclick="return confirm('确认删除吗?')" href="/delete?id=<%=stu.id%>">删除</a>
<a href="/to-update?id=<%=stu.id%>">修改</a>
</td>
</tr>
<br />
<% } %>
</tbody>
</table>
<% }else{ %>
<p>学生列表为空!</p>
<% } %>
<form action="/add-student" method="post">
<div>
姓名:
<input type="text" name="name" />
</div>
<div>
年龄:
<input type="number" max="150" min="0" name="age" />
</div>
<div>
性别:
<input type="radio" name="gender" value="男" />男 <input type="radio" name="gender" value="女" />女
</div>
<div>
地址:
<input type="text" name="address" />
</div>
<div>
<button>添加</button>
</div>
</form>
</body>
</html>
update.ejs代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>修改学生信息</h1>
<form action="/update-student?id=student.id" method="post">
<!-- 直接传入请求体 -->
<!-- hidden是一个隐藏的表单项,可以通过它传递一些不希望被用户看见的数据 -->
<input type="hidden" name="id" value="<%=student.id%>">
<div>
姓名:
<input type="text" name="name" value="<%=student.name %>" />
</div>
<div>
年龄:
<input type="number" max="150" min="0" name="age" value="<%=student.age%>" />
</div>
<!-- <%#student.gender === '男' && 'checked' %> -->
<div>
性别: <input type="radio" name="gender" value="男" <%=student.gender === '男' && 'checked' %> />男 <input type="radio" name="gender" value="女"
<%=student.gender === '女' && 'checked' %> />女
</div>
<div>
地址:
<input type="text" name="address" value="<%=student.address %>" />
</div>
<div>
<button>修改</button>
</div>
</form>
</body>
</html>
students.json代码如下
[
{ "id": 1, "name": "孙悟空", "age": 18, "gender": "男", "address": "花果山" },
{ "id": 2, "name": "猪八戒", "age": 28, "gender": "男", "address": "高老庄" },
{ "id": 3, "name": "沙和尚", "age": 38, "gender": "男", "address": "流沙河" }
]