☰
first assignment
2026/9/30 9:33:00 网站建设 项目流程

第一次作业:前后端分离计算器系统

课程信息说明

项目内容
832402108解皓喆
Assignment Requirements前后端分离计算器系统
Objectives of This Assignment理解前后端职责划分、HTTP API、表达式解析和数据库持久化
Deadline2026 年 10 月 7 日 23:59

目录

  • 课程信息说明
  • Git 仓库和代码规范链接
  • PSP 表
  • 成品展示
  • 设计与实现过程
  • 代码说明
  • 部署和测试
  • 个人总结

Git 仓库和代码规范链接

  • Frontend Repository: GitHub - jasonxie2026-fzu/832402108_calculator_frontend · GitHub
  • Backend Repository: jasonxie2026-fzu/calculator_backend
  • Frontend Code Standard: 832402108_calculator_frontend/codestyle.md at main · jasonxie2026-fzu/832402108_calculator_frontend · GitHub
  • Backend Code Standard: jasonxie2026-fzu/calculator_backend
  • Frontend Deployment Address: Calculator
  • Backend Deployment Address: https://calculator-backend-1-ua8m.onrender.com

PSP 表

阶段预计时间(分钟)实际时间(分钟)
需求分析3020
系统设计4050
前端开发90120
后端开发12060
表达式计算模块9060
数据库设计3090
前后端联调6025
测试6015
部署60120
博客写作90100

上表记录了各阶段的实际耗时,用于对比计划与实际的差异。

成品展示

1. 基础计算

前端部署地址为:Calculator

页面采用两栏布局,左侧为计算器,右侧为历史记录。计算结果由后端 API 返回,前端负责显示。

  • 图 1:部署后的初始计算器页面
  • 图 2:1 + 2返回3
  • 图 3:1 + 2 * 3返回7
  • 图 4:-5 + 8返回3
  • 图 5:0.5 + 1.25返回1.75

2. 复合表达式

测试1 + 2 * 3时,后端返回7,说明乘法优先于加法。

测试(1 + 2) * 3时,后端返回9,说明括号优先级生效。

3. 错误处理

输入2 / 0后,页面显示Division by zero,说明后端识别了除零错误并返回错误信息。

非法表达式也由后端校验,前端不会自行计算或伪造结果。

4. 历史记录

成功计算后,历史列表显示表达式、结果、时间和删除按钮。刷新页面后,历史记录仍从后端数据库读取。

历史记录功能展示如下:

  • 图 6:历史记录列表
  • 图 7:刷新后的历史记录
  • 图 8:删除指定记录后的历史列表

删除记录的操作可以使用下面两张截图进行前后对比:

图 9:历史记录列表中仍然包含待删除的计算记录,点击该记录右侧的“删除”按钮。

图 10:删除请求完成后,页面重新读取后端历史列表,目标记录不再显示。

5. 取余运算

项目还支持%取余运算。例如输入10 % 3后,后端返回结果1,并将本次计算保存到历史记录中。

图 11:输入10%3后返回结果1,说明后端正确处理了取余运算。

如果只输入%符号而不输入操作数,后端会返回错误提示,前端将错误信息显示在计算器下方。

设计与实现过程

需求分析

本次作业要求实现一个前后端分离的计算器。前端负责用户输入、按钮操作、结果展示和历史展示;后端负责输入校验、表达式解析、计算、异常处理以及数据库操作。

系统架构

浏览器前端 ├── 输入表达式 ├── 发送 HTTP JSON 请求 └── 展示后端返回结果和历史 │ ▼ Node.js 后端 ├── POST /api/calculate ├── GET /api/history ├── DELETE /api/history/:id ├── 表达式解析器 └── SQLite 数据库

前端和后端通过 JSON API 通信。前端不计算最终结果,只把表达式发送给后端。

数据库设计

数据库使用 SQLite,表名为calculation_history:

字段类型说明
idINTEGER主键
expressionTEXT用户提交的表达式
resultREAL后端计算结果
created_atTEXT计算时间

每次计算成功后,后端插入一条记录;页面刷新时重新请求数据库中的历史;删除操作通过后端 DELETE 接口完成。

代码说明

前端请求

前端调用:

fetch(`${API_BASE}/api/calculate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ expression }) });

前端只发送表达式,结果使用后端返回的result字段。

后端计算

后端使用递归下降解析器,把表达式拆分为数字、运算符和括号,再按照表达式、项、一元运算和基本值的层级解析。这样可以正确处理运算符优先级、括号、小数以及一元正负号。

项目没有使用eval、exec或其他任意代码执行方式处理用户输入。

错误处理

非法表达式、括号不匹配和除零会返回 HTTP 400 和错误消息,前端将消息显示在计算器下方。

部署和测试

后端公开 API 地址为:

https://calculator-backend-1-ua8m.onrender.com

前端部署地址为:

https://eight32402108-calculator-frontend3.onrender.com

前端在app.js中通过API_BASE连接后端:

const API_BASE = 'https://calculator-backend-1-ua8m.onrender.com';

部署后测试:

  1. 打开前端公开地址,确认页面显示API ready。
  2. 测试1 + 2 * 3和(1 + 2) * 3。
  3. 测试非法表达式和除零。
  4. 刷新页面,确认历史仍然存在。
  5. 删除一条历史,确认页面更新。
  6. 直接访问/api/history,确认后端接口可用。

后端历史接口地址:

https://calculator-backend-1-ua8m.onrender.com/api/history

个人总结

这次作业让我更清楚地理解了前端和后端的职责划分。开始时我把注意力放在计算器界面,后来发现真正的难点是让前端只负责交互,把表达式校验和计算放到后端,并且把历史记录持久化到数据库。

实现过程中,表达式解析需要处理运算符优先级、括号和一元负号,不能直接把用户输入当成程序执行。前后端联调时还需要检查请求格式、错误状态和跨域配置。

后续可以继续增加历史搜索、统计信息或科学计算功能。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询