├── README.md ├── fj.jpg ├── images ├── image.png └── none ├── login.py ├── sql_base.py └── test.db /README.md: -------------------------------------------------------------------------------- 1 | # 一、 概述 2 | 3 | 民航售票管理系统主要分为机场、航空公司和客户三方的服务。航空公司提供航线和飞机的资料,机场则对在本机场起飞和降落的航班和机票进行管理,而客户能得到的服务应该有航班线路和剩余票数的查询,以及网上订票等功能。客户又可以分为两类,一类是普通客户,对于普通客户只有普通的查询功能和订票功能,没有相应的机票优惠,另一种是经常旅客,需要办理注册手续,但增加了里程积分功能和积分优惠政策。机场还要有紧急应对措施,在航班出现延误时,要发送相应的信息。 4 | 5 | 本系统能够完成如下功能: 6 | 7 | **订票用户** 8 | 9 | (1) 查询当前的航班信息,包括航班时间,机型,价格,余票数量等数据,并且可以根据不同得选择对机票进行筛选,选择购买后积分自动累加。 10 | 11 | (2) 查询自己已经订购得机票,并且可以修改乘客或者进行退票。 12 | 13 | (3) 查询自己得个人信息,可以修改账户密码,未注册的用户可以自行注册VIP。 14 | 15 | 16 | 17 | **航空公司管理员** 18 | 19 | (1) 查看公司的航班信息,包括航班时间,机型,价格,余票数量等,并且可以进行筛选。。 20 | 21 | (2) 查询公司航班的售票情况,包括航班,乘客,价格,付款金额等数据,并且可以进行筛选。 22 | 23 | (3) 添加或修改公司的航班信息,包括航班时间,机型,价格,余票数量等。 24 | 25 | 26 | 27 | **机场管理员** 28 | 29 | (1) 查询当前所有的顾客信息,可以对顾客信息进行修改或者注册新用户。 30 | 31 | (2) 查询涉及本机场的航班,并且可以对航班进行修改。 32 | 33 | (3) 对发生异动的航班,管理员可以选择对相关用户发送公告,告知其相关信息。 34 | 35 | (4) 可以查询或修改当前的售票信息,并且可以添加销售信息。 36 | 37 | # 二、 实验环境 38 | 39 | 本系统开发平台及运行环境如下: 40 | 41 | 系统开发语言:Python 42 | 43 | 数据库管理软件:SQL Server 2017 44 | 45 | 运行平台:Windows10 46 | 47 | # 三、 实验内容与步骤 48 | 49 | ## 3.1系统需求分析 50 | 51 | ## 3.1.1系统工作原理 52 | 53 | 1) 注册。由用户向机场管理员申请注册,由管理员将信息表单提交到系统,由控制层调用数据逻辑层操作数据库,完成用户的注册。 54 | 55 | 2) 用户登录。对用户输入的登录信息进行验证,判定用户选择的用户类别和输入的用户名和密码是否匹配,若不匹配则无权使用该系统,反之则能合法使用系统。 56 | 57 | 3) 修改个人信息。用户对可以对个人信息进行查询及修改。 58 | 59 | 4) 航班查询。用户对数据库中航班信息进行查询,显示满足用户查询条件的航班信息。 60 | 61 | 5) 订票。用户查询到自己需要的航班信息后可进行订购操作,首先查询用户所享受的优惠,确定付款金额后,系统会将相关信息一并发送到机票订购模块,将信息写入订单信息存储,并且运行积分模块,进行积分的累计。 62 | 63 | 6) 修改信息。此工作接受用户的修改信息,根据用户ID和预订的航班号,对满足条件的已预订机票进行修改处理。 64 | 65 | 7) 退票。此工作接受用户的退票信息,根据用户ID和预订的航班号,对满足退票条件的已预订机票进行退票处理,并且扣除所加积分。 66 | 67 | 8) 航班信息录入。此工作接收由航空公司管理员录入的航班信息,并将其导入数据库进行存储,供用户查询和预订。 68 | 69 | 9) 航班信息更新。此工作接收管理员对某些需要更新的航班信息的更新操作,并修改存储在数据库中相关信息。 70 | 71 | 10) 订单查询。用户可以查询自己已完成的或未出行的订单,管理员可以查看所属用户的所有订单。 72 | 73 | 74 | 75 | ### 3.1.3表的设计 76 | 77 | 本系统采用MySQL数据库。在系统中创建test数据库包含8张表,各个表的详细设计如下: 78 | 79 | **公司管理员信息****表** 80 | 81 | 表名:companyUser 82 | 83 | 公司管理员信息表 84 | 85 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 86 | | --------- | ----------- | -------- | ---- | -------- | 87 | | userId | INT | No | 主键 | 用户编号 | 88 | | userName | VARCHAR(50) | Yes | | 用户名 | 89 | | password | VARCHAR(50) | Yes | | 密码 | 90 | | companyId | INT | Yes | 外键 | 所属公司 | 91 | 92 | ​ 93 | 94 | **机场管理员信息表** 95 | 96 | 表名:airportUser 97 | 98 | 机场管理员信息表 99 | 100 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 101 | | --------- | ----------- | -------- | ---- | -------- | 102 | | userId | INT | No | 主键 | 用户编号 | 103 | | userName | VARCHAR(50) | No | | 用户名 | 104 | | password | VARCHAR(50) | No | | 密码 | 105 | | airportId | INT | No | 外键 | 所属机场 | 106 | 107 | 108 | 109 | **顾客信息表** 110 | 111 | 表名:customerUser 112 | 113 | 顾客信息表 114 | 115 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | | 116 | | -------- | ----------- | -------- | ---- | ------------ | ---- | 117 | | userId | INT | No | 主键 | 用户编号 | | 118 | | userName | VARCHAR(50) | No | | 用户名 | | 119 | | password | VARCHAR(50) | No | | 密码 | | 120 | | Vip | INT | No | | 是否注册用户 | | 121 | | Point | INT | No | | 积分 | | 122 | | realName | VARCHAR(50) | Yes | | 姓名 | | 123 | | phone | VARCHAR(50) | Yes | | 手机号 | | 124 | | sex | VARCHAR(50) | Yes | | 性别 | | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | **公告信息表** 135 | 136 | 表名:board 137 | 138 | 公告信息表 139 | 140 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 141 | | -------- | ---- | -------- | ---- | ------------ | 142 | | boardId | INT | No | 主键 | 公告编号 | 143 | | flightId | INT | No | 外键 | 涉及航班编号 | 144 | | dueTime | INT | No | | 截止日期 | 145 | 146 | 147 | 148 | **机场信息表** 149 | 150 | 表名:airport 151 | 152 | 机场信息表 153 | 154 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 155 | | ----------- | ----------- | -------- | ---- | -------- | 156 | | airportId | INT | No | 主键 | 机场编号 | 157 | | airportName | VARCHAR(50) | No | | 机场名称 | 158 | 159 | 160 | 161 | **公司信息表** 162 | 163 | 表名:company 164 | 165 | 公司信息表 166 | 167 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 168 | | ----------- | ----------- | -------- | ---- | -------- | 169 | | companyId | INT | No | 主键 | 公司编号 | 170 | | companyName | VARCHAR(50) | No | | 公司名称 | 171 | 172 | 173 | 174 | **机票销售信息表** 175 | 176 | 表名:ticket 177 | 178 | 表3-4 机票销售信息表 179 | 180 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 181 | | ------------- | ----------- | -------- | ---- | ---------- | 182 | | ticketId | INT | No | 主键 | 机票编号 | 183 | | userId | INT | No | 外键 | 顾客编号 | 184 | | flightId | INT | No | 外键 | 航班编号 | 185 | | companyId | INT | No | 外键 | 航班公司 | 186 | | seatNumber | INT | No | | 座位号 | 187 | | passagerName | VARCHAR(50) | No | | 乘客姓名 | 188 | | passagerPhone | VARCHAR(50) | No | | 乘客手机号 | 189 | | paidMoney | INT | No | | 付款金额 | 190 | | paidTime | VARCHAR(50) | No | | 付款时间 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | **航班信息表** 199 | 200 | 表名:flight 201 | 202 | 表3-5 宠物用品销售信息表 203 | 204 | | 属性名 | 类型 | 允许为空 | 主键 | 描述 | 205 | | ----------- | ----------- | -------- | ---- | ---------- | 206 | | flightID | INT | No | 主键 | 航班号 | 207 | | plane | VARCHAR(50) | No | | 飞机机型 | 208 | | departure | INT | No | 外键 | 出发地编号 | 209 | | terminal | INT | No | 外键 | 目的地编号 | 210 | | leaveTime | VARCHAR(50) | No | | 出发时间 | 211 | | arrivetime | VARCHAR(50) | No | | 到达时间 | 212 | | leftTicket | INT | No | | 余票数量 | 213 | | totalTicket | INT | No | | 总票数 | 214 | | ticketMoneu | INT | No | | 票价 | 215 | | companyID | INT | No | 外键 | 所属公司 | 216 | 217 | 218 | 219 | # 四、 程序运行展示 220 | ![](images/image.png) 221 | -------------------------------------------------------------------------------- /fj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy1999/Civil-aviation-management-system/853919afea5ad62d6c5e8edfcf836654395f6f32/fj.jpg -------------------------------------------------------------------------------- /images/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy1999/Civil-aviation-management-system/853919afea5ad62d6c5e8edfcf836654395f6f32/images/image.png -------------------------------------------------------------------------------- /images/none: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /login.py: -------------------------------------------------------------------------------- 1 | from tkinter import * 2 | from sql_base import * 3 | import tkinter.messagebox 4 | from tkinter import ttk 5 | #import pymysql 6 | from PIL import Image,ImageTk 7 | import sqlite3 8 | import time 9 | 10 | def center(window, w, h): # 设置窗口大小且居中 11 | ws = window.winfo_screenwidth() 12 | hs = window.winfo_screenheight() 13 | x = (ws / 2) - (w / 2) 14 | y = (hs / 2) - (h / 2) 15 | window.geometry("{:.0f}x{:.0f}+{:.0f}+{:.0f}".format(w, h, x, y)) 16 | 17 | 18 | class Main(Frame): 19 | """主窗口""" 20 | flag = None 21 | def __init__(self,user): 22 | Frame.__init__(self, master=None) 23 | self.pack(fill=BOTH, expand=YES) 24 | self.master.geometry("1200x800") 25 | self.master.title("民航销售管理系统") 26 | self.frame_top = Frame(self) 27 | self.frame_top.pack(side="top", fill=X) 28 | Label(self.frame_top, text="民航销售管理系统", font=("微软雅黑", 30), fg='black', bg='beige').pack(fill=X) 29 | # im=Image.open("fj.jpg") 30 | # img=ImageTk.PhotoImage(im) 31 | # Label(self.frame_top,image=img).pack(fill=X) 32 | self.frame_bottom = Frame(self) # 下方frame 33 | self.frame_bottom.pack(side="bottom", fill=BOTH, expand=YES) 34 | frame_left = FrameLeft(self.frame_bottom,user) # 下方左边 35 | frame_left.pack(side="left", fill=Y) 36 | self.frame_right = Home(self.frame_bottom) # 下方右边 37 | self.frame_right.pack(side="right", fill=BOTH, expand=YES) 38 | 39 | 40 | class Home(Frame): # 主页 41 | def __init__(self, master): 42 | Frame.__init__(self, master) 43 | # self.label = Label(self, text=time.strftime('%Y-%m-%d %H:%M:%S %A', time.localtime(time.time())) 44 | # , font=("Arial Black", 24)) 45 | # self.label.after(1000, self.trickit) 46 | # self.label.pack(pady=20) 47 | self.im=Image.open("fj.jpg") 48 | self.img=ImageTk.PhotoImage(self.im) 49 | self.label = Label(self,image=self.img).pack(pady=20) 50 | 51 | # def trickit(self): 52 | # currentTime = time.strftime('%Y-%m-%d %H:%M:%S %A', time.localtime(time.time())) 53 | # self.label.config(text=currentTime) 54 | # self.update() 55 | # self.label.after(1000, self.trickit) 56 | 57 | 58 | def go_home(win): # 返回主页 59 | win.frame_right.destroy() 60 | win.frame_right = Home(Main.flag.frame_bottom) 61 | win.frame_right.pack(side="right", fill=BOTH, expand=YES) 62 | 63 | 64 | def personal_data(window,userName): # 查询个人信息 65 | window.frame_right.destroy() 66 | window.frame_right = Frame(Main.flag.frame_bottom) 67 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 68 | frame_top = Frame(window.frame_right) 69 | frame_top.pack(side='top', fill=BOTH) 70 | frame_bottom = Frame(window.frame_right) 71 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 72 | scrollbar = Scrollbar(frame_bottom) 73 | scrollbar.pack(side='right', fill=Y) 74 | tree = ttk.Treeview(frame_bottom, columns=list(range(5)), show='headings', yscrollcommand=scrollbar.set) 75 | column_name = ["顾客编号", "姓名", "性别", "联系电话","积分"] 76 | for i in range(5): 77 | tree.column(str(i), anchor='w') 78 | tree.heading(str(i), text=column_name[i], anchor='w') 79 | tree.pack(fill=BOTH, expand=YES) 80 | for row in get_userData("userName = '{}'".format(userName)): 81 | tree.insert('', 'end', values=row) 82 | scrollbar.config(command=tree.yview) 83 | 84 | 85 | popup_menu = Menu(frame_bottom, tearoff=0) 86 | 87 | def is_select(): # 判断Treeview中是否有行被选中 88 | flag = False 89 | for elem in tree.selection(): 90 | flag = True 91 | return flag 92 | 93 | def show_all(): 94 | [tree.delete(item) for item in tree.get_children()] 95 | for row in get_userData("userName = '{}'".format(userName)): 96 | tree.insert('', 'end', values=row) 97 | 98 | def alter(): # 修改顾客信息 99 | if is_select(): 100 | for elem in tree.selection(): 101 | win = Toplevel() 102 | win.grab_set() # 模态 103 | win.focus() 104 | center(win, 300, 400) 105 | xb = ttk.Combobox(win, value=['M','F'], state='readonly') 106 | labels = [Label(win, text='修改个人信息', fg='blue', font=('楷体', 14)), 107 | Label(win, text='顾客编号:' + tree.item(elem, 'values')[0]), 108 | Label(win, text="姓名"), Entry(win), 109 | Label(win, text="性别"), xb, 110 | Label(win, text="密码"), Entry(win), 111 | Label(win, text="联系电话"), Entry(win)] 112 | for l in labels: 113 | l.pack() 114 | 115 | def confirm(): # 确认添加事件 116 | sql = "update customerUser set realName='%s', sex='%s', password='%s', phone='%s', vip = 1.0 where userId='%s'" 117 | data = [] 118 | for text in labels[3::2]: # 切片 获取Entry, 再将其上面的文本内容添加到data里 119 | data.append(text.get()) 120 | data.append(tree.item(elem, 'values')[0]) 121 | try: 122 | execute_sql(sql % tuple(data)) # 字符串格式化 123 | tkinter.messagebox.showinfo("SUCCEED", "修改成功!") 124 | show_all() 125 | win.destroy() 126 | except pymysql.Error: 127 | tkinter.messagebox.showerror("ERROR", "输入有误!") 128 | win.focus() 129 | 130 | Button(win, text='确认修改', command=lambda: confirm()).pack() 131 | else: 132 | tkinter.messagebox.showerror("ERROR", "未选择顾客!") 133 | 134 | def delete(): # 删除顾客信息 135 | if is_select(): 136 | if tkinter.messagebox.askokcancel('警告', '确认注销账号吗,您的所有积分将会丢失?'): 137 | for elem in tree.selection(): 138 | try: 139 | execute_sql("delete from customerUser where userId='{}'".format(tree.item(elem, 'values')[0])) 140 | tkinter.messagebox.showinfo('Succeed', '注销成功!') 141 | tkinter.messagebox.showinfo('即将退出', '期待您的再次使用') 142 | sys.exit(0) 143 | except pymysql.Error: 144 | tkinter.messagebox.showerror('Failed', '删除失败!') 145 | else: 146 | tkinter.messagebox.showerror('ERROR', '未选择!') 147 | 148 | def popup(event): # 弹出右键菜单 149 | popup_menu.post(event.x_root, event.y_root) 150 | if VIPorNOT(userName): 151 | popup_menu.add_command(label='修改信息', command=lambda: alter()) 152 | else: 153 | popup_menu.add_command(label='注册会员', command=lambda: alter()) 154 | popup_menu.add_separator() 155 | popup_menu.add_command(label='注销账号', command=lambda: delete()) 156 | tree.bind("", popup) 157 | 158 | 159 | def personal_notice(window,userName): # 查看个人消息 160 | userId = get_userId(userName) 161 | window.frame_right.destroy() 162 | window.frame_right = Frame(Main.flag.frame_bottom) 163 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 164 | frame_top = Frame(window.frame_right) 165 | frame_top.pack(side='top', fill=BOTH) 166 | frame_bottom = Frame(window.frame_right) 167 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 168 | scrollbar = Scrollbar(frame_bottom) 169 | scrollbar.pack(side='right', fill=Y) 170 | tree = ttk.Treeview(frame_bottom, columns=list(range(3)), show='headings', yscrollcommand=scrollbar.set) 171 | column_name = ["公告编号", "航班编号", "公告内容"] 172 | for i in range(3): 173 | tree.column(str(i), anchor='w') 174 | tree.heading(str(i), text=column_name[i], anchor='w') 175 | tree.pack(fill=BOTH, expand=YES) 176 | for row in get_board(userId): 177 | tree.insert('', 'end', values=row) 178 | scrollbar.config(command=tree.yview) 179 | 180 | 181 | popup_menu = Menu(frame_bottom, tearoff=0) 182 | 183 | 184 | def personal_flight(window,userName=''): # 查询, 统计航班信息 185 | window.frame_right.destroy() 186 | window.frame_right = Frame(Main.flag.frame_bottom) 187 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 188 | frame_top = Frame(window.frame_right) 189 | frame_top.pack(side='top', fill=BOTH) 190 | frame_bottom = Frame(window.frame_right) 191 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 192 | 193 | scrollbar = Scrollbar(frame_bottom) 194 | scrollbar.pack(side='right', fill=Y) 195 | tree = ttk.Treeview(frame_bottom, columns=list(range(8)), show='headings', yscrollcommand=scrollbar.set) 196 | column_name = ["编号", "飞机机型", "出发地","目的地","票价","航空公司", "出发时间", "剩余票量"] 197 | 198 | for i in range(8): 199 | tree.column(str(i), width=100, anchor='w') 200 | tree.heading(str(i), text=column_name[i], anchor='w') 201 | tree.column('3', width=120) 202 | tree.pack(fill=BOTH, expand=YES) 203 | for row in get_flightData(1): 204 | tree.insert('', 'end', values=row) 205 | scrollbar.config(command=tree.yview) 206 | 207 | def show_all(): 208 | [tree.delete(item) for item in tree.get_children()] 209 | for new_row in get_flightData(1): 210 | tree.insert('', 'end', values=new_row) 211 | 212 | def no_search(event): 213 | [tree.delete(item) for item in tree.get_children()] 214 | for row_search in get_flightData(" flightId = '{}'".format(label_list[1].get())): 215 | tree.insert('', 'end', values=row_search) 216 | 217 | def show_no(): 218 | [tree.delete(item) for item in tree.get_children()] 219 | for new_row in get_flightData(" leftTicket>0"): 220 | tree.insert('', 'end', values=new_row) 221 | 222 | def show_yes(): 223 | [tree.delete(item) for item in tree.get_children()] 224 | for new_row in get_flightData(" leftTicket=0"): 225 | tree.insert('', 'end', values=new_row) 226 | 227 | def show_d(event): 228 | [tree.delete(item) for item in tree.get_children()] 229 | for new_row in get_flightData(" departure='{}'".format(get_airportId1(cmb_d.get()))): 230 | tree.insert('', 'end', values=new_row) 231 | 232 | def show_t(event): 233 | [tree.delete(item) for item in tree.get_children()] 234 | for new_row in get_flightData(" terminal='{}'".format(get_airportId1(cmb_t.get()))): 235 | tree.insert('', 'end', values=new_row) 236 | 237 | popup_menu = Menu(frame_bottom, tearoff=0) 238 | 239 | def is_select(): # 判断Treeview中是否有行被选中 240 | flag = False 241 | for elem in tree.selection(): 242 | flag = True 243 | return flag 244 | 245 | def buy(): # 购买机票 246 | if is_select(): 247 | for elem in tree.selection(): 248 | leftTicket = get_leftTicket(tree.item(elem, 'values')[0])-1 249 | if leftTicket<0: 250 | tkinter.messagebox.showinfo("提示", "余票不足,无法购买!") 251 | return 252 | win = Toplevel() 253 | win.grab_set() # 模态 254 | win.focus() 255 | center(win, 300, 400) 256 | seat = ttk.Combobox(win, value=get_seat(tree.item(elem, 'values')[0]), state='readonly') 257 | discount = get_discount(userName) 258 | d_price = int(float(tree.item(elem, 'values')[4]) * discount) 259 | labels = [Label(win, text='购买机票', fg='blue', font=('楷体', 14)), 260 | Label(win, text='航班编号:' + tree.item(elem, 'values')[0]), 261 | Label(win, text='优惠价格:' + str(d_price)), 262 | Label(win, text="乘客姓名"), Entry(win), 263 | Label(win, text="乘客手机号"), Entry(win), 264 | Label(win, text="选择座位"), seat] 265 | for l in labels: 266 | l.pack() 267 | 268 | 269 | def confirm(): # 确认添加事件 270 | string_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) 271 | new_points = get_points(userName)+int(tree.item(elem, 'values')[4]) 272 | sql1= "insert into ticket values ('%s','%s','%s','%s','%s','%s','%s','%s','%s')" 273 | sql2= "update flight set leftTicket = {} where flightId = {}".format(leftTicket,tree.item(elem, 'values')[0]) 274 | sql3= "update customerUser set point = {} where userName = '{}'".format(new_points,userName) 275 | data = [string_time,get_userId(userName),tree.item(elem, 'values')[0],get_companyId(tree.item(elem, 'values')[5]), labels[8].get(),labels[4].get(),labels[6].get(), d_price,time.strftime("%Y/%m/%d", time.localtime())] 276 | try: 277 | execute_sql(sql1 % tuple(data)) # 添加购买记录 278 | execute_sql(sql2) # 更新余票数额 279 | execute_sql(sql3) # 更新用户积分 280 | tkinter.messagebox.showinfo("SUCCEED", "购买成功!") 281 | show_all() 282 | win.destroy() 283 | except pymysql.Error: 284 | tkinter.messagebox.showerror("ERROR", "输入有误!") 285 | win.focus() 286 | Button(win, text='确认购买', command=lambda: confirm()).pack() 287 | else: 288 | tkinter.messagebox.showerror("ERROR", "未选择航班!") 289 | 290 | def popup(event): # 弹出右键菜单 291 | popup_menu.post(event.x_root, event.y_root) 292 | 293 | def price_sort(): 294 | [tree.delete(item) for item in tree.get_children()] 295 | for new_row in get_flightData(" 1 order by ticketMoney"): 296 | tree.insert('', 'end', values=new_row) 297 | 298 | def time_sort(): 299 | [tree.delete(item) for item in tree.get_children()] 300 | for new_row in get_flightData(" 1 order by leaveTime"): 301 | tree.insert('', 'end', values=new_row) 302 | 303 | tree.heading("0", text="航班编号", command=lambda: show_all()) # 点击表头排序 304 | tree.heading("4", text="票价", command=lambda: price_sort()) # 点击表头排序 305 | tree.heading("6", text="出发时间", command=lambda: time_sort()) # 点击表头排序 306 | 307 | popup_menu.add_command(label='购买', command=lambda: buy()) 308 | 309 | 310 | Label(frame_top, text='查询售票 :', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 311 | Label(frame_top, text='出发地').pack(side="left", fill=X, expand=YES, padx=3, pady=2) 312 | cmb_d = ttk.Combobox(frame_top, value=get_airportName('all'), state='readonly', width=5) 313 | cmb_d.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 314 | cmb_d.bind("<>", show_d) 315 | 316 | Label(frame_top, text='目的地').pack(side="left", fill=X, expand=YES, padx=3, pady=2) 317 | cmb_t = ttk.Combobox(frame_top, value=get_airportName('all'), state='readonly', width=5) 318 | cmb_t.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 319 | cmb_t.bind("<>", show_t) 320 | 321 | Label(frame_top, text='价格区间').pack(side="left", fill=X, expand=YES, padx=3, pady=2) 322 | left = Entry(frame_top, width=8) 323 | left.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 324 | Label(frame_top, text='至').pack(side="left", fill=X, expand=YES, padx=0, pady=2) 325 | right = Entry(frame_top, width=8) 326 | right.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 327 | 328 | def range_search(event): 329 | [tree.delete(item) for item in tree.get_children()] 330 | for new_row in get_flightData(" ticketMoney>={} and ticketMoney<={};".format(left.get(), right.get())): 331 | tree.insert('', 'end', values=new_row) 332 | right.bind('', range_search) 333 | button_no = Button(frame_top, text='未售空', font=('楷体', 12), command=show_no) 334 | button_yes = Button(frame_top, text='已售空', font=('楷体', 12), command=show_yes) 335 | button = Button(frame_top, text='显示所有', font=('楷体', 12), command=show_all) 336 | button_no.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 337 | button_yes.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 338 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 339 | tree.bind("", popup) 340 | 341 | 342 | def personal_ticket(window,username): # 查询个人票务信息 343 | window.frame_right.destroy() 344 | window.frame_right = Frame(Main.flag.frame_bottom) 345 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 346 | frame_top = Frame(window.frame_right) 347 | frame_top.pack(side='top', fill=BOTH) 348 | frame_bottom = Frame(window.frame_right) 349 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 350 | Label(frame_top, text='查询个人票务信息:', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 351 | label_list = [Label(frame_top, text='顾客姓名'), Entry(frame_top, width=10), 352 | Label(frame_top, text='航班编号'), Entry(frame_top, width=10), 353 | Label(frame_top, text='选择所属公司')] 354 | for label in label_list: 355 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 356 | scrollbar = Scrollbar(frame_bottom) 357 | scrollbar.pack(side='right', fill=Y) 358 | tree = ttk.Treeview(frame_bottom, columns=list(range(9)), show='headings', yscrollcommand=scrollbar.set) 359 | column_name = ["订单号", "用户ID", "航班ID", "航空公司", "座位号", "乘客姓名", 360 | "电话号码", "售票价格","销售日期"] 361 | for i in range(9): 362 | tree.column(str(i), width=50, anchor='w') 363 | tree.heading(str(i), text=column_name[i], anchor='w') 364 | tree.column('6', width=100) 365 | tree.column('5', width=80) 366 | tree.column('8', width=120) 367 | tree.column('7', width=80) 368 | tree.pack(fill=BOTH, expand=YES) 369 | user_id = get_userId(username) 370 | for row in get_ticketData(" userId = '{}'".format(user_id)): 371 | tree.insert('', 'end', values=row) 372 | scrollbar.config(command=tree.yview) 373 | 374 | def show_all(): # 显示所有销售信息 375 | [tree.delete(item) for item in tree.get_children()] 376 | for new_row in get_ticketData(' userId = {}'.format(user_id)): 377 | tree.insert('', 'end', values=new_row) 378 | 379 | def cname_search(event): # 按顾客姓名查找 380 | [tree.delete(item) for item in tree.get_children()] 381 | for row_search in get_ticketData(" userId = {} and passagerName like '%{}%'".format(user_id,label_list[1].get())): 382 | tree.insert('', 'end', values=row_search) 383 | 384 | def pno_search(event): # 按飞机编号查找 385 | [tree.delete(item) for item in tree.get_children()] 386 | for row_search in get_ticketData(" flightId = {} and userId = {}".format(label_list[3].get(),user_id)): 387 | tree.insert('', 'end', values=row_search) 388 | 389 | popup_menu = Menu(frame_bottom, tearoff=0) 390 | 391 | def is_select(): # 判断Treeview中是否有行被选中 392 | flag = False 393 | for elem in tree.selection(): 394 | flag = True 395 | return flag 396 | 397 | def alter(): # 修改销售信息 398 | if is_select(): 399 | for elem in tree.selection(): 400 | win = Toplevel() 401 | win.grab_set() # 模态 402 | win.focus() 403 | center(win, 300, 300) 404 | labels = [Label(win, text='修改销售信息', fg='blue', font=('楷体', 14)), 405 | Label(win, text='订单编号:' + tree.item(elem, 'values')[0]), 406 | Label(win, text="乘客姓名"), Entry(win), 407 | Label(win, text="手机号码"), Entry(win)] 408 | for l in labels: 409 | l.pack() 410 | def confirm(): 411 | sql_update = "update ticket set passagerName='%s', passagerPhone='%s' where ticketId= '%s'" 412 | data = (labels[3].get(), labels[5].get(), tree.item(elem, 'values')[0]) 413 | try: 414 | execute_sql(sql_update % data) 415 | tkinter.messagebox.showinfo("SUCCEED", "修改成功") 416 | win.destroy() 417 | show_all() 418 | except pymysql.Error: 419 | tkinter.messagebox.showerror("Failed", "修改失败") 420 | win.focus() 421 | 422 | Button(win, text='确认修改', command=lambda: confirm()).pack(pady=20) 423 | else: 424 | tkinter.messagebox.showerror("ERROR", "未选择机票信息!") 425 | 426 | def delete(): # 删除机票信息 427 | if is_select(): 428 | if tkinter.messagebox.askokcancel('警告', '确认退订该机票吗?'): 429 | for elem in tree.selection(): 430 | try: 431 | new_points = get_points(username)-int(tree.item(elem, 'values')[7]) 432 | sql= "update customerUser set point = {} where userName = '{}'".format(new_points,username) 433 | execute_sql(sql) 434 | execute_sql("delete from ticket where ticketId='{}'".format(tree.item(elem, 'values')[0])) 435 | tkinter.messagebox.showinfo('Succeed', '删除成功!') 436 | show_all() 437 | except pymysql.Error: 438 | tkinter.messagebox.showerror('Failed', '删除失败!') 439 | else: 440 | tkinter.messagebox.showerror('ERROR', '未选择机票信息!') 441 | 442 | def popup(event): # 弹出右键菜单 443 | popup_menu.post(event.x_root, event.y_root) 444 | 445 | def price_sort(): 446 | [tree.delete(item) for item in tree.get_children()] 447 | for new_row in get_ticketData("1 order by paidMoney"): 448 | tree.insert('', 'end', values=new_row) 449 | 450 | def date_sort(): 451 | [tree.delete(item) for item in tree.get_children()] 452 | for new_row in get_ticketData("1 order by paidTime"): 453 | tree.insert('', 'end', values=new_row) 454 | 455 | tree.heading("7", text="单价", command=lambda: price_sort()) # 点击表头排序 456 | tree.heading("8", text="销售日期", command=lambda: date_sort()) # 点击表头排序 457 | 458 | popup_menu.add_command(label='修改乘客', command=lambda: alter()) 459 | popup_menu.add_separator() 460 | popup_menu.add_command(label='退票', command=lambda: delete()) 461 | 462 | label_list[1].bind('', cname_search) # 回车 按顾客姓名查询 463 | label_list[3].bind('', pno_search) # 回车 按宠物编号查询 464 | 465 | def show(event): 466 | [tree.delete(item) for item in tree.get_children()] 467 | for new_row in get_ticketData(" ticket.companyId ={}".format(cmb.get())): 468 | tree.insert('', 'end', values=new_row) 469 | 470 | cmb = ttk.Combobox(frame_top, value=get_companyId('ticket'), state='readonly', width=5) 471 | cmb.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 472 | cmb.bind("<>", show) 473 | 474 | button = Button(frame_top, text='显示所有', font=('楷体', 14), command=show_all) 475 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 476 | tree.bind("", popup) 477 | 478 | 479 | def search_client(window): # 查询, 统计客户信息 480 | window.frame_right.destroy() 481 | window.frame_right = Frame(Main.flag.frame_bottom) 482 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 483 | frame_top = Frame(window.frame_right) 484 | frame_top.pack(side='top', fill=BOTH) 485 | frame_bottom = Frame(window.frame_right) 486 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 487 | Label(frame_top, text='查询统计顾客信息:', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 488 | label_list = [Label(frame_top, text='顾客编号:'), Entry(frame_top), Label(frame_top, text='顾客姓名:'), 489 | Entry(frame_top)] 490 | for label in label_list: 491 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 492 | scrollbar = Scrollbar(frame_bottom) 493 | scrollbar.pack(side='right', fill=Y) 494 | tree = ttk.Treeview(frame_bottom, columns=list(range(5)), show='headings', yscrollcommand=scrollbar.set) 495 | column_name = ["顾客编号", "姓名", "性别", "联系电话","积分"] 496 | for i in range(5): 497 | tree.column(str(i), anchor='w') 498 | tree.heading(str(i), text=column_name[i], anchor='w') 499 | tree.pack(fill=BOTH, expand=YES) 500 | for row in get_userData('vip = 1'): 501 | tree.insert('', 'end', values=row) 502 | scrollbar.config(command=tree.yview) 503 | 504 | def show_all(): 505 | [tree.delete(item) for item in tree.get_children()] 506 | for new_row in get_userData(1): 507 | tree.insert('', 'end', values=new_row) 508 | 509 | def no_search(event): 510 | [tree.delete(item) for item in tree.get_children()] 511 | sql = "SELECT * FROM psms.client where cno={}" 512 | for row_search in get_userData('userId = {}'.format(label_list[1].get())): 513 | tree.insert('', 'end', values=row_search) 514 | 515 | def name_search(event): 516 | [tree.delete(item) for item in tree.get_children()] 517 | for row_search in get_userData(" realName like '%{}%'".format(label_list[3].get())): 518 | tree.insert('', 'end', values=row_search) 519 | 520 | popup_menu = Menu(frame_bottom, tearoff=0) 521 | 522 | def is_select(): # 判断Treeview中是否有行被选中 523 | flag = False 524 | for elem in tree.selection(): 525 | flag = True 526 | return flag 527 | 528 | def alter(): # 修改顾客信息 529 | if is_select(): 530 | for elem in tree.selection(): 531 | win = Toplevel() 532 | win.grab_set() # 模态 533 | win.focus() 534 | center(win, 300, 400) 535 | labels = [Label(win, text='修改顾客信息', fg='blue', font=('楷体', 14)), 536 | Label(win, text='顾客编号:' + tree.item(elem, 'values')[0]), 537 | Label(win, text="姓名"), Entry(win), 538 | Label(win, text="性别"), Entry(win), 539 | Label(win, text="积分"), Entry(win), 540 | Label(win, text="联系电话"), Entry(win)] 541 | for l in labels: 542 | l.pack() 543 | 544 | def confirm(): # 确认添加事件 545 | sql = "update customerUser set realName='%s', sex='%s', point='%s', phone='%s' where userId='%s'" 546 | data = [] 547 | for text in labels[3::2]: # 切片 获取Entry, 再将其上面的文本内容添加到data里 548 | data.append(text.get()) 549 | data.append(tree.item(elem, 'values')[0]) 550 | try: 551 | execute_sql(sql % tuple(data)) # 字符串格式化 552 | tkinter.messagebox.showinfo("SUCCEED", "修改成功!") 553 | show_all() 554 | win.destroy() 555 | except pymysql.Error: 556 | tkinter.messagebox.showerror("ERROR", "输入有误!") 557 | win.focus() 558 | 559 | Button(win, text='确认修改', command=lambda: confirm()).pack() 560 | else: 561 | tkinter.messagebox.showerror("ERROR", "未选择顾客!") 562 | 563 | def delete(): # 删除顾客信息 564 | if is_select(): 565 | if tkinter.messagebox.askokcancel('警告', '确认删除该顾客信息吗?'): 566 | for elem in tree.selection(): 567 | try: 568 | execute_sql("delete from customerUser where userId='{}'".format(tree.item(elem, 'values')[0])) 569 | tkinter.messagebox.showinfo('Succeed', '删除成功!') 570 | show_all() 571 | except pymysql.Error: 572 | tkinter.messagebox.showerror('Failed', '删除失败!') 573 | else: 574 | tkinter.messagebox.showerror('ERROR', '未选择顾客!') 575 | 576 | def popup(event): # 弹出右键菜单 577 | popup_menu.post(event.x_root, event.y_root) 578 | popup_menu.add_command(label='修改', command=lambda: alter()) 579 | popup_menu.add_separator() 580 | popup_menu.add_command(label='删除', command=lambda: delete()) 581 | label_list[1].bind('', no_search) 582 | label_list[3].bind('', name_search) 583 | button = Button(frame_top, text='显示所有', font=('楷体', 14), command=show_all) 584 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 585 | tree.bind("", popup) 586 | 587 | 588 | def search_flight(window,userName='',usertype = 0): # 查询, 统计航班信息 589 | window.frame_right.destroy() 590 | window.frame_right = Frame(Main.flag.frame_bottom) 591 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 592 | frame_top = Frame(window.frame_right) 593 | frame_top.pack(side='top', fill=BOTH) 594 | frame_bottom = Frame(window.frame_right) 595 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 596 | Label(frame_top, text='查询售票 :', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 597 | label_list = [Label(frame_top, text='机票编号'), Entry(frame_top, width=7), Label(frame_top, text='选择飞机类型')] 598 | for label in label_list: 599 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 600 | scrollbar = Scrollbar(frame_bottom) 601 | scrollbar.pack(side='right', fill=Y) 602 | tree = ttk.Treeview(frame_bottom, columns=list(range(8)), show='headings', yscrollcommand=scrollbar.set) 603 | column_name = ["编号", "飞机机型", "出发地","目的地","票价","航空公司", "出发时间", "剩余票量"] 604 | 605 | for i in range(8): 606 | tree.column(str(i), width=100, anchor='w') 607 | tree.heading(str(i), text=column_name[i], anchor='w') 608 | tree.column('3', width=120) 609 | tree.pack(fill=BOTH, expand=YES) 610 | for row in get_flightData(1): 611 | tree.insert('', 'end', values=row) 612 | scrollbar.config(command=tree.yview) 613 | 614 | def show_all(): 615 | [tree.delete(item) for item in tree.get_children()] 616 | for new_row in get_flightData(1): 617 | tree.insert('', 'end', values=new_row) 618 | 619 | def no_search(event): 620 | [tree.delete(item) for item in tree.get_children()] 621 | for row_search in get_flightData(" flightId = '{}'".format(label_list[1].get())): 622 | tree.insert('', 'end', values=row_search) 623 | 624 | def show_no(): 625 | [tree.delete(item) for item in tree.get_children()] 626 | for new_row in get_flightData(" leftTicket>0"): 627 | tree.insert('', 'end', values=new_row) 628 | 629 | def show_yes(): 630 | [tree.delete(item) for item in tree.get_children()] 631 | for new_row in get_flightData(" leftTicket=0"): 632 | tree.insert('', 'end', values=new_row) 633 | 634 | popup_menu = Menu(frame_bottom, tearoff=0) 635 | 636 | def is_select(): # 判断Treeview中是否有行被选中 637 | flag = False 638 | for elem in tree.selection(): 639 | flag = True 640 | return flag 641 | 642 | def buy(): # 购买机票 643 | if is_select(): 644 | for elem in tree.selection(): 645 | leftTicket = get_leftTicket(tree.item(elem, 'values')[0])-1 646 | if leftTicket<0: 647 | tkinter.messagebox.showinfo("提示", "余票不足,无法购买!") 648 | return 649 | win = Toplevel() 650 | win.grab_set() # 模态 651 | win.focus() 652 | center(win, 300, 400) 653 | seat = ttk.Combobox(win, value=get_seat(tree.item(elem, 'values')[0]), state='readonly') 654 | discount = get_discount(userName) 655 | d_price = int(float(tree.item(elem, 'values')[4]) * discount) 656 | labels = [Label(win, text='购买机票', fg='blue', font=('楷体', 14)), 657 | Label(win, text='航班编号:' + tree.item(elem, 'values')[0]), 658 | Label(win, text='优惠价格:' + str(d_price)), 659 | Label(win, text="乘客姓名"), Entry(win), 660 | Label(win, text="乘客手机号"), Entry(win), 661 | Label(win, text="选择座位"), seat] 662 | for l in labels: 663 | l.pack() 664 | 665 | 666 | def confirm(): # 确认添加事件 667 | string_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) 668 | new_points = get_points(userName)+int(tree.item(elem, 'values')[4]) 669 | sql1= "insert into ticket values ('%s','%s','%s','%s','%s','%s','%s','%s','%s')" 670 | sql2= "update flight set leftTicket = {} where flightId = {}".format(leftTicket,tree.item(elem, 'values')[0]) 671 | sql3= "update customerUser set point = {} where userName = '{}'".format(new_points,userName) 672 | data = [string_time,get_userId(userName),tree.item(elem, 'values')[0],get_companyId(tree.item(elem, 'values')[5]), labels[8].get(),labels[4].get(),labels[6].get(), d_price,time.strftime("%Y/%m/%d", time.localtime())] 673 | try: 674 | execute_sql(sql1 % tuple(data)) # 添加购买记录 675 | execute_sql(sql2) # 更新余票数额 676 | execute_sql(sql3) # 更新用户积分 677 | tkinter.messagebox.showinfo("SUCCEED", "购买成功!") 678 | show_all() 679 | win.destroy() 680 | except pymysql.Error: 681 | tkinter.messagebox.showerror("ERROR", "输入有误!") 682 | win.focus() 683 | Button(win, text='确认购买', command=lambda: confirm()).pack() 684 | else: 685 | tkinter.messagebox.showerror("ERROR", "未选择航班!") 686 | 687 | def alter(): # 修改航班信息 688 | if is_select(): 689 | for elem in tree.selection(): 690 | win = Toplevel() 691 | win.grab_set() # 模态 692 | win.focus() 693 | center(win, 300, 400) 694 | labels = [Label(win, text='修改航班信息', fg='blue', font=('楷体', 14)), 695 | Label(win, text='航班编号:' + tree.item(elem, 'values')[0]), 696 | Label(win, text="出发时间"), Entry(win), 697 | Label(win, text="票价"), Entry(win), 698 | Label(win, text="出发地"), Entry(win), 699 | Label(win, text="目的地"), Entry(win), 700 | Label(win, text="余票数量"), Entry(win)] 701 | for l in labels: 702 | l.pack() 703 | 704 | def confirm(): # 确认添加事件 705 | sql = "update flight set plane='%s',leaveTime=%s, ticketMoney=%s, departure'%s', terminal='%s' where flightId='%s'" 706 | data = [] 707 | for text in labels[3::2]: # 切片 获取Entry, 再将其上面的文本内容添加到data里 708 | data.append(text.get()) 709 | data.append(tree.item(elem, 'values')[0]) 710 | try: 711 | execute_sql(sql % tuple(data)) # 字符串格式化 712 | tkinter.messagebox.showinfo("SUCCEED", "修改成功!") 713 | show_all() 714 | win.destroy() 715 | except pymysql.Error: 716 | tkinter.messagebox.showerror("ERROR", "输入有误!") 717 | win.focus() 718 | Button(win, text='确认修改', command=lambda: confirm()).pack() 719 | else: 720 | tkinter.messagebox.showerror("ERROR", "未选择航班!") 721 | 722 | def delete(): # 删除航班信息 723 | if is_select(): 724 | if tkinter.messagebox.askokcancel('警告', '确认删除航班信息吗?'): 725 | for elem in tree.selection(): 726 | try: 727 | execute_sql("delete from flight where flightId='{}'".format(tree.item(elem, 'values')[0])) 728 | tkinter.messagebox.showinfo('Succeed', '删除成功!') 729 | show_all() 730 | except pymysql.Error: 731 | tkinter.messagebox.showerror('Failed', '删除失败!') 732 | else: 733 | tkinter.messagebox.showerror('ERROR', '未选择航班!') 734 | 735 | def popup(event): # 弹出右键菜单 736 | popup_menu.post(event.x_root, event.y_root) 737 | 738 | def price_sort(): 739 | [tree.delete(item) for item in tree.get_children()] 740 | for new_row in get_flightData(" 1 order by ticketMoney"): 741 | tree.insert('', 'end', values=new_row) 742 | 743 | def time_sort(): 744 | [tree.delete(item) for item in tree.get_children()] 745 | for new_row in get_flightData(" 1 order by leaveTime"): 746 | tree.insert('', 'end', values=new_row) 747 | 748 | tree.heading("0", text="航班编号", command=lambda: show_all()) # 点击表头排序 749 | tree.heading("4", text="票价", command=lambda: price_sort()) # 点击表头排序 750 | tree.heading("6", text="出发时间", command=lambda: time_sort()) # 点击表头排序 751 | 752 | if usertype == 1: 753 | popup_menu.add_command(label='购买', command=lambda: buy()) 754 | else: 755 | popup_menu.add_command(label='修改', command=lambda: alter()) 756 | popup_menu.add_separator() 757 | popup_menu.add_command(label='删除', command=lambda: delete()) 758 | 759 | label_list[1].bind('', no_search) # 回车 按航班编号查询 760 | 761 | def show(event): 762 | [tree.delete(item) for item in tree.get_children()] 763 | for new_row in get_flightData(" plane='{}'".format(cmb.get())): 764 | tree.insert('', 'end', values=new_row) 765 | 766 | type_p = [] 767 | for result in execute_sql("select distinct plane from flight"): 768 | type_p.append(result) 769 | cmb = ttk.Combobox(frame_top, value=type_p, state='readonly', width=5) # 添加选择宠物类型的下拉列表 770 | cmb.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 771 | cmb.bind("<>", show) 772 | Label(frame_top, text='价格区间').pack(side="left", fill=X, expand=YES, padx=3, pady=2) 773 | left = Entry(frame_top, width=8) 774 | left.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 775 | Label(frame_top, text='至').pack(side="left", fill=X, expand=YES, padx=0, pady=2) 776 | right = Entry(frame_top, width=8) 777 | right.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 778 | 779 | def range_search(event): 780 | [tree.delete(item) for item in tree.get_children()] 781 | for new_row in get_flightData(" ticketMoney>={} and ticketMoney<={};".format(left.get(), right.get())): 782 | tree.insert('', 'end', values=new_row) 783 | right.bind('', range_search) 784 | button_no = Button(frame_top, text='未售空', font=('楷体', 12), command=show_no) 785 | button_yes = Button(frame_top, text='已售空', font=('楷体', 12), command=show_yes) 786 | button = Button(frame_top, text='显示所有', font=('楷体', 12), command=show_all) 787 | button_no.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 788 | button_yes.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 789 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 790 | tree.bind("", popup) 791 | 792 | 793 | def airport_flight(window,userName=''): # 查询机场航班信息 794 | window.frame_right.destroy() 795 | window.frame_right = Frame(Main.flag.frame_bottom) 796 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 797 | frame_top = Frame(window.frame_right) 798 | frame_top.pack(side='top', fill=BOTH) 799 | frame_bottom = Frame(window.frame_right) 800 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 801 | Label(frame_top, text='查询售票 :', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 802 | label_list = [Label(frame_top, text='机票编号'), Entry(frame_top, width=7), Label(frame_top, text='选择飞机类型')] 803 | for label in label_list: 804 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 805 | scrollbar = Scrollbar(frame_bottom) 806 | scrollbar.pack(side='right', fill=Y) 807 | tree = ttk.Treeview(frame_bottom, columns=list(range(8)), show='headings', yscrollcommand=scrollbar.set) 808 | column_name = ["编号", "飞机机型", "出发地","目的地","票价","航空公司", "出发时间", "剩余票量"] 809 | airportId = get_airportId(userName) 810 | for i in range(8): 811 | tree.column(str(i), width=100, anchor='w') 812 | tree.heading(str(i), text=column_name[i], anchor='w') 813 | tree.column('3', width=120) 814 | tree.pack(fill=BOTH, expand=YES) 815 | for row in get_airport_flightData(airportId,1): 816 | tree.insert('', 'end', values=row) 817 | scrollbar.config(command=tree.yview) 818 | 819 | def show_all(): 820 | [tree.delete(item) for item in tree.get_children()] 821 | for new_row in get_airport_flightData(airportId,1): 822 | tree.insert('', 'end', values=new_row) 823 | 824 | def no_search(event): 825 | [tree.delete(item) for item in tree.get_children()] 826 | for row_search in get_airport_flightData(airportId," flightId = '{}'".format(label_list[1].get())): 827 | tree.insert('', 'end', values=row_search) 828 | 829 | def show_no(): 830 | [tree.delete(item) for item in tree.get_children()] 831 | for new_row in get_airport_flightData(airportId," leftTicket>0"): 832 | tree.insert('', 'end', values=new_row) 833 | 834 | def show_yes(): 835 | [tree.delete(item) for item in tree.get_children()] 836 | for new_row in get_airport_flightData(airportId," leftTicket=0"): 837 | tree.insert('', 'end', values=new_row) 838 | 839 | popup_menu = Menu(frame_bottom, tearoff=0) 840 | 841 | def is_select(): # 判断Treeview中是否有行被选中 842 | flag = False 843 | for elem in tree.selection(): 844 | flag = True 845 | return flag 846 | 847 | def alter(): # 修改航班信息 848 | if is_select(): 849 | for elem in tree.selection(): 850 | win = Toplevel() 851 | win.grab_set() # 模态 852 | win.focus() 853 | center(win, 300, 400) 854 | c = tkinter.IntVar() 855 | c.set(1) 856 | check = tkinter.Checkbutton(win,text='通知已购票用户',variable = c,onvalue =1,offvalue=2) 857 | labels = [Label(win, text='修改航班信息', fg='blue', font=('楷体', 14)), 858 | Label(win, text='航班编号:' + tree.item(elem, 'values')[0]), 859 | Label(win, text="出发时间"), Entry(win), 860 | Label(win, text="票价"), Entry(win), 861 | Label(win, text="出发地"), Entry(win), 862 | Label(win, text="目的地"), Entry(win), 863 | Label(win, text="余票数量"), Entry(win)] 864 | for l in labels: 865 | l.pack() 866 | check.pack() 867 | 868 | def confirm(): # 确认添加事件 869 | sql = "update flight set leaveTime='%s', ticketMoney=%s, departure = '%s', terminal='%s',leftTicket = '%s' where flightId='%s'" 870 | 871 | data = [] 872 | for text in labels[3::2]: # 切片 获取Entry, 再将其上面的文本内容添加到data里 873 | data.append(text.get()) 874 | data.append(tree.item(elem, 'values')[0]) 875 | try: 876 | if c.get() == 1: 877 | add_board(tree.item(elem, 'values')[0],labels[3].get()) #添加公告,提示所有预定了此航班的乘客 878 | execute_sql(sql % tuple(data)) # 字符串格式化 879 | tkinter.messagebox.showinfo("SUCCEED", "修改成功!") 880 | show_all() 881 | win.destroy() 882 | except pymysql.Error: 883 | tkinter.messagebox.showerror("ERROR", "输入有误!") 884 | win.focus() 885 | Button(win, text='确认修改', command=lambda: confirm()).pack() 886 | else: 887 | tkinter.messagebox.showerror("ERROR", "未选择航班!") 888 | 889 | def delete(): # 删除航班信息 890 | if is_select(): 891 | if tkinter.messagebox.askokcancel('警告', '确认删除航班信息吗?'): 892 | for elem in tree.selection(): 893 | try: 894 | execute_sql("delete from flight where flightId='{}'".format(tree.item(elem, 'values')[0])) 895 | tkinter.messagebox.showinfo('Succeed', '删除成功!') 896 | show_all() 897 | except pymysql.Error: 898 | tkinter.messagebox.showerror('Failed', '删除失败!') 899 | else: 900 | tkinter.messagebox.showerror('ERROR', '未选择航班!') 901 | 902 | def popup(event): # 弹出右键菜单 903 | popup_menu.post(event.x_root, event.y_root) 904 | 905 | def price_sort(): 906 | [tree.delete(item) for item in tree.get_children()] 907 | for new_row in get_airport_flightData(airportId," 1 order by ticketMoney"): 908 | tree.insert('', 'end', values=new_row) 909 | 910 | def time_sort(): 911 | [tree.delete(item) for item in tree.get_children()] 912 | for new_row in get_airport_flightData(airportId," 1 order by leaveTime"): 913 | tree.insert('', 'end', values=new_row) 914 | 915 | tree.heading("0", text="航班编号", command=lambda: show_all()) # 点击表头排序 916 | tree.heading("4", text="票价", command=lambda: price_sort()) # 点击表头排序 917 | tree.heading("6", text="出发时间", command=lambda: time_sort()) # 点击表头排序 918 | 919 | popup_menu.add_command(label='修改', command=lambda: alter()) 920 | popup_menu.add_separator() 921 | popup_menu.add_command(label='删除', command=lambda: delete()) 922 | 923 | label_list[1].bind('', no_search) # 回车 按航班编号查询 924 | 925 | def show(event): 926 | [tree.delete(item) for item in tree.get_children()] 927 | for new_row in get_airport_flightData(airportId," plane='{}'".format(cmb.get())): 928 | tree.insert('', 'end', values=new_row) 929 | 930 | type_p = [] 931 | for result in execute_sql("select distinct plane from flight"): 932 | type_p.append(result) 933 | cmb = ttk.Combobox(frame_top, value=type_p, state='readonly', width=5) # 添加选择宠物类型的下拉列表 934 | cmb.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 935 | cmb.bind("<>", show) 936 | Label(frame_top, text='价格区间').pack(side="left", fill=X, expand=YES, padx=3, pady=2) 937 | left = Entry(frame_top, width=8) 938 | left.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 939 | Label(frame_top, text='至').pack(side="left", fill=X, expand=YES, padx=0, pady=2) 940 | right = Entry(frame_top, width=8) 941 | right.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 942 | 943 | def range_search(event): 944 | [tree.delete(item) for item in tree.get_children()] 945 | for new_row in get_airport_flightData(airportId," ticketMoney>={} and ticketMoney<={};".format(left.get(), right.get())): 946 | tree.insert('', 'end', values=new_row) 947 | right.bind('', range_search) 948 | button_no = Button(frame_top, text='未售空', font=('楷体', 12), command=show_no) 949 | button_yes = Button(frame_top, text='已售空', font=('楷体', 12), command=show_yes) 950 | button = Button(frame_top, text='显示所有', font=('楷体', 12), command=show_all) 951 | button_no.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 952 | button_yes.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 953 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 954 | tree.bind("", popup) 955 | 956 | 957 | def company_flight(window,userName=''): # 查询公司航班信息 958 | window.frame_right.destroy() 959 | window.frame_right = Frame(Main.flag.frame_bottom) 960 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 961 | frame_top = Frame(window.frame_right) 962 | frame_top.pack(side='top', fill=BOTH) 963 | frame_bottom = Frame(window.frame_right) 964 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 965 | Label(frame_top, text='查询售票 :', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 966 | label_list = [Label(frame_top, text='机票编号'), Entry(frame_top, width=7), Label(frame_top, text='选择飞机类型')] 967 | for label in label_list: 968 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 969 | scrollbar = Scrollbar(frame_bottom) 970 | scrollbar.pack(side='right', fill=Y) 971 | tree = ttk.Treeview(frame_bottom, columns=list(range(8)), show='headings', yscrollcommand=scrollbar.set) 972 | column_name = ["编号", "飞机机型", "出发地","目的地","票价","航空公司", "出发时间", "剩余票量"] 973 | 974 | for i in range(8): 975 | tree.column(str(i), width=100, anchor='w') 976 | tree.heading(str(i), text=column_name[i], anchor='w') 977 | tree.column('3', width=120) 978 | tree.pack(fill=BOTH, expand=YES) 979 | companyId = get_companyId_by_user(userName) 980 | for row in get_flightData2(companyId,1): 981 | tree.insert('', 'end', values=row) 982 | scrollbar.config(command=tree.yview) 983 | 984 | def show_all(): 985 | [tree.delete(item) for item in tree.get_children()] 986 | for new_row in get_flightData2(companyId,1): 987 | tree.insert('', 'end', values=new_row) 988 | 989 | def no_search(event): 990 | [tree.delete(item) for item in tree.get_children()] 991 | for row_search in get_flightData2(companyId," flightId = '{}'".format(label_list[1].get())): 992 | tree.insert('', 'end', values=row_search) 993 | 994 | def show_no(): 995 | [tree.delete(item) for item in tree.get_children()] 996 | for new_row in get_flightData2(companyId," leftTicket>0"): 997 | tree.insert('', 'end', values=new_row) 998 | 999 | def show_yes(): 1000 | [tree.delete(item) for item in tree.get_children()] 1001 | for new_row in get_flightData2(companyId," leftTicket=0"): 1002 | tree.insert('', 'end', values=new_row) 1003 | 1004 | popup_menu = Menu(frame_bottom, tearoff=0) 1005 | 1006 | def is_select(): # 判断Treeview中是否有行被选中 1007 | flag = False 1008 | for elem in tree.selection(): 1009 | flag = True 1010 | return flag 1011 | 1012 | def alter(): # 修改航班信息 1013 | if is_select(): 1014 | for elem in tree.selection(): 1015 | win = Toplevel() 1016 | win.grab_set() # 模态 1017 | win.focus() 1018 | center(win, 300, 400) 1019 | c = tkinter.IntVar() 1020 | check = tkinter.Checkbutton(win,text='通知已购票用户',variable = c,onvalue =1,offvalue=2) 1021 | labels = [Label(win, text='修改航班信息', fg='blue', font=('楷体', 14)), 1022 | Label(win, text='航班编号:' + tree.item(elem, 'values')[0]), 1023 | Label(win, text="出发时间"), Entry(win), 1024 | Label(win, text="票价"), Entry(win), 1025 | Label(win, text="出发地"), Entry(win), 1026 | Label(win, text="目的地"), Entry(win), 1027 | Label(win, text="余票数量"), Entry(win)] 1028 | for l in labels: 1029 | l.pack() 1030 | check.pack() 1031 | def confirm(): # 确认添加事件 1032 | sql = "update flight set plane='%s',leaveTime=%s, ticketMoney=%s, departure='%s', terminal='%s' where flightId='%s'" 1033 | data = [] 1034 | for text in labels[3::2]: # 切片 获取Entry, 再将其上面的文本内容添加到data里 1035 | data.append(text.get()) 1036 | data.append(tree.item(elem, 'values')[0]) 1037 | try: 1038 | if c.get() == 1: 1039 | add_board(tree.item(elem, 'values')[0],labels[3].get()) #添加公告,提示所有预定了此航班的乘客 1040 | execute_sql(sql % tuple(data)) # 字符串格式化 1041 | tkinter.messagebox.showinfo("SUCCEED", "修改成功!") 1042 | show_all() 1043 | win.destroy() 1044 | except pymysql.Error: 1045 | tkinter.messagebox.showerror("ERROR", "输入有误!") 1046 | win.focus() 1047 | Button(win, text='确认修改', command=lambda: confirm()).pack() 1048 | else: 1049 | tkinter.messagebox.showerror("ERROR", "未选择航班!") 1050 | 1051 | def delete(): # 删除航班信息 1052 | if is_select(): 1053 | if tkinter.messagebox.askokcancel('警告', '确认取消该航班吗?'): 1054 | for elem in tree.selection(): 1055 | try: 1056 | if is_saled(tree.item(elem, 'values')[0]): 1057 | tkinter.messagebox.showinfo('Failed', '目前有{}位客户预定了机票,请通知所有用户退订后再删除!'.format(is_saled(tree.item(elem, 'values')[0]))) 1058 | return 1059 | execute_sql("delete from flight where flightId='{}'".format(tree.item(elem, 'values')[0])) 1060 | tkinter.messagebox.showinfo('Succeed', '删除成功!') 1061 | show_all() 1062 | except pymysql.Error: 1063 | tkinter.messagebox.showerror('Failed', '删除失败!') 1064 | else: 1065 | tkinter.messagebox.showerror('ERROR', '未选择航班!') 1066 | 1067 | def popup(event): # 弹出右键菜单 1068 | popup_menu.post(event.x_root, event.y_root) 1069 | 1070 | def price_sort(): 1071 | [tree.delete(item) for item in tree.get_children()] 1072 | for new_row in get_flightData2(companyId," 1 order by ticketMoney"): 1073 | tree.insert('', 'end', values=new_row) 1074 | 1075 | def time_sort(): 1076 | [tree.delete(item) for item in tree.get_children()] 1077 | for new_row in get_flightData2(companyId," 1 order by leaveTime"): 1078 | tree.insert('', 'end', values=new_row) 1079 | 1080 | tree.heading("0", text="航班编号", command=lambda: show_all()) # 点击表头排序 1081 | tree.heading("4", text="票价", command=lambda: price_sort()) # 点击表头排序 1082 | tree.heading("6", text="出发时间", command=lambda: time_sort()) # 点击表头排序 1083 | 1084 | 1085 | popup_menu.add_command(label='修改航班', command=lambda: alter()) 1086 | popup_menu.add_separator() 1087 | popup_menu.add_command(label='取消航班', command=lambda: delete()) 1088 | 1089 | label_list[1].bind('', no_search) # 回车 按航班编号查询 1090 | 1091 | def show(event): 1092 | [tree.delete(item) for item in tree.get_children()] 1093 | for new_row in get_flightData2(companyId," plane='{}'".format(cmb.get())): 1094 | tree.insert('', 'end', values=new_row) 1095 | 1096 | type_p = [] 1097 | for result in execute_sql("select distinct plane from flight"): 1098 | type_p.append(result) 1099 | cmb = ttk.Combobox(frame_top, value=type_p, state='readonly', width=5) # 添加选择宠物类型的下拉列表 1100 | cmb.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 1101 | cmb.bind("<>", show) 1102 | Label(frame_top, text='价格区间').pack(side="left", fill=X, expand=YES, padx=3, pady=2) 1103 | left = Entry(frame_top, width=8) 1104 | left.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 1105 | Label(frame_top, text='至').pack(side="left", fill=X, expand=YES, padx=0, pady=2) 1106 | right = Entry(frame_top, width=8) 1107 | right.pack(side="left", fill=X, expand=YES, padx=0, pady=2) 1108 | 1109 | def range_search(event): 1110 | [tree.delete(item) for item in tree.get_children()] 1111 | for new_row in get_flightData2(companyId," ticketMoney>={} and ticketMoney<={};".format(left.get(), right.get())): 1112 | tree.insert('', 'end', values=new_row) 1113 | right.bind('', range_search) 1114 | button_no = Button(frame_top, text='未售空', font=('楷体', 12), command=show_no) 1115 | button_yes = Button(frame_top, text='已售空', font=('楷体', 12), command=show_yes) 1116 | button = Button(frame_top, text='显示所有', font=('楷体', 12), command=show_all) 1117 | button_no.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 1118 | button_yes.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 1119 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 1120 | tree.bind("", popup) 1121 | 1122 | 1123 | def company_sale(window,userName): # 查询公司票务信息 1124 | companyId = get_companyId_by_user(userName) 1125 | window.frame_right.destroy() 1126 | window.frame_right = Frame(Main.flag.frame_bottom) 1127 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 1128 | frame_top = Frame(window.frame_right) 1129 | frame_top.pack(side='top', fill=BOTH) 1130 | frame_bottom = Frame(window.frame_right) 1131 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 1132 | Label(frame_top, text='查询统计销售信息:', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 1133 | label_list = [Label(frame_top, text='顾客编号'), Entry(frame_top, width=10), 1134 | Label(frame_top, text='顾客姓名'), Entry(frame_top, width=10), 1135 | Label(frame_top, text='航班编号'), Entry(frame_top, width=10), 1136 | Label(frame_top, text='选择所属公司')] 1137 | for label in label_list: 1138 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 1139 | scrollbar = Scrollbar(frame_bottom) 1140 | scrollbar.pack(side='right', fill=Y) 1141 | tree = ttk.Treeview(frame_bottom, columns=list(range(9)), show='headings', yscrollcommand=scrollbar.set) 1142 | column_name = ["订单号", "用户ID", "航班ID", "航空公司", "座位号", "乘客姓名", 1143 | "电话号码", "售票价格","销售日期"] 1144 | for i in range(9): 1145 | tree.column(str(i), width=50, anchor='w') 1146 | tree.heading(str(i), text=column_name[i], anchor='w') 1147 | tree.column('6', width=100) 1148 | tree.column('5', width=80) 1149 | tree.column('8', width=120) 1150 | tree.column('7', width=80) 1151 | tree.pack(fill=BOTH, expand=YES) 1152 | 1153 | for row in get_ticketData(" ticket.companyId = {}".format(companyId)): 1154 | tree.insert('', 'end', values=row) 1155 | scrollbar.config(command=tree.yview) 1156 | 1157 | def show_all(): # 显示所有销售信息 1158 | [tree.delete(item) for item in tree.get_children()] 1159 | for new_row in get_ticketData(" ticket.companyId = {}".format(companyId)): 1160 | tree.insert('', 'end', values=new_row) 1161 | 1162 | def cno_search(event): # 按顾客编号查找 1163 | [tree.delete(item) for item in tree.get_children()] 1164 | for row_search in get_ticketData(" userId = {} and ticket.companyId = {}".format(label_list[1].get(),companyId)): 1165 | tree.insert('', 'end', values=row_search) 1166 | 1167 | def cname_search(event): # 按顾客姓名查找 1168 | [tree.delete(item) for item in tree.get_children()] 1169 | for row_search in get_ticketData(" passagerName like '%{}%' and ticket.companyId = {}".format(label_list[3].get(),companyId)): 1170 | tree.insert('', 'end', values=row_search) 1171 | 1172 | def pno_search(event): # 按航班编号查找 1173 | [tree.delete(item) for item in tree.get_children()] 1174 | for row_search in get_ticketData(" flightId = {} and ticket.companyId = {}".format(label_list[5].get(),companyId)): 1175 | tree.insert('', 'end', values=row_search) 1176 | 1177 | popup_menu = Menu(frame_bottom, tearoff=0) 1178 | 1179 | def is_select(): # 判断Treeview中是否有行被选中 1180 | flag = False 1181 | for elem in tree.selection(): 1182 | flag = True 1183 | return flag 1184 | 1185 | def price_sort(): 1186 | [tree.delete(item) for item in tree.get_children()] 1187 | for new_row in get_ticketData(" ticket.companyId = {} order by paidMoney".format(companyId)): 1188 | tree.insert('', 'end', values=new_row) 1189 | 1190 | def date_sort(): 1191 | [tree.delete(item) for item in tree.get_children()] 1192 | for new_row in get_ticketData(" ticket.companyId = {} order by paidTime".format(companyId)): 1193 | tree.insert('', 'end', values=new_row) 1194 | 1195 | tree.heading("7", text="单价", command=lambda: price_sort()) # 点击表头排序 1196 | tree.heading("8", text="销售日期", command=lambda: date_sort()) # 点击表头排序 1197 | 1198 | 1199 | label_list[1].bind('', cno_search) # 回车 按顾客编号查询 1200 | label_list[3].bind('', cname_search) # 回车 按顾客姓名查询 1201 | label_list[5].bind('', pno_search) # 回车 按编号查询 1202 | 1203 | button = Button(frame_top, text='显示所有', font=('楷体', 14), command=show_all) 1204 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 1205 | 1206 | 1207 | def search_sale(window,userName): # 查询机场票务信息 1208 | window.frame_right.destroy() 1209 | window.frame_right = Frame(Main.flag.frame_bottom) 1210 | window.frame_right.pack(side="right", fill=BOTH, expand=YES) 1211 | frame_top = Frame(window.frame_right) 1212 | frame_top.pack(side='top', fill=BOTH) 1213 | frame_bottom = Frame(window.frame_right) 1214 | frame_bottom.pack(side='bottom', fill=BOTH, expand=YES) 1215 | Label(frame_top, text='查询统计销售信息:', font=('楷体', 18), fg='blue').pack(side='left', fill=BOTH, expand=YES) 1216 | label_list = [Label(frame_top, text='顾客编号'), Entry(frame_top, width=10), 1217 | Label(frame_top, text='顾客姓名'), Entry(frame_top, width=10), 1218 | Label(frame_top, text='航班编号'), Entry(frame_top, width=10), 1219 | Label(frame_top, text='选择所属公司')] 1220 | for label in label_list: 1221 | label.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 1222 | scrollbar = Scrollbar(frame_bottom) 1223 | scrollbar.pack(side='right', fill=Y) 1224 | tree = ttk.Treeview(frame_bottom, columns=list(range(9)), show='headings', yscrollcommand=scrollbar.set) 1225 | column_name = ["订单号", "用户ID", "航班ID", "航空公司", "座位号", "乘客姓名", 1226 | "电话号码", "售票价格","销售日期"] 1227 | for i in range(9): 1228 | tree.column(str(i), width=50, anchor='w') 1229 | tree.heading(str(i), text=column_name[i], anchor='w') 1230 | tree.column('6', width=100) 1231 | tree.column('5', width=80) 1232 | tree.column('8', width=120) 1233 | tree.column('7', width=80) 1234 | tree.pack(fill=BOTH, expand=YES) 1235 | 1236 | for row in get_ticketData(1): 1237 | tree.insert('', 'end', values=row) 1238 | scrollbar.config(command=tree.yview) 1239 | 1240 | def show_all(): # 显示所有销售信息 1241 | [tree.delete(item) for item in tree.get_children()] 1242 | for new_row in get_ticketData(1): 1243 | tree.insert('', 'end', values=new_row) 1244 | 1245 | def cno_search(event): # 按顾客编号查找 1246 | [tree.delete(item) for item in tree.get_children()] 1247 | for row_search in get_ticketData(" userId = {}".format(label_list[1].get())): 1248 | tree.insert('', 'end', values=row_search) 1249 | 1250 | def cname_search(event): # 按顾客姓名查找 1251 | [tree.delete(item) for item in tree.get_children()] 1252 | for row_search in get_ticketData(" passagerName like '%{}%'".format(label_list[3].get())): 1253 | tree.insert('', 'end', values=row_search) 1254 | 1255 | def pno_search(event): # 按宠物编号查找 1256 | [tree.delete(item) for item in tree.get_children()] 1257 | for row_search in get_ticketData(" flightId = {}".format(label_list[5].get())): 1258 | tree.insert('', 'end', values=row_search) 1259 | 1260 | popup_menu = Menu(frame_bottom, tearoff=0) 1261 | 1262 | def is_select(): # 判断Treeview中是否有行被选中 1263 | flag = False 1264 | for elem in tree.selection(): 1265 | flag = True 1266 | return flag 1267 | 1268 | def alter(): # 修改销售信息 1269 | if is_select(): 1270 | for elem in tree.selection(): 1271 | win = Toplevel() 1272 | win.grab_set() # 模态 1273 | win.focus() 1274 | center(win, 300, 600) 1275 | labels = [Label(win, text='修改销售信息', fg='blue', font=('楷体', 14)), 1276 | Label(win, text='订单编号:' + tree.item(elem, 'values')[0]), 1277 | Label(win, text="乘客姓名"), Entry(win), 1278 | Label(win, text="手机号码"), Entry(win)] 1279 | for l in labels: 1280 | l.pack() 1281 | def confirm(): 1282 | sql_update = "update ticket set passagerName='%s', passagerPhone='%s' where ticketId= '%s'" 1283 | data = (labels[3].get(), labels[5].get(), tree.item(elem, 'values')[0]) 1284 | try: 1285 | execute_sql(sql_update % data) 1286 | tkinter.messagebox.showinfo("SUCCEED", "修改成功") 1287 | win.destroy() 1288 | show_all() 1289 | except pymysql.Error: 1290 | tkinter.messagebox.showerror("Failed", "修改失败") 1291 | win.focus() 1292 | 1293 | Button(win, text='确认修改', command=lambda: confirm()).pack(pady=20) 1294 | else: 1295 | tkinter.messagebox.showerror("ERROR", "未选择销售信息!") 1296 | 1297 | def delete(): # 删除宠物信息 1298 | if is_select(): 1299 | if tkinter.messagebox.askokcancel('警告', '确认删除该销售信息吗?'): 1300 | for elem in tree.selection(): 1301 | try: 1302 | execute_sql("delete from ticket where ticketId='{}'".format(tree.item(elem, 'values')[0])) 1303 | tkinter.messagebox.showinfo('Succeed', '删除成功!') 1304 | show_all() 1305 | except pymysql.Error: 1306 | tkinter.messagebox.showerror('Failed', '删除失败!') 1307 | else: 1308 | tkinter.messagebox.showerror('ERROR', '未选择销售信息!') 1309 | 1310 | def popup(event): # 弹出右键菜单 1311 | popup_menu.post(event.x_root, event.y_root) 1312 | 1313 | def price_sort(): 1314 | [tree.delete(item) for item in tree.get_children()] 1315 | for new_row in get_ticketData("1 order by paidMoney"): 1316 | tree.insert('', 'end', values=new_row) 1317 | 1318 | def date_sort(): 1319 | [tree.delete(item) for item in tree.get_children()] 1320 | for new_row in get_ticketData("1 order by paidTime"): 1321 | tree.insert('', 'end', values=new_row) 1322 | 1323 | tree.heading("7", text="单价", command=lambda: price_sort()) # 点击表头排序 1324 | tree.heading("8", text="销售日期", command=lambda: date_sort()) # 点击表头排序 1325 | 1326 | popup_menu.add_command(label='修改', command=lambda: alter()) 1327 | popup_menu.add_separator() 1328 | popup_menu.add_command(label='删除', command=lambda: delete()) 1329 | 1330 | label_list[1].bind('', cno_search) # 回车 按顾客编号查询 1331 | label_list[3].bind('', cname_search) # 回车 按顾客姓名查询 1332 | label_list[5].bind('', pno_search) # 回车 按宠物编号查询 1333 | 1334 | def show(event): 1335 | [tree.delete(item) for item in tree.get_children()] 1336 | for new_row in get_ticketData(" ticket.companyId ={}".format(cmb.get())): 1337 | tree.insert('', 'end', values=new_row) 1338 | 1339 | cmb = ttk.Combobox(frame_top, value=get_companyId('ticket'), state='readonly', width=5) 1340 | cmb.pack(side="left", fill=X, expand=YES, padx=3, pady=2) 1341 | cmb.bind("<>", show) 1342 | 1343 | button = Button(frame_top, text='显示所有', font=('楷体', 14), command=show_all) 1344 | button.pack(side='left', fill=X, expand=YES, padx=3, pady=5) 1345 | tree.bind("", popup) 1346 | 1347 | 1348 | def add_sale(win): # 添加订单信息 1349 | win.frame_right.destroy() 1350 | win.frame_right = Frame(Main.flag.frame_bottom) 1351 | win.frame_right.pack(side='right', fill=BOTH, expand=YES) 1352 | Label(win.frame_right, text="添 加 订 单 信 息:", fg='blue', font=('华文彩云', 16)).pack(pady=10) 1353 | string_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) 1354 | Label(win.frame_right, text='订单编号:' + string_time).pack(pady=10) 1355 | Label(win.frame_right, text="销售日期:" + time.strftime("%Y-%m-%d", time.localtime())).pack(pady=10) 1356 | Label(win.frame_right, text="选择航班编号:", fg='MediumBlue', font=("楷体", 14)).pack(pady=10) 1357 | cursor_c = execute_sql("SELECT flightId FROM flight;") 1358 | no_c = [] 1359 | for result in cursor_c.fetchall(): # 查询所有航班编号添加到下拉列表供用户选择 1360 | no_c.append(result[0]) 1361 | cmb_c = ttk.Combobox(win.frame_right, value=no_c, state='readonly') 1362 | cmb_c.pack(pady=2) 1363 | string_show_c = [StringVar(), StringVar(), StringVar(), StringVar(),StringVar()] 1364 | label_show_c = [Label(win.frame_right), Label(win.frame_right), Label(win.frame_right), Label(win.frame_right),Label(win.frame_right)] 1365 | init_name_c = ['航空公司:', '出发地:', '目的地:', '出发时间:','票价:'] 1366 | for i in range(5): 1367 | string_show_c[i].set(init_name_c[i]) 1368 | label_show_c[i]['textvariable'] = string_show_c[i] 1369 | label_show_c[i].pack(pady=2) 1370 | 1371 | def show_c(event): 1372 | global string_time 1373 | string_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) 1374 | sql_select = "SELECT companyName,departure,terminal,leaveTime,ticketMoney FROM flight,company where flight.companyId =company.companyId and flightId={};" 1375 | result_row = execute_sql(sql_select.format(cmb_c.get())).fetchone() 1376 | for j in range(5): 1377 | string_show_c[j].set(init_name_c[j] + str(result_row[j])) 1378 | 1379 | cmb_c.bind("<>", show_c) 1380 | 1381 | Label(win.frame_right, fg='MediumBlue', font=("楷体", 14), text="选择购票用户编号:").pack(pady=10) 1382 | cursor_p = execute_sql("SELECT userId FROM customerUser") 1383 | no_p = [] 1384 | for result in cursor_p.fetchall(): # 查询所有未售出宠物编号名添加到下拉列表供用户选择 1385 | no_p.append(result[0]) 1386 | cmb_p = ttk.Combobox(win.frame_right, value=no_p, state='readonly') 1387 | cmb_p.pack(pady=2) 1388 | string_show_p = [StringVar(), StringVar(), StringVar(), StringVar(), StringVar()] 1389 | label_show_p = [Label(win.frame_right), Label(win.frame_right), 1390 | Label(win.frame_right),Label(win.frame_right)] 1391 | init_name_p = ['用户名:', '用户类型:', '积分:','优惠折扣:'] 1392 | for i in range(4): 1393 | string_show_p[i].set(init_name_p[i]) 1394 | label_show_p[i]['textvariable'] = string_show_p[i] 1395 | label_show_p[i].pack(pady=2) 1396 | 1397 | def show_p(event): 1398 | sql_select = "SELECT userName,vip,point FROM customerUser where userId={};" 1399 | result_row = execute_sql(sql_select.format(cmb_p.get())).fetchone() 1400 | for j in range(3): 1401 | string_show_p[j].set(init_name_p[j] + str(result_row[j])) 1402 | if result_row[1] == 1.0: 1403 | string_show_p[1].set(init_name_p[1] + 'VIP注册会员') 1404 | string_show_p[3].set(init_name_p[3] + str(10*get_discount(result_row[0]))+"折") 1405 | else: 1406 | string_show_p[1].set(init_name_p[1] + '未注册会员') 1407 | string_show_p[3].set(init_name_p[3] + '无') 1408 | 1409 | 1410 | cmb_p.bind("<>", show_p) 1411 | 1412 | labels = [Label(win.frame_right, text="乘客姓名"), Entry(win.frame_right), 1413 | Label(win.frame_right, text="手机号码"), Entry(win.frame_right), 1414 | Label(win.frame_right, text="座位号"), Entry(win.frame_right)] 1415 | for l in labels: 1416 | l.pack() 1417 | 1418 | def confirm(): 1419 | global string_time 1420 | _companyId, _money = execute_sql("SELECT companyId,ticketMoney FROM flight where flightId={};".format(cmb_c.get())).fetchone() 1421 | money = _money*get_discount(get_userName(cmb_p.get())) 1422 | leftTicket = get_leftTicket(cmb_c.get())-1 1423 | if leftTicket<0: 1424 | tkinter.messagebox.showinfo("提示", "余票不足,无法购买!") 1425 | return 1426 | new_points = get_points(get_userName(cmb_p.get()))+int(money) 1427 | sql = "insert into ticket values(%s,%s, %s,%s, '%s','%s',%s,%s,'%s');" 1428 | sql2= "update flight set leftTicket = {} where flightId = {}".format(leftTicket,cmb_c.get()) 1429 | sql3= "update customerUser set point = {} where userName = '{}'".format(new_points,get_userName(cmb_p.get())) 1430 | data = (string_time, cmb_p.get(),cmb_c.get(),_companyId,labels[5].get(),labels[1].get(),labels[3].get(),money,time.strftime("%Y/%m/%d", time.localtime())) 1431 | try: 1432 | execute_sql(sql % data) 1433 | execute_sql(sql2) 1434 | execute_sql(sql3) 1435 | tkinter.messagebox.showinfo("SUCCEED", "添加成功") 1436 | except pymysql.Error: 1437 | tkinter.messagebox.showerror("Failed", "添加失败") 1438 | 1439 | Button(win.frame_right, text='确认添加', command=lambda: confirm()).pack(pady=20) 1440 | 1441 | 1442 | class FrameLeft(Frame): # 左侧菜单栏 1443 | def __init__(self, master, user): 1444 | self.userType = user[0] 1445 | self.userName = user[1] 1446 | Frame.__init__(self, master, bg='gray', width=180, borderwidth=2) 1447 | self.pack_propagate(False) #固定frame大小 1448 | self.create() 1449 | 1450 | def create(self): 1451 | if self.userType == "customerUser": 1452 | Button(self, text="主 页", bg='#7fffd4', font=('华文琥珀', 16), command=lambda: go_home(Main.flag)).pack(fill=X) 1453 | Label(self, text="统计信息", bg='maroon1', fg='blue', font=("楷体", 16)).pack(fill=X) 1454 | Button(self, text="公告信息", command=lambda: personal_notice(Main.flag,self.userName)).pack(fill=X) 1455 | Button(self, text="我的信息", command=lambda: personal_data(Main.flag,self.userName)).pack(fill=X) 1456 | Button(self, text="航班信息", command=lambda: personal_flight(Main.flag, self.userName)).pack(fill=X) 1457 | Button(self, text="我的机票", command=lambda: personal_ticket(Main.flag,self.userName)).pack(fill=X) 1458 | elif self.userType == "companyUser": 1459 | Button(self, text="主 页", bg='#7fffd4', font=('华文琥珀', 16), command=lambda: go_home(Main.flag)).pack(fill=X) 1460 | Label(self, text="统计信息", bg='maroon1', fg='blue', font=("楷体", 16)).pack(fill=X) 1461 | Button(self, text="公司航班", command=lambda: company_flight(Main.flag,self.userName)).pack(fill=X) 1462 | Button(self, text="售票信息", command=lambda: company_sale(Main.flag,self.userName)).pack(fill=X) 1463 | Label(self, text="录入信息", bg='maroon1', fg='blue', font=("楷体", 16)).pack(fill=X) 1464 | Button(self, text="添加航班", command=lambda: self.add_flight(self.userName)).pack(fill=X) 1465 | else: 1466 | Button(self, text="主 页", bg='#7fffd4', font=('华文琥珀', 16), command=lambda: go_home(Main.flag)).pack(fill=X) 1467 | Label(self, text="统计信息", bg='maroon1', fg='blue', font=("楷体", 16)).pack(fill=X) 1468 | Button(self, text="顾客信息", command=lambda: search_client(Main.flag)).pack(fill=X) 1469 | Button(self, text="机场航班", command=lambda: airport_flight(Main.flag,self.userName)).pack(fill=X) 1470 | Button(self, text="票务信息", command=lambda: search_sale(Main.flag,self.userName)).pack(fill=X) 1471 | Label(self, text="录入信息", bg='maroon1', fg='blue', font=("楷体", 16)).pack(fill=X) 1472 | Button(self, text="添加旅客", command=lambda: self.add_user()).pack(fill=X) 1473 | Button(self, text="添加销售信息", command=lambda: add_sale(Main.flag)).pack(fill=X) 1474 | def quit_sys(): 1475 | if tkinter.messagebox.askokcancel('提示', '确认退出吗?'): 1476 | sys.exit(0) 1477 | 1478 | Button(self, text="退出系统", fg='blue', font=('楷体', 14), command=lambda: quit_sys()).pack(fill=X) 1479 | 1480 | @staticmethod 1481 | def add_user(): # 添加用户信息事件 1482 | win = Toplevel() 1483 | win.grab_set() 1484 | win.focus() 1485 | center(win, 300, 400) 1486 | labels = [Label(win, text='旅客编号'), Entry(win), 1487 | Label(win, text="账号"), Entry(win), 1488 | Label(win, text="密码"), Entry(win)] 1489 | for label in labels: 1490 | label.pack() 1491 | 1492 | labels_vip = [ Label(win, text='姓名'), Entry(win), 1493 | Label(win, text="手机号"), Entry(win), 1494 | Label(win, text="性别"), Entry(win)] 1495 | 1496 | Label(win, text="是否注册VIP?", fg='MediumBlue', font=("楷体", 12)).pack(pady=10) 1497 | choose = ttk.Combobox(win, value=['是','否'], state='readonly') 1498 | choose.pack(pady=2) 1499 | 1500 | 1501 | def show_choose(event): 1502 | if choose.get() == '是': 1503 | for label in labels_vip: 1504 | label.pack() 1505 | else: 1506 | pass 1507 | Button(win, text='确认', command=lambda: confirm()).pack() 1508 | 1509 | choose.bind("<>", show_choose) 1510 | 1511 | 1512 | 1513 | def confirm(): # 确认添加事件4 1514 | if choose.get() == "否": 1515 | sql = "insert into customerUser values('%s', '%s', '%s', '0.0', '0','None','None','None');" 1516 | data = [labels[1].get(),labels[3].get(),labels[5].get()] 1517 | else: 1518 | sql = "insert into customerUser values('%s', '%s', '%s', '1.0', '0','%s','%s','%s');" 1519 | data = [labels[1].get(),labels[3].get(),labels[5].get(),labels_vip[1].get(),labels_vip[3].get(),labels_vip[5].get()] 1520 | try: 1521 | execute_sql(sql % tuple(data)) # 字符串格式化 1522 | tkinter.messagebox.showinfo("SUCCEED", "录入成功!") 1523 | win.destroy() 1524 | except pymysql.Error: 1525 | tkinter.messagebox.showerror("ERROR", "输入有误!") 1526 | win.focus() 1527 | 1528 | 1529 | @staticmethod 1530 | def add_flight(v): # 添加航班事件 1531 | string_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) 1532 | win = Toplevel() 1533 | win.grab_set() 1534 | win.focus() 1535 | center(win, 300, 600) 1536 | choose_p1 = ttk.Combobox(win, value=get_airportName('all'), state='readonly') 1537 | choose_p2 = ttk.Combobox(win, value=get_airportName('all'), state='readonly') 1538 | choose_co = ttk.Combobox(win, value=get_companyName(get_companyId_by_user(v)), state='readonly') 1539 | labels = [Label(win, text='航班编号:' + string_time), 1540 | Label(win, text="飞机类型"), Entry(win), 1541 | Label(win, text="出发地"), choose_p1, 1542 | Label(win, text="目的地"), choose_p2, 1543 | Label(win, text="起飞时间"), Entry(win), 1544 | Label(win, text="到达时间"), Entry(win), 1545 | Label(win, text="可售票数"), Entry(win), 1546 | Label(win, text="总票数"), Entry(win), 1547 | Label(win, text="票价"), Entry(win), 1548 | Label(win, text="所属公司"), choose_co] 1549 | for label in labels: 1550 | label.pack() 1551 | 1552 | 1553 | def confirm(): # 确认添加事件 1554 | sql = "insert into flight values('%s', '%s', '%s','%s', '%s', '%s','%s', '%s', '%s', '%s')" 1555 | data = [string_time] 1556 | for text in labels[2::2]: 1557 | data.append(text.get()) 1558 | data[2] = get_airportId2(data[2]) 1559 | data[3] = get_airportId2(data[3]) 1560 | data[-1] = get_companyId(data[-1]) 1561 | try: 1562 | execute_sql(sql % tuple(data)) 1563 | tkinter.messagebox.showinfo("SUCCEED", "录入成功!") 1564 | win.destroy() 1565 | except pymysql.Error: 1566 | tkinter.messagebox.showerror("ERROR", "输入有误!") 1567 | win.focus() 1568 | 1569 | Button(win, text='确认', command=lambda: confirm()).pack() 1570 | 1571 | 1572 | def sign_in(event): # 登录 1573 | cursor= get_connect().cursor() 1574 | user = [userType.get(),entry.get()] 1575 | sql = "select password from "+userType.get()+" where userName='" + entry.get()+"'" 1576 | 1577 | try: 1578 | cursor.execute(sql) 1579 | password_input = entry_password.get() # 获取用户输入的密码 1580 | password_db = (cursor.fetchone())[0] # 获取数据中的密码 1581 | if password_input == password_db: # 判断用户输入的密码与数据库中的是否一致 1582 | tkinter.messagebox.showinfo(title="succeed", message="登陆成功") 1583 | login.destroy() # 销毁当前窗口 1584 | new_win = Tk() # 进入主界面 1585 | # center(login, login.winfo_screenwidth(,) login.winfo_screenheight()) # 最大化,效果不好 1586 | center(new_win, 1200, 800) 1587 | new_win.title("民航售票管理系统") 1588 | app = Main(user) 1589 | Main.flag = app 1590 | center(app.master, 1200, 800) 1591 | else: 1592 | tkinter.messagebox.showerror(title="failed", message="账号或者密码错误1") 1593 | except (pymysql.Error, TypeError): 1594 | tkinter.messagebox.showerror(title="failed", message="账号或密码错误2") 1595 | 1596 | 1597 | login = Tk() # 登陆界面 1598 | center(login, 600, 440) 1599 | login.resizable(0, 0) 1600 | login.title("民航票务系统") 1601 | 1602 | fm1 = Frame(login) 1603 | fm1.place(x=280, y=400) 1604 | group = LabelFrame(fm1,text="请选择您的身份",padx=5,pady=5) 1605 | group.pack(padx=10,pady=10) 1606 | userType = StringVar() 1607 | userType.set('customerUser') 1608 | radio = tkinter.Radiobutton(group,variable = userType,value ='customerUser',text='购票用户') 1609 | radio.pack() 1610 | radio = tkinter.Radiobutton(group,variable = userType,value ='airportUser',text='机场管理员') 1611 | radio.pack() 1612 | radio = tkinter.Radiobutton(group,variable = userType,value ='companyUser',text='航空公司管理员') 1613 | radio.pack() 1614 | fm1.pack(side=LEFT, fill=BOTH, expand=YES) 1615 | 1616 | fm2 = Frame(login) 1617 | fm2.place(x=180, y=200) 1618 | label_1 = Label(fm2, text="账号:", font=("宋体", 12)) 1619 | label_1.grid(row=0, column=0, pady=5) 1620 | entry = Entry(fm2, show=None, font=("Arial", 12)) 1621 | entry.grid(row=0, column=1) 1622 | entry.focus() 1623 | label_2 = Label(fm2, text="密码:", font=("宋体", 12)) 1624 | label_2.grid(row=1, column=0) 1625 | entry_password = Entry(fm2, show="*", font=("Arial", 12)) 1626 | entry_password.grid(row=1, column=1, pady=5) 1627 | entry_password.bind('', sign_in) # 密码输入框回车登录 1628 | button_sign_in = Button(fm2, text=' 登 录 ', fg='black', command=lambda: sign_in(None)) 1629 | button_sign_in.grid(row=2, column=1) 1630 | 1631 | login.mainloop() 1632 | -------------------------------------------------------------------------------- /sql_base.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | import sqlite3 3 | import time 4 | 5 | def get_connect(): # 获取连接 6 | connect = sqlite3.connect('test.db') 7 | # connect = pymssql.connect(host='127.0.0.1' ,user='test' ,password = 'test',database='test', charset='utf8') 8 | return connect 9 | 10 | 11 | def execute_sql(sql): # 执行SQL语句并返回执行结果的游标 12 | connect = get_connect() 13 | cursor = connect.cursor() 14 | cursor.execute(sql) 15 | connect.commit() 16 | return cursor 17 | 18 | 19 | def get_airportName(num): 20 | if num == 'all': 21 | sql = "select airportName from airport " 22 | result = [] 23 | for r in execute_sql(sql).fetchall(): 24 | result.append(r[0]) 25 | else: 26 | sql = "select airportName from airport where airportId = "+str(num) 27 | result = execute_sql(sql).fetchone()[0] 28 | return result 29 | 30 | def get_airportId1(name): 31 | sql = "select airportId from airport where airportName = '"+ str(name)+"'" 32 | result = execute_sql(sql).fetchone()[0] 33 | return result 34 | 35 | 36 | def get_companyName(num): 37 | if num == 'all': 38 | sql = "select companyName from company " 39 | result = [] 40 | for r in execute_sql(sql).fetchall(): 41 | result.append(r[0]) 42 | else: 43 | sql = "select companyName from company where companyId = "+str(num) 44 | result = execute_sql(sql).fetchone()[0] 45 | return result 46 | 47 | def get_companyId_by_user(v): 48 | sql = "select companyId from companyUser where userName = '"+str(v)+"'" 49 | result = execute_sql(sql).fetchone()[0] 50 | return result 51 | 52 | def get_companyId(name): 53 | if name == 'ticket': 54 | result = [] 55 | sql = "select distinct companyId from ticket" 56 | for r in execute_sql(sql).fetchall(): 57 | result.append(r[0]) 58 | else: 59 | sql = "select companyId from company where companyName = '"+ str(name)+"'" 60 | result = execute_sql(sql).fetchone()[0] 61 | return result 62 | 63 | def get_userData(conditiom): 64 | result = execute_sql("SELECT userId,realName,sex,phone,point FROM customerUser WHERE "+str(conditiom)) 65 | return result 66 | 67 | def get_userId(username): 68 | sql = "select userId from customerUser where userName = '"+ str(username)+"'" 69 | result = str(execute_sql(sql).fetchone()[0]) 70 | return result 71 | 72 | def get_userName(userId): 73 | sql = "select userName from customerUser where userId = '"+ str(userId)+"'" 74 | result = str(execute_sql(sql).fetchone()[0]) 75 | return result 76 | 77 | def get_airportId(username): 78 | sql = "select airportId from airportUser where userName = '"+ str(username)+"'" 79 | result = str(execute_sql(sql).fetchone()[0]) 80 | return result 81 | 82 | def get_airportId2(airportName): 83 | sql = "select airportId from airport where airportName = '"+ str(airportName)+"'" 84 | result = str(execute_sql(sql).fetchone()[0]) 85 | return result 86 | 87 | def transform_airport_ID(v): 88 | r = [] 89 | for i,v in enumerate(v): 90 | r.append([]) 91 | for j in v: 92 | r[i].append(j) 93 | 94 | for i,v in enumerate(r): 95 | r[i][2] = get_airportName(r[i][2]) 96 | r[i][3] = get_airportName(r[i][3]) 97 | r[i][5] = get_companyName(r[i][5]) 98 | return r 99 | 100 | def get_flightData(conditiom): 101 | result = execute_sql("SELECT flightId,plane,departure,terminal,ticketMoney,companyId,leaveTime,leftTicket FROM flight WHERE "+str(conditiom)) 102 | return transform_airport_ID(result) 103 | 104 | def get_flightData2(companyId,conditiom): 105 | result = execute_sql("SELECT flightId,plane,departure,terminal,ticketMoney,companyId,leaveTime,leftTicket FROM flight WHERE companyId = " + str(companyId) +" and "+str(conditiom)) 106 | return transform_airport_ID(result) 107 | 108 | def get_airport_flightData(airportId,conditiom): 109 | result = execute_sql("SELECT flightId,plane,departure,terminal,ticketMoney,companyId,leaveTime,leftTicket FROM flight WHERE (departure = "+str(airportId)+" or terminal = "+str(airportId)+" ) and "+str(conditiom)) 110 | return transform_airport_ID(result) 111 | 112 | def get_ticketData(conditiom): 113 | result = execute_sql("SELECT ticketId,userId,flightId,companyName,seatNumber,passagerName,passagerPhone,paidMoney,paidTime from ticket, company where ticket.companyId = company.companyId and "+str(conditiom)) 114 | return result 115 | 116 | def get_leftTicket(flightId): 117 | sql = "select leftTicket from flight where flightId = '"+ str(flightId)+"'" 118 | result = execute_sql(sql).fetchone()[0] 119 | return result 120 | 121 | def VIPorNOT(username): 122 | sql = "select vip from customerUser where userName = '{}'".format(username) 123 | result = execute_sql(sql).fetchone()[0] 124 | if result == 1.0: 125 | return True 126 | else: 127 | return False 128 | 129 | def get_seat(num): 130 | result = [] 131 | seats = [] 132 | sql = "select seatNumber from ticket where flightId = '{}'".format(num) 133 | for r in execute_sql(sql).fetchall(): 134 | result.append(r[0]) 135 | for i in range(1,51): 136 | if i not in result: 137 | seats.append(i) 138 | return seats 139 | 140 | def get_points(username): 141 | sql = "select point from customerUser where userName = '{}'".format(username) 142 | result = execute_sql(sql).fetchone()[0] 143 | return result 144 | 145 | 146 | def is_saled(flightId): # 查询航班是否有顾客购买,作为能否删除的依据 147 | sql = "select count(*) from ticket where flightId = '{}'".format(flightId) 148 | result = execute_sql(sql).fetchone()[0] 149 | return result 150 | 151 | def add_board(flightId,dueTime): 152 | string_time = time.strftime("%Y%m%d%H%M%S", time.localtime()) 153 | _time = time.strptime(dueTime, '%Y/%m/%d') 154 | duetime = time.strftime("%Y%m%d%H%M%S", _time) 155 | sql = "insert into board values('{}','{}','{}');".format(string_time,flightId,duetime) 156 | execute_sql(sql) 157 | 158 | def get_board(userid): 159 | sql = "select * from customer_notice where userId = {}".format(userid) 160 | r = execute_sql(sql).fetchall() 161 | result = [] 162 | for i in r: 163 | result.append([i[0],i[1],"您好,本次航班时刻有所调整,请及时在我的机票中查看~"]) 164 | return result 165 | 166 | def get_discount(userName): 167 | points = get_points(userName) 168 | if points >= 10000: 169 | return 0.8 170 | elif points >= 5000: 171 | return 0.9 172 | else: 173 | return 1 174 | 175 | -------------------------------------------------------------------------------- /test.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czy1999/Civil-aviation-management-system/853919afea5ad62d6c5e8edfcf836654395f6f32/test.db --------------------------------------------------------------------------------