Front-Backend separation calculator programming on Idea and Vscode
****This project is based on Java and developed using IDEA and VScode***
The Link Your Class | https://bbs.csdn.net/forums/ssynkqtd-04 |
---|---|
Asignment Requirement | https://bbs.csdn.net/topics/617378696 |
Link to the finished project | https://github.com/473244238/832102107_liyujie_calculator2 |
The Aim of This Assignment | Front-Back-end calculator |
MU and FZU | 832102107 21127077 |
一.PSP Table
Personal Software Process Stages | Estimated Time(minutes) | Actual Time(minutes) |
---|---|---|
Planning | 30 | 30 |
• Estimate | 30 | 40 |
Development | 600 | 670 |
• Analysis | 50 | 50 |
• Design Spec | 20 | 30 |
• Design Review | 20 | 40 |
• Coding Standard | 50 | 70 |
• Design | 130 | 150 |
• Coding | 60 | 120 |
• Code Review | 190 | 200 |
• Test | 180 | 200 |
Reporting | 160 | 300 |
• Test Repor | 30 | 40 |
• Size Measurement | 30 | 40 |
• Postmortem & Process Improvement Plan | 120 | 200 |
Sum | 1580 | 2180 |
二.Introdrection
The back end of the project is based on Java and developed using IDEA.
Its front-end is based on HTML,CSS,JS and uses Vscode for page visualization and function implementation
The calculator can realize addition, subtraction, multiplication, division and power operations, and can also realize the operation of trigonometric functions.
Through the connection of IDEA and mysql database, we can use the front-end calculator to calculate the results, use the back-end database to save the results and formulas, you can use sql query statements to query your history.
Link to the finished project code:Gitup
三. Design and Implementation Process
1.Learning
(1).Use native JS to achieve front-end separation
In native js we use the XMLHttpRequest object to send ajax requests
The main steps are:
1.create the XMLHTTPRequest object
2.Use the open method to set the interaction with the server
3.Set the data to be sent and start the interaction with the server
4.Register events
Get :
//Step1: create asynchronous obejects
var ajax=new XMLHttpRequest();
//Step2: Set the url parameters of the request and parameter2 is the url of the request. You can pass the parameter starName to the server dynamically with parameters
ajax.open('get','getStar.php? starName='+name);
//Step3:Send the request
ajax.send();
//Step4:Register event
ajax.onreadystatechange=function(){
if(ajax.readystate==4&&ajax.status==200){
console.log(ajax.responseText);}
}
Post
var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.open('post', '02.post.php' );
xhr.send('name=fox&age=18');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
(2)Mysql
I am using the mybatisplus framework to write mysql
The benefits and characteristics of MyBatis Plus:
Simplify CRUD operations: MyBatis Plus provides a powerful code generator that can automatically generate common add, delete, modify, and query operations, saving time writing a large amount of SQL and Mapper interface code.
Powerful Conditional Constructor: MyBatis Plus provides a Conditional Constructor that supports chain calls, making it easy to build complex query conditions without the need for handwritten complex SQL statements.
Paging support: MyBatis Plus provides a built-in pagination plugin, making pagination queries very simple. Developers only need to specify page numbers and the number of records displayed per page.
Logical deletion: MyBatis Plus supports logical deletion and can configure logical deletion fields through annotations, making it easy to manage the status of deleted data.
Optimistic lock support: MyBatis Plus supports optimistic locks, allowing developers to easily implement data version control.
Code Generator: MyBatis Plus provides a code generator that can generate corresponding entity classes, Mapper interfaces, and XML mapping files based on database tables.
Automatic filling: MyBatis Plus supports automatic filling function, which can automatically fill specified fields such as creation time and update time when inserting and updating records
四.code layout
html:
<!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">
<link rel="stylesheet" href="NewCalcu.css"> <!--这个连接CSS文件-->
<title>NewCalcu</title>
</head>
<body>
<div class="container">
<div class="calculator dark">
<div class="theme-toggler active">
<i class="toggler-icon"></i>
</div>
<div class="display-screen">
<div id="display"></div>
</div>
<div>
<div class="buttons"><!--包含操作按钮的容器,通常用于组织和布局按钮元素。-->
<table> <!--这是一个HTML表格元素,用于创建一个表格布局,其中的按钮将被放置在表格的不同单元格中。表格通常用于创建规则的布局。-->
<tr>
<td><button class="btn-function" id="search">Search</button></td>
</tr>
<tr>
<td><button class="btn-operator" id="clear">C</button></td>
<td><button class="btn-operator" id="/">÷</button></td>
<td><button class="btn-operator" id="*">×</button></td>
<td><button class="btn-operator" id="backspace"><</button></td>
</tr>
<tr>
<td><button class="btn-number" id="7">7</button></td>
<td><button class="btn-number" id="8">8</button></td>
<td><button class="btn-number" id="9">9</button></td>
<td><button class="btn-operator" id="-">-</button></td>
</tr>
<tr>
<td><button class="btn-number" id="4">4</button></td>
<td><button class="btn-number" id="5">5</button></td>
<td><button class="btn-number" id="6">6</button></td>
<td><button class="btn-operator" id="+">+</button></td>
</tr>
<tr>
<td><button class="btn-number" id="1">1</button></td>
<td><button class="btn-number" id="2">2</button></td>
<td><button class="btn-number" id="3">3</button></td>
<td><button class="btn-operator"id=".">.</button></td>
</tr>
<tr>
<td><button class="btn-operator" id="(">(</button></td>
<td><button class="btn-number" id="0">0</button></td>
<td><button class="btn-operator" id=")">)</button></td>
<td rowspan="3"><button class="btn-equal" id="equal">=</button></td>
</tr>
<tr>
<td><button class="btn-high" id="sin">sin</button></td>
<td><button class="btn-high" id="cos">cos</button></td>
<td><button class="btn-high" id="tan">tan</button></td>
</tr>
<tr>
<td><button class="btn-operator" id="PI">PI</button></td>
<td><button class="btn-operator" id="%">%</button></td>
<td><button class="btn-operator" id="sqrt">sqrt</button></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<script src="Newscript.js"></script><!--这个连接JS文件-->
</body>
</html>
css:
*{
padding: 0;
margin:0;
box-sizing:border-box;
outline:0;
transition:all 0.5s ease;
}
body{
font-family: sans-serif;
}
a{
text-decoration: none;
color:chartreuse
}
body{
background-image: linear-gradient(to bottom right,rgb(161, 51, 139),rgba(53, 108, 210, 0.521));
}
.container{
height: 100vh;
width:100vw;
display: grid;
place-items: center;
}
.calculator{
position: relative;
height:auto;
width:auto;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 30px #000;
}
.theme-toggler{
position: absolute;
top:30px;
right: 30px;
color:#fff;
cursor:pointer;
z-index: 1;
}
.theme-toggler.active{
color:#333
}
.theme-toggler.active::before{
background-color: #fff;
}
.theme-toggler::before{
content: '';
height: 15px;
width: 15px;
position: absolute;
top:50%;
transform: translate(-50%,-50%);
border-radius: 50%;
background-color: #333;
z-index:-1;
}
#display{
margin:0 10px;
height:150px;
width:auto;
max-width:270px;
display: flex;
align-items: flex-end;
justify-content: flex-end;
font-size: 30px;
margin-bottom: 20px;
overflow-x:scroll;
}
#display::-webkit-scrollbar{
display: block;
height: 3px;
}
button{
height:60px;
width: 60px;
border:0;
border-radius: 30px;
margin:5px;
font-size: 20px;
cursor: pointer;
transition: all 200ms ease;
}
button:hover{
transform: scale(1.1); /* 当用户将鼠标悬停在按钮上时,会触发一个悬停效果,将按钮放大到原来的1.15倍*/
}
button#equal{
height: 195px; /*按钮的高度设置为195像素,使该按钮相对于其他按钮更大。*/
}
/*light theme*/
.calculator{
background-color: #c3dc1e;
}
.calculator #display{
color:#212425
}
.calculator button#search{
background-color: #4431e8;
color: #b61e1e;
}
.calculator button#clear{
background-color: #c9325c;
color: blueviolet;
}
.calculator button.btn-operator{
background-color: rgb(89, 42, 165);
color: azure;
}
.calculator button.btn-number{
background-color: #c3eaff;
color:black
}
.calculator button.btn-high{
background-color: blanchedalmond;
color:black;
}
.calculator button.btn-equal{
background-color: #adf9e7;
color: black
}
.calculator.dark{
background-color: #071115;
}
.calculator.dark #display{
color:#fff
}
.calculator.dark button#search{
background-color: #223323;
color: #000;
}
.calculator.dark button#clear{
background-color: #2d191e;
color:#bd3740;
}
.calculator.dark button.btn-number{
background-color: #1b2f38;
color:#bd3740
}
.calculator.dark button.btn-operator{
background-color: #2e1f39;
color:#aa00a4;
}
.calculator.dark button.btn-high{
background-color: #2d191e;
color: #4431e8;
}
.calculator.dark button.btn-equal{
background-color: #223323;
color: #fff;
}
js:
const display=document.querySelector('#display');
const buttons=document.querySelectorAll('button')
buttons.forEach((item)=>{
item.onclick=() =>{
if(item.id=='clear' ){
display.innerText="";
}else if(item.id=='backspace'){
let string=display.innerText.toString();
display.innerText=string.substr(0,string.length-1);
}else if(display.innerText!=''&&item.id=='equal'){
const expression = display.innerText;
const modifiedExpression = expression.replace(/%/g, '%');
display.innerText=eval(modifiedExpression);
ajax(expression,eval(modifiedExpression));
}else if(display.innerText==""&&item.id=='equal'){
display.innerText='Empty!';
setTimeout(()=>(display.innerText=''),2000);
}else if(item.id=='sin'){
const expression = display.innerText;
try {
const result = eval(expression);
const sinValue = Math.sin(result);
display.innerText = `sin(${expression}) = ${sinValue.toFixed(2)}`;
ajax(display.innerText,sinValue.toFixed(2))
} catch (error) {
display.innerText = 'Error';
}
setTimeout(()=>(display.innerText=''),3000);
}else if(item.id=='cos'){
const expression=display.innerText;
try {
const result = eval(expression);
const cosValue = Math.cos(result);
display.innerText = `cos(${expression}) = ${cosValue.toFixed(2)}`;
ajax(display.innerText,cosValue.toFixed(2));
} catch (error) {
display.innerText = 'Error';
}
setTimeout(()=>(display.innerText=''),3000);
}else if(item.id=='tan'){
const expression=display.innerText;
try {
const result = eval(expression);
const tanValue = Math.tan(result);
display.innerText = `tan(${expression}) = ${tanValue.toFixed(2)}`;
ajax(display.innerText,tanValue.toFixed(2))
} catch (error) {
display.innerText = 'Error';
}
setTimeout(()=>(display.innerText=''),3000);
}else if(item.id=='sqrt'){
const expression=display.innerText;
const result=eval(expression);
const sq=Math.sqrt(result);
display.innerText=sq.toFixed(2);
}else if(item.id=="PI"){
display.innerText+=Math.PI;
}else if(item.id=="search"){
let xhr;
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else{
xhr=new ActiveXObject("Microsoft.XMLHTTP")
}
xhr.timeout=4000;
xhr.ontimeout=function(){
console.log('抱歉,超时了');
}
xhr.open('POST',"http://localhost:8080/info")
xhr.onreadystatechange=function(){
if(xhr.status==200){
console.log(xhr.responseText);
display.innerText=search;
}
}
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send();
setTimeout(()=>(display.innerText=''),3000);
}
else{
display.innerText+=item.id;
}
}
})
const themeToggleBtn=document.querySelector('.theme-toggler');
const calculator=document.querySelector('.calculator');
const toggleIcon=document.querySelector(".toggler-icon");
let isDark=true;
themeToggleBtn.onclick=()=>{
calculator.classList.toggle('dark');
themeToggleBtn.classList.toggle('active');
isDark=!isDark;
}
function ajax(data1,data2){
let xhr;
if(window.XMLHttpRequest){
xhr=new XMLHttpRequest();
}else{
xhr=new ActiveXObject("Microsoft.XMLHTTP")
}
xhr.timeout=4000;
xhr.ontimeout=function(){
console.log('抱歉,超时了');
}
xhr.open('POST',"http://localhost:8080/give")
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responsText);
}
}
let formual = encodeURIComponent(data1); // 对数据进行编码
let answer = encodeURIComponent(data2); // 对数据进行编码
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('formual='+formual+'&answer='+answer);
}
package org.example.Controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.example.Service.CalculatorService;
import org.example.entity.Calculator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
@Controller
@Slf4j
@ResponseBody
public class controller {
@Autowired
private CalculatorService calculatorService;
long value=0;
@RequestMapping ("/give")
public void info(@RequestParam("formual") String formual, @RequestParam("answer") String answer){
log.info("公式为:{}",formual);
log.info("答案为{}",answer);
Calculator calculator=new Calculator();
calculator.setFormula(formual);
calculator.setAnswer(answer);
log.info(calculator.toString());
calculatorService.save(calculator);
log.info(calculator.toString());
value=calculator.getId();
}
@RequestMapping("/info")
@Transactional
public String Search() throws JsonProcessingException {
if(value==0){
Calculator calculator=calculatorService.getById(1);
String msg=calculator.getFormula();
ObjectMapper objectMapper=new ObjectMapper();
String str=objectMapper.writeValueAsString(msg);
return str;
}else{
Calculator calculator=calculatorService.getById(value);
log.info(calculator.toString());
String msg=calculator.getFormula();
ObjectMapper objectMapper=new ObjectMapper();
String str=objectMapper.writeValueAsString(msg);
return str;
}
}
}
Perform
1.click the button
the front display
the idea display
the database display:
20231022_145205
五.code explaniation
(1)Frontend data collection: Users interact with the front-end, input or select data, such as form fields, button clicks, page events, etc. The front-end uses HTML forms or JavaScript to obtain these user data. After the user completes the form or triggers the corresponding event, the data needs to be submitted to the backend for processing.
(2)Frontend data verification: Before submitting data, it is usually necessary to perform front-end verification on the data input by users to ensure the validity and legality of the data. This can be achieved through JavaScript or front-end frameworks, such as checking required fields, data formats, length restrictions, ranges, etc. Verification helps to reduce invalid data transmission to the backend and improve data quality.
(3)Data transmission to the backend: Once the data passes the front-end validation, it will be transmitted to the backend application. This can be achieved through HTTP requests, typically POST requests. The front-end uses AJAX, Fetch API, or form submission methods to send data to a specific interface (usually a URL) on the back-end.
Backend receiving data: The backend application receives HTTP requests from the front-end. It can be a web server (such as Spring Boot, Django, Express.js, etc.) or a web framework (such as Spring MVC, Flask, Node. js, etc.).
(4)Backend data processing: After receiving a request, the backend application will parse the data in the request and extract it for processing. Data processing can include verifying data, constructing SQL query statements, executing database operations, and applying business logic.
(5)MySQL database operation: Backend applications use SQL queries or update statements to interact with MySQL databases. This includes inserting new records, updating existing records, deleting records, or querying data. SQL queries typically use database connection pools to maintain connections to improve performance and resource management.
(6)Transaction management: If multiple database operations are involved, it is usually necessary to implement transaction management to ensure the atomicity of the operations. Transactions can ensure that multiple operations either succeed or fail, thereby maintaining data consistency.
Database response: The MySQL database executes the request and returns the corresponding result. If it is an insert, update, or delete operation, typically returns the number of affected records. If it is a query operation, the required data will be returned.
Backend response: The backend application processes the results of database operations and generates corresponding HTTP responses. This may include returning success or failure messages to the forward end, or returning query results.
Front end response: The front end receives the response from the back end and updates the user interface based on the response. Users may see success messages, error messages, or updated data.
六.Personal Journey and Learnings
Communication protocols and data transmission: Understand different communication protocols, such as HTTP, WebSocket, and how to transmit data. Understand data formats such as JSON, XML, etc. for effective data transmission between the front and back ends.
Frontend data verification: Frontend verification is very important to prevent invalid or malicious data from entering the backend system. The front-end can perform data validation and formatting to ensure data quality.
Backend security: Understand how to protect backend systems from potential attacks, including SQL injection, cross site scripting (XSS), cross site request forgery (CSRF), etc. Use security frameworks and best practices to improve system security.
Database design: Familiar with database design principles, including table structure, indexes, associations, etc., in order to effectively store and retrieve data. Optimize database queries to improve performance.
七.How to further optimize front - and back-end interactions
Front and rear end separation (independent development of front and rear ends): Adopting a front and rear end separation architecture, the front and rear teams can develop independently and communicate through APIs. This improves development efficiency and flexibility.
Automated testing: Implement front-end and back-end automated testing, including unit testing, integration testing, and end-to-end testing, to ensure the quality of the application.
Document writing: Write clear documents, including API documents, data model documents, and system documents, so that team members can understand the working principles of the system.
Performance optimization: Regularly conduct performance testing and optimization to ensure that the application can still provide good performance under high loads.