前后端分离的多功能计算器 vue+go实现

102101328林驰易 2023-10-21 21:22:50

前后端分离的多功能计算器 vue+go实现

————102101328林驰易

目录

  • 前后端分离的多功能计算器 vue+go实现
  • 作业基本信息
  • Gitcode项目地址
  • 成品及功能演示
  • 基础功能实现
  • 标准计算器
  • 加减乘除取余
  • 清零回退
  • 错误提示
  • 历史记录
  • 附加功能实现
  • 科学计算器
  • 加减乘除取余括号
  • 附加功能:三角函数、科学计数法、对数
  • 根号
  • 历史记录
  • 清零回退
  • 利率计算器
  • 利率计算
  • 后端修改利率表
  • 不同计算器间切换
  • PSP表格
  • 设计实现过程
  • 前端
  • 后端
  • 关键代码说明
  • 前端
  • 后端
  • 心路历程和收获

作业基本信息

这个作业属于哪个课程https://bbs.csdn.net/forums/ssynkqtd-05
这个作业要求在哪里https://bbs.csdn.net/topics/617377308
这个作业的目标完成一个前后端交互的科学计算器
其他参考文献https://uniapp.dcloud.net.cn/component/

Gitcode项目地址

GitHub项目地址--前端
GitHub项目地址--后端

成品及功能演示

基础功能实现

标准计算器

加减乘除取余

img

清零回退

img

错误提示

img

历史记录

img

附加功能实现

科学计算器

加减乘除取余括号

img

附加功能:三角函数、科学计数法、对数

img

根号

img

历史记录

img

清零回退

img

利率计算器

利率计算

img

后端修改利率表

img

修改前:
存款利率:

img

借款利息:

img

修改后:
存款利率:

img

借款利息:

img

不同计算器间切换

img

PSP表格

PSPPersonal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning计划1510
• Estimate• 估计这个任务需要多少时间105
Development开发720700
• Analysis• 需求分析 (包括学习新技术)6080
• Design Spec• 生成设计文档4025
• Design Review• 设计复审55
• Coding Standard• 代码规范 (为目前的开发制定合适的规范)1010
• Design• 具体设计6075
• Coding• 具体编码360420
• Code Review• 代码复审120120
• Test• 测试(自我测试,修改代码,提交修改)100120
Reporting报告3045
• Test Repor• 测试报告2020
• Size Measurement• 计算工作量107
• Postmortem & Process Improvement Plan• 事后总结, 并提出过程改进计划1210
合计15721652

设计实现过程

前端

利用Hbuilderx可以实现Android、小程序、ios的多端开发。但为了适应计算器的界面,选择了Android的开发。
此次作业开发使用了html+css+js开发,其中主要的代码都写在vue文件中。开发的主要思路是利用在vue文件中添加一系列组件,并利用css渲染,并对组件添加一系列js函数以实现反馈:
对计算器的按钮添加click_buttom函数,当按下对应的按钮时,屏幕上的calculate_stringans会相应发生改变。同时前端利用fetch向后端服务器发送运算数据和接受后端服务器发来的结果数据,并根据发送过来的数据修改屏幕上的结果。

后端

后端主要是利用go语言的gin和gorm框架。
利用gin框架处理前端发送过来的数据请求,经过运算逻辑运算后将结果返回给前端。
利用gorm处理数据库。当前端发送来运算数据时,后端将其存入数据库中。之后当前端发送来运算指令时,后端从数据库中取出运算数据,经过运算模块进行一系列运算后发送给前端,并将相应记录保存到数据库中,以便后续对历史记录的访问。

关键代码说明

前端

通过在pages.json中定义出三个页面,分别对应三个计算器

    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
        
        {
            "path": "pages/calculate/calculate",
            "style": {
                "navigationStyle": "custom",
                "navigationBarTitleText": "标准计算器"
            }
        },
        {
            "path": "pages/science/science",
            "style": {
                "navigationStyle": "custom",
                "navigationBarTitleText": "科学计算器"
            }
        },
        {
            "path": "pages/bonus/bonus",
            "style": {
                "navigationStyle": "custom",
                "navigationBarTitleText": "利率计算器"
            }
        }
    ],

三个页面对应代码:
标准计算器:

<template>
    <view class="content" >
        
        <MyNavigationbarVue title="标准计算器" :is_show_temp="is_show" @sendback="getNewData"/>
        
        
        <view class="screen" @click="menu_hide">
            <view class="calculate_string_area">
                {{calculate_string}}
            </view> 
            <view class="ans_area">
                {{ans}}
            </view>
        </view>
        
        <view class="button_group">
            <view v-for="(item,index) in button_items" :key="index" class="button_item" 
            :id="item.id" hover-class="hover_button_item" hover-stay-time="1.5s" @click="click_button(item)">
                {{item.value}}
            </view>
        </view>
        
        <view class="history_list" :hidden="history_hide">
            <view class="history_title">
                <h1>History</h1>
            </view>
            <view class="history_item_group">
                <view class="history_item" v-for="(item,index) in history_list" :key="index" 
                hover-class="hover_item" hover-stay-time="1.5s" @click="get_history_item(item)">
                    {{ item.calc_s}}
                    <p class="cu">={{item.ans}}</p>
                </view>
            </view>
            
        </view>
        
    </view>
</template>

科学计算器:

<template>
    <view class="content" >
        
        <MyNavigationbarVue title="科学计算器" :is_show_temp="is_show" @sendback="getNewData"/>
        
        
        <view class="screen" @click="menu_hide">
            <view class="calculate_string_area">
                {{calculate_string}}
            </view> 
            <view class="ans_area">
                {{ans}}
            </view>
        </view>
        
        <view class="button_group" >
            <view v-for="(item,index) in button_items" :key="index" class="button_item" 
            :id="item.id" hover-class="hover_button_item" hover-stay-time="1.5s" @click="click_button(item)">
                {{item.value}}
            </view>
        </view>
        
        
        <view class="history_list" :hidden="history_hide">
            <view class="history_title">
                <h1>History</h1>
            </view>
            <view class="history_item_group">
                <view class="history_item" v-for="(item,index) in history_list" :key="index" 
                hover-class="hover_item" hover-stay-time="1.5s" @click="get_history_item(item)">
                    {{ item.calc_s}}
                    <p class="cu">={{item.ans}}</p>
                </view>
            </view>
            
        </view>
        
    </view>
</template>

利率计算器:

<template>
    <view class="content bg_color">
        <MyNavigationbarVue title="利率计算器" :is_show_temp="is_show" @sendback="getNewData"/>
        <view class="bonus_table" v-if="bonus_table">
            <view class="save_bonus">
                <view style="font-size: 50rpx; margin: 20rpx;">
                    存款利率
                </view>
                <form @submit="edit_save_bonus">
                    <view class="bonus_txt">
                        活期存款:
                    </view>
                    <input class="uni-input" type="number" placeholder="活期存款利率" v-model="alive_bonus" />
                    <view class="bonus_txt">
                        整存整取定期存款
                    </view><br>
                    <view class="bonus_txt">
                        三个月:
                    </view>
                    <input class="uni-input" placeholder="定期存款三个月利率" v-model="three_month_save_bonus"/>
                    <view class="bonus_txt">
                        半年:
                    </view>
                    <input class="uni-input" placeholder="定期存款半年利率" v-model="half_year_save_bonus"/>
                    <view class="bonus_txt">
                        一年:
                    </view>
                    <input class="uni-input" placeholder="定期存款一年利率" v-model="a_year_save_bonus"/>
                    <view class="bonus_txt">
                        二年:
                    </view>
                    <input class="uni-input" placeholder="定期存款二年利率" v-model="two_year_save_bonus"/>
                    <view class="bonus_txt">
                        三年:
                    </view>
                    <input class="uni-input" placeholder="定期存款三年利率" v-model="three_year_save_bonus"/>
                    <view class="bonus_txt">
                        五年:
                    </view>
                    <input class="uni-input" placeholder="定期存款五年利率" v-model="five_year_save_bonus"/>
                    <button form-type="submit">确认修改</button>
                </form>
            </view>
            <view class="borrow_bonus">
                <view style="font-size: 50rpx; margin: 20rpx;">
                    贷款利息
                </view>
                <form @submit="edit_borrow_bonus">
                    <view class="bonus_txt">
                        各项贷款
                    </view><br>
                    <view class="bonus_txt">
                        六个月:
                    </view>
                    <input class="uni-input" placeholder="六个月利息" v-model="interest_1"/>
                    <view class="bonus_txt">
                        一年:
                    </view>
                    <input class="uni-input" placeholder="六个月利息" v-model="interest_2"/>
                    <view class="bonus_txt">
                        一至三年:
                    </view>
                    <input class="uni-input" placeholder="一至三年利息" v-model="interest_3"/>
                    <view class="bonus_txt">
                        三至五年:
                    </view>
                    <input class="uni-input" placeholder="三至五年利息" v-model="interest_4"/>
                    <view class="bonus_txt">
                        五年:
                    </view>
                    <input class="uni-input" placeholder="五年利息" v-model="interest_5"/>
                    <button form-type="submit">确认修改</button>
                </form>
            </view>
            <button @click="shut_down">Quit</button>
        </view>
        <button class="change_bonus" @click="bonus_table_show()">修改利率表</button>
        <view class="bonus_calc" style="padding: 40rpx;">
            <form @submit="bonus_calc">
                <view class="uni-form-item uni-column">
                    <view class="title">计算类型</view>
                        <radio-group name="radio" @change="radioChange">
                            <label>
                                <radio value="save" class="botton_dis"/><text>存款</text>
                            </label>
                            <label>
                                <radio value="borrow" class="botton_dis"/><text>贷款</text>
                            </label>
                        </radio-group>
                </view>
                <view class="uni-form-item uni-column" v-if="select_option==='save'">
                    <view class="title">活期/定期存款</view>
                        <radio-group name="radio" @change="radioChange2">
                            <label>
                                <radio value="alive" class="botton_dis"/><text>活期</text>
                            </label>
                            <label>
                                <radio value="dead" class="botton_dis"/><text>定期</text>
                            </label>
                        </radio-group>
                </view>
                <view class="input_box">
                    <label class="inputTxt">存/贷款金额</label>
                    <input type="text" class="uni-input" v-model="money">
                    <label class="inputTxt">存/贷款年份(单位:年)</label>
                    <input type="text" class="uni-input" v-model="years">
                </view>
                <button form-type="submit" class="btn_calc">计算</button>
            </form>
            <p style="font-size: 50rpx; margin: 50rpx;">利率:</p>
            <view class="ans_area">
                {{ans}}
            </view>
        </view>
    </view>
</template>

引入自定义组件MyNavigationbar以实现顶部的导航栏和界面切换的侧边栏,不同的页面会传递不同的参数给MyNavigationbar,后者根据不同的参数渲染出不同的页面

<template>
    <view>
        <view class="status_bar">
            <!-- 这里是状态栏 -->
        </view>
        <view class="navBar" style="height:93rpx;">
             <view  style="display: flex; flex-direction: row;align-items: center;">
                 <image src="../static/back.png" style="height: 80rpx;width: 80rpx;" @click="goback"></image>
                <image src="../static/menu.png" style="height: 60rpx;width: 60rpx; margin-right: 40rpx;" @click="menu_show"></image>
                <p style="line-height: 80rpx;">{{title}}</p>
             </view>
        </view>
        
        
        <view class="menu_content" :hidden="is_show_temp">
            
            <!-- <view :hidden="title === '科学计算器' "> -->
            <view v-if="title === '标准计算器'">
                <view class="standar" style="background-color: #dbdbdb;" >
                    <view style="width: 10rpx; height: 40rpx; background-color: #00bbbe; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/standar_icon.png" style="width:50rpx; height:55rpx; margin-right: 7rpx;" ></image>
                    <p style="line-height: 40rpx;">标准计算器</p>
                </view>
                <view class="standar" hover-class="hover_option" hover-stay-time="10s" style="margin-top: 40rpx;" @click="goto_science">
                    <view style="width: 10rpx; height: 40rpx; background-color: #f8f8f8; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/science_icon.png" style="width:35rpx; height:45rpx; margin-right: 10rpx; margin-left: 10rpx;" ></image>
                    <p style="line-height: 40rpx;">科学计算器</p>
                </view>
                <view class="standar" hover-class="hover_option" hover-stay-time="10s" style="margin-top: 40rpx;" @click="goto_bonus">
                    <view style="width: 10rpx; height: 40rpx; background-color: #f8f8f8; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/bonus.png" style="width:50rpx; height:50rpx; margin-right: 7rpx;" ></image>
                    <p style="line-height: 40rpx;">利率计算器</p>
                </view>
            </view>
            
            
            <!-- <view :hidden="title === '标准计算器'"> -->
            <view v-if="title === '科学计算器'">
                <view class="standar" @click="goto_standar" hover-class="hover_option" hover-stay-time="10s" style="margin-top: 40rpx;" >
                    <view style="width: 10rpx; height: 40rpx; background-color: #f8f8f8; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/standar_icon.png" style="width:50rpx; height:55rpx; margin-right: 7rpx;" ></image>
                    <p style="line-height: 40rpx;">标准计算器</p>
                </view>
                <view class="standar" style="background-color: #dbdbdb;">
                    <view style="width: 10rpx; height: 40rpx; background-color: #00bbbe; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/science_icon.png" style="width:35rpx; height:45rpx; margin-right: 10rpx; margin-left: 10rpx;" ></image>
                    <p style="line-height: 42rpx;">科学计算器</p>
                </view>
                <view class="standar" @click="goto_bonus" hover-class="hover_option" hover-stay-time="10s" style="margin-top: 40rpx;" >
                    <view style="width: 10rpx; height: 40rpx; background-color: #f8f8f8; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/bonus.png" style="width:50rpx; height:50rpx; margin-right: 7rpx;" ></image>
                    <p style="line-height: 40rpx;">利率计算器</p>
                </view>
            </view>
            
            <view v-if="title === '利率计算器'">
                <view class="standar" @click="goto_standar" hover-class="hover_option" hover-stay-time="10s" style="margin-top: 40rpx;" >
                    <view style="width: 10rpx; height: 40rpx; background-color: #f8f8f8; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/standar_icon.png" style="width:50rpx; height:55rpx; margin-right: 7rpx;" ></image>
                    <p style="line-height: 40rpx;">标准计算器</p>
                </view>
                <view class="standar" @click="goto_science" hover-class="hover_option" hover-stay-time="10s" style="margin-top: 40rpx;">
                    <view style="width: 10rpx; height: 40rpx; background-color: #f8f8f8; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/science_icon.png" style="width:35rpx; height:45rpx; margin-right: 10rpx; margin-left: 10rpx;" ></image>
                    <p style="line-height: 42rpx;">科学计算器</p>
                </view>
                <view class="standar" style="background-color: #dbdbdb;" >
                    <view style="width: 10rpx; height: 40rpx; background-color: #00bbbe; margin-left: 10rpx; border-radius: 30%;" ></view>
                    <image src="../static/bonus.png" style="width:50rpx; height:50rpx; margin-right: 7rpx;" ></image>
                    <p style="line-height: 40rpx;">利率计算器</p>
                </view>
            </view>
        </view>
        
    </view>
</template>

<script>
    export default {
        
        data(){
            return{
                // is_show:this.is_show_temp,
            }
        },
        props:{
            title:{
                type:String,
                default:"",
                
            },
            is_show_temp:{
                type:Boolean,
                default:true,
                
            },
            
        },
            
        methods:{
            goback(){
                uni.navigateBack()
            },
            
            
            
            menu_show(){
                // this.is_show=!this.is_show;
                this.$emit("sendback",!this.is_show_temp);
                
            },
            
            goto_standar(){
                uni.navigateTo({
                    url:'/pages/calculate/calculate'
                })
            },
            
            goto_science(){
                uni.navigateTo({
                    url:'/pages/science/science'
                })
            },
            
            goto_bonus(){
                uni.navigateTo({
                    url:'/pages/bonus/bonus'
                })
            }
        }
            
    }
</script>

<style>
    
     .status_bar {
            height: var(--status-bar-height);
            width: 100%;
        }
    
    
    .menu_content{
        position: absolute;
        width: 50%;
        height: 100%;
        background-color: #f8f8f8;
        z-index: 99;
    }
    
    .menu_icon{
            
            height: 45rpx;
            width:45rpx;
            
    }
    
    .standar{
        margin-top: 10rpx;
        display: flex;
        align-items: center;
        flex-direction: row;
        width: 100%;
        height: 100rpx;
    }
    
    .hover_option{
        color: #8e8e8e;
        background-color: #6c6c6c;
    }
</style>

当按下对应的数字和运算按钮时,会触发click_button函数,屏幕上用于计算的calculate_string会对应发生改变,并根据按钮的类型向后端服务器发送不同的请求

            math_trans(v){
                // 添加你的数学转换逻辑  
                if(v==='×'){
                    this.ans+='×';
                    this.to_calculate_string+='*';
                }
                else if(v==='÷'){
                    //return '/';
                    this.ans+='÷';
                    this.to_calculate_string+='/';
                }
                else if(v==='√'){
                    //return "sqrt(";
                    this.ans+="√("    ;
                    this.to_calculate_string+="sqrt(";
                }
                else if(v==='sec'){
                    this.to_calculate_string+="sec(";
                    this.ans+="sec("
                }
                else if(v==="csc"){
                    this.to_calculate_string+="csc(";
                    this.ans+="csc(";
                }
                else if(v==="cot"){
                    this.to_calculate_string+="cot(";
                    this.ans+="cot(";
                }
                else if(v==="log2"){
                    this.to_calculate_string+="log2(";
                    this.ans+="log2(";
                }
                else if(v==="sin"){
                    this.to_calculate_string+="sin(";
                    this.ans+="sin(";
                }
                else if(v==="cos"){
                    this.to_calculate_string+="cos(";
                    this.ans+="cos(";
                }
                else if(v==="tan"){
                    this.to_calculate_string+="tan(";
                    this.ans+="tan(";
                }
                else if(v==='E'){
                    this.to_calculate_string+="e";
                    this.ans+="E";
                }
                else if(v==="lg"){
                    this.to_calculate_string+="lg(";
                    this.ans+="lg(";
                }
                else if(v==="ln"){
                    this.to_calculate_string+="log(";
                    this.ans+="ln(";
                }
                else if(v==="π"){
                    this.to_calculate_string+="pi";
                    this.ans+="π";
                }
                else{
                    this.ans+=v;
                    this.to_calculate_string+=v;
                }
                return;
            },  
            //返回历史记录
            get_history(){
                this.history_hide=!this.history_hide;
                console.log(this.history_hide);
                fetch('http://localhost:9090/calc/history',{
                    method:'GET',
                })
                .then(response => {  
                    if (!response.ok) {  
                        console.log(response);
                        throw new Error('Network response was not ok');  
                    }
                    return response.json();
                })  
                .then(data=>{
                    //返回前十个历史内容
                    this.history_list=data.history_list;
                    console.log(this.history_list);
                })
                .catch(error => {
                    console.error('请求出错:', error);  
                    // 这里可以添加更多的错误处理逻辑  
                });
            },
            //删除
            delete_input(){
                if(this.ans[this.ans.length>=2&&this.ans.length-1]=="n"&&this.ans[this.ans.length-2]=="l"){
                    this.ans=this.ans.slice(0,-2);
                    this.to_calculate_string=this.to_calculate_string.slice(0,-3);
                }
                else if(this.ans.length>=1&&this.ans[this.ans.length-1]=="π"){
                    this.ans = this.ans.slice(0, -1);
                    this.to_calculate_string=this.to_calculate_string.slice(0,-2);
                }
                else if(this.ans.length>=1&&this.ans[this.ans.length-1]=='√'){
                    this.ans = this.ans.slice(0, -1);
                    this.to_calculate_string=this.to_calculate_string.slice(0,-4);
                }else{
                    this.ans = this.ans.slice(0, -1);
                this.to_calculate_string=this.to_calculate_string.slice(0,-1);
                }
                
                if(this.ans===""){
                    this.ans=0;
                }
                return;              
            },
            //按下等号为get,创建为post,修改为put
            click_button(item){
                //定义一个发送的对象
                var tran_data={
                    calc_s:this.calculate_string,
                    to_calc_s:this.to_calculate_string
                };
                //如果按下的是等号
                if(item.value==='='){
                    //console.log(this.to_calculate_string);
                    this.is_new=1;
                    fetch('http://localhost:9090/calc',{
                        method:'GET',
                    })
                    .then(response => {  
                        if (!response.ok) {  
                            throw new Error('Network response was not ok');  
                        }  
                        return response.json(); // 或者 response.text(),取决于服务器返回的内容类型  
                    })  
                    .then(data=>{
                        console.log(data)
                        this.calculate_string=data.calculate_string
                        this.to_calculate_string=data.to_calculate_string
                        this.ans=data.ans
                        
                    })
                    .catch(error => {  
                        console.error('请求出错:', error);  
                        // 这里可以添加更多的错误处理逻辑  
                    });
                    this.to_calculate_string="";
                    console.log(this.to_calculate_string);
                    return;
                }
                //读取历史记录
                else if(item.value==="Ans"){
                    this.get_history();
                }
                //清除
                else if(item.value==="C"){
                    this.ans="0";
                    this.is_new=1;
                    this.calculate_string="";
                    fetch('http://localhost:9090/calc',{
                        method:'DELETE',
                        headers: {
                            'Content-Type': 'application/json'  
                        },  
                        //body: JSON.stringify(tran_data)
                    })
                }
            
                else if(item.value==='Back'){
                    if(this.ans===0)
                        return;
                    this.delete_input();
                    //清完了
                    //console.log(this.ans);
                    if(this.to_calculate_string===""){
                        this.is_new=1;
                        fetch('http://localhost:9090/calc',{
                            method:'DELETE',
                            headers: {
                                'Content-Type': 'application/json'  
                            },  
                            body: JSON.stringify(tran_data)
                        })
                    }
                    else{
                        tran_data.calc_s=this.ans;
                        tran_data.to_calc_s=this.to_calculate_string;
                        fetch('http://localhost:9090/calc',{
                            method:'PUT',
                            headers: {
                                'Content-Type': 'application/json'  
                            },  
                            body: JSON.stringify(tran_data)
                        })
                    }
                }
                //按下的不是等号
                else if(this.is_new===1){    //创建
                    this.ans="";
                    this.to_calculate_string="";
                    this.math_trans(item.value);
                    tran_data.calc_s=this.ans;
                    tran_data.to_calc_s=this.to_calculate_string;
                    this.is_new=0;
                    
                    fetch('http://localhost:9090/calc',{
                        method:'POST',
                        headers: {  
                            'Content-Type': 'application/json'  
                        },  
                        body: JSON.stringify(tran_data)
                    })
                    
                }
                else if(this.is_new==0){    //修改
                    this.math_trans(item.value);
                    tran_data.calc_s=this.ans;
                    tran_data.to_calc_s=this.to_calculate_string;
                    fetch('http://localhost:9090/calc',{
                        method:'PUT',
                        headers: {
                            'Content-Type': 'application/json'  
                        },  
                        body: JSON.stringify(tran_data)
                    })
                    
                }
                
            },

在利率计算器中,利用v-model对form表单中的值实现动态绑定。
当计算利率时,利用radio组件实现不同的存借款类型,当点击不同radio时,触发radioChange函数

            radioChange: function(evt){
                this.select_option=evt.detail.value;
            },
            radioChange2: function(evt){
                this.option2=evt.detail.value;
            },

并在点击运算后,触发bonus_calc函数,将表单中的数据通过fetch传递给后端

            bonus_calc(){
                
                var msg={
                    money:this.money,
                    years:this.years,
                    select_option:this.select_option,
                    option2:this.option2,
                };
                fetch('http://localhost:9090/calc/bonus',{
                    method:'POST',
                    headers: {
                        'Content-Type': 'application/json'  
                    },  
                    body: JSON.stringify(msg)
                })
                .then(response => {
                    if (!response.ok) {  
                        throw new Error('Network response was not ok');  
                    }  
                    return response.json(); // 或者 response.text(),取决于服务器返回的内容类型  
                })  
                .then(data=>{
                    //console.log(data)
                    this.ans=data.ans;
                })
            },

对利率表的修改同理,利用v-model进行数据绑定,并在点击“确认修改”后触发函数,利用fetch向后端传递数据

            //提交存款表单
            edit_save_bonus(){
                //console.log(this.alive_bonus);
                var msg={
                    alive_bonus:this.alive_bonus,
                    three_month_save_bonus:this.three_month_save_bonus,
                    half_year_save_bonus:this.half_year_save_bonus,
                    a_year_save_bonus:this.a_year_save_bonus,
                    two_year_save_bonus:this.two_year_save_bonus,
                    three_year_save_bonus:this.three_year_save_bonus,
                    five_year_save_bonus:this.five_year_save_bonus
                };
                fetch('http://localhost:9090/calc/bonus/save',{
                    method:'PUT',
                    headers: {
                        'Content-Type': 'application/json'  
                    },  
                    body: JSON.stringify(msg)
                })
            },
            //提交借款表单
            edit_borrow_bonus(){
                var msg={
                    interest_1:this.interest_1,
                    interest_2:this.interest_2,
                    interest_3:this.interest_3,
                    interest_4:this.interest_4,
                    interest_5:this.interest_5,
                };
                fetch('http://localhost:9090/calc/bonus/borrow',{
                    method:'PUT',
                    headers: {
                        'Content-Type': 'application/json'  
                    },  
                    body: JSON.stringify(msg)
                })
            },

后端

服务器启动并连接数据库db1

    //建立路由
    r := gin.Default()
    //跨域
    r.Use(cors.Default())
    //连接mysql数据库
    //之前要手动创建一个数据库db1
    db, err := gorm.Open("mysql", "root:030223@tcp(127.0.0.1:3306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
    if err != nil {
        panic(err)
    }
    //自动迁移,把结构体和数据表进行对应
    db.AutoMigrate(&UserInfo{})
    defer db.Close()

处理计算器发送来的数据请求

    var now_id int //数据库中的数据记录id
    now_id = 0
    // 创建
    r.POST("/calc", func(c *gin.Context) {
        // 将传送过来的数据接收
        now_id += 1
        var u1 UserInfo
        body, _ := io.ReadAll(c.Request.Body)
        defer c.Request.Body.Close()
        err := json.Unmarshal(body, &u1)
        if err != nil {
            return
        }
        calculate_string := u1.Calculate_string
        to_calculate_string := u1.To_calculate_string
        u2 := UserInfo{Rank: now_id, Calculate_string: calculate_string, To_calculate_string: to_calculate_string, Result: ""}

        db.Create(&u2)
    })
    //修改
    r.PUT("/calc", func(c *gin.Context) {
        //将传送过来的数据接收
        body, _ := io.ReadAll(c.Request.Body)
        defer c.Request.Body.Close()
        var u1 UserInfo
        err := json.Unmarshal(body, &u1)
        if err != nil {
            return
        }
        calculate_string := u1.Calculate_string
        to_calculate_string := u1.To_calculate_string
        //查找
        var u2 UserInfo
        //更新
        db.Model(&u2).Where("`rank` = ?", now_id).Debug().Updates(map[string]interface{}{
            "calculate_string":    calculate_string,
            "to_calculate_string": to_calculate_string,
        })
    })
    //返回计算结果
    r.GET("/calc", func(c *gin.Context) {
        // GET

        var u1 UserInfo
        // 根据ID从数据库中查找用户
        db.Where("`rank` = ?", now_id).Debug().First(&u1)
        result, err := engine.ParseAndExec(u1.To_calculate_string)
        if err != nil {
            u1.Result = "error"
        } else {
            u1.Result = fmt.Sprintf("%v", result)
        }

        db.Model(&u1).Where("`rank`=?", now_id).Update(&u1)

        c.JSON(http.StatusOK, gin.H{
            "calculate_string":    u1.Calculate_string,
            "to_calculate_string": u1.To_calculate_string,
            "ans":                 u1.Result,
        })
    })
    //删除
    r.DELETE("/calc", func(c *gin.Context) {
        var u1 UserInfo
        // db.Where("`rank` = ?", now_id).Debug().Find(&u1)
        db.Where("`rank` = ?", now_id).Debug().Delete(&u1)
        now_id--
    })

运算模块:
引入math-engine,math-engine能够处理算式,并运算出结果。为了math-engine能够处理对数,需要对对数函数进行函数注册

//注册函数
    engine.RegFunction("lg", 1, func(expr ...engine.ExprAST) float64 {
        return math.Log10(engine.ExprASTResult(expr[0]))
    })

    engine.RegFunction("log2", 1, func(expr ...engine.ExprAST) float64 {
        return math.Log2(engine.ExprASTResult(expr[0]))
    })

    engine.RegFunction("log", 1, func(expr ...engine.ExprAST) float64 {
        return math.Log(engine.ExprASTResult(expr[0]))
    })

利用GET来处理前端发送过来的运算请求,从数据库中取出算式,交给math-engine运算,并更新数据库中的数据

    //返回计算结果
    r.GET("/calc", func(c *gin.Context) {
        // GET

        var u1 UserInfo
        // 根据ID从数据库中查找用户
        db.Where("`rank` = ?", now_id).Debug().First(&u1)
        result, err := engine.ParseAndExec(u1.To_calculate_string)
        if err != nil {
            u1.Result = "error"
        } else {
            u1.Result = fmt.Sprintf("%v", result)
        }

        db.Model(&u1).Where("`rank`=?", now_id).Update(&u1)

        c.JSON(http.StatusOK, gin.H{
            "calculate_string":    u1.Calculate_string,
            "to_calculate_string": u1.To_calculate_string,
            "ans":                 u1.Result,
        })
    })

返回前十条历史记录

    //返回历史记录(前十条)
    r.GET("/calc/history", func(c *gin.Context) {
        var history_list []UserInfo
        db.Debug().Where("`rank` >= ?", max(now_id-9, 1)).Order("rank").Find(&history_list)

        c.JSON(http.StatusOK, gin.H{
            "history_list": history_list,
        })
    })

利率计算器:
在数据库中先存入默认数据表,之后通过PUT请求来修改数据库中的数据表

        //修改存款利率
    db.AutoMigrate(&MsgSave{})
    msg1 := MsgSave{Alivebonus: "0.5", Three_month: "2.85", Half_year: "3.05", A_year: "3.25", Two_year: "4.15", Three_year: "4.75", Five_year: "5.25"}
    db.Create(msg1)
    r.PUT("/calc/bonus/save", func(c *gin.Context) {
        body, _ := io.ReadAll(c.Request.Body)
        defer c.Request.Body.Close()
        var u1 MsgSave
        err := json.Unmarshal(body, &u1)
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }

        if u1.Alivebonus == "" {
            u1.Alivebonus = msg1.Alivebonus
        }
        if u1.Three_month == "" {
            u1.Three_month = msg1.Three_month
        }
        if u1.Half_year == "" {
            u1.Half_year = msg1.Half_year
        }
        if u1.A_year == "" {
            u1.A_year = msg1.A_year
        }
        if u1.Two_year == "" {
            u1.Two_year = msg1.Two_year
        }
        if u1.Three_year == "" {
            u1.Three_year = msg1.Three_year
        }
        if u1.Five_year == "" {
            u1.Five_year = msg1.Five_year
        }
        db.Model(&u1).Debug().Updates(map[string]interface{}{
            "alivebonus":  u1.Alivebonus,
            "three_month": u1.Three_month,
            "half_year":   u1.Half_year,
            "a_year":      u1.A_year,
            "two_year":    u1.Two_year,
            "three_year":  u1.Three_year,
            "five_year":   u1.Five_year,
        })
        db.First(&msg1)
    })
    //修改贷款利息
    db.AutoMigrate(&MsgBorrow{})
    msg2 := MsgBorrow{Interest_1: "5.85", Interest_2: "6.31", Interest_3: "6.40", Interest_4: "6.65", Interest_5: "6.80"}
    db.Create(msg2)
    r.PUT("/calc/bonus/borrow", func(c *gin.Context) {
        body, _ := io.ReadAll(c.Request.Body)
        defer c.Request.Body.Close()
        var u1 MsgBorrow
        err := json.Unmarshal(body, &u1)
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        if u1.Interest_1 == "" {
            u1.Interest_1 = msg2.Interest_1
        }
        if u1.Interest_2 == "" {
            u1.Interest_2 = msg2.Interest_2
        }
        if u1.Interest_3 == "" {
            u1.Interest_3 = msg2.Interest_3
        }
        if u1.Interest_4 == "" {
            u1.Interest_4 = msg2.Interest_4
        }
        if u1.Interest_5 == "" {
            u1.Interest_5 = msg2.Interest_5
        }
        db.Model(&u1).Debug().Updates(u1)
        db.First(&msg2)
    })

通过GET请求来返回计算结果

    //计算利率
    r.POST("/calc/bonus", func(c *gin.Context) {
        body, _ := io.ReadAll(c.Request.Body)
        defer c.Request.Body.Close()
        var u1 Bonus
        err := json.Unmarshal(body, &u1)
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
        yearsFloat, err := strconv.ParseFloat(u1.Years, 64)
        if err != nil {
            // 处理转换错误的情况
            u1.Ans = "error"
            c.JSON(http.StatusOK, gin.H{
                "ans": u1.Ans,
            })
            return
        }
        temp := "xxx"
        if u1.Select_option == "save" {
            if u1.Option2 == "alive" {
                temp = msg1.Alivebonus
            } else if yearsFloat <= 0.25 {
                temp = msg1.Three_month
            } else if yearsFloat <= 0.5 {
                temp = msg1.Half_year
            } else if yearsFloat <= 1 {
                temp = msg1.A_year
            } else if yearsFloat <= 2 {
                temp = msg1.Two_year
            } else if yearsFloat <= 3 {
                temp = msg1.Three_year
            } else if yearsFloat > 3 {
                temp = msg1.Five_year
            }
            // temp = temp
        } else {
            if yearsFloat <= 0.5 {
                temp = msg2.Interest_1
            } else if yearsFloat <= 1 {
                temp = msg2.Interest_2
            } else if yearsFloat <= 3 {
                temp = msg2.Interest_3
            } else if yearsFloat < 5 {
                temp = msg2.Interest_4
            } else if yearsFloat >= 5 {
                temp = msg2.Interest_5
            }
            // temp = temp
        }

        calcS := fmt.Sprintf("%s * %s * %s", u1.Money, temp, u1.Years)
        result, err := engine.ParseAndExec(calcS)
        if err != nil {
            u1.Ans = "error"
        } else {
            result /= 100
            u1.Ans = fmt.Sprintf("%v", result)
        }
        c.JSON(http.StatusOK, gin.H{
            "ans": u1.Ans,
        })
    })

心路历程和收获

本次前后端计算器不同于之前的计算器。这次的计算器需要同时具备前端和后端的知识,而且需要我们深刻理解前端和后端的交互过程。经过这次学习,我深入理解了前端和后端的交互过程,学会了vue和前端三件套的用法,还学会了对Go语言gin和gorm的框架的使用,以及mySQL的一系列操作。受益匪浅。

...全文
197 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

158

社区成员

发帖
与我相关
我的任务
社区描述
FZU-CS-SE
软件工程 高校
社区管理员
  • LinQF39
  • Jcandc
  • chjinhuu
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧