管理信息系统 课程设计
1、系统概要说明
1.1 系统分析
开发一个系统,首先要进行系统分析。其主要任务是确定系统的规模和范围,确定软件的总体要求以及所需要的硬件环境和支撑软件平台、确定待开发软件与外界的接口,根据用户的情况确定软件对操作系统的要求,以及待开发软件总体上的约束和限制。系统分析有助于弄清所需开发的软件、硬件环境、支撑软件和操作人员的要求。
1. Mysql 简介
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件。
MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。
MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。
由于其社区版的性能卓越,搭配 PHP 和 Apache 可组成良好的开发环境。2、 Java Server Page 简介
Java Server Page或简称为JSP是由Sun公司在Java语言上开发出来的一种动态网页制作技术,它提供了一种建立动态网页的简单方法,并为开发人员提供了一个Server端框架,基于这个框架,开发人员可以综合使用 HTML,XML,JAVA语言以及其他脚本语言,灵活,快速地创建和维护动态网页,特别是目前的商业系统。作为JavaTM 技术的一部分,JSP能够快速的开发出基于所有Web服务器和应用服务器环境,独立于平台的应用程序,而且具有非常强的可伸缩性。
1.2 开发环境
操作系统 Windows 10 64位 ( DirectX 12 )
处理器 英特尔 Core i5-6300HQ @ 2.30GHz 四核
内存 8 GB
硬盘 东芝 MQ01ABD100 ( 1 TB / 5400 转/分 )
显卡 Nvidia GeForce GTX 1060 ( 3 GB / 华硕 )
1.3 系统需求分析
本大学生就业信息管理系统主要包含一下几个子系统:用户管理;信息管理。
(1)用户类别:用户主要可分为两种:一是访客,二是会员。
(2)权限管理:用户在不登录的情况下可以查看文章并使用热门文章的功能,但是当未登录的用户需要评论或者收藏等功能时就自动跳转到登录界面,要经过登录的用户才能进行操作。
(3)用户管理:会员能在个人中心进行上传头像,修改密码等操作。
(4)信息发布:会员能够发布系统消息。
2、模块详细设计
1.注册模块
功能:提醒用户进行注册并将用户输入的用户名,密码等关键信息存入数据库中,等待进行登录验证。
主要代码:
<div class="login">
<form action="{{ url_for('zhuce') }}" method="post">
<div class="log-input">
<div class="log-input-left">
账号:<input type="text" class="user" name="user" id="user" placeholder="请输入用户名">
</div>
<div class="clear"></div>
</div>
<div class="log-input">
<div class="log-input-left">
昵称:<input type="text" class="user" name="nickname" id="nickname" placeholder="请输入昵称">
</div>
<div class="clear"></div>
</div>
<div class="log-input">
<div class="log-input-left">
密码:<input type="password" class="lock" name="pass" id="pass" placeholder="请输入密码">
</div>
<div class="clear"></div>
</div>
<div class="log-input">
<div class="log-input-left">
密码:<input type="password" class="lock" name="again" id="again" placeholder="再次输入密码">
</div>
<div class="clear"></div>
</div>
2.登录模块
功能:对数据库中的user进行校验,用户要登录本系统需要提供用户名和密码,在这里就是要检验用户是否满足输入的要求,即检验用户名和密码文本框是否为空,若为空,则提示用户输入用户名和密码。检验用户名是否存在或密码是否正确,即是否存在用户输入的用户名,并且密码是否正确。
主要代码:
<div class="login">
<form action="{{ url_for('denglu') }}" method="post">
<div class="log-input">
<div class="log-input-left">
账号:<input type="text" class="user" name="user" id="user" placeholder="请输入用户名">
</div>
</div>
<div class="log-input">
<div class="log-input-left">
密码:<input type="password" class="lock" name="pass" id="pass" placeholder="请输入密码">
</div>
</div>
<div id="error_box"><br></div>
<div class="log-input">
<div class="log-input-left">
<input type="submit" value="login" onclick="return fnLogin()">
</div>
</div>
<div class="clear"></div>
</form>
</div>
3.导航模块
功能:整合所有模块到一起,提供对关键字的搜索,并且提供分类查看,推荐文章等功能,用户能在本模块跳转到发布,登录注册等模块。
主要代码:
<body id="mybody">
<nav class="navbar navbar-inverse" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="{{ url_for('daohang') }}"style="color: #ee5f1f"><span class="glyphicon glyphicon-home"></span>携程旅游</a>
</div>
<div>
<ul class="nav navbar-nav
navbar-right">
{% if sessionusername %}
<li><a href="{{ url_for('yonghu',username_id=sessionuserid,tag=1) }}"
onclick="">{{ sessionusername }}</a></li>
<li><a href="{{ url_for('logout') }}" onclick=""><span class="glyphicon
glyphicon-log-out"></span>
注销</a></li>
{% else %}
<li><a href="{{ url_for('denglu') }}" onclick=""><span class="glyphicon
glyphicon-log-in"></span> 登陆</a>
</li>
<li><a href="{{ url_for('zhuce') }}" onclick=""><span class="glyphicon
glyphicon-user"></span>
注册</a></li>
{% endif %}
</ul>
</div>
<div>
<ul class="nav navbar-nav">
<li><a href="{{ url_for('fabu') }}" onclick=""><span class="glyphicon
glyphicon-user"></span> 发布</a></li>
</ul>
<ul class="nav navbar-nav">
{% if sessionuserid %}
<li class="dropdown">
<a href="#" class="dropdown-toggle"
data-toggle="dropdown"><span class="glyphicon glyphicon-list"></span>
设置 <b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('yonghu',username_id=sessionuserid,tag=1) }}">个人信息</a></li>
<li class="divider"></li>
<li><a href="{{ url_for('password_update',user_id=sessionuserid) }}">修改密码</a></li>
<li><a href="{{ url_for('yonghu',username_id=sessionuserid,tag=4) }}">收藏</a></li>
</ul>
</li>
<li><a href="#">||</a></li>
{% else %}
<li></li>
{% endif %}
</ul>
</div>
<form class="form-inline" role="form" action="{{ url_for('search') }}" method="get">
<div class="form-group">
<label class="sr-only" for="sousuo">名称</label>
<input type="text" class="form-control" name="sousuo" id="sousuo" placeholder="请输入内容">
<input type="submit" value="搜索" class="button1
button2" onclick="">
</div>
</form>
</div>
</nav>
<nav class="navbar navbar-inverse
navbar-fixed-bottom" role="navigation">
</nav>
<div id="navtop"></div>
{% block daohangbody %}
<div class="container" style="width: 1200px;">
<div class="row clearfix">
<div class="col-md-3
column" style="color: #3229ff">
<br>
<br>
<table class="table table-hover" style="color: #7c7c14">
<thead>
<tr>
<th>
<small>推荐作者</small>
</th>
</tr>
</thead>
<tbody>
{% for foo in author %}
<tr>
<td><a href="{{ url_for('yonghu',username_id=foo.id,tag=1) }}">{{ foo.nickname
}}</a></td>
<td><em>
<small>文章数:{{ foo.fabu
| length }}</small>
</em></td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table table-hover"style="color: #7c7c14">
<thead>
<tr>
<th>
<small>推荐文章</small>
</th>
</tr>
</thead>
<tbody>
{% for foo in ydfabu %}
<tr>
<td><a href="{{ url_for('fabuview',fabu_id=foo.id) }}">{{ foo.title
}}</a></td>
<td><span class="
glyphicon glyphicon-eye-open"></span><em>
<small>浏览:{{ foo.yuedu
}}</small>
</em></td>
</tr>
{% endfor %}
</tbody>
</table>
<br>
<br>
<br>
</div>
<div class="col-md-1
column" style="color: #3229ff"></div>
<div class="col-md-8
column" style="color: #7c7c14" >
<h3 class="text-center">发布行程</h3>
<form class="form-horizontal" role="form" action="{{ url_for('fenlei') }}" method="get">
<div class="form-group" id="haha">
<input type="submit" value="中国" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="美国" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="日本" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="韩国" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="瑞士" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="英国" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="巴西" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="荷兰" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="南非" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="埃及" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="新西兰" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="俄罗斯" id="fenlei" name="fenlei" class="btn
btn-warning">
<input type="submit" value="迪拜" id="fenlei" name="fenlei" class="btn
btn-warning">
</div>
</form>
<ul class="list-unstyled">
{% for foo in fabus %}
<li class="rgbal">
<a href="{{ url_for('yonghu',username_id=foo.author_id,tag=1) }}"><span
class="glyphicon
glyphicon-fire"></span>{{ foo.author.username
}}</a>
<span class="badge">{{ foo.creat_time }}</span>
<span class="badge pull-right">{{ foo.leixing }}</span>
<h4 class="text-center"><a
href="{{ url_for('fabuview',fabu_id=foo.id) }}">{{ foo.title
}}</a></h4>
<p>{{ foo.detail
}}</p>
<span class="
glyphicon glyphicon-eye-open"></span><em>浏览:{{ foo.yuedu
}}</em>   
<span class=""></span><em>评论:{{ foo.comments|length }}</em>   
<span class=""></span><em>点赞:{{ foo.dianzangs|length }}</em>
<hr>
</li>
{% endfor %}
</ul>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
</body>
4.发布模块
功能:输入标题内容,并且可以选择发布的分类,发布的内容会显示到首页上
<div class="form-group col-md-6
column">
<label for="title">标题</label>
<textarea class="form-control" rows="1" id="title" name="title"></textarea>
<label for="detail">详情</label>
<textarea class="form-control" rows="10" id="detail" name="detail"></textarea>
<div class="log-input">
<label for="lastname" class=" control-label"></label>
<div class="">
<select class="" name="leixing" id="leixing">
<option value="None" selected>请选择类型</option>
<option value="中国">中国</option>
<option value="美国">美国</option>
<option value="日本">日本</option>
<option value="韩国">韩国</option>
<option value="瑞士">瑞士</option>
<option value="英国">英国</option>
<option value="巴西">巴西</option>
<option value="荷兰">荷兰</option>
<option value="南非">南非</option>
<option value="埃及">埃及</option>
<option value="新西兰">新西兰</option>
<option value="俄罗斯">俄罗斯</option>
<option value="迪拜">迪拜</option>
</select>
</div>
</div>
<div id=""><br></div>
<input type="submit" value="发布" class="btn
btn-default" onclick="">
</div>
3、数据库设计
设计表“comment”
列名 |
数据类型 |
长度 |
允许空 |
Id |
Int |
4 |
否 |
author_id |
Nvarchar |
50 |
否 |
fabu_id |
Nvarchar |
50 |
否 |
creat_time |
Datetime |
8 |
否 |
detail |
String |
4 |
否 |
设计表“dianzan”
列名 |
数据类型 |
长度 |
允许空 |
Id |
Int |
10 |
否 |
author_id |
Int |
10 |
否 |
fabu_id |
Int |
10 |
否 |
设计表“fabu”,"shoucang"
列名 |
数据类型 |
长度 |
允许空 |
id |
Int |
4 |
否 |
title |
String |
50 |
是 |
detail |
String |
5 |
是 |
leixing |
String |
50 |
是 |
creat_time |
Int |
150 |
是 |
author_id |
Int |
50 |
是 |
yuedu |
Int |
150 |
是 |
设计表“user”
列名 |
数据类型 |
长度 |
允许空 |
id |
Int |
4 |
否 |
username |
String |
50 |
是 |
_password |
Int |
5 |
是 |
nickname |
String |
50 |
是 |
img |
jpg |
150 |
是 |
5、系统实现的关键算法与数据结构
# 跳转首页。
@app.route('/')
def daohang():
pl = request.args.get('pl') # 接收顺序排列的关键词,接收不到就按时间排列
if pl == '按热度':
context = {
'fabus': Fabu.query.order_by('-yuedu').all(),
'author': User.query.all(),
'ydfabu': Fabu.query.filter(Fabu.yuedu > 5).all() # 当发布的文章阅读量大于多少时取出这些文章,显示在首页的推荐文章
# order_by('-creat_time')按时间降序排列,Fabu.query.all()查出了Fabu类的所有元组
}
return render_template('daohang.html', **context)
else:
context = {
'fabus': Fabu.query.order_by('-creat_time').all(),
'author': User.query.all(),
'ydfabu': Fabu.query.filter(Fabu.yuedu > 5).all() # 当发布的文章阅读量大于多少时取出这些文章,显示在首页的推荐文章
# order_by('-creat_time')按时间降序排列,Fabu.query.all()查出了Fabu类的所有元组
}
return render_template('daohang.html', **context)
# 跳转测试。
@app.route('/lin/')
def lin():
return 'lin'
# 跳转登陆。
@app.route('/denglu/', methods=['GET', 'POST']) # methods定义它有两种请求方式
def denglu():
if request.method == 'GET':
return render_template('denglu.html')
else:
username = request.form.get('user') # post请求模式,安排对象接收数据
password = request.form.get('pass')
user = User.query.filter(User.username == username).first() # 作查询,并判断
if user: # 判断用户名
if user.check_password(password): # 判断密码
session['user'] = username # 利用session添加传回来的值username
session['user_id'] = user.id
session.permanent = True # 设置session过期的时间
return redirect(url_for('daohang'))
else:
return u'用户密码错误'
else:
return u'用户不存在,请先注册'
# 跳转密码修改页。
@app.route('/password_update/<user_id>')
def password_update(user_id):
users = User.query.filter(User.id == user_id).first() # 查询出要修改密码的该用户
return render_template('password_update.html', users=users)
# 跳转修改密码后接受数据。
@app.route('/password_update1/', methods=['POST'])
def password_update1():
username = request.form.get('username') # 接收username的值,知道要修改的是哪个用户
password = request.form.get('password')
users = User.query.filter(User.username == username).first() # 查询出要修改用户的整条信息
users.password = password # 执行修改
db.session.commit()
return redirect(url_for('yonghu', username_id=users.id, tag='1'))
@app.context_processor # 上下文处理器,定义变量然后在所有模板中都可以调用,类似idea中的model
def mycontext():
user = session.get('user')
user_id = session.get('user_id')
if user:
return {'sessionusername': user, 'sessionuserid': user_id} # 包装到username,在所有html模板中可调用
else:
return {} # 返回空字典,因为返回结果必须是dict
# 跳转注销。
@app.route('/logout')
def logout():
session.clear() # 注销时删除所有session
return redirect(url_for('daohang'))
# 跳转注册。
@app.route('/zhuce/', methods=['GET', 'POST']) # methods定义它有两种请求方式,因为它在表单的请求是post,类似我们在idea中的sava请求模式
def zhuce():
if request.method == 'GET':
return render_template('zhuce.html')
else:
username = request.form.get('user') # post请求模式,安排对象接收数据
password = request.form.get('pass')
nickname = request.form.get('nickname')
user = User.query.filter(User.username == username).first() # 作查询,并判断
if user:
return u'该用户已存在'
else:
user = User(username=username, password=password, nickname=nickname) # 将对象接收的数据赋到User类中,即存到数据库
db.session.add(user) # 执行操作
db.session.commit()
return redirect(url_for('denglu')) # redirect重定向
# 跳转某页面之前先进行登录。定义decorator可以增强函数功能,装饰器本身是函数,入参是函数,返回值也是函数
def loginFirst(fabu):
@wraps(fabu) # 加上wraps,它可以保留原有函数的__name__,docstring
def wrapper(*args, **kwargs): # 定义wrapper函数将其返回,用*args, **kwargs把原函数的参数进行传递
if session.get('user'): # 只有经过登陆,session才能记住并get到值
return fabu(*args, **kwargs)
else:
return redirect(url_for('denglu'))
return wrapper
# 跳转图片。
@app.route('/tupian/')
def tupian():
return render_template('tupian.html')
# 跳转发布。
@app.route('/fabu/', methods=['GET', 'POST']) # methods定义它有两种请求方式
@loginFirst # 将decorator定义的增强函数放在待增强函数定义的上面
def fabu():
if request.method == 'GET':
return render_template('fabu.html')
else:
title = request.form.get('title') # post请求模式,安排对象接收数据
detail = request.form.get('detail')
leixing = request.form.get('leixing')
yuedu = 0
author_id = User.query.filter(
User.username == session.get('user')).first().id # 将session get到的user进行查询并取出id放到外键author_id中
fabu = Fabu(title=title, detail=detail, author_id=author_id, leixing=leixing,
yuedu=yuedu) # 将对象接收的数据赋到Fabu类中,即存到数据库
db.session.add(fabu) # 执行操作
db.session.commit() # 提交到数据库
return redirect(url_for('daohang')) # redirect重定向
# 跳转发布详情
@app.route('/fabuview/<fabu_id>') # 和idea的update一样,将id带到控制器
def fabuview(fabu_id):
yes = Shoucang.query.filter( # yes用在用户详情页判断是否已收藏的按钮
and_(
Shoucang.author_id == session.get('user_id'), Shoucang.fabu_id == fabu_id
)
).first()
dzyes = Dianzang.query.filter( # dzyes用在用户详情页判断是否已点赞的按钮
and_(
Dianzang.author_id == session.get('user_id'), Dianzang.fabu_id == fabu_id
)
).first()
fa = Fabu.query.filter(Fabu.id == fabu_id).first() # 根据主页带回来的id查询出整条元组记录,丢进fa
comments = Comment.query.filter(Comment.fabu_id == fabu_id).all() # 根据带回来的Fabu的id在Comment查询出所有评论
fa.yuedu = fa.yuedu + 1 # 定义浏览功能,每次进去详情页,浏览次数加1
db.session.commit()
return render_template('fabuview.html', fa=fa, comments=comments, yes=yes,
dzyes=dzyes) # 把值fa丢进键fa,在fabuview.html页面调用
# 跳转评论。
@app.route('/comment/', methods=['POST'])
@loginFirst # 装饰器,跳转某页面之前先进行登录
def comment():
detail = request.form.get('pinglun') # post请求模式,安排对象接收数据
author_id = User.query.filter(User.username == session.get('user')).first().id
fabu_id = request.form.get('fa_id')
comment = Comment(detail=detail, author_id=author_id, fabu_id=fabu_id) # 将对象接收的数据赋到Comment类中,即存到数据库
db.session.add(comment) # 执行操作
db.session.commit() # 提交到数据库
return redirect(url_for('fabuview', fabu_id=fabu_id)) # 重定向到fabuview请求时要带fabu_id
# 跳转用户详情
@app.route('/yonghu/<username_id>/<tag>') # 为了把页面分开,我们在html页面传了一个tag参数
def yonghu(username_id, tag):
user = User.query.filter(User.id == username_id).first()
shoucang = Shoucang.query.filter(Shoucang.author_id == username_id).all()
context = {
'userid': user.id,
'username': user.username,
'nickname': user.nickname,
'fabus': user.fabu,
'comments': user.comments,
'shoucang': shoucang,
'img':user.img
} # 根据tag的不同去到不同页面,一个请求跳转3个不同页面
if tag == '1':
return render_template('yonghu1.html', **context)
elif tag == '2':
return render_template('yonghu2.html', **context)
elif tag == '3':
return render_template('yonghu3.html', **context)
else:
return render_template('yonghu4.html', **context)
@app.route('/search/')
def search():
sousuo = request.args.get('sousuo') # args获取关键字,区别form
author = User.query.all()
ydfabu = Fabu.query.filter(Fabu.yuedu > 5).all()
fabus = Fabu.query.filter(
or_( # 两种查询条件
Fabu.title.contains(sousuo), # contains模糊查
Fabu.detail.contains(sousuo)
)
).order_by('-creat_time')
return render_template('daohang.html', fabus=fabus, author=author, ydfabu=ydfabu) # fabus要和原首页数据模型一样
# 跳转高级分类查询
@app.route('/fenlei/')
def fenlei():
fenlei = request.args.get('fenlei') # args获取关键字,区别form
author = User.query.all()
ydfabu = Fabu.query.filter(Fabu.yuedu > 5).all()
fenlei_fabus = Fabu.query.filter(
or_( # 两种查询条件
# Fabu.title.contains(fenlei), # contains模糊查
Fabu.leixing.contains(fenlei),
# Fabu.creat_time.contains(fenlei)
)
).order_by('-creat_time')
return render_template('daohang.html', fabus=fenlei_fabus, author=author, ydfabu=ydfabu) # fabus要和原首页数据模型一样
# 跳转文章收藏
@app.route('/shoucang/', methods=['POST'])
@loginFirst
def shoucang():
scfabu_id = request.form.get('scfabu_id')
scuser_id = request.form.get('scuser_id')
shoucang = Shoucang(fabu_id=scfabu_id, author_id=scuser_id)
db.session.add(shoucang) # 执行操作
db.session.commit() # 提交到数据库
return redirect(url_for('fabuview', fabu_id=scfabu_id))
# 跳转文章点赞
@app.route('/dianzang/', methods=['POST'])
@loginFirst
def dianzang():
dzfabu_id = request.form.get('dzfabu_id')
dzuser_id = request.form.get('dzuser_id')
dianzang = Dianzang(fabu_id=dzfabu_id, author_id=dzuser_id)
db.session.add(dianzang) # 执行操作
db.session.commit() # 提交到数据库
return redirect(url_for('fabuview', fabu_id=dzfabu_id))
#上传头像
@app.route('/uploadLogo/<user_id>', methods=['GET', 'POST'])
def uploadLogo(user_id):
user = User.query.filter(User.id == user_id).first()
f = request.files['logo']
basepath = os.path.dirname(__file__) # 当前文件所在路径
upload_path = os.path.join(basepath, 'static/img', f.filename) # 注意:没有的文件夹一定要先创建,不然会提示没有该路径
f.save(upload_path)
user.img = 'img/' + f.filename
db.session.commit()
return redirect(url_for('yonghu', username_id=user_id,tag=1));
6、成品展示