You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

625 lines
26 KiB

from PyQt5.QtGui import QStandardItem, QStandardItemModel, QPixmap
from PyQt5.QtSql import QSqlTableModel, QSqlDatabase
from LoginUi import *
from InterfaceUi import *
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, QTableView, QWidget, QVBoxLayout, QComboBox, \
QButtonGroup, QMessageBox, QRadioButton
from PyQt5.QtCore import Qt, QTimer, QTime, QDateTime
import sys
import pymysql
import random
from datetime import datetime
user_now=""
class LoginWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui=Ui_LoginWindow()
self.ui.setupUi(self)
#去除边框
self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
#阴影
self.shadow = QtWidgets.QGraphicsDropShadowEffect(self)
self.shadow.setOffset(0,0)
self.shadow.setBlurRadius(10)
self.shadow.setColor(QtCore.Qt.black)
self.ui.frame.setGraphicsEffect(self.shadow)
#按钮切换登录和注册、以及按登录键实现页面跳转
self.ui.login_button.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(0))
self.ui.register_button.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(1))
self.ui.login_sure.clicked.connect(self.login_in)
self.ui.register_sure.clicked.connect(self.register_in)
self.show()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_position = event.globalPos() - self.frameGeometry().topLeft()
event.accept()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
self.move(event.globalPos() - self.drag_position)
event.accept()
def mouseReleaseEvent(self, event):
self.drag_position = None
#注册账号
def register_in(self):
account = self.ui.register_account.text()
password_1 = self.ui.register_psw.text()
password_2 = self.ui.register_psw2.text()
# 判断是否输入为空
if not account or not password_1 or not password_2:
self.ui.stackedWidget.setCurrentIndex(2) # 设置当前页面索引为空输入错误页面
return
# 判断账号是否已存在
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
cur.execute('select cid from customer')
rows = cur.fetchall()
db.close()
except Exception as e:
print(f"Database error: {e}")
self.ui.stackedWidget.setCurrentIndex(2) # 设置为数据库错误页面(可以调整索引)
return
# 提取所有现有账号
existing_accounts = [row[0] for row in rows]
if account in existing_accounts:
self.ui.stackedWidget.setCurrentIndex(3) # 设置当前页面索引为账号已存在错误页面
return
# 判断两次输入密码是否正确
if password_1 == password_2:
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
cur.execute(f"insert into customer(cid, cpsw) values('{account}', '{password_2}')")
db.commit() # 提交事务
db.close()
self.ui.stackedWidget.setCurrentIndex(4) # 设置当前页面索引为注册成功页面
except Exception as e:
print(f"Database error: {e}")
self.ui.stackedWidget.setCurrentIndex(2) # 设置为数据库错误页面
return
else:
self.ui.stackedWidget.setCurrentIndex(1) # 设置当前页面索引为密码不匹配错误页面
return
#登录验证
def login_in(self):
account = self.ui.login_account.text()
password = self.ui.login_psw.text()
# 检查输入框是否为空
if not account or not password:
self.ui.stackedWidget.setCurrentIndex(2) # 设置当前页面索引为空输入错误页面
return
account_list = []
password_list = []
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
cur.execute('select cid, cpsw from customer')
rows = cur.fetchall()
db.close()
except Exception as e:
print(f"Database error: {e}")
self.ui.stackedWidget.setCurrentIndex(2) # 设置为数据库错误页面(可以调整索引)
return
for row in rows:
account_list.append(row[0])
password_list.append(row[1])
# 验证账号和密码
for i in range(len(account_list)):
if account == account_list[i] and password == password_list[i]: # 假设密码是字符串
global user_now
user_now = account
self.win = MainWindow()
self.win.show()
self.close()
return
# 如果没有匹配成功
self.ui.stackedWidget.setCurrentIndex(5) # 设置当前页面索引为账号或密码错误页面
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.model = None
self.ui=Ui_MainWindow()
self.ui.setupUi(self)
self.initialize_image() #初始化图片
try:
# 设置定时器
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_time)
self.timer.start(1000) # 每秒更新一次
self.update_time() # 初始化时间显示
except Exception as e:
print(e)
#去除边框
self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
#阴影
self.shadow = QtWidgets.QGraphicsDropShadowEffect(self)
self.shadow.setOffset(0,0)
self.shadow.setBlurRadius(10)
self.shadow.setColor(QtCore.Qt.black)
self.ui.frame_6.setGraphicsEffect(self.shadow)
#按钮切换到各个操作面
self.ui.logout_button.clicked.connect(self.log_out)
self.ui.pushButton_home.clicked.connect(self.home_in)
self.ui.pushButton_add.clicked.connect(self.add_in)
self.ui.pushButton_get.clicked.connect(self.get_out)
self.ui.pushButton_transfer.clicked.connect(self.transfer_in)
self.ui.pushButton_look.clicked.connect(self.look_in)
self.ui.pushButton_irt.clicked.connect(self.irt_in)
self.ui.pushButton_info.clicked.connect(self.info_in)
self.ui.pushButton_6.clicked.connect(lambda :self.ui.stackedWidget.setCurrentIndex(6))
# 创建 tableView 属性,并将其设置为 UI 文件中的 tableView 对象
self.tableView = self.ui.tableView # 这里的 self.ui.tableView 是 UI 文件中 tableView 对象的引用
self.show()
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_position = event.globalPos() - self.frameGeometry().topLeft()
event.accept()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
self.move(event.globalPos() - self.drag_position)
event.accept()
def mouseReleaseEvent(self, event):
self.drag_position = None
def update_time(self):
current_time = QTime.currentTime()
self.ui.label_17.setText(current_time.toString('hh:mm:ss'))
def update_time(self):
current_date_time = QDateTime.currentDateTime()
formatted_time = current_date_time.toString('yyyy-MM-dd hh:mm:ss dddd')
self.ui.label_17.setText(formatted_time)
#初始化图片,应用在info中
def initialize_image(self):
try:
pixmap = QPixmap(":/images/images/123.jpg")
self.ui.label_16.setScaledContents(True) # 让图片填充满 QLabel
self.ui.label_16.setPixmap(pixmap)
#self.ui.label_16.setPixmap(pixmap.scaled(self.ui.label_16.size(), Qt.KeepAspectRatio))
except Exception as e:
print(f"Error loading image: {e}")
#将account表中数据导出到home界面,使用的是tableWidget
def home_in(self):
global user_now
self.ui.stackedWidget.setCurrentIndex(0)
try:
# 连接数据库
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
cur.execute(f"SELECT * FROM account WHERE cid = '{user_now}'")
rows = cur.fetchall()
db.commit()
db.close()
# 填充表格数据
for row_index, row_data in enumerate(rows):
for col_index, data in enumerate(row_data):
item = QTableWidgetItem(str(data))
item.setFlags(item.flags() & ~Qt.ItemIsEditable) # 禁止编辑
item.setTextAlignment(Qt.AlignCenter) #居中
self.ui.tableWidget.setItem(row_index, col_index, item)
except Exception as e:
print(f"Database error: {e}")
# 连接数据库或执行查询时出错,可以在界面上显示相应的错误提示
def add_in(self):
self.ui.stackedWidget.setCurrentIndex(1)
self.ui.submit_button.clicked.connect(self.add_acc)
def add_acc(self):
global user_now
try:
accid = self.generator_accid()
accbalance = self.ui.get_savings.text()
current_date = datetime.now().date()
acc_start = current_date.strftime('%Y-%m-%d')
cid = user_now
acctime = self.ui.deposit_time.currentText()
# 获取 QGroupBox 中选中的 QRadioButton
typebox = self.ui.type_box
acctype = None
for button in typebox.findChildren(QRadioButton):
if button.isChecked():
acctype = button
break
if acctype is None:
raise ValueError("未选择账户类型")
acc_type = acctype.text()
# 确认选择活期类型时长只能选择不定期
if acc_type == "活期" and acctime != "不定期":
raise ValueError("活期账户的时长只能选择不定期")
# 验证输入是否为空
if not accbalance or not acc_type or not acctime:
raise ValueError("所有输入字段必须填写")
accbalance_old=accbalance
accbalance=int(accbalance)
if acc_type=="定期":
if acctime=='1年':
accbalance=accbalance*(1+0.017)
elif acctime=='2年':
accbalance=accbalance*(1+0.019)**2
elif acctime=='3年':
accbalance=accbalance*(1+0.022)**3
else:
accbalance=accbalance*(1+0.024)**5
# 输出到控制台
print(accid, accbalance, acc_start, acctime, cid, acc_type)
# 将新账户信息插入数据库
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
query = "INSERT INTO account (accid, accbalance, acctime_start, accdur_time, cid, acc_type) VALUES (%s, %s, %s, %s, %s, %s)"
cur.execute(query, (accid, accbalance, acc_start, acctime, cid, acc_type))
db.commit()
db.close()
QMessageBox.information(self, "成功", "账户添加成功")
except Exception as db_error:
print(f"数据库错误: {db_error}")
QMessageBox.critical(self, "错误", "添加账户到数据库失败")
return
# 将信息写入文件
try:
filename = f"{user_now}.txt"
if acc_type=="定期":
s = f"用户于{acc_start},开通账号:{accid},存取金额为{accbalance_old},期限为{acctime},到期后待取金额为{accbalance:.3f}\n"
else:
s = f"用户于{acc_start},开通账号:{accid},存取金额为{accbalance_old},期限为{acctime}\n"
with open(filename, "a", encoding='UTF-8') as file:
file.write(s)
file.write("-" * 76 + "\n")
print(f"信息已写入文件: {filename}")
except Exception as file_error:
print(f"文件写入错误: {file_error}")
# 清空输入框
self.ui.get_savings.clear()
self.ui.deposit_time.setCurrentIndex(0)
for button in typebox.findChildren(QRadioButton):
button.setAutoExclusive(False)
button.setChecked(False)
button.setAutoExclusive(True)
except ValueError as ve:
QMessageBox.critical(self, "错误", str(ve))
except Exception as e:
print(e)
QMessageBox.critical(self, "错误", f"发生错误: {e}")
def generator_accid(self):
while True:
accid = random.randint(10000, 99999)
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
cur.execute('SELECT * FROM account WHERE accid = %s', (accid,))
rows = cur.fetchone()
if not rows:
db.close()
return accid
else:
print("Accid already exists. Generating a new one.")
db.close()
except Exception as e:
print(f"Database error: {e}")
return accid
def get_out(self):
self.ui.stackedWidget.setCurrentIndex(2)
self.ui.sure_button1.clicked.connect(self.get_money)
def get_money(self):
global user_now
accid=self.ui.accid_1.text()
savings=self.ui.money_1.text()
psw=self.ui.psw_sure1.text()
self.ui.accid_1.clear()
self.ui.money_1.clear()
self.ui.psw_sure1.clear()
# 检查取款金额是否为空
if not savings:
QMessageBox.critical(self, "错误", "请输入取款金额")
return
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
# 查询密码是否匹配
cur.execute(f"SELECT cpsw FROM customer WHERE cid='{user_now}'")
rows = cur.fetchone()
if not rows or rows[0] != psw:
QMessageBox.critical(self, "错误", "密码错误")
db.close()
return
# 查询账户余额
cur.execute(f"SELECT accbalance, acc_type FROM account WHERE accid='{accid}' AND cid='{user_now}'")
rows = cur.fetchone()
if not rows:
QMessageBox.critical(self, "错误", "账户不存在或不属于当前用户")
db.close()
return
accbalance, acc_type = rows
# 检查账户类型是否是活期
if acc_type != "活期":
QMessageBox.critical(self, "错误", "账户类型不是活期,无法取款")
db.close()
return
# 检查余额是否足够
if float(accbalance) < float(savings):
QMessageBox.critical(self, "错误", "账户余额不足")
db.close()
return
# 更新账户余额
new_balance = float(accbalance) - float(savings)
cur.execute(f"UPDATE account SET accbalance={new_balance} WHERE accid='{accid}' AND cid='{user_now}'")
db.commit()
QMessageBox.information(self, "成功", f"成功取款 {savings} 元,当前余额为 {new_balance}")
db.close()
current_date = datetime.now().date()
acctime= current_date.strftime('%Y-%m-%d')
# 将信息写入文件
try:
filename = f"{user_now}.txt"
s = f"用户于{acctime},在账户{accid},取款{savings}元,当前余额为{new_balance}\n"
with open(filename, "a", encoding='UTF-8') as file:
file.write(s)
file.write("-" * 76 + "\n")
print(f"信息已写入文件: {filename}")
except Exception as file_error:
print(f"文件写入错误: {file_error}")
except Exception as e:
print(f"数据库错误: {e}")
QMessageBox.critical(self, "错误", "数据库错误")
def transfer_in(self):
self.ui.stackedWidget.setCurrentIndex(3)
self.ui.sure_button2.clicked.connect(self.transfer)
def transfer(self):
out_account = self.ui.out_accid.text()
in_account = self.ui.in_accid.text()
out_saving = self.ui.out_money.text()
psw = self.ui.sure_psw2.text()
self.ui.out_accid.clear()
self.ui.in_accid.clear()
self.ui.out_money.clear()
self.ui.sure_psw2.clear()
# 检查输入是否为空
if not out_account or not in_account or not out_saving or not psw:
QMessageBox.critical(self, "错误", "请输入完整信息")
return
try:
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
# 查询密码是否匹配
cur.execute(f"SELECT cpsw FROM customer WHERE cid='{user_now}'")
rows = cur.fetchone()
if not rows or rows[0] != psw:
QMessageBox.critical(self, "错误", "密码错误")
db.close()
return
# 查询转出账号是否存在并且是活期类型
cur.execute(
f"SELECT accbalance FROM account WHERE accid='{out_account}' AND cid='{user_now}' AND acc_type='活期'")
rows = cur.fetchone()
if not rows:
QMessageBox.critical(self, "错误", "转出账号不存在或不是活期类型")
db.close()
return
out_balance = float(rows[0])
# 检查转出金额是否大于转出账号余额
if float(out_saving) > out_balance:
QMessageBox.critical(self, "错误", "转出账号余额不足")
db.close()
return
# 查询收款账号是否存在并且是活期类型
cur.execute(f"SELECT acc_type FROM account WHERE accid='{in_account}' AND acc_type='活期'")
rows = cur.fetchone()
if not rows:
QMessageBox.critical(self, "错误", "收款账号不存在或不是活期类型")
db.close()
return
# 更新转出账号余额和收款账号余额
new_out_balance = out_balance - float(out_saving)
cur.execute(
f"UPDATE account SET accbalance={new_out_balance} WHERE accid='{out_account}' AND cid='{user_now}'")
cur.execute(f"UPDATE account SET accbalance=accbalance+{out_saving} WHERE accid='{in_account}'")
# 获取收款账号所属用户的cid和新余额
cur.execute(f"SELECT cid FROM account WHERE accid='{in_account}'")
row = cur.fetchone()
if not row:
QMessageBox.critical(self, "错误", "获取收款账号信息失败")
db.close()
return
recipient_cid = row[0]
cur.execute(f"SELECT accbalance FROM account WHERE accid='{in_account}'")
row = cur.fetchone()
if not row:
QMessageBox.critical(self, "错误", "获取收款账号余额失败")
db.close()
return
new_in_balance = float(row[0])
db.commit()
QMessageBox.information(self, "成功", f"成功转账 {out_saving} 元到账户 {in_account}")
db.close()
# 写入转账信息到文件
try:
current_date = datetime.now().date()
acctime = current_date.strftime('%Y-%m-%d')
filename1 = f"{user_now}.txt"
filename2 = f"{recipient_cid}.txt"
out_info = f"用户于{acctime},账号:{out_account}转给{in_account}, {out_saving}元,当前余额为{new_out_balance}\n"
in_info = f"用户于{acctime},账号:{in_account} 收到{out_saving}元,当前余额为{new_in_balance}\n"
with open(filename1, "a", encoding='UTF-8') as file1:
file1.write(out_info)
file1.write("-" * 76 + "\n")
with open(filename2, "a", encoding='UTF-8') as file2:
file2.write(in_info)
file2.write("-" * 76 + "\n")
print(f"信息已写入文件: {filename1}{filename2}")
except Exception as file_error:
print(f"文件写入错误: {file_error}")
except Exception as e:
print(f"数据库错误: {e}")
QMessageBox.critical(self, "错误", "数据库错误")
def look_in(self):
try:
global user_now
self.ui.stackedWidget.setCurrentIndex(4)
textname=f"{user_now}.txt"
with open(textname,'r',encoding='utf-8') as f:
f.seek(0)
str=f.read()
self.ui.textEdit.setPlainText(str)
except Exception as e:
print(e)
def irt_in(self):
self.ui.stackedWidget.setCurrentIndex(5)
try:
# 连接数据库
db = pymysql.connect(host='127.0.0.1', user='root', password='20021220', database='pybank')
cur = db.cursor()
cur.execute("SELECT * FROM irt")
rows = cur.fetchall()
db.commit()
db.close()
# 设置表格行数
self.ui.tableWidget_2.setRowCount(len(rows))
# 填充表格数据
for row_index, row_data in enumerate(rows):
for col_index, data in enumerate(row_data):
item = QTableWidgetItem(str(data))
item.setFlags(item.flags() & ~Qt.ItemIsEditable) # 禁止编辑
item.setTextAlignment(Qt.AlignCenter) # 居中
self.ui.tableWidget_2.setItem(row_index, col_index, item)
except Exception as e:
print(f"Database error: {e}")
# 连接数据库或执行查询时出错,可以在界面上显示相应的错误提示
def info_in(self):
try:
# 切换到包含 QTableView 的页面
self.ui.stackedWidget.setCurrentIndex(7)
# 设置模型
self.model = QStandardItemModel(0, 7)
self.model.setHorizontalHeaderLabels(['身份证号', '姓名', '性别', '年龄', '电话号码', '户籍', '密码'])
self.tableView.setModel(self.model)
# 加载数据
self.load_data()
# 使表格可编辑
self.tableView.setEditTriggers(QTableView.AllEditTriggers)
# 捕捉模型数据改变信号
self.model.itemChanged.connect(self.update_database)
except Exception as e:
print(f"Error in info_in: {e}")
# 连接 MySQL 并获取数据
def load_data(self):
global user_now
try:
connection = pymysql.connect(
host='127.0.0.1',
user='root',
password='20021220',
database='pybank'
)
cursor = connection.cursor()
cursor.execute(f"SELECT * FROM customer where cid='{user_now}'")
data = cursor.fetchall()
cursor.close()
connection.close()
for row in data:
items = [QStandardItem(str(field)) for field in row]
for item in items:
item.setTextAlignment(Qt.AlignCenter)
self.model.appendRow(items)
except Exception as e:
print(f"Error loading data: {e}")
def update_database(self, item):
row = item.row()
col = item.column()
new_value = item.text()
print(row, col, new_value)
try:
# 获取主键(第一列是主键)
primary_key = self.model.item(row, 0).text()
# 映射列名
columns = ['cid', 'cname', 'csex', 'cage', 'cnumber', 'caddress', 'cpsw']
column_name = columns[col]
# 更新数据库
connection = pymysql.connect(
host='127.0.0.1',
user='root',
password='20021220',
database='pybank'
)
cursor = connection.cursor()
query = f"UPDATE customer SET {column_name} = %s WHERE cid = %s"
cursor.execute(query, (new_value, primary_key))
connection.commit()
cursor.close()
connection.close()
print(f"Updated row {row}, column {col} with new value {new_value}")
except Exception as e:
print(f"Error updating database: {e}")
#退出当前账号回到登录界面
def log_out(self):
global user_now
self.close()
self.login = LoginWindow()
user_now = ""
if __name__ == '__main__':
app = QApplication(sys.argv)
win = LoginWindow()
sys.exit(app.exec_())