附件下载:附件下载
Python 代码:复制
import sys from PyQt5.QtWidgets import QApplication,QDateEdit,QDialog,QMainWindow,QDateTimeEdit, QLabel, QComboBox,QGridLayout,QDialog, QWidget, QTableWidget, QTableWidgetItem, QPushButton, QVBoxLayout, QHBoxLayout, QLineEdit, QMessageBox, QTabWidget,QFileDialog from PyQt5.QtCore import Qt,QDate from PyQt5.QtGui import QFont import sqlite3 import re import os import shutil import openpyxl from datetime import datetime import glob # 建立数据库连接 conn = sqlite3.connect('members.db') cursor = conn.cursor() # 创建会员表 cursor.execute('''CREATE TABLE IF NOT EXISTS members ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, phone TEXT NOT NULL, register_date TEXT NOT NULL, last_consume_date TEXT, birthday DATE, balance REAL, remark TEXT )''') # 创建充值/消费记录表 cursor.execute('''CREATE TABLE IF NOT EXISTS transactions ( id INTEGER PRIMARY KEY AUTOINCREMENT, member_id INTEGER, amount REAL, transaction_date TEXT, remark TEXT, project TEXT, balance REAL, clerk_id INTEGER, FOREIGN KEY (member_id) REFERENCES members (id) )''') # 创建美容项目表 cursor.execute('''CREATE TABLE IF NOT EXISTS beauty_projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, times INTEGER NOT NULL, datetime TEXT, remark TEXT )''') # 创建会员美容项目表 cursor.execute('''CREATE TABLE IF NOT EXISTS member_beauty_projects ( member_id INTEGER, beauty_project_id INTEGER, sessions INTEGER, FOREIGN KEY (member_id) REFERENCES members (id), FOREIGN KEY (beauty_project_id) REFERENCES beauty_projects (id) )''') #创建营业员表 cursor.execute("CREATE TABLE IF NOT EXISTS clerks (id INTEGER PRIMARY KEY, name TEXT,is_deleted INTEGER DEFAULT 0)") search_entry = None search_table = None transaction_table = None transaction_member_entry = None #备份数据库 def backup_database(): DATABASE = 'members.db' # Replace this with your actual database file path BACKUP_DIR = 'database_backups' # The name of the backup directory # 获取当前运行的脚本路径 current_path = os.path.dirname(os.path.abspath(__file__)) backup_dir_path = os.path.join(current_path, BACKUP_DIR) # Create the backup directory if it doesn't exist os.makedirs(backup_dir_path, exist_ok=True) # 根据当前日期时间创建备份文件名 backup_name = f"backup_{datetime.now().strftime('%Y%m%d%H%M%S')}.db" # 拼接出备份文件的完整路径 backup_path = os.path.join(backup_dir_path, backup_name) # 复制数据库文件到备份路径 shutil.copyfile(DATABASE, backup_path) # 获取当前目录下所有的备份文件 all_backups = glob.glob(os.path.join(backup_dir_path, "backup_*.db")) # 如果备份文件数量超过 30,删除最早的备份文件 if len(all_backups) > 30: all_backups.sort() os.remove(all_backups[0]) # 登录界面 class LoginWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle("会员储值管理系统") self.setGeometry(300, 300, 350, 200) layout = QVBoxLayout() username_label = QLabel("用户名:") self.username_entry = QLineEdit() password_label = QLabel("密码:") self.password_entry = QLineEdit() self.password_entry.setEchoMode(QLineEdit.Password) login_button = QPushButton("登录") login_button.clicked.connect(self.login) font = QFont() font.setBold(True) username_label.setFont(font) password_label.setFont(font) login_button.setFont(font) layout.addWidget(username_label) layout.addWidget(self.username_entry) layout.addWidget(password_label) layout.addWidget(self.password_entry) layout.addWidget(login_button) self.setLayout(layout) def login(self): username = self.username_entry.text() password = self.password_entry.text() if username == "admin" and password == "123": self.close() # 关闭登录窗口 self.main_window = MainWindow() # 创建主窗口 self.main_window.show() # 显示主窗口 else: QMessageBox.warning(self, "警告", "用户名或密码错误!") #主界面 class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("会员管理系统") self.setGeometry(20, 20, 1000, 700) main_widget = QWidget() self.setCentralWidget(main_widget) # 创建Tab控件 tab_widget = QTabWidget() # 创建会员查询界面 search_widget = QWidget() search_layout = QVBoxLayout() # 会员查询界面 search_label = QLabel("请输入会员姓名或手机号:") self.search_entry = QLineEdit() self.search_entry.returnPressed.connect(self.search_member) search_button = QPushButton("查询") search_button.clicked.connect(self.search_member) search_layout.addWidget(search_label) search_layout.addWidget(self.search_entry) search_layout.addWidget(search_button) # 创建按钮布局 button_layout = QHBoxLayout() add_button = QPushButton("新增会员") add_button.clicked.connect(self.create_add_member_window) edit_button = QPushButton("修改会员信息") edit_button.clicked.connect(self.edit_member) delete_button = QPushButton("删除会员") delete_button.clicked.connect(self.delete_member) recharge_button = QPushButton("充值") recharge_button.clicked.connect(self.recharge_dialog) transaction_button = QPushButton("会员消费") transaction_button.clicked.connect(self.create_consume_dialog) buy_beauty_project_button = QPushButton("购买美容项目") buy_beauty_project_button.clicked.connect(self.buy_beauty_project) #设置CSS样式 font = QFont() font.setBold(True) search_label.setStyleSheet("color: red;") search_label.setFont(font) search_button.setFont(font) add_button.setFont(font) edit_button.setFont(font) delete_button.setFont(font) recharge_button.setFont(font) transaction_button.setFont(font) buy_beauty_project_button.setFont(font) #################################################### button_layout.addWidget(add_button) button_layout.addWidget(edit_button) button_layout.addWidget(delete_button) button_layout.addWidget(recharge_button) button_layout.addWidget(transaction_button) button_layout.addWidget(buy_beauty_project_button) self.search_table = QTableWidget() self.search_table.setColumnCount(8) self.search_table.setHorizontalHeaderLabels([ "姓名", "手机号", "生日", "注册日期", "最后消费日期", "余额", "备注","ID"]) self.search_table.setSelectionBehavior(QTableWidget.SelectRows) self.search_table.doubleClicked.connect(self.edit_member) #双击事件 self.search_table.setColumnWidth(0, 80) # 第一列宽度为80 self.search_table.setColumnWidth(1, 150) self.search_table.setColumnWidth(2, 150) self.search_table.setColumnWidth(3, 200) self.search_table.setColumnWidth(4, 200) self.search_table.setColumnWidth(5, 120) self.search_table.setColumnWidth(6, 100) self.search_table.setColumnWidth(7, 10) search_layout.addLayout(button_layout) search_layout.addWidget(self.search_table) search_widget.setLayout(search_layout) # 创建充值/消费记录界面 transaction_widget = QWidget() transaction_layout = QVBoxLayout() transaction_label = QLabel("请输入会员姓名或手机号:") transaction_label.setStyleSheet("color: red;") transaction_label.setFont(font) self.transaction_member_entry = QLineEdit() self.transaction_member_entry.returnPressed.connect(self.search_transaction) transaction_button = QPushButton("查询") transaction_button.clicked.connect(self.search_transaction) export_button = QPushButton("导出") export_button.clicked.connect(self.export_transaction_table) self.transaction_table = QTableWidget() self.transaction_table.setColumnCount(8) self.transaction_table.setHorizontalHeaderLabels(["姓名", "手机号", "金额", "时间", "项目", "备注", "余额","营业员"]) self.transaction_table.setColumnWidth(0, 80) # 第一列宽度为80 self.transaction_table.setColumnWidth(1, 150) self.transaction_table.setColumnWidth(2, 100) self.transaction_table.setColumnWidth(3, 200) self.transaction_table.setColumnWidth(4, 200) self.transaction_table.setColumnWidth(5, 80) self.transaction_table.setColumnWidth(6, 100) self.transaction_table.setColumnWidth(7, 80) transaction_layout.addWidget(transaction_label) transaction_layout.addWidget(self.transaction_member_entry) transaction_layout.addWidget(transaction_button) transaction_layout.addWidget(self.transaction_table) transaction_layout.addWidget(export_button) transaction_widget.setLayout(transaction_layout) # 创建美容项目管理界面 beauty_project_widget = QWidget() beauty_project_layout = QVBoxLayout() # 美容项目管理界面 beauty_project_label = QLabel("请输入美容项目名称:") beauty_project_label.setStyleSheet("color: red;") beauty_project_label.setFont(font) self.beauty_project_entry = QLineEdit() self.beauty_project_entry.returnPressed.connect(self.search_beauty_project) beauty_project_button = QPushButton("查询") beauty_project_button.clicked.connect(self.search_beauty_project) beauty_project_layout.addWidget(beauty_project_label) beauty_project_layout.addWidget(self.beauty_project_entry) beauty_project_layout.addWidget(beauty_project_button) # 创建按钮布局 beauty_project_button_layout = QHBoxLayout() add_beauty_project_button = QPushButton("新增美容项目") add_beauty_project_button.clicked.connect(self.create_add_beauty_project_window) edit_beauty_project_button = QPushButton("修改美容项目信息") edit_beauty_project_button.clicked.connect(self.edit_beauty_project) delete_beauty_project_button = QPushButton("删除美容项目") delete_beauty_project_button.clicked.connect(self.delete_beauty_project) beauty_project_button_layout.addWidget(add_beauty_project_button) beauty_project_button_layout.addWidget(edit_beauty_project_button) beauty_project_button_layout.addWidget(delete_beauty_project_button) self.beauty_project_table = QTableWidget() self.beauty_project_table.setColumnCount(4) self.beauty_project_table.setHorizontalHeaderLabels(["ID", "美容项目名称","次数","新建时间"]) self.beauty_project_table.setSelectionBehavior(QTableWidget.SelectRows) self.beauty_project_table.doubleClicked.connect(self.edit_beauty_project) #双击事件 self.beauty_project_table.setColumnWidth(0, 30) # 第一列宽度为80 self.beauty_project_table.setColumnWidth(1, 250) self.beauty_project_table.setColumnWidth(2, 100) self.beauty_project_table.setColumnWidth(3, 200) beauty_project_layout.addLayout(beauty_project_button_layout) beauty_project_layout.addWidget(self.beauty_project_table) beauty_project_widget.setLayout(beauty_project_layout) # 创建营业员管理界面 clerks_widget = QWidget() clerks_layout = QVBoxLayout() # 营业员管理界面 clerks_label = QLabel("请输入营业员名称:") clerks_label.setStyleSheet("color: red;") clerks_label.setFont(font) self.clerks_entry = QLineEdit() self.clerks_entry.returnPressed.connect(self.search_clerk) clerks_button = QPushButton("查询") clerks_button.clicked.connect(self.search_clerk) clerks_layout.addWidget(clerks_label) clerks_layout.addWidget(self.clerks_entry) clerks_layout.addWidget(clerks_button) # 创建按钮布局 clerks_button_layout = QHBoxLayout() add_clerks_button = QPushButton("新增营业员") add_clerks_button.clicked.connect(self.create_add_clerk_window) delete_clerks_button = QPushButton("删除营业员") delete_clerks_button.clicked.connect(self.delete_clerks) clerks_button_layout.addWidget(add_clerks_button) clerks_button_layout.addWidget(delete_clerks_button) self.clerks_table = QTableWidget() self.clerks_table.setColumnCount(2) self.clerks_table.setHorizontalHeaderLabels(["ID", "营业员名称"]) self.clerks_table.setColumnWidth(0, 80) # 第一列宽度为80 self.clerks_table.setColumnWidth(1, 200) clerks_layout.addLayout(clerks_button_layout) clerks_layout.addWidget(self.clerks_table) clerks_widget.setLayout(clerks_layout) # 创建会员美容项目次数报表界面 report_widget = QWidget() report_layout = QVBoxLayout() report_label = QLabel("请输入会员姓名或手机号:") report_label.setStyleSheet("color: red;") report_label.setFont(font) self.report_entry = QLineEdit() self.report_entry.returnPressed.connect(self.search_report) report_button = QPushButton("查询") report_button.clicked.connect(self.search_report) self.report_table = QTableWidget() self.report_table.setColumnCount(4) self.report_table.setHorizontalHeaderLabels(["会员姓名", "手机号码","美容项目", "剩余次数"]) report_layout.addWidget(report_label) report_layout.addWidget(self.report_entry) report_layout.addWidget(report_button) report_layout.addWidget(self.report_table) report_widget.setLayout(report_layout) tab_widget.addTab(search_widget, "会员查询") tab_widget.addTab(transaction_widget, "会员充值/消费记录") tab_widget.addTab(report_widget, "会员项目次数查询") tab_widget.addTab(beauty_project_widget, "美容项目设置") tab_widget.addTab(clerks_widget, "营业员设置") main_layout = QVBoxLayout() main_layout.addWidget(tab_widget) main_widget.setLayout(main_layout) self.sort_order = Qt.AscendingOrder # 初始排序顺序为升序 # 点击充值/消费记录表头进行排序 self.transaction_table.horizontalHeader().sectionClicked.connect(self.sort_transaction_table) # 会员查询功能 def search_member(self): keyword = self.search_entry.text() query = f"SELECT members.name, members.phone, members.birthday, members.register_date, MAX(transactions.transaction_date), members.balance, members.remark,members.id FROM members LEFT JOIN transactions ON transactions.member_id = members.id WHERE members.name LIKE '%{keyword}%' OR members.phone LIKE '%{keyword}%' GROUP BY members.id ORDER BY MAX(transactions.transaction_date) DESC" cursor.execute(query) members = cursor.fetchall() self.search_table.setRowCount(0) for row, member in enumerate(members): self.search_table.insertRow(row) for col, data in enumerate(member): item = QTableWidgetItem(str(data)) item.setFlags(Qt.ItemIsEnabled) self.search_table.setItem(row, col, item) # 会员新增 def create_add_member_window(self): add_member_window = AddMemberWindow(self) add_member_window.exec_() # 会员修改 def edit_member(self): selected_row = self.search_table.currentRow() if selected_row != -1: member_id = self.search_table.item(selected_row, 7).text() edit_member_window = EditMemberWindow(member_id, self) edit_member_window.exec_() else: QMessageBox.warning(self, "警告", "请选择要修改的会员。") # 会员删除 def delete_member(self): selected_row = self.search_table.currentRow() if selected_row != -1: member_id = self.search_table.item(selected_row, 7).text() query = f"SELECT * FROM members WHERE id = {member_id}" cursor.execute(query) member = cursor.fetchone() if member: confirm = QMessageBox.question(self, "确认", "【警告】确定要删除该会员吗?") if confirm == QMessageBox.Yes: query = f"DELETE FROM members WHERE id = {member_id}" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "会员删除成功。") self.search_member() else: QMessageBox.warning(self, "错误", "选择的会员不存在。") else: QMessageBox.warning(self, "警告", "请选择要删除的会员。") # 会员充值 def recharge_dialog(self): selected_row = self.search_table.currentRow() if selected_row != -1: member_id = self.search_table.item(selected_row, 7).text() recharge_dialog = RechargeDialog(member_id, self) recharge_dialog.exec_() else: QMessageBox.warning(self, "警告", "请选择要充值的会员。") # 会员消费 def create_consume_dialog(self): selected_row = self.search_table.currentRow() if selected_row != -1: member_id = self.search_table.item(selected_row, 7).text() consume_dialog = ConsumeDialog(member_id, self) consume_dialog.exec_() else: QMessageBox.warning(self, "警告", "请选择要消费的会员。") # 会员购卡 def buy_beauty_project(self): selected_row = self.search_table.currentRow() if selected_row != -1: member_id = self.search_table.item(selected_row, 7).text() buy_beauty_project_dialog = BuyBeautyProjectDialog(member_id, self) buy_beauty_project_dialog.exec_() else: QMessageBox.warning(self, "警告", "请选择要购买美容项目的会员。") # 会员充值消费记录查询 def search_transaction(self): keyword = self.transaction_member_entry.text() query = f"SELECT members.name, members.phone, transactions.amount, strftime('%Y-%m-%d %H:%M:%S', transactions.transaction_date), transactions.project, transactions.remark, transactions.balance, clerks.name FROM transactions LEFT JOIN members ON transactions.member_id = members.id LEFT JOIN clerks ON transactions.clerk_id = clerks.id WHERE members.name LIKE '%{keyword}%' OR members.phone LIKE '%{keyword}%' ORDER BY transactions.transaction_date DESC" cursor.execute(query) transactions = cursor.fetchall() self.transaction_table.setRowCount(0) for row, transaction in enumerate(transactions): self.transaction_table.insertRow(row) for col, data in enumerate(transaction): item = QTableWidgetItem(str(data)) item.setFlags(Qt.ItemIsEnabled) self.transaction_table.setItem(row, col, item) #导出会员充值/消费记录 def export_transaction_table(self): workbook = openpyxl.Workbook() sheet = workbook.active # 添加表头 headers = ["姓名", "手机号", "金额", "时间", "项目", "备注", "余额", "营业员"] for col_num, header in enumerate(headers, 1): sheet.cell(row=1, column=col_num, value=header) # 添加数据 cursor.execute("SELECT members.name, members.phone, transactions.amount, transactions.transaction_date, transactions.project, transactions.remark, transactions.balance, clerks.name FROM transactions JOIN members ON transactions.member_id = members.id JOIN clerks ON transactions.clerk_id = clerks.id") transactions = cursor.fetchall() for row_num, transaction in enumerate(transactions, 2): for col_num, value in enumerate(transaction, 1): sheet.cell(row=row_num, column=col_num, value=value) # 选择保存路径 filename, _ = QFileDialog.getSaveFileName(self, "保存文件", "", "Excel Files (*.xlsx)") if filename: workbook.save(filename) QMessageBox.information(self, "提示", f"会员充值/消费记录表已成功导出为:{filename}") #排序 def sort_transaction_table(self, column): self.transaction_table.sortItems(column, self.sort_order) self.sort_order = Qt.DescendingOrder if self.sort_order == Qt.AscendingOrder else Qt.AscendingOrder #查询美容项目 def search_beauty_project(self): keyword = self.beauty_project_entry.text() query = f"SELECT id, name, times, strftime('%Y-%m-%d %H:%M:%S', datetime) FROM beauty_projects WHERE name LIKE '%{keyword}%'" cursor.execute(query) beauty_projects = cursor.fetchall() self.beauty_project_table.setRowCount(0) for row, beauty_project in enumerate(beauty_projects): self.beauty_project_table.insertRow(row) for col, data in enumerate(beauty_project): item = QTableWidgetItem(str(data)) item.setFlags(Qt.ItemIsEnabled) self.beauty_project_table.setItem(row, col, item) #新建美容项目 def create_add_beauty_project_window(self): add_beauty_project_window = AddBeautyProjectWindow(self) add_beauty_project_window.exec_() #修改美容项目 def edit_beauty_project(self): selected_row = self.beauty_project_table.currentRow() if selected_row != -1: beauty_project_id = self.beauty_project_table.item(selected_row, 0).text() edit_beauty_project_window = EditBeautyProjectWindow(beauty_project_id, self) edit_beauty_project_window.exec_() else: QMessageBox.warning(self, "警告", "请选择要修改的美容项目。") #删除美容项目 def delete_beauty_project(self): selected_row = self.beauty_project_table.currentRow() if selected_row != -1: beauty_project_id = self.beauty_project_table.item(selected_row, 0).text() query = f"SELECT * FROM beauty_projects WHERE id = {beauty_project_id}" cursor.execute(query) beauty_project = cursor.fetchone() if beauty_project: confirm = QMessageBox.question(self, "确认", "【警告】确定要删除该美容项目吗?") if confirm == QMessageBox.Yes: query = f"DELETE FROM beauty_projects WHERE id = {beauty_project_id}" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "美容项目删除成功。") self.search_beauty_project() else: QMessageBox.warning(self, "错误", "选择的美容项目不存在。") else: QMessageBox.warning(self, "警告", "请选择要删除的美容项目。") #查询营业员 def search_clerk(self): keyword = self.clerks_entry.text() query = f"SELECT id, name FROM clerks WHERE name LIKE '%{keyword}%' AND is_deleted = 0" cursor.execute(query) clerks = cursor.fetchall() self.clerks_table.setRowCount(0) for row, clerks in enumerate(clerks): self.clerks_table.insertRow(row) for col, data in enumerate(clerks): item = QTableWidgetItem(str(data)) item.setFlags(Qt.ItemIsEnabled) self.clerks_table.setItem(row, col, item) #新增营业员窗口 def create_add_clerk_window(self): add_clerk_window = AddClerkWindow(self) add_clerk_window.exec_() # 营业员删除 def delete_clerks(self): selected_row = self.clerks_table.currentRow() if selected_row != -1: clerks_id = self.clerks_table.item(selected_row, 7).text() query = f"SELECT * FROM clerks WHERE id = {clerks_id}" cursor.execute(query) clerks = cursor.fetchone() if clerks: confirm = QMessageBox.question(self, "确认", "【警告】确定要删除该营业员吗?") if confirm == QMessageBox.Yes: # 不真正删除营业员,而是将其标记为已删除 query = f"UPDATE clerks SET is_deleted = 1 WHERE id = {clerks_id}" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "营业员删除成功。") self.search_clerk() else: QMessageBox.warning(self, "错误", "选择的营业员不存在。") else: QMessageBox.warning(self, "警告", "请选择要删除的营业员。") #查询会员项目 def search_report(self): keyword = self.report_entry.text() query = f"SELECT members.name, members.phone, beauty_projects.name, member_beauty_projects.sessions FROM member_beauty_projects JOIN members ON member_beauty_projects.member_id = members.id JOIN beauty_projects ON member_beauty_projects.beauty_project_id = beauty_projects.id WHERE members.name LIKE '%{keyword}%' OR members.phone LIKE '%{keyword}%'" cursor.execute(query) reports = cursor.fetchall() self.report_table.setRowCount(0) for row, report in enumerate(reports): self.report_table.insertRow(row) for col, data in enumerate(report): item = QTableWidgetItem(str(data)) item.setFlags(Qt.ItemIsEnabled) self.report_table.setItem(row, col, item) #新增会员对话框 class AddMemberWindow(QDialog): def __init__(self, parent): super().__init__(parent) self.setWindowTitle("新增会员") name_label = QLabel("会员姓名:") self.name_entry = QLineEdit() phone_label = QLabel("手机号:") self.phone_entry = QLineEdit() birthday_label = QLabel("生日:") # 新增 self.birthday_entry = QDateEdit() # 新增 self.birthday_entry.setCalendarPopup(True) # 新增 layout = QGridLayout() layout.addWidget(name_label, 0, 0) layout.addWidget(self.name_entry, 0, 1) layout.addWidget(phone_label, 1, 0) layout.addWidget(self.phone_entry, 1, 1) layout.addWidget(birthday_label, 2, 0) # 新增 layout.addWidget(self.birthday_entry, 2, 1) # 新增 add_button = QPushButton("确定") add_button.clicked.connect(self.add_member) layout.addWidget(add_button, 3, 0, 1, 2) # 修改 self.setLayout(layout) def validate_phone(self, phone): pattern = r"^1[3456789]\d{9}$" if not re.match(pattern, phone): return False return True def check_phone_exists(self, phone): query = f"SELECT * FROM members WHERE phone = '{phone}'" cursor.execute(query) member = cursor.fetchone() if member: return True return False def add_member(self): name = self.name_entry.text() phone = self.phone_entry.text() birthday = self.birthday_entry.date().toString("yyyy-MM-dd") # 新增 if not self.validate_phone(phone): QMessageBox.warning(self, "错误", "手机号格式不正确。") return if self.check_phone_exists(phone): QMessageBox.warning(self, "错误", "手机号已存在,请输入其他手机号。") return query = f"INSERT INTO members (name, phone, birthday, register_date, balance) VALUES ('{name}', '{phone}', '{birthday}', '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}', 0)" # 修改 cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "会员添加成功。") self.parent().search_member() self.close() #修改会员信息 class EditMemberWindow(QDialog): def __init__(self, member_id, parent): super().__init__(parent) self.setWindowTitle("修改会员信息") self.member_id = member_id query = f"SELECT * FROM members WHERE id = {self.member_id}" cursor.execute(query) member = cursor.fetchone() self.old_balance = member[6] name_label = QLabel("会员姓名:") self.name_entry = QLineEdit() self.name_entry.setText(member[1]) phone_label = QLabel("手机号:") self.phone_entry = QLineEdit() self.phone_entry.setText(member[2]) birthday_label = QLabel("生日:") # 新增 self.birthday_entry = QDateEdit() # 新增 self.birthday_entry.setCalendarPopup(True) # 新增 self.birthday_entry.setDate(QDate.fromString(member[5], "yyyy-MM-dd")) # 新增 balance_label = QLabel("余额:") self.balance_entry = QLineEdit() self.balance_entry.setText(str(member[6])) layout = QGridLayout() layout.addWidget(name_label, 0, 0) layout.addWidget(self.name_entry, 0, 1) layout.addWidget(phone_label, 1, 0) layout.addWidget(self.phone_entry, 1, 1) layout.addWidget(birthday_label, 2, 0) # 新增 layout.addWidget(self.birthday_entry, 2, 1) # 新增 layout.addWidget(balance_label, 3, 0) # 修改 layout.addWidget(self.balance_entry, 3, 1) # 修改 save_button = QPushButton("保存") save_button.clicked.connect(self.save_member) layout.addWidget(save_button, 4, 0, 1, 2) # 修改 self.setLayout(layout) def validate_phone(self, phone): pattern = r"^1[3456789]\d{9}$" if not re.match(pattern, phone): return False return True def check_phone_exists(self, phone): query = f"SELECT * FROM members WHERE phone = '{phone}'" cursor.execute(query) member = cursor.fetchone() if member: return True return False def save_member(self): name = self.name_entry.text() phone = self.phone_entry.text() birthday = self.birthday_entry.date().toString("yyyy-MM-dd") # 新增 balance = self.balance_entry.text() # 检查手机号是否已经被修改 query = f"SELECT phone FROM members WHERE id = {self.member_id}" cursor.execute(query) old_phone = cursor.fetchone()[0] if phone != old_phone and self.check_phone_exists(phone): QMessageBox.warning(self, "错误", "手机号已存在,请输入其他手机号。") return if not self.validate_phone(phone): QMessageBox.warning(self, "错误", "手机号格式不正确。") return query = f"UPDATE members SET name = '{name}', phone = '{phone}', birthday = '{birthday}', balance = {balance} WHERE id = {self.member_id}" # 修改 cursor.execute(query) conn.commit() query = f"SELECT * FROM members WHERE id = {self.member_id}" cursor.execute(query) updated_member = cursor.fetchone() new_balance = updated_member[6] if self.old_balance != new_balance: amount = float(new_balance) - float(self.old_balance) transaction_query = f"INSERT INTO transactions (member_id, amount, project,transaction_date, balance, remark) VALUES ({self.member_id}, {amount}, '无','{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}', {new_balance},'修改余额')" cursor.execute(transaction_query) conn.commit() QMessageBox.information(self, "提示", "会员信息修改成功。") self.parent().search_transaction() self.parent().search_member() self.close() #会员充值 class RechargeDialog(QDialog): def __init__(self, member_id, parent): super().__init__(parent) self.setWindowTitle("会员充值") self.member_id = member_id amount_label = QLabel("充值金额:") self.amount_entry = QLineEdit() clerk_label = QLabel("营业员:") self.clerk_combo = QComboBox() self.load_clerks() layout = QVBoxLayout() # 定义布局 layout.addWidget(amount_label) layout.addWidget(self.amount_entry) layout.addWidget(clerk_label) layout.addWidget(self.clerk_combo) confirm_button = QPushButton("确认") confirm_button.clicked.connect(self.confirm_recharge) layout.addWidget(confirm_button) self.setLayout(layout) #读取营业员信息 def load_clerks(self): cursor.execute("SELECT name FROM clerks") clerks = cursor.fetchall() for clerk in clerks: self.clerk_combo.addItem(clerk[0]) #确认充值信息 def confirm_recharge(self): try: amount = float(self.amount_entry.text()) if amount > 0: query = f"SELECT balance FROM members WHERE id = {self.member_id}" cursor.execute(query) member = cursor.fetchone() if member: current_balance = member[0] new_balance = current_balance + amount clerk_name = self.clerk_combo.currentText() cursor.execute("SELECT id FROM clerks WHERE name = ?", (clerk_name,)) clerk = cursor.fetchone() if clerk is not None: clerk_id = clerk[0] query = f"UPDATE members SET balance = {new_balance} WHERE id = {self.member_id}" cursor.execute(query) conn.commit() transaction_query = f"INSERT INTO transactions (member_id, amount, project,transaction_date, balance, remark, clerk_id) VALUES ({self.member_id}, {amount}, '无','{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}',{new_balance}, '充值', {clerk_id})" cursor.execute(transaction_query) conn.commit() QMessageBox.information(self, "提示", "充值成功。") self.parent().search_member() self.parent().search_transaction() self.close() else: QMessageBox.information(self, "提示", "请输入营业员!") return else: QMessageBox.warning(self, "错误", "选择的会员不存在。") else: QMessageBox.warning(self, "错误", "充值金额必须大于0。") except ValueError: QMessageBox.warning(self, "错误", "请输入有效的充值金额。") #会员消费窗口 class ConsumeDialog(QDialog): def __init__(self, member_id, parent): super().__init__(parent) self.setWindowTitle("会员消费") self.member_id = member_id amount_label = QLabel("消费金额:") self.amount_entry = QLineEdit("0") project_label = QLabel("美容项目:") self.project_combo = QComboBox() self.load_projects() clerk_label = QLabel("营业员:") self.clerk_combo = QComboBox() self.load_clerks() layout = QVBoxLayout() layout.addWidget(clerk_label) layout.addWidget(self.clerk_combo) layout.addWidget(amount_label) layout.addWidget(self.amount_entry) layout.addWidget(project_label) layout.addWidget(self.project_combo) confirm_button = QPushButton("确认") confirm_button.clicked.connect(self.confirm_consume) layout.addWidget(confirm_button) self.setLayout(layout) #读取营业员信息 def load_clerks(self): cursor.execute("SELECT name FROM clerks") clerks = cursor.fetchall() for clerk in clerks: self.clerk_combo.addItem(clerk[0]) #读取会员美容项目 def load_projects(self): self.project_combo.addItem("无") # Add "无" option query = f"SELECT beauty_projects.name FROM beauty_projects JOIN member_beauty_projects ON beauty_projects.id = member_beauty_projects.beauty_project_id WHERE member_beauty_projects.member_id = {self.member_id}" cursor.execute(query) projects = cursor.fetchall() if projects: for project in projects: self.project_combo.addItem(project[0]) #确认消费 def confirm_consume(self): project_name = self.project_combo.currentText() clerk_name = self.clerk_combo.currentText() cursor.execute("SELECT id FROM clerks WHERE name = ?", (clerk_name,)) clerk = cursor.fetchone() if clerk is not None: clerk_id = clerk[0] else: QMessageBox.warning(self, "错误", "请输入营业员!") return amount = float(self.amount_entry.text()) if project_name != "无": # 获取项目ID cursor.execute("SELECT id FROM beauty_projects WHERE name = ?", (project_name,)) project_id = cursor.fetchone()[0] # 使用项目ID替换项目名 query = f"SELECT * FROM member_beauty_projects WHERE member_id = {self.member_id} AND beauty_project_id = {project_id}" cursor.execute(query) member_project = cursor.fetchone() if member_project: if member_project[2] > 0: # 检查剩余次数 # 使用项目ID替换项目名 query = f"UPDATE member_beauty_projects SET sessions = sessions - 1 WHERE member_id = {self.member_id} AND beauty_project_id = {project_id}" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "消费成功。") # 获取当前余额 query = f"SELECT balance FROM members WHERE id = {self.member_id}" cursor.execute(query) member = cursor.fetchone() current_balance = member[0] new_balance = current_balance - amount transaction_query = f"INSERT INTO transactions (member_id, amount, project, transaction_date, balance, remark, clerk_id) VALUES ({self.member_id}, {-amount}, '{self.project_combo.currentText()}','{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}',{new_balance}, '消费', {clerk_id})" cursor.execute(transaction_query) conn.commit() self.parent().search_member() self.parent().search_transaction() self.close() else: QMessageBox.warning(self, "错误", "该会员的此项目次数已用完。") else: QMessageBox.warning(self, "错误", "该会员没有购买此项目。") else: if amount > 0: query = f"SELECT balance FROM members WHERE id = {self.member_id}" cursor.execute(query) member = cursor.fetchone() if member: current_balance = member[0] if current_balance >= amount: new_balance = current_balance - amount query = f"UPDATE members SET balance = {new_balance}, last_consume_date = '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}' WHERE id = {self.member_id}" cursor.execute(query) conn.commit() transaction_query = f"INSERT INTO transactions (member_id, amount, transaction_date, balance, project, remark, clerk_id) VALUES ({self.member_id}, {-amount}, '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}',{new_balance}, '{self.project_combo.currentText()}','消费', {clerk_id})" cursor.execute(transaction_query) conn.commit() QMessageBox.information(self, "提示", "消费成功。") self.parent().search_member() self.parent().search_transaction() self.close() else: QMessageBox.warning(self, "错误", "余额不足,无法消费。") #会员购卡 class BuyBeautyProjectDialog(QDialog): def __init__(self, member_id, parent): super().__init__(parent) self.setWindowTitle("购买美容项目") self.member_id = member_id project_label = QLabel("选择美容项目:") self.project_combo = QComboBox() self.load_beauty_projects() clerk_label = QLabel("营业员:") self.clerk_combo = QComboBox() self.load_clerks() layout = QVBoxLayout() # 定义布局 layout.addWidget(clerk_label) layout.addWidget(self.clerk_combo) layout.addWidget(project_label) layout.addWidget(self.project_combo) confirm_button = QPushButton("确认") confirm_button.clicked.connect(self.buy_beauty_project) layout.addWidget(confirm_button) self.setLayout(layout) #读取营业员信息 def load_clerks(self): cursor.execute("SELECT name FROM clerks") clerks = cursor.fetchall() for clerk in clerks: self.clerk_combo.addItem(clerk[0]) #读取美容项目 def load_beauty_projects(self): cursor.execute("SELECT name FROM beauty_projects") beauty_projects = cursor.fetchall() for project in beauty_projects: self.project_combo.addItem(project[0]) #购买美容项目 def buy_beauty_project(self): project_name = self.project_combo.currentText() cursor.execute("SELECT id, times FROM beauty_projects WHERE name = ?", (project_name,)) project = cursor.fetchone() project_id = project[0] project_times = project[1] # 获取项目的次数 # 检查会员是否已经购买了这个项目 cursor.execute("SELECT * FROM member_beauty_projects WHERE member_id = ? AND beauty_project_id = ?", (self.member_id, project_id)) if cursor.fetchone(): # 如果会员已经购买了这个项目,那么显示一个错误消息并返回 QMessageBox.warning(self, "错误", "你已经购买了这个项目。") return cursor.execute("INSERT INTO member_beauty_projects (member_id, beauty_project_id, sessions) VALUES (?, ?, ?)", (self.member_id, project_id, project_times)) conn.commit() clerk_name = self.clerk_combo.currentText() cursor.execute("SELECT id FROM clerks WHERE name = ?", (clerk_name,)) clerk_id = cursor.fetchone()[0] transaction_query = f"INSERT INTO transactions (member_id, project, transaction_date, remark, clerk_id) VALUES ({self.member_id}, '{project_name}', '{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}', '购卡', {clerk_id})" cursor.execute(transaction_query) conn.commit() QMessageBox.information(self, "提示", "购买成功。") self.close() #新增美容项目对话框 class AddBeautyProjectWindow(QDialog): def __init__(self, parent): super().__init__(parent) self.setWindowTitle("新增美容项目") name_label = QLabel("美容项目名称:") self.name_entry = QLineEdit() times_label = QLabel("次数:") self.times_entry = QLineEdit() datetime_label = QLabel("新建时间:") self.datetime_entry = QDateTimeEdit(datetime.now()) self.datetime_entry.setDisplayFormat("yyyy-MM-dd HH:mm:ss") layout = QGridLayout() layout.addWidget(name_label, 0, 0) layout.addWidget(self.name_entry, 0, 1) layout.addWidget(times_label, 1, 0) layout.addWidget(self.times_entry, 1, 1) layout.addWidget(datetime_label, 2, 0) layout.addWidget(self.datetime_entry, 2, 1) add_button = QPushButton("确定") add_button.clicked.connect(self.add_beauty_project) layout.addWidget(add_button, 3, 0, 1, 2) self.setLayout(layout) def add_beauty_project(self): name = self.name_entry.text() times = self.times_entry.text() datetime = self.datetime_entry.dateTime().toString("yyyy-MM-dd HH:mm:ss") if self.check_beauty_project_exists(name): QMessageBox.warning(self, "错误", "美容项目已存在,请输入其他美容项目。") return query = f"INSERT INTO beauty_projects (name, times, datetime) VALUES ('{name}', {times}, '{datetime}')" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "美容项目添加成功。") self.parent().search_beauty_project() self.close() def check_beauty_project_exists(self, name): query = f"SELECT * FROM beauty_projects WHERE name = '{name}'" cursor.execute(query) beauty_project = cursor.fetchone() if beauty_project: return True return False #修改美容项目对话框 class EditBeautyProjectWindow(QDialog): def __init__(self, beauty_project_id, parent): super().__init__(parent) self.setWindowTitle("修改美容项目") self.beauty_project_id = beauty_project_id query = f"SELECT * FROM beauty_projects WHERE id = {self.beauty_project_id}" cursor.execute(query) beauty_project = cursor.fetchone() name_label = QLabel("美容项目名称:") self.name_entry = QLineEdit() self.name_entry.setText(beauty_project[1]) times_label = QLabel("次数:") self.times_entry = QLineEdit() self.times_entry.setText(str(beauty_project[2])) layout = QGridLayout() layout.addWidget(name_label, 0, 0) layout.addWidget(self.name_entry, 0, 1) layout.addWidget(times_label, 1, 0) layout.addWidget(self.times_entry, 1, 1) save_button = QPushButton("保存") save_button.clicked.connect(self.save_beauty_project) layout.addWidget(save_button, 2, 0, 1, 2) self.setLayout(layout) def save_beauty_project(self): name = self.name_entry.text() times = self.times_entry.text() query = f"UPDATE beauty_projects SET name = '{name}', times = {times} WHERE id = {self.beauty_project_id}" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "美容项目信息修改成功。") self.parent().search_beauty_project() self.close() #新增营业员对话框 class AddClerkWindow(QDialog): def __init__(self, parent): super().__init__(parent) self.setWindowTitle("新增营业员") name_label = QLabel("营业员名称:") self.name_entry = QLineEdit() layout = QGridLayout() layout.addWidget(name_label, 0, 0) layout.addWidget(self.name_entry, 0, 1) add_button = QPushButton("确定") add_button.clicked.connect(self.add_clerk) layout.addWidget(add_button, 3, 0, 1, 2) self.setLayout(layout) def add_clerk(self): name = self.name_entry.text() if self.check_clerk_exists(name): QMessageBox.warning(self, "错误", "营业员已存在,请输入其他营业员。") return query = f"INSERT INTO clerks (name) VALUES ('{name}')" cursor.execute(query) conn.commit() QMessageBox.information(self, "提示", "营业员添加成功。") self.parent().search_clerk() self.close() def check_clerk_exists(self, name): query = f"SELECT * FROM clerks WHERE name = '{name}'" cursor.execute(query) clerk = cursor.fetchone() if clerk: return True return False if __name__ == "__main__": backup_database() app = QApplication(sys.argv) login_window = LoginWindow() login_window.show() sys.exit(app.exec_())