目录
一、题目要求
二、系统分析
1.可行性研究:
2.可行性研究过程
3.需求分析
系统的综合要求:
4.数据流图
三、数据库设计
1.概念结构设计
四、系统设计与实现
1.使用软件
2.命令
3.Python实现界面窗口
五、源码下载
校园核酸检测预约系统功能参考
1)我们在检查或自己使用校园核酸系统时,用户可以使用,暂时没有出现问题。
2)目前市面上所使用核酸预约检测软件,各具特色,我们做的系统能完成基本功能。
1) E-R图
2)关系模式
学生(姓名,身份证,性别,采样点编号,时间)
管理员(姓名,采样点编号,预约人数)
医生(核验码,结果)
预约(核验码,用户编号,采样点编号,日期,时间段,状态)
mysql数据库,使用Navicat Premium图形界面显示数据库信息。
# 创建数据库
Create database NucleicAcidInformationBase;
# 创建数据表
Create Table UserTable(id int auto_increment not null UNIQUE,Uname VARCHAR(255) not null,Uno CHAR(18) PRIMARY KEY UNIQUE,Sex CHAR(2) default("男") CHECK(Sex in("男","女")));
Create Table SamplingPoinTable(id int auto_increment not null UNIQUE,SName VARCHAR(255) not null,Sno CHAR(8) PRIMARY KEY,Amount int default 0);
Create Table AppointmenTable(Uno CHAR(18) not null,Sno CHAR(8) not null,AppointmentDate Date not null,Timing VARCHAR(255) default "09:00-12:00" CHECK (Timing in ("09:00-12:00","14:00-17:00")), VerificationCode CHAR(12) default 'null' UNIQUE,Status CHAR(2) default "否" CHECK(Status in("是","否")),PRIMARY KEY(Uno,AppointmentDate,Timing),FOREIGN KEY(Uno) REFERENCES UserTable(uno),FOREIGN KEY(Sno) REFERENCES SamplingPoinTable(Sno));
CREATE TABLE ResulTable(VerificationCode CHAR(12) PRIMARY KEY,Result CHAR(8) default "阴性" CHECK (Result in("阴性","阳性")),FOREIGN KEY (VerificationCode) REFERENCES AppointmenTable(VerificationCode));
# 插入数据 向用户中
INSERT INTO UserTable (Uname,Uno,Sex) values ("xxx","xxxxxxxxxxxxx","男"),
("xxx","xxxxxxxxxxxx","女");
# 向工作地点中
INSERT INTO SamplingPoinTable (SName,Sno)
values
("京江报告厅","1902E04"),
("研究生报告厅","1902W01"),
("学苑楼","1902N03"),
("大学生创业孵化基地","1902N02");
# 添加触发器
# 设置MySQL执行结束标志 默认为;
# 触发器1:当有人申请预约时且通过申请时该地区人数加一
DELIMITER //
CREATE TRIGGER Appoint
After Insert
on Appointmentable
FOR EACH ROW
BEGIN
IF(new.VerificationCode!='null') then
UPDATE SamplingPoinTable set Amount = Amount+1 WHERE Sno=new.Sno;
END IF;
END//
DELIMITER ;
# 触发器2:当用户完成核酸后,该地区人减一
DELIMITER //
CREATE TRIGGER AfterCompleteAppoint
After Update
on Appointmentable
FOR EACH ROW
BEGIN
IF(new.Status!=old.Status) then
UPDATE SamplingPoinTable set Amount = Amount-1 WHERE Sno=old.Sno;
END IF;
END//
DELIMITER ;
# 触发器3:当用户完成核酸结果后,该用户状态自然置为是。
DELIMITER //
CREATE TRIGGER AfterResult
After Insert
on ResulTable
FOR EACH ROW
BEGIN
UPDATE Appointmentable set Status="是" WHERE Appointmentable.VerificationCode=new.VerificationCode;
END//
DELIMITER ;
# 触发器4:当用户取消预约时,该地区预约人数-1
DELIMITER //
CREATE TRIGGER Deleteappoint
After Delete on appointmentable
for each row
begin
IF (old.Status="否") then
Update SamplingPoinTable set Amount = Amount-1 WHERE Sno=old.Sno;
END IF;
END //
DELIMITER ;
医生管理上报窗口:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :message
@File :manager.py
@IDE :PyCharm
@Author :昊昊
@Date :2022/6/22 上午 12:17
'''
import tkinter as tk
from tkinter import messagebox
import pymysql
datebase = "nucleicacidinformationbase"
messagetable = "appointmentable"
resultable = "resultable"
userName = "root"
pwd = "123456"
class DocterMenu():
def __init__(self):
self.root = tk.Tk()
self.root.title("医生管理系统")
self.root.resizable(False, False)
screenheight = self.root.winfo_screenheight()
screenwidth = self.root.winfo_screenwidth()
self.size = "%dx%d+%d+%d" % (300, 200, (screenwidth - 300) / 2, (screenheight - 200) / 2)
self.root.geometry(self.size)
self.frame = tk.Frame(self.root, width=300, height=200)
self.__menu()
self.frame.place(x=0,y=0)
self.root.mainloop()
def __menu(self):
self.CodeLable = tk.Label(self.frame,text="核验码:",width=10,font=("heiti",20))
self.CodeLable.place(x=0,y=30)
self.CodeEntry = tk.Entry(self.frame,width=10,font=("heiti",20))
self.CodeEntry.place(x=120,y=30,height=30)
self.ResultLable = tk.Label(self.frame,text="结 果:",width=10,font=("heiti",20))
self.ResultLable.place(x=0,y=80)
self.ResultEntry = tk.Entry(self.frame,font=("heiti",20),width=10)
self.ResultEntry.place(x=120,y=80,height=30)
Submit = tk.Button(self.frame,text="提交",command=self.__Submit,font=("heiti",20))
Submit.place(x=100,y=120)
def __Submit(self):
Code = self.CodeEntry.get()
Result = self.ResultEntry.get()
sql = 'select * from {} where VerificationCode="{}"'.format(messagetable,Code)
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
flag = cursor.execute(sql)
if flag == 0:
tk.messagebox.showerror("请校对核验码!")
else:
sql = 'Insert into {} value ("{}","{}")'.format(resultable,Code,Result)
try:
cursor.execute(sql)
conn.commit()
tk.messagebox.showinfo(title="Success",message="录入成功")
except:
conn.rollback()
tk.messagebox.showerror(title="Error",message="请勿重复录入!")
cursor.close()
conn.close()
if __name__ == "__main__":
DocterMenu()
用户预约界面
需要提前在该目录下创建一个img文件夹
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :message
@File :usermanager.py
@IDE :PyCharm
@Author :昊昊
@Date :2022/6/21 下午 2:46
'''
import pymysql
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import FindMessage as FM
import FindResult as FR
'''
表数据
'''
datebase = "nucleicacidinformationbase"
usertable = "usertable"
locationtable = "samplingpointable"
resultable = "resultable"
messagetable = "appointmentable"
userName = "root"
pwd = "123456"
Time = ["09:00-12:00","14:00-17:00"]
Local = ["京江报告厅","大学生创业孵化基地","学苑楼","研究生报告厅"]
Date = ["2021-10-30","2021-10-31","2021-11-1","2021-11-2","2021-11-3","2021-11-1","2021-11-4","2021-11-5"]
class UserTkinter():
def __init__(self):
# 窗口设置。
self.root = tk.Tk()
self.root.title("预约")
self.root.iconbitmap('./001.ico')
# 画布搭建
self.root.resizable(False,False)
screenheight = self.root.winfo_screenheight()
screenwidth = self.root.winfo_screenwidth()
self.size = "%dx%d+%d+%d"%(400,250,(screenwidth-400)/2,(screenheight-250)/2)
self.root.geometry(self.size)
self.frame = tk.Frame(self.root,width=400,height=250)
self.__menu()
self.root.mainloop()
def __menu(self):
# 主界面
self.label = None
self.frame.place(x=0,y=0)
SamplingpointLabel = tk.Label(self.frame,text="采样点:",width=10)
SamplingpointLabel.place(x=10,y=10)
self.SamplingpointChose = ttk.Combobox(self.frame)
self.SamplingpointChose.place(x=80,y=10)
self.SamplingpointChose["value"] = Local
UserNameLable = tk.Label(self.frame,text="用户姓名:",width=10)
UserNameLable.place(x=10,y=50)
self.UserNameEntry= tk.Entry(self.frame,width=23,validate="focusout",validatecommand=self.__test)
self.UserNameEntry.place(x=80,y=50)
AuthenticationLabel = tk.Label(text="身份证号:")
AuthenticationLabel.place(x=18,y=90)
self.AuthenticationEntry = tk.Entry(self.frame,width=23,validate="focusout",validatecommand=self.__test)
self.AuthenticationEntry.place(x=80,y=90)
DateLable = tk.Label(self.frame,text="选择时间:")
DateLable.place(x=18,y=130)
self.DateChose = ttk.Combobox(self.frame)
self.DateChose.place(x=80, y=130)
self.DateChose["value"] = Date
TimeLable = tk.Label(self.frame,text="选择时间:")
TimeLable.place(x=18,y=170)
self.TimeChose = ttk.Combobox(self.frame)
self.TimeChose.place(x=80,y=170)
self.TimeChose["value"]=Time
SubmitCommit = tk.Button(self.frame,text="提交",width=20,command=self.__Submit,bg="green")
SubmitCommit.place(x=80,y=210)
tk.Button(self.frame,text="查询预约",command=self.__find,width=18,bg="green").place(x=250,y=175)
tk.Button(self.frame,text="查看结果",command=self.__Result,width=18,bg="green").place(x=250,y=210)
def __Result(self):
username = self.UserNameEntry.get()
auth = self.AuthenticationEntry.get()
if not (username and auth):
tk.messagebox.showerror(title="Error", message="请输入用户完整信息")
return False
FR.FindResult(auth)
def __test(self):
# 身份输入验证
username = self.UserNameEntry.get()
authentication = self.AuthenticationEntry.get()
if username == "" or authentication == "":
return True
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
sql = 'select * from {} where Uname="{}" and Uno="{}"'.format(usertable, username, authentication)
result = cursor.execute(sql)
if result == 0:
self.label = tk.Label(self.frame, text="身份错误,请重新输入!")
self.label.place(x=250, y=80)
if result == 1:
try:
self.label.destroy()
except AttributeError:
pass
cursor.close()
conn.close()
return True
def __Submit(self):
# 提交按钮
Sno = self.__FindLocation()
Uno = self.AuthenticationEntry.get()
Timing = self.TimeChose.get()
date = self.DateChose.get()
if Timing not in Time:
tk.messagebox.showerror(title="Error",message="请输入正确的时间")
return False
if date not in Date:
tk.messagebox.showerror(title="Error",message="请输入正确的日期")
return False
if not (Sno and Uno and date and Timing):
tk.messagebox.showerror(title="Error",message="请输入完整信息")
return False
Code = self.__VerificationCode(Uno,Sno,date,Timing)
if not Code:
tk.messagebox.showerror(title="error",message="请勿重复预约!如有其他问题请联系管理员!")
return
sql = 'Insert into {} (Uno,Sno,AppointmentDate,Timing,VerificationCode) value ("{}", "{}", "{}", "{}","{}")'.format(messagetable,Uno,Sno,date,Timing,Code)
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
print(Code)
cursor = conn.cursor()
flag = cursor.execute(sql)
if flag== 1:
conn.commit()
tk.messagebox.showinfo(title="success",message="预约成功")
else:
conn.rollback()
tk.messagebox.showerror(title="Error",message="预约失败")
cursor.close()
conn.close()
def __FindLocation(self):
# 查找采样点编号
location = self.SamplingpointChose.get()
if location not in Local:
return
sql = 'select Sno from {} where Sname="{}"'.format(locationtable,location)
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
cursor.execute(sql)
Sno = cursor.fetchone()
cursor.close()
conn.close()
if Sno:
return Sno[0]
def __find(self):
username = self.UserNameEntry.get()
auth = self.AuthenticationEntry.get()
if not (username and auth):
tk.messagebox.showerror(title="Error",message="请输入用户完整信息")
return False
FM.FindMessageMenu(auth)
def __VerificationCode(self,Uno,Sno,date,Timing):
sql = 'select * from {} where Uno="{}" and Appointmentdate="{}"'.format(messagetable,Uno,date)
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
if cursor.execute(sql) == 0:
Code = Sno[-2:]+date[5:7]+date[8:10]
if Timing == "09:00-12:00":
Code += "0"
else:
Code += "1"
cursor.execute('select VerificationCode from {} where AppointmentDate="{}" and Timing="{}" and Sno="{}" Order by VerificationCode DESC'.format(messagetable,date,Timing,Sno))
num = cursor.fetchone()
if num and Code[-1]==num[0][-6]:
Code += '0'*(5-len(str(int(num[0][-5:])+1))) + str(int(num[0][-5:])+1)
else:
Code += "00001"
return Code
else:
return None
if __name__ == "__main__":
UserTkinter()
FindMessage.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :message
@File :FindMessage.py
@IDE :PyCharm
@Author :昊昊
@Date :2022/6/24 0024 上午 8:24
'''
import pymysql
import tkinter as tk
from PIL import Image,ImageTk
import qrcode
import warnings
from tkinter import messagebox
warnings.filterwarnings("ignore",category=DeprecationWarning)
datebase = "nucleicacidinformationbase"
usertable = "usertable"
locationtable = "samplingpointable"
resultable = "resultable"
messagetable = "appointmentable"
userName = "root"
pwd = "123456"
img_file = r'./img/'
class FindMessageMenu():
def __init__(self,auth):
# 查询预约界面
sql = 'select AppointmentDate,Timing,VerificationCode from {} where Uno="{}" and Status="{}" Order by' \
' AppointmentDate '.format(messagetable, auth,"否")
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
cursor.execute(sql)
self.messages = cursor.fetchone()
cursor.close()
conn.close()
find = tk.Toplevel()
find.title("查询预约")
find.iconbitmap('./001.ico')
find.resizable(False, False)
screenheight = find.winfo_screenheight()
screenwidth = find.winfo_screenwidth()
size = "%dx%d+%d+%d" % (300, 250, (screenwidth - 300) / 2, (screenheight - 250) / 2)
find.geometry(size)
frame = tk.Frame(find, width=300, height=250)
frame.place(x=0, y=0)
frame1 = tk.Frame(frame, width=180, height=100)
frame1.place(x=40, y=10)
if not self.messages :
tk.Label(frame1, text="当前用户无预约!!!!").place(x=50, y=25)
else:
messages = list(self.messages)
message = str(messages[0]) + " " + messages[1] + "\r\n" +\
"当前尚未核验\r\n" + "您的验证码为: "
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_H,
box_size=10,
border=4
)
qr.add_data(messages[-1])
img = qr.make_image()
img.save(img_file+str(auth)+".png")
tk.Label(frame1,text=message,wraplength=150).place(x=30,y=10)
frame2 = tk.Frame(frame,width=100,height=100)
frame2.place(x=100,y=110)
img = ImageTk.PhotoImage(Image.open("./img/" + str(auth) +".png").resize((80,80),Image.ANTIALIAS))
tk.Label(frame2,image=img).place(x=0,y=0)
tk.Button(frame, text="Cannel", command=find.destroy).place(x=75, y=200)
tk.Button(frame, text="取消预约", command=self.__Cannel).place(x=140, y=200)
find.mainloop()
def __Cannel(self):
if tk.messagebox.askokcancel("Warin","确定取消预约吗?"):
sql = 'Delete from {} where VerificationCode="{}"'.format(messagetable,self.messages[-1])
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
cursor.execute(sql)
conn.commit()
cursor.close()
conn.close()
if __name__ == '__main__':
FindMessageMenu(120223200204245552)
FindResult.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
@Project :message
@File :FindResult.py
@IDE :PyCharm
@Author :昊昊
@Date :2022/6/24 0024 上午 9:28
'''
import tkinter as tk
import pymysql
from PIL import Image,ImageTk
datebase = "nucleicacidinformationbase"
usertable = "usertable"
locationtable = "samplingpointable"
resultable = "resultable"
messagetable = "appointmentable"
userName = "root"
pwd = "123456"
class FindResult():
def __init__(self,auth):
self.auth = auth
Tk = tk.Toplevel()
Tk.geometry("300x200")
Tk.title("结果")
Tk.iconbitmap('./001.ico')
Tk.resizable(False,False)
resultmessage = self.__FindVerCode()
if not resultmessage[0]:
message = "该用户暂时 "+resultmessage[1]
tk.Label(Tk, text=message, wraplength=150).place(x=90, y=80)
else:
message = str(resultmessage[0][0]) + " " + resultmessage[0][1] + "\r\n" + \
"当前已核验\r\n" + "您的结果为: " + resultmessage[1][0]
img = ImageTk.PhotoImage(Image.open("./img/" + str(auth) +".png").resize((80,80),Image.ANTIALIAS))
tk.Label(Tk, image=img).place(x=110, y=90)
tk.Label(Tk,text=message,wraplength=150).place(x=80,y=0)
tk.mainloop()
def __FindVerCode(self):
sql = 'select AppointmentDate,Timing,VerificationCode from {} where Uno="{}" and Status="{}" Order by' \
' AppointmentDate DESC'.format(messagetable, self.auth, "是")
conn = pymysql.connect(host="localhost", user=userName, password=pwd, database=datebase, charset="utf8")
cursor = conn.cursor()
cursor.execute(sql)
message = cursor.fetchone()
if not message:
result = "尚无结果"
return message,result
sql1 = 'select Result from {} where VerificationCode="{}"'.format(resultable,message[-1])
cursor.execute(sql1)
result = cursor.fetchone()
cursor.close()
conn.close()
return message,result
GitHub:GitHub - ITApeDeHao/MysqlNucleicAcidAppointment: 核酸预约管理系统【python/MySQL】