前后端分离

这个作业属于哪个课程2301-计算机学院-软件工程
这个作业要求在哪里第二次作业-前后端交互计算器
这个作业的目标继续实现更完善的计算器功能,体现前后端分离
其他参考文献SpringBoot、Axios

Gitcode项目地址

作业代码

PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划2025
• Estimate• 估计这个任务需要多少时间2025
Development开发5005850
• Analysis• 需求分析 (包括学习新技术)140130
• Design Spec• 生成设计文档3025
• Design Review• 设计复审3040
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)1530
• Design• 具体设计2050
• Coding• 具体编码210260
• Code Review• 代码复审1520
• Test• 测试(自我测试,修改代码,提交修改)4030
Reporting报告170185
• Test Repor• 测试报告8085
• Size Measurement• 计算工作量4030
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划5070
合计660785

成品展示

科学计算器

功能一、基础运算

计算
请添加图片描述

结果存储到数据库

在这里插入图片描述

/功能二、清零回退

清零
在这里插入图片描述

回退

在这里插入图片描述

功能三、错误提示

在这里插入图片描述

功能四、读取历史记录

点击ans显示历史记录,点击x取消显示
在这里插入图片描述

功能五、科学计算

三角函数计算
在这里插入图片描述

log计算、阶乘计算

在这里插入图片描述

利率计算器

功能一、计算利息

计算存款利息

在这里插入图片描述

计算贷款利息

在这里插入图片描述

功能二、前端修改利息

在这里插入图片描述

功能结构图

在这里插入图片描述

原型设计

设计实现过程

  • 设计数据库表结果,创建deposit_interest_rate、loan_interest_rate、historical_records三个表,分别用于存储存款利率、贷款利率和用户计算历史记录。
  • 前端实现,使用html+css+js实现计算器页面,添加一个页面切换的按钮,用户切换到不同的计算器。使用axios发送请求到后端的API接口,处理后端返回的响应,根据返回结果显示成功或失败。
  • 后端实现,使用springboot和mybatis来实现网络传输和数据库的存取。

代码说明

前端部分代码

JavaScript-利率计算器

calculateInterest()函数:

  • 当调用该函数时,获取页面上输入的金额和时间。
  • shu组成一个JavaScript对象data,其中包含rateType、amount和duration属性,用于表示利率类型、金额和期限的信息。
  • 使用axios库发送一个POST请求到"http://localhost:8080/t/calculateInterest"的URL,将data作为请求的主体数据发送给后端。
    接收到后端的响应后,将响应数据中的利息值设置到页面id为result的input标签中

updateRate()函数

  • 调用该函数时,它会获取页面上指定的利率类型、和新利率的输入值
  • 将rateType、option和rate值组成一个对象data
  • 使用axios库发送一个POST请求到"http://localhost:8080/t/Rate"的URL,将data作为请求的主体数据发送给后端。
  • 成功接收到后端的响应后,它会显示一个成功的弹窗提示"修改成功".
  
  function calculateInterest() {
    var rateType = document.getElementById("rate_type").value;
    var amount = document.getElementById("amount").value;
    var duration = document.getElementById("duration").value;
    
    var data = {
        rateType: rateType,
        amount: amount,
        duration: duration
    }; 
    // alert("click")
    axios.post("http://localhost:8080/t/calculateInterest", data,{
        headers:{
            "Content-Type":"application/json",
        }
    })
        .then(function(response) {
            console.log(response.data);
            //var result =response.data.interest;
            document.getElementById("result").value = response.data;
            
        })
        .catch(function(error) {
            console.error(error);
        });
}
function updateRate() {
    var rateType = document.getElementById("rate_type").value;
    var selectedOption = document.getElementById("type").value;
    var newRate = document.getElementById("newRate").value;
    
    var data = {
        rateType: rateType,
        option: selectedOption,
        rate: newRate
    };
    console.log(data)
    axios.post("http://localhost:8080/t/Rate", data, {
        headers: {
            "Content-Type": "application/json"
        }
    })
    .then(function (response) {
        //console.log(1);
        alert("修改成功");
    })
    .catch(function (error) {
        console.error(error);
    });
}

JavaScript-科学计算器

  • 对于每个按钮,添加了’click’事件监听器,点击按钮时,根据按钮的值执行相应的操作。
  • 按下ans,则获取id为’ans’的按钮,显示历史计算列表(id为’history’),使用fetch函数发送GET请求到"http://localhost:8080/t/recentCalculations"的URL,获取最近的计算历史数据。
    将计算历史数据显示在id为’calculation-list’的列表元素中,页面的x时,隐藏历史计算列表。
  • 按下‘=’后,获取当前的表达式(operation-screen的文本内容),计算出结果,并将表达式与结果发送到后端,存在数据库中。
 window.onload = function () {
  const radBtn = document.getElementById('Rad');
  const degBtn = document.getElementById('Deg');

  radBtn.addEventListener('click', function () {
    radBtn.classList.add('active');
    degBtn.classList.remove('active');
  });

  degBtn.addEventListener('click', function () {
    degBtn.classList.add('active');
    radBtn.classList.remove('active');
  });

  const operationScreen = document.getElementById('operation-screen');
  const resultScreen = document.getElementById('result-screen');
  document.querySelectorAll
    ('.number, .operator, .clear, .reset, .calculate').forEach(button => {
      button.addEventListener('click', () => {
        const buttonValue = button.value;
        if (buttonValue === 'C') {
          operationScreen.textContent = '';
          resultScreen.textContent = '';
        } else if (buttonValue === '=') {
          const currentExpression = operationScreen.textContent;
          const Expression = operationScreen.textContent;
          operationScreen.textContent = currentExpression + buttonValue;
          const result = calculate(Expression);
          resultScreen.textContent = result;
          var data = {
            expression: currentExpression,
            result: result
          };
          console.log(data);
          axios.post("http://localhost:8080/t/calculate", data, {
            headers: {
              "Content-Type": "application/json",
            }
          })
            .then(function (response) {
              console.log(1);
            })
            .catch(function (error) {
              console.error(error);
            });
        }
        else if (buttonValue === 'ans') {        
            const ansButton = document.getElementById('ans');
            const calculationList = document.getElementById('history');        
            ansButton.addEventListener('click', function() {
              calculationList.style.display = 'block';
            });           
            fetch("http://localhost:8080/t/recentCalculations")
              .then(response => response.json())
              .then(data => {
                  const calculationList = document.getElementById('calculation-list');
                  calculationList.innerHTML = '';
                  data.forEach(calculation => {
                  const calculationItem = document.createElement('li');
                  calculationItem.textContent =calculation.expression +"="+ calculation.result;
                  calculationList.appendChild(calculationItem);
                  });
                });
                const delans = document.getElementById('del');
                delans.addEventListener('click',function(){
                  calculationList.style.display = 'none';
                })
        }
        else if (buttonValue === '⌫') {
          const currentExpression = operationScreen.textContent;
          operationScreen.textContent = currentExpression.slice(0, -1);
        } else {
          const currentExpression = operationScreen.textContent;
          operationScreen.textContent = currentExpression + buttonValue;
        }
      })
    })
}

后端部分代码

在这里插入图片描述

利率更新

  • 使用Spring Boot框架编写的Java Controller类。
  • @CrossOrigin(origins = “*”),用于启用跨域资源共享(CORS)支持。
  • public void UpdateRate(@RequestBody RateRequest req):用于处理接收到的HTTP POST请求,接受一个RateRequest对象作为请求的主体数据,使用@RequestBody注解将请求主体映射到该对象。
//RateController.java
package com.example.demo3.controller;
import com.example.demo3.domain.RateRequest;
import com.example.demo3.service.RateService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/t")
public class RateController {

    @Autowired
    private RateService rateService;

    @PostMapping("/Rate")

    public void UpdateRate(@RequestBody RateRequest req ) {
        String rateType = req.getRateType();
        String option = req.getOption();
        //String rateType = "deposit";
        //String option = "current";
        double rate = req.getRate();
        System.out.println(req.toString());
        String getback = rateService.UpdateRate(rateType,option,rate);
        System.out.println(getback);
        return;
    }
}
  • RateRequest 用于表示利率请求对象
//RateRequest.java
package com.example.demo3.domain;

public class RateRequest {
    private String rateType;
    private String option;
    private double rate;

    public String getRateType() {
        return rateType;
    }

    public void setRateType(String rateType) {
        this.rateType = rateType;
    }

    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    public double getRate() {
        return rate;
    }

    public void setRate(double rate) {
        this.rate = rate;
    }

    @Override
    public String toString() {
        return "RateRequest{" +
                "rateType='" + rateType + '\'' +
                ", option='" + option + '\'' +
                ", rate=" + rate +
                '}';
    }
}
  • 使用MyBatis框架编写的数据访问对象接口
  • void UpdateDeposit(@Param(“rowType”) String rowType, @Param(“newRate”) double newRate):用于更新存款利率,rowType参数表示修改的利率类型,newRate参数表示新的利率
  • void UpdateLoan(@Param(“rowType”) String rowType, @Param(“newRate”) double newRate):用于更新贷款利率

//RateMapper.java
package com.example.demo3.mapper;


import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

@Mapper
public interface RateMapper {
    void UpdateDeposit(@Param("rowType") String rowType,@Param("newRate") double newRate);
    void UpdateLoan(@Param("rowType") String rowType,@Param("newRate") double newRate);
}
// //RateMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.demo3.mapper.RateMapper">
    <update id="UpdateDeposit">
        UPDATE Deposit_interest_rate
        SET  rate = #{newRate}
        WHERE DepositTime = #{rowType}
    </update>

    <update id="UpdateLoan">
        UPDATE Loan_interest_rate
        SET rate = #{newRate}
        WHERE  LoanTime = #{rowType}
    </update>
</mapper>
  • 使用Springboot框架编写的服务类,用于处理利率修改的操作。
  • 根据rateType的值判断是更新存款利率还是贷款利率。如果是存款利率,根据selectedOption的值确定存款类型,并将新的利率传递给rateMapper.UpdateDeposit()方法进行更新。
    如果是贷款利率,根据selectedOption的值确定贷款类型,并将新的利率传递给rateMapper.UpdateLoan()方法进行更新。

// RateService.java
package com.example.demo3.service;

import com.example.demo3.mapper.RateMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class RateService {
    @Autowired
    private RateMapper rateMapper;
    public String UpdateRate(String rateType,String selectedOption,double newRate){
        String rowType="";
        if(rateType.equals("deposit")) {
            System.out.println(selectedOption);
            if (selectedOption.equals("current"))
                rowType = "活期";
            else if (selectedOption.equals("3months"))
                rowType = "三个月定期";
            else if (selectedOption.equals("6months"))
                rowType = "半年定期";
            else if (selectedOption.equals("1year"))
                rowType = "一年定期";
            else if (selectedOption.equals("2years"))
                rowType = "两年定期";
            else if (selectedOption.equals("3years"))
                rowType = "三年定期";
            else if(selectedOption.equals("5years"))
                rowType = "五年定期";
            System.out.println(rowType);
            System.out.println(newRate);
            rateMapper.UpdateDeposit(rowType,newRate);
        }
        else if(rateType.equals("loan")){
            if(selectedOption.equals("loan6months"))
                rowType="六个月";
            else if(selectedOption.equals("loan1year"))
                rowType="一年";
            else if(selectedOption.equals("loan1to3years"))
                rowType="一年至三年";
            else if(selectedOption.equals("loan3to5years"))
                rowType="三年至五年";
            else if(selectedOption.equals("loan5years"))
                rowType="五年";
            rateMapper.UpdateLoan(rowType,newRate);
        }
        return "ok";
    }

}

心路历程和收获

通过这次作业,我实现了前后端分离的计算器,我深刻体会到了前后端分离开发的优势,熟悉了Spring Boot和MyBatis的使用,提升了接口设计、错误处理和异常处理的能力。这是我第一次尝试前后端开发,遇到了不少问题,通过查阅文档、参考示例代码、与同学讨论等途径,不断学习和改进自己的技术能力。同时,及时反思和总结经验,以便在未来的项目中能够更好地应用所学。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值