需求分析
  1. 查询API(状态、页码、行数)
  2. 新增API(任务名称、截止日期、内容)
  3. 修改:首先通过查询API(ID)获得修改行数据,修改API提交最终修改(任务名称、截止日期、内容、ID)
  4. 删除API(ID)
  5. 更新状态API(ID、状态【待办、完成】)

    api设计
  6. 初始化项目:

    1. mkdir nodejs-express-vue-backEnd
    2. cd nodejs-express-vue-backEnd
    3. git init
    4. npm init -y
    5. // 创建.gitignore文件,添加忽略配置:node_modules、.lh
    6. npm i express sequelize sequelize-cli mysql2 body-parser -S
    7. npm i nodemon -D
    8. mkdir src
    9. //在src文件夹下创建app.js文件
  • express web服务框架
  • sequelize ORM对象管理模型,用来处理代码与数据库的通信
  • sequelize-cli 使用sequelize的脚手架工具
  • mysql2 mysql数据库驱动,连接数据库
  • body-parser 处理body形式的传参,JSON(例如:post请求) ```javascript const express = require(‘express’); const bodyParser = require(‘body-parser’); const app = express();

/**

  • 应用级别中间件
  • 处理参数 */ app.use(express.json());

app.use(express.urlencoded());

app.use(bodyParser.urlencoded({ extended: true }));

/**

  • API
    */ app.get(‘/list’, (req, res, next) => { // throw new Error(‘异常测试’); // next(new Error(‘异常测试’)); res.json({ list: [] }); });

app.post(‘/create’, (req, res, next) => { let { name, date, content, id } = req.body; res.json({ todo: {}, name, date, content, id, message: “创建成功” }); });

app.post(‘/edit’, (req, res, next) => { let { name, date, content, id } = req.body; res.json({ todo: {}, name, date, content, id, message: “创建成功” }); });

app.post(‘/action’, (req, res, next) => { let { status, id } = req.body; res.json({ status, id, message: “执行成功” }); });

app.post(‘/delete’, (req, res, next) => { let { id } = req.body; res.json({ id, message: “删除成功” });

});

/** 应用级中间件 1.所有错误Error:status=500 2.所有业务异常:status=1003 3.404错误 **/ app.use(‘*’, (req, res, next) => {//404服务器不认为是ERR所以此处使用通配符去处理404异常 res.json({ message: ‘请求资源不存在’ }); }); app.use((err, req, res, next) => { if (err) { res.statusCode = 500; res.json({ message: err.message }); } });

/**

  • 监听服务器的端口 **/ app.listen(8080, () => { console.log(‘服务器启动成功!’) }); ```
    ORM模型创建
  1. 创建数据库

20220324150229003.png

  1. 使用‘sequelize-cli’初始化项目的数据库配置信息npx sequelize init(建议新建一个文件夹,不建议在根目录下执行)
  2. 生成模型文件models、migrations.

    npx sequelize model:generate —name Business —attributes name:String,date:Date,content:String

  3. 持久化 模型对应的【数据库表】

npx sequelize db:migrate

API具体实现
  1. const express = require('express');
  2. const bodyParser = require('body-parser');
  3. const app = express();
  4. const models = require('../db/models');
  5. /********************************************
  6. * 应用级别中间件
  7. * 处理参数
  8. *********************************************/
  9. app.use(express.json());
  10. app.use(express.urlencoded());
  11. app.use(bodyParser.urlencoded({ extended: true }));
  12. /********************************************
  13. * API
  14. *********************************************/
  15. app.get('/list',async (req, res, next) => {
  16. // throw new Error('异常测试');
  17. // next(new Error('异常测试'));
  18. //offset代表从第几条记录“之后“开始查询,limit表明查询多少条结果
  19. try {
  20. let { status, page } = req.query;
  21. let limit = 10;//每页10条
  22. let offset = (page - 1) * limit;//开始从那个位置读取数据库
  23. let where = {};
  24. if (status != -1) {
  25. where.status = status;
  26. }
  27. let obj =await models.Business.findAndCountAll({
  28. where,
  29. offset,
  30. limit
  31. });
  32. res.json({
  33. obj
  34. });
  35. } catch (error) {
  36. next(error);
  37. }
  38. });
  39. app.post('/create', async (req, res, next) => {
  40. try {
  41. let { name, date, content } = req.body;
  42. /** 数据持久化到数据库 */
  43. let obj = await models.Business.create({
  44. name, date, content
  45. });
  46. res.json({
  47. obj,
  48. message: "创建成功"
  49. });
  50. } catch (error) {
  51. next(error);
  52. }
  53. });
  54. app.post('/edit', async (req, res, next) => {
  55. try {
  56. let { name, date, content, id } = req.body;
  57. /** 数据持久化到数据库 */
  58. let obj = await models.Business.findOne({
  59. where: {
  60. id
  61. }
  62. });
  63. if (obj) {//防止多人处理
  64. obj = await obj.update({
  65. name,
  66. date,
  67. content
  68. });
  69. res.json({
  70. obj,
  71. message: "修改成功"
  72. });
  73. }
  74. } catch (error) {
  75. next(error);
  76. }
  77. });
  78. app.post('/action', async (req, res, next) => {
  79. try {
  80. let { status, id } = req.body;
  81. let obj = await models.Business.findOne({
  82. where: {
  83. id
  84. }
  85. });
  86. if (obj && status != obj.status) {
  87. obj = obj.update({
  88. status
  89. });
  90. res.json({
  91. obj,
  92. message: "执行成功"
  93. });
  94. } else {
  95. next(new Error('状态与数据库一致,或者行明细不存在'));
  96. }
  97. } catch (error) {
  98. next(error);
  99. }
  100. });
  101. app.post('/delete', (req, res, next) => {
  102. let { id } = req.body;
  103. res.json({
  104. id,
  105. message: "删除成功"
  106. });
  107. });
  108. /**********************************************
  109. 应用级中间件
  110. 1.所有错误Error:status=500
  111. 2.所有业务异常:status=1003
  112. 3.404错误
  113. ************************************************/
  114. app.use('*', (req, res, next) => {//404服务器不认为是ERR所以此处使用通配符去处理404异常
  115. res.json({
  116. message: '请求资源不存在'
  117. });
  118. });
  119. app.use((err, req, res, next) => {
  120. if (err) {
  121. res.statusCode = 500;
  122. res.json({
  123. message: err.message
  124. });
  125. }
  126. });
  127. /**********************************************
  128. * 监听服务器的端口
  129. **********************************************/
  130. app.listen(8080, () => {
  131. console.log('服务器启动成功!')
  132. });

前端效果演示(略)

运维和发布

pm2是一个工具。
npm i pm2 -g
pm2 init //初始化项目启动或者是运维的脚本
pm2 start ecosystem.config.js //启动服务
pm2 list //查看启动的服务
pm2 restart id/name//重启指定的服务 例如: pm2 restart 0
pm2 log//查看服务器运行日志