JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库) 饭前点心: 前置知识: 三层架构流程(通过增加用户举例): Code: 客官勿踩坑: 客官请看: 客官留步:

该程序采用三层架构的模式实现对用户信息的增删改查,功能尚未完善,不过实现基本的要求应该是没问题的。
采用的数据库是 Mysql.

前置知识:

三层架构

三层架构流程(通过增加用户举例):

JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
饭前点心:
前置知识:
三层架构流程(通过增加用户举例):
Code:
客官勿踩坑:
客官请看:
客官留步:

Code:

表示层前台:

index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import = "java.util.List" %>
<%@ page import = "org.entity.Student" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
		<% 
			// 增加 一个标记,用作提示是否增加成功
			String error = (String)request.getAttribute("error");
			if(error != null ) {
				if(error.equals("addError")){
					out.print("增加失败");
				} else if(error.equals("successAdd")){
					out.print("增加成功");
				}
			}
		%>
		<!-- 表格布局实现显示用户的各个信息 -->
		<table border = "1">
			<tr>
				<th>学号</th>
				<th>姓名</th>
				<th>年龄</th>
				<th>性别</th>
				<th>地址</th>
				<th>操作</th>
			</tr>
		<!-- 因为用户是动态的,所以我们选择用循环进行动态添加 -->
				<% 
					// 后台通过 request 进行请求转发将所有用户传输到前台,通过 getAttribute(),setAttribute()可以添加请求中的信息
					List<Student> students = (List<Student>)request.getAttribute("students");
					
					for(Student student:students) {
				%>	 
					<tr>
						<!-- 将学号设置成一个超链接,点击即可实现查看用户的详细信息 -->
						<td> <a href = "QueryStudentStudent?sno=<%=student.getSno() %>"><%=student.getSno() %></a>  </td>
						<td> <%=student.getName()%></td>
						<td> <%=student.getAge() %></td>
						<td> <%=student.getSex() %></td>
						<td> <%=student.getSad() %></td>
						<td> <a href = "DeleteStudentServlet?sno=<%=student.getSno()%>">删除 </a></td>
					</tr>
				 <% 
				 	}
					
				 %>
			
		</table>
		<!-- 超链接到 add.jsp 进行 增加用户 -->
		<a href = "add.jsp">注册</a>
</body>
</html>

studentInfo.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "org.entity.Student" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
		<%
			// 获取从后台传过来的数据域(根据 Key 取 Value)
			Student student = (Student)request.getAttribute("student");
		
		%>
		
		<form action="UpdateStudentServlet">
			<!-- Value 用来显示文本框中的内容,通过request传过来的数据域,我们可以显示用户的信息 -->
			学号:<input type = "text" name = "sno" value = <%=student.getSno() %>>       <br>
			姓名:<input type = "text" name = "sname" value = <%=student.getName() %>>		<br>
			年龄:<input type = "text" name = "sage" value = <%=student.getAge() %>>		<br>
			性别:<input type = "text" name = "ssex" value = <%=student.getSex() %>>		<br>
			地址:<input type = "text" name = "sad" value = <%=student.getSad() %>>		<br>
			
			<input type = "submit" value = "修改">
			<!-- 返回当然要先查询信息,即更新信息再返回,我们在 QueryAllStudentServlet中就会跳转到首页 -->
			<a href = "QueryAllStudentServlet">返回</a>
		</form>
		
</body>
</html>

add.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
		<!-- 跳转到Servlet 实现用户的增加 -->
		<form action="AddStudentServlet" method = "post">
			学号: <input type = "text" name = "sno"> <br/>
			姓名: <input type = "text" name = "sname"> <br/>
			年龄: <input type = "text" name = "sage"> <br/>
			性别: <input type = "text" name = "ssex"> <br/>
			地址: <input type = "text" name = "sad"> <br/>
			
			<input type = "submit" value = "注册">

		</form>
</body>
</html>

表示层后台(一个Servlet 对应一个功能):

AddStudentServlet.java:

package org.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.entity.Student;
import org.service.StudentService;

@WebServlet("/AddStudentServlet")
public class AddStudentServlet extends HttpServlet {
	
	/*
	 *  增加用户
	 * 用户在前台输入信息,在Servlet中将用户信息封装成一个实体类
	 * 通过Service(业务逻辑层)将用户信息添加到数据库
	 *
	 * */
	
	
	private static final long serialVersionUID = 1L;
       
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 一定要设置成统一的编码
		request.setCharacterEncoding("utf-8");
		
		int sno = Integer.parseInt(request.getParameter("sno"));
		String sname = request.getParameter("sname");
		int age = Integer.parseInt(request.getParameter("sage"));
		String sex = request.getParameter("ssex");
		String address = request.getParameter("sad");
		// 将用户信息封装成一个实体类,便于传递
		Student student = new Student(sno,sname,age,sex,address);
		// new 一个 StudentService 对象(业务逻辑层)
		StudentService studentService = new StudentService();
		// 调用方法实现增加用户的信息(在业务逻辑层实现逻辑,具体功能在 Dao 层实现)
		boolean result = studentService.addStudent(student);
		// 响应时编码问题进行统一
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		
		
		if(!result) {
			request.setAttribute("error", "addError");
		} else {
			request.setAttribute("error", "successAdd");
		}
		// 无论增加成功与失败都要将结果返回到前台,通过请求转发的形式,不会丢失数据
		request.getRequestDispatcher("QueryAllStudentServlet").forward(request, response);
		
	}
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		doGet(request, response);
	}

}

DeleteStudentServlet.java

package org.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.service.StudentService;

@WebServlet("/DeleteStudentServlet")
public class DeleteStudentServlet extends HttpServlet {
	
	/*
	 * 功能: 根据学号删除某个学生
	 * 
	 * */
	
	private static final long serialVersionUID = 1L;
       
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		request.setCharacterEncoding("utf-8");
		int sno = Integer.parseInt(request.getParameter("sno"));
		
		StudentService studentService = new StudentService();
		// 设置响应时编码
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		boolean result = studentService.deleteStudent(sno);
		if(result) {
			response.getWriter().println("删除成功");
			response.sendRedirect("QueryAllStudentServlet");
		} else {
			response.getWriter().println("删除失败");
		}
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

QueryAllStudentServlet:

package org.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.entity.Student;
import org.service.StudentService;


@WebServlet("/QueryAllStudentServlet")
public class QueryAllStudentServlet extends HttpServlet {
	
	/*
	 * 功能:查询所有用户信息
	 *     所有用户肯定要用一个 List集合来存储
	 * 
	 * */
	
	private static final long serialVersionUID = 1L;
       
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		request.setCharacterEncoding("utf-8");
		StudentService studentService = new StudentService();
		
		List<Student> students = studentService.queryAllStudents();
		
		System.out.println(students);
		// 将数据内容存在数据域中
		request.setAttribute("students", students);
		// 将数据内容通过跳转的方式传输到 index.jsp
		request.getRequestDispatcher("index.jsp").forward(request, response);
		
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

QueryStudentStudent.java

package org.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.entity.Student;
import org.service.StudentService;


@WebServlet("/QueryStudentStudent")
public class QueryStudentStudent extends HttpServlet {
	
	/*
	 * 功能: 根据学号查询用户信息
	 * 
	 * */
	
	private static final long serialVersionUID = 1L;
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		int no = Integer.parseInt(request.getParameter("sno"));
		
		StudentService studentService = new StudentService();
		
		Student student = studentService.queryStudentBySno(no);
		
		System.out.println(student);
		
		// 将用户的信息通过 request 进行请求转发的方式跳转到另一个页面
		// 通过 setAttribute()方法增加请求信息,另一个页面通过前面的 key("student") 取到后面的 value
		request.setAttribute("student",student);
		
		request.getRequestDispatcher("studentInfo.jsp").forward(request, response);
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

UpdateStudentServlet.java

package org.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.entity.Student;
import org.service.StudentService;


@WebServlet("/UpdateStudentServlet")
public class UpdateStudentServlet extends HttpServlet {
	
	/*
	 * 功能: 根据用户的学号更新用户的其他信息
	 * 
	 * */
	
	private static final long serialVersionUID = 1L;
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		int sno = Integer.parseInt(request.getParameter("sno"));

		String name = request.getParameter("sname");
		int age = Integer.parseInt(request.getParameter("sage"));
		String sex = request.getParameter("ssex");
		String sad = request.getParameter("sad");
		// 将要修改的内容封装到一个实体类中
		Student student = new Student(sno,name,age,sex,sad);
		
		StudentService studentService = new StudentService();
		
		// 设置响应时编码
		response.setContentType("text/html; charset=UTF-8");
		response.setCharacterEncoding("utf-8");
		
		boolean result = studentService.updateStudent(sno, student);
		if(result) {
			response.getWriter().println("修改成功");
			// 修改成功后返回到所有用户的界面
			response.sendRedirect("QueryAllStudentServlet");
			
		} else {
			response.getWriter().println("修改失败");
		}
		
	}

	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

业务逻辑层(Service):

StudentService.java

package org.service;

import java.util.List;

// 业务逻辑层

import org.dao.StudentDao;
import org.entity.Student;

/* 
 * 业务逻辑层:组合各种信息,返回给 Servlet
 * 	实现功能:
 * 		1、增加用户(增加用户之前需要先判断用户是否已经存在)
 * 		2、删除用户(删除用户之前需要先判断用户是否已经存在)
 * 		3、更新用户(更新用户之前需要先判断用户是否已经存在)
 * 		4、根据用户号查询用户信息
 * 		5、查询所有用户信息
 * 	具体来说,每一个功能都对应一个 Servlet。
 * */

public class StudentService {
	// 所有的具体功能都通过 StudentDao 进行实现
	StudentDao stu = new StudentDao();
	// 根据用户号查询用户信息
	public Student queryStudentBySno(int sno) {
		return stu.queryStudentBySno(sno);
	}
	// 查询所有用户信息
	public List<Student> queryAllStudents() {
		return stu.queryAllStudents();
	}
	// 更新用户(更新用户之前需要先判断用户是否已经存在)
	public boolean updateStudent(int sno,Student student) {
		if(stu.isExist(sno)) {
			return stu.updateStudentBySno(sno, student);
		}
		return false;
	}
	// 删除用户(删除用户之前需要先判断用户是否已经存在)
	public boolean deleteStudent(int sno) {
		if(stu.isExist(sno)) {
			return stu.deleteStudentBySno(sno);
		}
		return false;
	}
	// 增加用户(增加用户之前需要先判断用户是否已经存在)
	public boolean addStudent(Student student) {
		
		// 不存在时返回 true, 存在时返回false
		if(!stu.isExist(student.getSno())) {
			stu.addStudent(student);
			return true;
		} else {
			return false;
		}
		
	}

}

数据访问(Dao 层):

package org.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.entity.Student;

public class StudentDao {
	private static final String URL = "jdbc:mysql://localhost:3306/sqltest";
	private static final String User = "root";
	private static final String Password = "root";
	
	// 判断该用户是否存在
	public boolean isExist(int sno) {
		// 查询该学生的学号是否存在,存在就返回true,不存在则返回 false
		return queryStudentBySno(sno) == null ? false : true; 
	}
	
	// 添加新用户
	public boolean addStudent(Student student) {
		Connection conn = null;
		PreparedStatement pstam = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			
			conn = DriverManager.getConnection(URL,User,Password);
			
			String sql = "insert into student values (?,?,?,?,?)";
			
			pstam = conn.prepareStatement(sql);
			
			pstam.setInt(1, student.getSno());
			pstam.setString(2, student.getName());
			pstam.setInt(3, student.getAge());
			pstam.setString(4,student.getSex());
			pstam.setString(5, student.getSad());
			
			int result = pstam.executeUpdate();
			
			if(result > 0) return true;
			else return false;
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(pstam != null )
				try {
					pstam.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(conn != null )
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return false;
	}
	
	// 根据学生学号修改学生信息
	public boolean updateStudentBySno(int sno,Student student) {
		Connection conn = null;
		PreparedStatement pstam = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			
			conn = DriverManager.getConnection(URL,User,Password);
			
			String sql = "update student set sname = ?,sage = ?,ssex = ?,sad = ? where sno = ?";
			
			pstam = conn.prepareStatement(sql);
			
			pstam.setString(1, student.getName());
			pstam.setInt(2, student.getAge());
			pstam.setString(3,student.getSex());
			pstam.setString(4,student.getSad());
			
			pstam.setInt(5, sno);
			
			int result = pstam.executeUpdate();
			
			if(result > 0) return true;
			else return false;
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(pstam != null )
				try {
					pstam.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(conn != null )
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return false;
	}
	
	// 删除用户
	public boolean deleteStudentBySno(int sno) {
		Connection conn = null;
		PreparedStatement pstam = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			
			conn = DriverManager.getConnection(URL,User,Password);
			
			String sql = "delete from student where sno = ?";
			
			pstam = conn.prepareStatement(sql);
			
			pstam.setInt(1, sno);
			
			
			int result = pstam.executeUpdate();
			
			if(result > 0) return true;
			else return false;
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			if(pstam != null )
				try {
					pstam.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(conn != null )
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
		}
	}
	
	// 查询所有用户
	public List<Student> queryAllStudents() {
		Connection conn = null;
		PreparedStatement pstam = null;
		ResultSet rs = null;
		
		List<Student> students = new ArrayList<>();
		Student student = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			
			conn = DriverManager.getConnection(URL,User,Password);
			
			String sql = "select * from student";
			
			pstam = conn.prepareStatement(sql);
			
			rs = pstam.executeQuery();
			
			while(rs.next()) {
				int no = rs.getInt("sno");
				String name = rs.getString("sname");
				int age = rs.getInt("sage");
				String sex = rs.getString("ssex");
				String sad = rs.getString("sad");
				// 将每个用户的信息封装成一个实体类,便于传递
				student = new Student(no,name,age,sex,sad);
				// 将每个用户添加到集合中进行返回
				students.add(student);
			}
			return students;
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null )
				try {
					rs.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(pstam != null )
				try {
					pstam.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(conn != null )
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return null;
	}
	
	// 通过学号查询学生信息(返回值是一个学生,如果学生不存在返回 Null)
	public Student queryStudentBySno(int sno) {
		
		Connection conn = null;
		PreparedStatement pstam = null;
		ResultSet rs = null;
		
		Student student = null;
		
		try {
			Class.forName("com.mysql.jdbc.Driver");
			
			conn = DriverManager.getConnection(URL,User,Password);
			
			String sql = "select * from student where sno = ?";
			
			pstam = conn.prepareStatement(sql);
			
			pstam.setInt(1, sno);
			
			rs = pstam.executeQuery();
			
			if(rs.next()) {
				int no = rs.getInt("sno");
				String name = rs.getString("sname");
				int age = rs.getInt("sage");
				String sex = rs.getString("ssex");
				String sad = rs.getString("sad");
				
				student = new Student(no,name,age,sex,sad);
				return student;

			} else {
				return null;
			}
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null )
				try {
					rs.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(pstam != null )
				try {
					pstam.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			if(conn != null )
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return null;
	}
}

实体类(用户封装用户信息):

package org.entity;

public class Student {
	
	/* 实体类:对应 数据库中的一张表
	 * 
	 * */
	
	
	private int sno;
	private String name;
	private int age;
	private String sex;
	private String sad;
	
	
	// 无参的构造
	public Student() {
		
	}
	
	public Student(int sno, String name, int age, String sex, String sad) {
		this.sno = sno;
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.sad = sad;
	}
	public int getSno() {
		return sno;
	}
	public void setSno(int sno) {
		this.sno = sno;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getSad() {
		return sad;
	}

	public void setSad(String sad) {
		this.sad = sad;
	}

	@Override
	public String toString() {
		return "Student [sno=" + sno + ", name=" + name + ", age=" + age + ", sex=" + sex + ", sad=" + sad + "]";
	}
	
	
	
}

客官勿踩坑:

运行改代码时首先访问的页面应该是  QueryAllStudent.java ,因为本系统首先映入眼帘的是各个用户的信息。
不过不用担心,QueryAllStudent.java 中会以请求转发的方式跳转到首页。
您也可以在 web.xml 中 将 QueryAllStudent 设置为第一个即可。

客官请看:

index:

JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
饭前点心:
前置知识:
三层架构流程(通过增加用户举例):
Code:
客官勿踩坑:
客官请看:
客官留步:

studentinfo:

JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
饭前点心:
前置知识:
三层架构流程(通过增加用户举例):
Code:
客官勿踩坑:
客官请看:
客官留步:

delete:

JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
饭前点心:
前置知识:
三层架构流程(通过增加用户举例):
Code:
客官勿踩坑:
客官请看:
客官留步:

update:

JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
饭前点心:
前置知识:
三层架构流程(通过增加用户举例):
Code:
客官勿踩坑:
客官请看:
客官留步:

add:

JavaWeb学习(16): 三层架构模式实现简单的学生管理系统(内含数据库)
饭前点心:
前置知识:
三层架构流程(通过增加用户举例):
Code:
客官勿踩坑:
客官请看:
客官留步:

客官留步:

本人深知,该系统还有很多的 Bug 及不足,如需要源代码及文件包,请私信我。
客官有任何问题可以在下方留言,共同学习交流,交个朋友。
感谢您的光顾。