第二次作业
第二次作业——具有登录功能的计算器
一、定义阶段
(一)软件计划
1、项目开发架构:
本项目开发架构采用瀑布模型,从系统需求分析到维护,每个阶段都会产生循环反馈。

2、项目所用的工具以及环境
Hbuilder X、Idea、Mysql数据库、Navicat管理数据库、Java Spring、语言:html、java语言
3、需求分析
包含登录界面的计算器软件,实现计算器加减乘除、开平方的功能,计算器软件的使用历史记录可以保存在数据库中。

二、开发阶段
(一)总体设计
1、登录界面流程图

2、计算器流程图

(一)详细设计
1、建立数据库

2、前端设计
(1)学生登录界面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>学生登录界面</title>
<style>
body {
background-image: url(picture.jpg);
background-size: cover;
background-repeat: no-repeat;
height: 100vh;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
form {
background-color: rgba(255, 255, 255, 0.8);
padding: 20px;
border-radius: 10px;
text-align: center;
}
input[type="text"],
input[type="password"] {
width: 100%;
padding: 10px;
margin: 5px 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 5px;
}
input[type="submit"] {
width: 100%;
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 5px;
cursor: pointer;
}
input[type="submit"]:hover {
background-color: #45a049;
}
</style>
</head>
<body>
<form action="login.php" method="post">
<h2>兰州财经大学学生登录</h2>
<label for="username">学生登录账号:</label>
<input type="text" id="username" name="username"><br>
<label for="password">密码:</label>
<input type="password" id="password" name="password"><br>
<input type="submit" value="登录">
</form>
<script>
// 前端 JavaScript 代码
function login() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
var data = { username: username, password: password };
// 发送登录请求到后端
fetch('http://yourserver.com/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
// 根据后端返回的数据进行处理
if (data.success) {
//登录成功,跳转到计算器界面
window.location.href = "jsq.html";
} else {
alert("登录失败,用户名或密码错误");
}
})
.catch((error) => {
console.error('Error:', error);
});
}
</script>
</body>
</html>

(2)计算器界面
<!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">
<title>Document</title>
</head>
<style>
#main {
width: 300px;
margin: 100px auto;
}
#main input {
width: 291px;
margin-bottom: 2px;
height: 30px;
outline: none;
}
#main button {
width: 71px;
height: 50px;
font-size: 20px;
cursor: pointer;
}
html {
background: linear-gradient(to right, #ff0052, #0072ff);
height: 100%;
}
</style>
<body>
<div id="main">
<input type="text" name="number" class="operation">
<input type="text" name="number" class="result">
<div id="buttons">
<button onclick="empty()" value="C">C</button>
<button onclick="square()" value="x^2">x^2</button>
<button onclick="sqrt()" value="sqrt">sqrt</button>
<button onclick="insert('/')" value="/">/</button>
<button onclick="insert(7)" value="7">7</button>
<button onclick="insert(8)" value="8">8</button>
<button onclick="insert(9)" value="9">9</button>
<button onclick="insert('*')" value="*">x</button>
<button onclick="insert(4)" value="4">4</button>
<button onclick="insert(5)" value="5">5</button>
<button onclick="insert(6)" value="6">6</button>
<button onclick="insert('-')" value="-">-</button>
<button onclick="insert(1)" value="1">1</button>
<button onclick="insert(2)" value="2">2</button>
<button onclick="insert(3)" value="3">3</button>
<button onclick="insert('+')" value="+">+</button>
<button onclick="back()" value="<"><</button>
<button onclick="insert(0)" value="0">0</button>
<button onclick="insert('.')" value=".">.</button>
<button onclick="result()" value="=">=</button>
</div>
</div>
<script>
// 获取元素
var ope = document.querySelector('.operation'); //运算框
var res = document.querySelector('.result'); //结果框
var btn = document.querySelectorAll('button');
function insert(num) {
ope.value = ope.value + num;
}
function empty() {
ope.value = null;
res.value = null;
}
function back() {
let exp = ope.value;
ope.value = exp.slice(0, exp.length - 1);
}
function result() {
if (ope.value == '') {
alert('请输入计算内容');
} else {
res.value = eval(ope.value);
}
}
function square() {
let squ = ope.value;
res.value = Math.pow(squ, 2);
}
function sqrt() {
let sqr = ope.value;
res.value = Math.sqrt(sqr);
}
</script>
</body>
</html>

3、后端设计
(1)前后端连接
java
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 从请求中获取用户名和密码
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String data = sb.toString();
JSONObject json = new JSONObject(data);
String username = json.getString("username");
String password = json.getString("password");
// 在这里进行用户名和密码的验证,可以是数据库查询等操作
if (username.equals("valid_username") && password.equals("valid_password")) {
// 登录成功
response.setContentType("application/json");
response.getWriter().write("{\"success\": true}");
} else {
// 登录失败
response.setContentType("application/json");
response.getWriter().write("{\"success\": false, \"message\": \"用户名或密码错误\"}");
}
}
}
(2)数据库的连接
package code;
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DBConn {
private Connection conn = null;
private Statement stmt = null;
private ResultSet rs=null;
String username="root";
String password ="123456";
public DBConn (){
try{
Class.forName("com.MySQL.jdbc.Driver");
//conn = DriverManager.getConnection(url,username,password);
}catch(java.lang.ClassNotFoundException e){
System.err.println(e.getMessage());
} //catch (SQLException ex) {
//Logger.getLogger(DBConn.class.getName()).log(Level.SEVERE, null, ex);
// }
}
public int Check(String sql){
// int result = 0;
try{
conn = DriverManager.getConnection( "jdbc:mysql://localhost/salarydb?characterEncoding=utf8",username,password);
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
if(rs.next()){
return 1 ;
}
}catch (SQLException e){
e.printStackTrace();
}
return 0;
}
public ResultSet Search(String sql){ //建立查询
try {
conn = DriverManager.getConnection( "jdbc:mysql://localhost/salarydb?characterEncoding=utf8",username,password);
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
} catch (SQLException ex) {
System.err.println(ex.getMessage());
}
return rs;
}
public int Update(String sql){ //操作数据库
int result = 0;
try {
conn = DriverManager.getConnection( "jdbc:mysql://localhost/salarydb?characterEncoding=utf8",username,password);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
result = stmt.executeUpdate(sql);
} catch (SQLException ex) {
result=0;
}
return result;
}
/**
* 关闭数据库连接
*/
public void close(){
try{
if(rs != null){
rs.close();
}
}catch(Exception e){
e.printStackTrace(System.err);
}
try{
if(stmt != null){
stmt.close();
}
}catch(Exception e){
e.printStackTrace(System.err);
}
try{
if(conn != null){
conn.close();
}
}catch(Exception e){
e.printStackTrace(System.err);
}
}
}
2、计算器使用的数据记录
(1)在计算器界面设计的基础上
<!-- 增加一个按钮来保存历史记录 -->
<button onclick="saveHistory()" value="Save">保存历史</button>
<script>
// 先定义一个全局数组来保存历史记录
var history = [];
// 保存历史记录的函数
function saveHistory() {
var expression = ope.value;
var result = res.value;
history.push({ expression: expression, result: result });
// 可以选择性地将历史记录显示在界面上
// 创建一个历史记录列表,将数据显示在页面上
// 然后发送历史记录到后端保存
sendHistoryToBackend(history);
}
// 向后端发送历史记录的函数
function sendHistoryToBackend(history) {
fetch('http://yourserver.com/save-history', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ history: history }),
})
.then(response => response.json())
.then(data => {
console.log('History saved:', data);
})
.catch((error) => {
console.error('Error:', error);
});
}
</script>

(2)后端处理
// 添加一个新的Servlet用于保存历史记录
public class SaveHistoryServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 从请求中获取历史记录
BufferedReader reader = request.getReader();
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String data = sb.toString();
JSONObject json = new JSONObject(data);
JSONArray history = json.getJSONArray("history");
// 可以将历史记录插入到数据库中
saveHistoryToDatabase(history);
// 发送成功响应
response.setContentType("application/json");
response.getWriter().write("{\"status\": \"success\"}");
}
private void saveHistoryToDatabase(JSONArray history) {
// 将历史记录插入到数据库中的逻辑
}
}
三、测试阶段
(一)登录界面测试
1、使用正确账号密码登录

2、使用错误账号密码登录

3、计算器的测试
(1)加法

(2)减法
(3)乘法

(4)除法
(5)开平方

(6)平方

对上述6组测试均进行了保存记录

四、实验分析
本次实验设计用户可登录的计算器,计算器的使用记录保存在数据库中,其中涉及到前后端的开发,UI界面设计,在前后端的衔接以及连接数据库需要进行一定的细化,
学生登录界面实现前后端的衔接,引用数据库,查询数据库,登录成功进行界面的跳转;登录失败,则显示错误,将对计算器的操作存入数据库中,也需要前后端的衔接。
对于数据库的引入、界面的跳转、前后端的搭建,是本次实验难以操作以及容易出错的点,需要细心以及一定的知识储备。

浙公网安备 33010602011771号