173
社区成员
发帖
与我相关
我的任务
分享codestyle.md fileThe front-end and back-end are maintained in separate repositories.
| PSP Stage | Estimated Time (Minutes) | Actual Time (Estimated, Minutes) |
|---|---|---|
| Read assignment requirements and analyze needs | 40 | 30 |
| Technical research and environment setup | 60 | 50 |
| System architecture, API, and database design | 50 | 40 |
| Back-end expression parsing and calculation | 90 | 75 |
| Back-end history logic and database operations | 60 | 45 |
| Front-end page and interaction design | 120 | 120 |
| Front-end and back-end integration and demo operations | 60 | 65 |
| Testing and bug fixing | 60 | 55 |
| Deployment and validation | 0 | 0 |
| Blog writing and screenshot preparation | 60 | 75 |
| Total | 600 | 555 (~9 hours 15 minutes) |
This assignment required building a front-end and back-end separated calculator system. The front end is responsible for expression input, button interactions, result display, and history presentation. The back end is responsible for validating input, parsing expressions, performing calculations, handling exceptions, and persisting calculation history. Front-end and back-end communicate through HTTP JSON APIs.
The design follows a clear separation of responsibilities:
The implemented system supports the following features:
The following 12 images are the actual runtime screenshots from this project and are stored in the blog-assets/ directory. They are displayed below in the sequence of the real demo.

This screenshot shows the main calculator UI, expression input area, number and operator buttons, the server-calculation indicator, and the empty history panel at startup.











The screenshots confirm the core workflow of this project: expression input, backend calculation, result display, history persistence, and history deletion. In particular, the deletion step shows a successful confirmation message (Calculation deleted from saved history.) and the count drops from 7 to 6.
| ID | Input/Action | Result in Screenshot | Verification |
|---|---|---|---|
| D01 | 12+8 | 20 | Addition |
| D02 | 17-3 | 14 | Subtraction |
| D03 | 12*9 | 108 | Multiplication |
| D04 | -9+3 | -6 | Unary negative |
| D05 | 6+6*9 | 60 | Operator precedence |
| D06 | (9-6)*3 | 9 | Parentheses |
| D07 | 10/4 | 2.5 | Division with decimal |
| D08 | 1/0 | Division by zero is not allowed. | Division-by-zero error; history count unchanged |
| D09 | 5* | Expected a number. | Invalid expression; history count unchanged |
| D10 | Delete one history record | Success prompt; count 7 -> 6 | History deletion refreshes the list |
Additional backend parsing tests cover expressions such as 1 + 2 * 3, (1 + 2) * 3, -5 + 8, 3 * -2, .25 + .25, invalid syntaxes, mismatched parentheses, and division by zero. During blog updates, the actual validation commands were run locally: the back-end mvn test passed successfully with 3 tests passing and 0 failing, and the front-end npm.cmd run build also succeeded.
Vue 3 Front-end
├─ Accepts expression input and button interactions
├─ Sends requests to the API and displays results
└─ Queries and deletes history records
│ HTTP / JSON (proxied through Vite during development)
▼
Spring Boot Back-end
├─ Validates input and returns error messages
├─ Parses and evaluates arithmetic expressions safely
└─ Saves, retrieves, and deletes history entries
│ Spring Data JPA
▼
H2 File Database
└─ calculation_history
The main front-end page is in src/App.vue, and the API logic is centralized in src/api.js.
calculateExpression(expression) sends a POST /api/calculate request with a payload containing only the expression.fetchHistory() calls GET /api/history to retrieve saved records.deleteHistory(id) calls DELETE /api/history/{id} to remove the selected record.On page load, the application fetches historical records. After a successful calculation, it reloads the history list. After a successful deletion, it reloads the list again so the removed record is no longer shown in the UI. The API layer checks HTTP status and extracts backend error messages for display.
The back-end performs the actual evaluation logic and persistence. The main procedures include:
CalculationHistory tableThe parser uses a structured evaluation approach rather than directly executing the user input as code. This is a key security and correctness measure.
The back-end persists calculation history in an H2 database. The stored fields typically include:
This ensures that every successful calculation becomes a durable record and can be viewed or deleted later from the front-end.
In src/api.js, the calculation request sends a JSON body like { expression }. The front-end only displays the server’s returned response.result in src/App.vue; it does not perform the final evaluation locally.
CalculatorService.calculate() normalizes the input expression, calls ExpressionEvaluator.evaluate(), formats the result, and saves the corresponding record to the database only after a successful evaluation.
CalculatorService.getHistory() queries the database using JPA and maps the results into a response DTO. deleteHistory(id) checks whether the record exists and removes it; if it does not exist, the API returns a 404 error.
The evaluator parses:
During implementation, BigDecimal is used for numeric precision. Division uses 12 decimal places with HALF_UP rounding, and the service layer removes unnecessary trailing zeros from the final result. The expression length is limited to 256 characters. Invalid inputs, division by zero, missing numeric values, and mismatched parentheses all produce explicit error messages rather than crashing the application.
Back-end terminal:
cd "C:\Users\Lenovo\Desktop\calculator-backend"
mvn spring-boot:run
Front-end terminal:
cd "C:\Users\Lenovo\Desktop\calculator-frontend"
npm install
npm run dev
Open the browser at http://localhost:5173 to use the calculator. The backend runs at http://localhost:8080.
During the blog writing phase, the following checks were run in the corresponding project directories:
mvn test: passed successfully; 3 tests passed and 0 failed.npm.cmd run build: completed successfully.These checks confirm the project builds and the expression evaluator behaves correctly for the tested arithmetic and validation scenarios.
The project was demonstrated locally and has not been published to a public deployment endpoint.
http://localhost:5173http://localhost:8080This assignment helped me understand that a front-end and back-end separated project is not simply a matter of placing code in different folders. More importantly, responsibilities must be clearly separated: the front-end handles user input and display, while the back-end performs the actual arithmetic, validation, and database persistence.
During implementation, I realized that user-entered expressions cannot be executed directly. They must be parsed according to operator precedence, then handled carefully for parentheses, unary signs, and invalid input cases. Through the live demo, I verified addition, subtraction, multiplication, division, parentheses, precedence, negative values, division by zero, and invalid-input warnings. I also observed the history list increase as calculations are added and decrease after deletion.
This project deepened my understanding of full-stack architecture, API design, input validation, and robust front-back-end collaboration. It also showed me the importance of testing real workflows rather than only coding for the “happy path.”
The current project covers the core arithmetic operations, history retrieval, and deletion by ID. Future extensions could include:
These improvements would make the project more scalable and better suited for real-world use.