提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
一、项目演示和源码
二、设计目的
2.1项目背景
2.2项目目标
三、需求分析
3.1功能需求
3.2安全性需求
3.3可靠性需求
四、概要设计
4.1登陆注册子系统
编辑4.2会员信息管理子系统
4.3详细的项目包图
五、开发环境
六、数据库设计
6.1数据库表的设计
6.2连接数据库
七、效果展示 与部分核心代码
7.1普通用户部分
7.2管理员部分
八、特殊功能
8.1图片验证码
8.2QQ邮箱验证码
九、总结
1.1项目演示地址:会员管理系统
1.2源码地址:
随着科学的飞速发展,Internet这个昔日只被少数科学家接触和使用的科研工具已经发展成了普通百姓都可触及的大众型媒体传输手段。随着用户的急剧增加,Internet的应用迅速进入到文化、产业、经济、政治、新闻、体育、娱乐、商业和服务业。各个行业都普及了Internet的应用,会员管理系统是Internet的一个重要应用领域,会员管理系统的开发,适合各大小商铺、理发店、娱乐场所的管理。
大量的大学理发店都没有自己的系统,会员的登记、理发预约、身份信息的更改等服务完全依靠管理人员操作,这样并不利于美发行业的发展和大大降低了工作人员的效率。因此,一个健全的管理系统是十分必要的,管理人员、会员、游客可以根据自己的权限,来自主完成的操作,提高工作效率。
本系统利用网络沟通、计算机信息存储管理,有着与传统的方式所无法替代的优点。比如计算检索速度特别快、可靠性特别高、存储容量特别大、保密性特别好、可保存时间特别长、开发成本低等。在工作效率上,能够得到极大地提高,延伸至服务水平也会有好的收获,有了网络,校园理发会员管理系统的各方面的管理更加科学和系统,更加规范和简便。
在学习的过程中,了解MVC的开发模式和开发环境,掌握前端、后端、数据库设计的知识,了解动态网页的开发过程,以及对书本上的知识加深印象,锻炼团队的合作与交流。完成项目的可行性分析、需求分析、框架设计、功能设计、界面设计等,再进行代码实现,完成项目实验的要求,最后,实验总结收获。
随着科学的飞速发展,Internet这个昔日只被少数科学家接触和使用的科研工具已经发展成了普通百姓都可触及的大众型媒体传输手段。随着用户的急剧增加,Internet的应用迅速进入到文化、产业、经济、政治、新闻、体育、娱乐、商业和服务业。各个行业都普及了Internet的应用,会员管理系统是Internet的一个重要应用领域。通过Internet这一电子媒介,向人们展示了一种全新的、有别于传统的会员管理模式。会员管理系统的开发,适合各大小商铺、理发店、娱乐场所的管理。
(1)增添会员信息录入功能需求。可录入用户的基本信息以及店铺消费记录,包含用户姓名(可匿名),联系方式,年龄,住址,会员等级,会员卡号,账户积分,账务余额,账户状态。
(2)删除会员信息功能需求可对已录入用户的信息进行各种删除操作,包含单个信息的单独删除以及全部信息的删除。
(3)修改会员信息功能需求可对已录入用户的信息进行修改,除系统固定值外,其他数值均可进行修改。
(4)查询会员信息功能需求可对已录入用户的信息进行查询,查询方式为输入用户名,商家客户在完成注册登录后,可在网页中查看个人信息资料、包含会员信息。
(1)用户名唯一,手机号码唯一,邮箱唯一
(2)用户名可用中文、大小写字母数组组成(3-16位)密码可有数字和字母组成(6-16位)
(3)不登陆无法查看个人信息,也无法查看会员信息
(4)代码数据、表单提交、url链接请求,AXAJ异步请求均采用POST请求方式
(5)本会员系统采用完备的密码管理系统,同时该系统的数据库管理系统实现了数据的保存和更新
(1)对已录入和修改的客户信息实现实时保存
(2)客户信息管理系统实时更新(在完成增添、删除、修改等功能后)
(3)本会员管理系统的目标系统功能基本齐全,能够完全满足校理发店的业务需求。理论上本系统能在大部分操作系统中正常运行,而各个模块接口能够保证完好。
会员管理系统的用例图:
动态模型:
登录注册子系统的用例图。
会员信息:
登录信息:
会员信息管理子系统的用例图:
前端:html、css、javascript、jquery;
后端:Java、MySQL 8.0.31、JDK 1.8、Navicat 15
接口:JDBC
服务器:Tocmat 9.0
项目管理:Maven
开发工具:eslipse--EE
max_user.db(管理员信息)
属性 |
名称 |
数据类型 |
约束条件 |
name |
用户名 |
Varchar(20) |
主键、非空 |
password |
登入密码 |
Varchar(20) |
|
eamil |
邮箱 |
Varchar(20) |
|
phonenumber |
手机号码 |
Varchar(11) |
users.db(用户信息)
属性 |
名称 |
数据类型 |
约束条件 |
id |
序号 |
int |
主键、非空、自增 |
username |
用户名 |
Varchar(20) |
非空 |
password |
登入密码 |
Varchar(20) |
|
age |
年龄 |
Varchar(5) |
|
sex |
性别 |
Varchar(5) |
|
phonenumber |
手机号码 |
Varchar(20) |
|
|
邮箱 |
Varchar(20) |
|
address |
地址 |
Varchar(50) |
|
creat_time |
创建时间 |
Varchar(30) |
|
id_number |
会员卡号 |
Varchar(15) |
|
member_class |
会员等级 |
Varchar(10) |
|
integral |
积分 |
Int |
|
balance |
余额 |
Double(10,2) |
|
status |
状态 |
Varchar(10) |
|
modif_time |
修改时间 |
Datetime |
|
login_time |
登入时间 |
Varchar(30) |
若采用三层架构的模式,JDBCUtil.java连接数据库,还需要建DAO.java,User.java,还有jsp,最后加一个servlet,再调用每一个类的方法。
JDBCUtil.java的代码:
public class JDBCUtil {
// 数据库的参数
private String dbUrl="jdbc:mysql://localhost:3306/my_login?useSSL=false";
private String dbUsername="root";
private String dbPassword="123456";
// 与数据库连接
public Connection getConn() {
try {
// 加载驱动
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
Connection conn = null;
try {
// 获得连接,返回connection 对象
conn = DriverManager.getConnection(dbUrl, dbUsername, dbPassword);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
(1)登入界面
邮箱登录:(具体的操作在最后的特色功能中展示)
报错提示:
login.jsp(部分代码样式)
/*******************************************/
var user_template = `
`
var phone_template = `
/*******************************************/
这里的获取验证码按钮需要用的AJAX请求。写在js/login.js中。
// 创建XMLHttpRequest
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
// 请求已经完成,信息已经成功返回,开始处理信息
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
// 将从服务器端返回是JSON格式数据转换成JavaScript对象
var res = xhr.responseText
var jsonObj = eval("("+res+")")
console.log("res:"+res)
if(jsonObj.type == 0) {
alert(jsonObj.error);
} else {
alert("邮箱发送成功,请查阅邮箱,尽快认证")
}
} else {
alert("邮箱发送失败")
}
}
}
xhr.open('POST','/T3/EmailServlet',true)
// 设置HTTP的输出内容类型为json格式数据:application/x-www-form-urlencoded
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 设置浏览器不使用缓存,服务器不从缓存中找,重新执行代码,而且服务器返回给浏览器的时候,告诉浏览器也不要保存缓存。
xhr.setRequestHeader('If-Modified-Since', '0')
// 发送请求
xhr.send("email="+email);
}/************************判断邮箱合法的else*/
/*******************************************/
LoginServlet.java(部分代码)
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 账号密码登录的方式
if(username != null && password != null) {/************如果这两个都为空,说明选择了邮箱登入********/
//解决中文字符乱码
byte[] bytes = username.getBytes("ISO-8859-1");
username = new String(bytes,"utf-8");
System.out.println(username);
JDBCUtil db = new JDBCUtil();
// 创建一个用户保存下将密码和用户名保存
User user = new User(username,password,email,login_time);
DAO dao = new DAO();
YanZheng yz=new YanZheng();
try {
//数据库连接
Connection conn = db.getConn();
if(dao.JudgeUser(conn, user)==false)//判断用户名是否存在
{
out.println("该用户不存在,请先去注册!
或者用户名错误,请重新输入!
");
out.println("3秒以后返回登入界面页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");
}
else if(dao.login(conn, user) != null) {
request.getSession().setAttribute("member_user", user.getUsername());//用来查询信息,用户打印用户信息
dao.ModifLogin_time1(conn, user);//修改登入时间
response.sendRedirect("jsp/member_index.jsp");
} else {
out.println("用户名或者密码错误,验证失败
");
out.println("3秒以后跳转回登录页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");
}
/********************邮箱登入验证********************/
else if(email != null && code != null) { //邮箱验证码方式*********少了验证QQ邮箱注册,否则没注册的也能登入*********
JDBCUtil db = new JDBCUtil();
User user = new User(username,password,email,login_time);
DAO dao = new DAO();
YanZheng yz=new YanZheng();
//数据库连接
try {
Connection conn = db.getConn();
// 判断emailCode是否正确
String s_emailCode = (String)request.getSession().getAttribute("emailCode");//调用存在服务器中的密码EmailServlet.java中
JsonResult jr = new JsonResult();
if(dao.JudgeEmail(conn, user)==false)
{
out.println("该邮箱不存在!或者输入的邮箱错误,请重新输入!
");
out.println("3秒以后返回注册页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");
}
else if(!code.equalsIgnoreCase(s_emailCode)) {//接收表单的验证码和服务器上的验证码比对
out.println("邮件验证码错误,验证失败
");
out.println("3秒以后跳转回登录页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");//AJAX跳转方式
} else { // 验证成功
request.getSession().setAttribute("member_user", user.getEmail());//用来查询信息,Member_index_ShowServlet.java用户打印用户信息
dao.ModifLogin_time2(conn, user);//修改登入时间
response.sendRedirect("jsp/member_index.jsp");}
/*********************************/
(2)用户注册界面
RegisterServlet.java(部分代码)
try {
//数据库连接
Connection conn = db.getConn();
if(yz.Username(username)==false)
{
out.println("输入的用户名不符合!
");
out.println("3秒以后返回注册页面
");
response.setHeader("Refresh", "3;url=jsp/register.jsp");
}
else {
if(dao.register(conn, user)==true) {//DAO.java中的函数,写入数据库
out.println("注册新用户成功
");
out.println("3秒以后跳转回登入页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");
}
(3)用户找回密码
HandlepwdServlet.java(部分代码)
try {
//数据库连接
Connection conn = db.getConn();
// 数据库中没有该用户
if(dao.JudgeUser(conn, user)==false)//判断用户名是否存在
{
out.println("该用户不存在,请先去注册
");
out.println("3秒以后返回修改密码页面
");
response.setHeader("Refresh", "3;url=jsp/find_password.jsp");
}
/*************************************************/
else if(email != null && code != null) { //判断输入的验证码和生成的是否相同
// 判断emailCode是否正确
String s_emailCode = (String)request.getSession().getAttribute("emailCode");//调用存在服务器中的密码EmailServlet.java中
JsonResult jr = new JsonResult();
if(!code.equalsIgnoreCase(s_emailCode)) {//接收表单的验证码和服务器上的验证码比对
out.println("邮件验证码错误,验证失败
");
out.println("3秒以后跳转回登录页面
");
response.setHeader("Refresh", "3;url=jsp/find_password.jsp");//AJAX跳转方式
}
else {
if(dao.ModifPassword(conn, user)==true) {
out.println("修改密码成功
");
out.println("3秒以后跳转回登录页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");
}
(4)用户注销
DeleteServlet.java(部分代码)
try {
//数据库连接
Connection conn = db.getConn();
if(yz.Username(username)==false)
{
out.println("输入的用户名不符合!
");
out.println("3秒以后返回注册页面
");
response.setHeader("Refresh", "3;url=jsp/register.jsp");
}
else {
if(dao.DeleteUser(conn, user)==true) {//DAO.java中的函数,写入数据库
out.println("注销用户成功
");
out.println("3秒以后跳转回登入页面
");
response.setHeader("Refresh", "3;url=jsp/login.jsp");
} else {//****************************后期需要改进,需要判断用户名是否存在;
out.println("密码错误,请重新输入!
");
out.println("3秒以后跳转回注销页面
");
response.setHeader("Refresh", "3;url=jsp/deleteuser.jsp");
}
}
(5)个人系统界面
(1)登录界面
Max_login_Servlet.java(部分代码)
try {
//数据库连接
Connection conn = db.getConn();
if(dao.JudgeUser(conn, user)==false)//判断用户名是否存在
{
out.println("该用户不存在!
或者用户名错误,请重新输入!
");
out.println("3秒以后返回登入界面页面
");
response.setHeader("Refresh", "3;url=jsp/Max_Login.jsp");
}
else if(dao.login(conn, user) == null) {//判断用户名和密码是否对的上
out.println("用户名或者密码错误,验证失败
");
out.println("3秒以后跳转回登录页面
");
response.setHeader("Refresh", "3;url=jsp/Max_Login.jsp");
}
else {
//request.getSession().setAttribute("user", user);
request.getSession().setAttribute("max_user", user.getUsername());//用来管理员登入了,直接查看网页看不到,ShowServlet.java在打印
response.sendRedirect("jsp/index.jsp");
}
(2)找回密码界面
// 修改密码验证,并修改密码
public boolean ModifPassword(Connection conn,User user) throws Exception {
boolean flag = false;
// sql 查询语句
String sql="update Max_user set password=? where name=?";
// 获得执行sql语句的对象
PreparedStatement pstatement =conn.prepareStatement(sql);
pstatement.setString(1, user.getAgain_password());
pstatement.setString(2, user.getUsername());
// 执行sql语句获得结果集
int res = pstatement.executeUpdate();
if(res > 0) {
flag = true;//则修改密码成功
}
return flag;
}
(3)管理系统界面
ShowServlet.java(部分代码)
//数据库连接
Connection conn = db.getConn();
/*******************************************/
if(dao.JudgeUser(conn, user)==true)//判断管理员是否登入。
{
Statement stmt=conn.createStatement();
String sql="select*from users";
ResultSet rs=stmt.executeQuery(sql);
ArrayList list=new ArrayList();
while(rs.next())
{
User info=new User();
info.setId(rs.getString("id"));
info.setUsersname(rs.getString("username"));
。。。。。。
info.setLogin_time(rs.getString("login_time"));//登入时间
list.add(info);
}
HttpSession session = request.getSession();
session.setAttribute("list",list);
/*******************************************/
(4)添加用户
(5)修改某一个用户的信息
(6)删除用户
Validate.jsp
<%
response.setContentType("image/jpeg;charsert=utf-8");//关键,防止图片变成乱码
response.setHeader("Cache-Control","no-cache");
//在内存中创建图像
int width=60,height=20;
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//获取笔画
Graphics g=image.getGraphics();
//设置背景
g.setColor(new Color(200,200,200));
g.fillRect(0, 0, width, height);
//随机产生的验证码(4位数)
Random rnd=new Random();
int randNum=rnd.nextInt(8999)+1000;
String randStr=String.valueOf(randNum);
//将验证码存入session
session.setAttribute("randStr",randStr);
//将验证码显示到图像中
g.setColor(Color.black);
g.setFont(new Font(" ",Font.PLAIN,20));
g.drawString(randStr, 10, 17);
//随机产生100个干扰点,是图像中的验证码不易被其他程序探测到
for(int i=0;i<100;i++)
{
int x=rnd.nextInt(width);
int y=rnd.nextInt(height);
g.drawOval(x, y, 1, 1);
}
//输出到图像页面
ImageIO.write(image,"JPEG",response.getOutputStream());
out.clear();
out=pageContext.pushBody();
%>