一个网站如何优化,建立自己的网站需要服务器吗,手机百度安装下载,业之峰装饰公司怎么样目录 仓库链接0.PSP表格1. 成品展示1.基础运算2. 清零回退3.错误提示4.历史记录拓展功能1.前端可修改的利率计算器2.科学计算器3. 按钮切换不同计算器模式4.用户在一次运算后不清零继续输入操作符#xff0c;替换表达式为上次答案 2.设计实现过程3.代码说明4.心路历程和收获 仓… 目录 仓库链接0.PSP表格1. 成品展示1.基础运算2. 清零回退3.错误提示4.历史记录拓展功能1.前端可修改的利率计算器2.科学计算器3. 按钮切换不同计算器模式4.用户在一次运算后不清零继续输入操作符替换表达式为上次答案 2.设计实现过程3.代码说明4.心路历程和收获 仓库链接
2301-计算机学院-软件工程https://bbs.csdn.net/forums/ssynkqtd-05这个作业要求在哪里https://bbs.csdn.net/topics/617377308这个作业的目标实现一个前后端分离计算器其他参考文献…
backend frontend Google 开源项目风格指南——中文版 Google Style Guides
0.PSP表格
PSPPersonal Software Process Stages预估耗时分钟实际耗时分钟Planning计划4020• Estimate估计这个任务需要多少时间1010Development开发650630• Analysis需求分析 (包括学习新技术4030• Design Spec生成设计文档8075• Design Review设计复审3545• Coding Standard代码规范 (为目前的开发制定合适的规范)2520• Design具体设计3530• Coding具体编码325320• Code Review代码复审6560• Test测试自我测试修改代码提交修改6050Reporting报告9590• Test Report测试报告2520• Size Measurement计算工作量1015• Postmortem Process Improvement Plan事后总结, 并提出过程改进计划4555合计670630
1. 成品展示
1.基础运算 2. 清零回退 3.错误提示 4.历史记录 拓展功能
1.前端可修改的利率计算器 2.科学计算器 3. 按钮切换不同计算器模式 4.用户在一次运算后不清零继续输入操作符替换表达式为上次答案 2.设计实现过程
前端前端需要在上一轮作业的基础上加以完善。首先要扩充为两个输入框一个用于显示用户输入的表达式一个用于显示答案。同时在上一轮的form基础上再做一个利率计算器利率计算器和存款计算器可以共用一个div。同时使用fetch向后端传发数据。后端后端使用Gin做Web框架。通过路由组和hander接前端请求。Gin相比于Hertz是一个轻量级的框架适合做这种小项目。数据库交互用Gorm。数据库只用到了Mysql。存历史记录存款、贷款三张表。暂且把这个计算器看作单机版本所以在存历史记录的时候没有特意区分不同用户ID。可视化工具推荐Dbeaver。
3.代码说明
前端采用fetch通信。fetch的语法很简明不再赘述。以查询历史记录为例
function ans() {fetch(http://localhost:8080/history/, {method: GET,headers: {Content-Type: application/json},}).then(response response.json()).then(data {// 处理后端的响应if (data.code 200) {const expVal data.result;if (expVal.length 0) {const displayText expVal.map((item, index) div classexpression-container idexpression-${index}$ ${item.Exp} ${item.Val} $/div).join(br);Swal.fire({title: 历史记录(近 10 条),html: displayText,icon: success,confirmButtonText: 关闭});// 使用MathJax渲染数学表达式for (let i 0; i expVal.length; i) {MathJax.Hub.Queue([Typeset, MathJax.Hub, expression-${i}]);}} else {// 如果没有之前的数据显示提示消息Swal.fire(没有可显示的数据, , error);}} else {// code 不为 200给出提示console.error(响应状态不是 200错误消息${data.msg});}}).catch(error {console.error(An error occurred while receiving the result from the backend: error);});
}页面的切换用一个变量来控制相当于一个mod 3 的加法控制div的可见性。
function mode() {st (st 1) % 3;const normalCalculator document.querySelector(.normal);const interestCalculator document.querySelector(.interest);let bt document.getElementById(topMode);var updateInter document.getElementById(update_inter);var updateInter2 document.getElementById(update_inter2);if (st 0) {normalCalculator.style.display block;interestCalculator.style.display none;bt.innerHTML 科学计算器} else if (st 1) {normalCalculator.style.display none;interestCalculator.style.display block;updateInter.style.display block;updateInter2.style.display none;bt.innerHTML 存款计算器} else if (st 2) {normalCalculator.style.display none;interestCalculator.style.display block;updateInter2.style.display block;updateInter.style.display none;bt.innerHTML 贷款计算器}
}后端启动服务
package mainimport (WebCalculator/dal/mysqlWebCalculator/routergithub.com/gin-contrib/corsgithub.com/gin-gonic/gin
)func main() {mysql.Init()r : gin.Default()// 解决跨域问题r.Use(cors.Default())router.SetUpRoutes(r)err : r.Run(:8080)if err ! nil {panic(err)}
}注意需要解决跨域问题。查阅资料得知最近的Gin官方已经给出了对于跨域的问题的默认配置无需再手动配置一行代码就可以了。同时在main函数中初始化mysql相关链接信息和路由组。
func SetUpRoutes(engine *gin.Engine) {home : engine.Group(/){home.GET(/hello, hello.Hello)}his : engine.Group(/history){his.POST(/, history.AddHistory)his.GET(/, history.QueryHistory)}dep : engine.Group(/deposit){dep.POST(/, deposit.UpdateDep)dep.GET(/, deposit.QueryInterest)}l : engine.Group(/loans){l.GET(/, loans.QueryInterest)l.POST(/, loans.UpdateLoans)}
}hander包编写具体实现方法。 以查询利息为例
func QueryInterest(c *gin.Context) {// 获取查询参数principalStr : c.DefaultQuery(principal, )durationStr : c.DefaultQuery(duration, )// 将字符串转换为浮点数principal, err1 : strconv.ParseFloat(principalStr, 64)duration, err2 : strconv.ParseFloat(durationStr, 64)if err1 ! nil || err2 ! nil {// 处理转换错误例如返回错误响应c.JSON(http.StatusOK, gin.H{code: 400,msg: 输入无效,})return}interest : service.CalInterest(entity.MoneyCal{Money: principal,Duration: duration,}, 1)c.JSON(http.StatusOK, gin.H{code: 200,msg: 计算成功,result: interest,})}注意存款和贷款的逻辑几乎相同。所以可以增加一个传入参数op0/1表示不同类型就可以复用计算函数。
func ExistDuration(duration float64, op int) bool {if op 1 {result : mysql.DB.Where(duration ?, duration).First(entity.Deposit{})return result.Error ! gorm.ErrRecordNotFound}result : mysql.DB.Where(duration ?, duration).First(entity.Loan{})return result.Error ! gorm.ErrRecordNotFound
}func CalInterest(cal entity.MoneyCal, op int) float64 {duration : cal.Durationmoney : cal.Moneyif op 1 {var deposit entity.Depositmysql.DB.Where(duration ?, duration).Order(duration desc).Limit(1).First(deposit)return money * deposit.Rate / 100}var loans entity.Loanmysql.DB.Where(duration ?, duration).Order(duration desc).Limit(1).First(loans)return money * loans. Rate / 100
}3.数据库 Gorm的数据库操作十分便利。提供了AutoMigrate来自动迁移表结构。有结构体的情况下可以自动建对应表.无需编写sql。
DB, err gorm.Open(mysql.Open(dsn), gorm.Config{SkipDefaultTransaction: true,PrepareStmt: true,Logger: logger.Default.LogMode(logger.Info),})if err ! nil {panic(err)}err DB.AutoMigrate(entity.History{}, entity.Deposit{}, entity.Loan{})if err ! nil {return}且gorm.Model包含许多实用信息IDCT,UPT等等。
4.心路历程和收获
后端部分其实没啥技术含量主要是CRUD… 感觉最难的部分还是在前端因为之前不会所以几乎是一直在对着已有的HTML和CSS代码不断增删猜测效果/询问他人。感觉前端代码实在写的不堪入目还好最后效果感觉还行。 有些疑惑为什么要一个人完成前后端可能全栈是学院派的宿命。