管理信息系統課程設計
一、系統概要說明
隨著我國經濟的發展,人民群眾的生活水平不斷提高。人民群眾日益增長的生活需求不斷高漲,尤其體現在旅遊出行方面,這在一定程度上帶動了旅遊業的發展,為了向旅遊愛好者提供更加精準的旅遊服務,本網站采用社區發帖和旅遊攻略評論的功能,讓作為旅遊愛好者的用戶進行旅遊方面的溝通與交流,同時也為一些初級旅遊愛好者提供一些中肯的建議。
二、系統結構說明
註冊賬號功能:這是使用本網頁使用旅遊攻略發布功能的前提,註冊賬號時,系統有兩次確認密碼的過程,當兩次密碼不一致時,會出現錯誤提示框。該功能由單獨一個頁面進行設計。
登錄賬號功能:在使用本網站發布旅遊攻略時需要進行登錄的步驟,當所填寫的賬號或者密碼不匹配時會彈出錯誤提示框,該功能由單獨一個頁面完成。
修改密碼功能:該功能由單獨一個頁面組成,可以使用戶對自己的賬號密碼進行修改,從而保證用戶賬戶密碼的安全。
發布功能:本網站的核心功能,通過該功能用戶可以將自已對於旅遊景點的感受和攻略發布上去,主要分為找攻略、看遊記、問達人、結伴、酒店、旅行商城、機票、當地玩樂八個模塊,用戶可以在八個模塊中進行查詢旅遊目的地相關方面的旅遊建議。
發布詳情頁:發布詳情頁是對發布內容的詳細介紹,由單獨一個頁面組成,主要包含點贊、收藏和評論功能。用戶可根據攻略的點贊數來判斷該旅遊攻略的價值,同時也可以對自己比較認同的旅遊攻略進行收藏,方便日後查看。用戶可以對於發布的旅遊攻略進行評論,有利於本網站旅遊愛好者之間的交流互動,也有利於本網站的旅遊攻略趨向於客觀的方向去發展。
導航頁:導航頁有首頁、登錄、註冊、註銷幾個鏈接,可分別跳轉到相對應的頁面。有收藏、修改密碼和個人信息三個鏈接,可分別跳轉到各自的頁面。有高級搜索功能,通過字段的查詢就能查詢到相對應的旅遊攻略。同時可通過點贊數的總數來判斷所發布的旅遊攻略的熱度。同時還有自動計時的時間表。導航頁有找攻略、看遊記、問達人、結伴、酒店、旅行商城、機票、當地玩樂八個模塊,根據這八個模塊分為八種類別,點擊可獲取相對應的旅遊攻略。
主頁:該頁面是本網站的首頁,繼承了導航頁的內容,有個人信息頁、發布信息頁、評論信息頁和收藏文章頁總共四個鏈接,可分別跳轉到相對應的頁面。
個人信息頁:該頁面也叫作個人中心頁,主要顯示用戶的個人賬號信息,包括編號、昵稱、頭像(頭像可通過上傳頭像功能獲得)、發布攻略的篇數、評論的總條數、收藏的總條數。
三、模塊詳細設計
登錄與註冊功能詳細設計:
// 驗證用戶名
if (uSer.value.length < 6 ||
uSer.value.length > 20)
{
oError.innerHTML = "用戶名只能6-20位";
isError = false;
return isError;
} else if ((uSer.value.charCodeAt(0)
>= 48)
&& (uSer.value.charCodeAt(0) <= 57)) {
oError.innerHTML = "用戶名首字母不能是數字";
isError = false;
return isError;
} else for (var i = 0;
i < uSer.value.length; i++) {
if ((uSer.value.charCodeAt(i)
< 48)
|| (uSer.value.charCodeAt(i)
> 57)
&& (uSer.value.charCodeAt(i) < 97) || (uSer.value.charCodeAt(i)
> 122)) {
oError.innerHTML = "用戶名只能由數字和字母組成";
isError = false;
return isError;
}
}
// 驗證密碼
if (pAss.value.length < 6 ||
pAss.value.length > 20)
{
oError.innerHTML = "密碼只能6-20位";
isError = false;
return isError;
}
// 驗證彈框
window.alert("登陸成功!");
return true;
}
function fnRegistration() {
var uSer
= document.getElementById("user");
var pAss
= document.getElementById("pass");
var aGain
= document.getElementById("again");
var oError
= document.getElementById("error_box");
var isError
= true;
oError.innerHTML = "<br>";
// 驗證用戶名
if (uSer.value.length < 6 || uSer.value.length
> 20) {
oError.innerHTML = "用戶名只能6-20位";
isError = false;
return isError;
} else if ((uSer.value.charCodeAt(0)
>= 48)
&& (uSer.value.charCodeAt(0) <= 57)) {
oError.innerHTML = "用戶名首字母不能是數字";
isError = false;
return isError;
} else for (var i = 0;
i < uSer.value.length; i++) {
if ((uSer.value.charCodeAt(i)
< 48)
|| (uSer.value.charCodeAt(i)
> 57)
&& (uSer.value.charCodeAt(i) < 97) || (uSer.value.charCodeAt(i)
> 122)) {
oError.innerHTML = "用戶名只能由數字和字母組成";
isError = false;
return isError;
}
}
// 驗證密碼
if (pAss.value.length < 6 ||
pAss.value.length > 20)
{
oError.innerHTML = "密碼只能6-20位";
isError = false;
return isError;
}
// 驗證再次輸入的密碼
if (aGain.value
!= pAss.value) {
oError.innerHTML = "密碼不一致";
isError = false;
return isError;
}
// 驗證彈框
window.alert("註冊成功!");
return true;
}
攻略發布功能詳細設計
class Fabu(db.Model): # 發布
__tablename__ = ‘fabu‘
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
detail = db.Column(db.Text, nullable=False)
leixing = db.Column(db.String(20), nullable=True)
creat_time = db.Column(db.DateTime, default=datetime.now) # 提交時間會自己賦值
author_id = db.Column(db.Integer, db.ForeignKey(‘user.id‘)) # 數據類型是db.Integer,db.ForeignKey參數指定外鍵是哪個表中哪個id
author = db.relationship(‘User‘, backref=db.backref(‘fabu‘)) # 建立關聯,其author屬性將返回與問答相關聯的用戶實例,相當於數據庫中的表連接
# 第一個參數表明這個關系的另一端是哪個類,第二個參數backref,將向User類中添加一個fabu屬性,從而定義反向關系,這一屬性可訪問Fabu類,獲取的是模型對象
yuedu = db.Column(db.Integer, nullable=False)
高級搜索功能詳細設計
# 跳轉高級搜索查詢
@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(‘/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));
四、數據庫設計
本網站運行所需的數據庫需要utf8格式的,數據庫裏需要有五張表,一張user表(用戶表),一張question表(問答表),一張comment表(評論表),一張cf表(分類表),一張collection表(收藏表)。
User表:用戶ID,username,password,icon,其中的password屬性需要加密處理。
Question表:問答id,title,detail,creat_time,用戶id,cf。look,click。
Comment表:評論id,用戶id,問答id,creat_time,detail
Cf表:分類id,分類name
Collection表:收藏id,問答id,用戶id。
五、系統實現的關鍵算法與數據結構
通過對主頁的各鏈接的點擊可跳轉到相對應的頁面,進行相關的操作。
# 跳轉首頁。
@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(‘/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));
六、成品展示
註冊頁面
登錄界面
發布功能頁面
評論功能頁面
個人信息頁
發布信息頁
評論信息頁
收藏文章頁面
主頁
管理信息系統課程設計