编辑代码

import sys
from PyQt5.QtWidgets import QApplication
from ui.main_window import MainWindow

def main():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

from PyQt5.QtWidgets import QMainWindow, QAction, QToolBar, QStatusBar, QPushButton, QLineEdit, QDialog, QLabel, QVBoxLayout, QWidget
from PyQt5.QtCore import QThread, pyqtSignal
from .settings_window import SettingsWindow
from .info_dialog import InfoDialog
from db.db_manager import DBManager
import serial
import logging
#import qrcode
class SerialReader(QThread):
    data_received = pyqtSignal(str)  # 定义一个信号,用于将数据传递到主线程

    def __init__(self, port, baudrate=9600):
        super().__init__()
        self.port = port
        self.baudrate = baudrate
        self.serial_conn = None
        self.running = True

    def run(self):
        try:
            self.serial_conn = serial.Serial(self.port, self.baudrate, timeout=1)
            while self.running:
                data = self.serial_conn.readline().decode().strip() if self.serial_conn.in_waiting > 0 else None
                if data:
                    self.data_received.emit(data)  # 主线程处理
        except Exception as e:
            logging.error("串口读取失败: %s", e)
        finally:
            if self.serial_conn:
                self.serial_conn.close()
    def stop(self):
        self.running = False
        self.wait()  # 等待线程安全退出
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("仓库管理系统")
        self.setGeometry(100, 100, 800, 600)
     
        # 创建主窗口的中心小部件和布局·
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        # 添加欢迎标签
        label = QLabel("欢迎使用仓库管理系统", self)
        layout.addWidget(label)
        # 添加输入框和扫描按钮
        self.scan_input = QLineEdit(self)
        self.scan_input.setPlaceholderText("输入或扫描条形码")
        layout.addWidget(self.scan_input)
        
        self.scan_btn = QPushButton("手动录入(备选)", self)
        self.scan_btn.clicked.connect(self.scan_barcode)
        layout.addWidget(self.scan_btn)
        
        # 创建菜单栏
        menu_bar = self.menuBar()
        settings_menu = menu_bar.addMenu("设置")

        # 添加设置菜单
        settings_action = QAction("设置数据库", self)
        settings_action.triggered.connect(self.open_settings_window)
        settings_menu.addAction(settings_action)
        export_menu = menu_bar.addMenu("导出数据")
        export_action = QAction("导出数据", self)
        export_action.triggered.connect(self.export_data)
        export_menu.addAction(export_action)

        # 状态栏显示数据
        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)

        # 显示仓库信息
        self.display_warehouse_data()
        self.serial_reader = SerialReader("COM1")  # 替换为实际的串口号
        self.serial_reader.data_received.connect(self.update_scan_input)
        self.serial_reader.start()
    def update_scan_input(self, data):
        try:
            self.scan_input.setText(data)
            print(f"输入框内容已更新为: {self.scan_input.text()}")
            self.scan_barcode()
        except Exception as e:
            logging.error(f"更新输入框内容时出错: {e}")
            QMessageBox.critical(self, "错误", f"扫码处理失败: {e}")
        self.scan_barcode()  # 扫码后自动调用扫码处理逻辑
    def open_settings_window(self):
        settings_window = SettingsWindow(self)
        settings_window.exec_()

    def export_data(self):
        # 导出数据逻辑,假设执行查询并保存到文件
        pass

    def display_warehouse_data(self):
        try:
            print("正在显示仓库数据...")
            # 添加逻辑展示数据
            self.statusBar.showMessage("今日入库数量:0,今日出库数量:0")
        except Exception as e:
            print(f"显示仓库数据时发生错误: {e}")

    def scan_barcode(self):
        logging.info("开始处理条码: %s", self.scan_input.text())
        if not hasattr(self, 'db_manager'):
            self.db_manager = DBManager()
        barcode = self.scan_input.text()
        device_info = self.db_manager.get_device_info(barcode)

        if device_info:
            # 弹出设备信息对话框
            dialog = DeviceInfoDialog(device_info, self)
            if dialog.exec_() == QDialog.Accepted:
                worker_id = dialog.worker_input.text()
                print(f"提交操作,工号:{worker_id}")
        else:
            self.prompt_for_new_device()
    def prompt_for_new_device(self):
        # 手动录入逻辑...
        QMessageBox.information(self, "手动录入", "设备信息不存在,请手动录入。")
        pass

    def closeEvent(self, event):
        # 在关闭窗口时停止串口线程并关闭数据库连接
        self.serial_reader.stop()
        if hasattr(self, 'db_manager'):
            self.db_manager.close_connection()
        event.accept()
import mysql.connector
import json
import threading
import datetime
from PyQt5.QtWidgets import QInputDialog
import logging
logging.basicConfig(
    level=logging.DEBUG,  # 设置日志级别
    filename='app.log',   # 日志输出到文件
    filemode='w',         # 写入模式('w' 会覆盖,'a' 会追加)
    format='%(asctime)s - %(levelname)s - %(message)s'  # 格式
)
class DBManager:
    def __init__(self):
        self.lock = threading.Lock()
        self.connection = None
        self.cursor = None
        self.load_config()
        self.connect_to_db()


    def load_config(self):
        logging.info("1")
        try:
            with open("config/config.json", "r") as file:
                logging.info("2")
                config = json.load(file)
                logging.info("3")
            self.db_host = config.get("db_host", "127.0.0.1")
            self.db_user = config.get("db_user", "root")
            self.db_password = config.get("db_password", "cx123456")
            self.db_name = config.get("db_name", "hecrk")
            if not all([self.db_host, self.db_user, self.db_password, self.db_name]):
                raise ValueError("配置文件内容不完整")
        except FileNotFoundError:
            logging.error("配置文件未找到,请检查路径")
            raise
        except json.JSONDecodeError:
            logging.error("配置文件格式错误")
            raise
        except Exception as e:
            logging.error(f"加载配置文件时发生错误: {e}")
            raise
        logging.info("4")
        logging.info(self.db_name)
    def connect_to_db(self):
        with self.lock:
            try:
                self.connection = mysql.connector.connect(
                    host=self.db_host,
                    user=self.db_user,
                    password=self.db_password,
                    database=self.db_name
                )
                self.cursor = self.connection.cursor()
                logging.info("数据库连接成功")
            except mysql.connector.Error as e:
                logging.error(f"数据库连接失败: {e}", exc_info=True)
    def get_device_info(self, barcode):
        query = "SELECT * FROM hwcrk.hw WHERE zcxlh = %s"
        try:
            # 执行查询
            self.cursor.execute(query, (barcode,))
            # 获取所有查询结果
            results = self.cursor.fetchone()
            if not results:
                logging.info(f"未找到设备信息: {barcode}")
                return None
            logging.info(f"查询成功: {result}")
            return results
        except mysql.connector.Error as err:
            logging.info(f"数据库查询失败: {err}")
            return None
    def process_device_operation(self, barcode, operation):
        device_info = self.get_device_info(barcode)
        current_time = datetime.datetime.now()
        target_table = "hwcrk.rk" if operation == "入库" else "hwcrk.ck"
    
        worker_id, ok_worker = QInputDialog.getText(None, "输入工号", "请输入工号:")
        if not ok_worker:
            return  # 用户取消了输入
        yt, ok_yt = QInputDialog.getText(None, "用途信息", "请输入用途信息或保持默认值:")
        if not ok_yt:
            return  # 用户取消了输入
        gc, ok_gc = QInputDialog.getText(None, "工程信息", "请输入工程信息:")
        if not ok_gc:
            return  # 用户取消了输入

        try:
            if device_info:
            # 更新 hwcrk.hw 表
                update_hw_query = """
                    UPDATE hwcrk.hw 
                    SET zcbm = %s,ywqf = %s,zcfldzw = %s,zcfldhw = %s,zcflxzw = %s,zcflxhw = %s,yt = %s,pp = %s,xh = %s,ggcs = %s,syzt = %s,sbzt = %s,gc = %s,qyzw = %s,xian = %s,xxgw = %s,nxbz = %s,ysynx = %s,gmrq = %s,gmrq1 = %s,djrp = %s,gbrq = %s,ghrq = %s,zcdw = %s,zcje = %s,gys = %s,xmmc = %s,ip = %s
                    WHERE zcxlh = %s
                """
                self.cursor.execute(update_hw_query, (zcbm,ywqf,zcfldzw,zcfldhw,zcflxzw,zcflxhw,yt,pp,xh,ggcs,syzt,sbzt,gc,qyzw,xian,xxgw,nxbz,ysynx,gmrq,gmrq1,djrp,gbrq,ghrq,zcdw,zcje,gys,xmmc,ip,barcode))

            # 插入记录到目标表(入库或出库表)
                insert_query = f"""
                    INSERT INTO {target_table} ( rksj, rkr, yt, zcxlh,bz)
                    VALUES (%s, %s, %s, %s, %s)
                """
                self.cursor.execute(insert_query, ( current_time, worker_id, yt,barcode,))  # 注意这里可能需要调整,因为yt的默认值可能不应该直接为yt变量(如果ok_yt为False)
            else:
            # 插入到 hwcrk.hw 表
                insert_hw_query = """
                    INSERT INTO hwcrk.hw (zcxlh, gc, rkr, yt)
                    VALUES (%s, %s, %s, %s)
                """
                self.cursor.execute(insert_hw_query, (barcode, gc, worker_id, yt if ok_yt else '默认值'))  # 同上,调整默认值逻辑

            # 插入到目标表
                insert_query = f"""
                    INSERT INTO {target_table} (zcxlh, cksj, rkr, yt, bz)
                    VALUES (%s, %s, %s, %s, %s)
                """
            # 注意:这里可能缺少一个与bz相关的参数,或者bz应该有一个默认值
            # 假设bz的值为'默认值',但您应该根据实际需求进行调整
                self.cursor.execute(insert_query, (barcode, current_time, worker_id, yt if ok_yt else '默认值', '默认值'))

            self.connection.commit()
        except mysql.connector.Error as err:
            print(f"数据库操作失败: {err}")
            self.connection.rollback()  # 发生错误时回滚事务

    def export_data(self, query):
        self.cursor.execute(query)
        return self.cursor.fetchall()
    def close_connection(self):
        with self.lock:
            try:
                if self.cursor:
                    self.cursor.close()
                if self.connection:
                    self.connection.close()
                logging.info("数据库连接关闭")
            except Exception as e:
                logging.error(f"关闭数据库连接时发生错误: {e}")
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QLineEdit, QPushButton
import json

class SettingsWindow(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("数据库设置")

        layout = QVBoxLayout()

        self.ip_input = QLineEdit(self)
        self.ip_input.setPlaceholderText("输入数据库IP地址")
        layout.addWidget(self.ip_input)
        self.user_input = QLineEdit(self)
        self.user_input.setPlaceholderText("输入数据库用户名")
        layout.addWidget(self.user_input)
        self.password_input = QLineEdit(self)
        self.password_input.setPlaceholderText("输入数据库密码")
        layout.addWidget(self.password_input)
        self.name_input = QLineEdit(self)
        self.name_input.setPlaceholderText("输入数据库名称")
        layout.addWidget(self.name_input)

        save_button = QPushButton("保存", self)
        save_button.clicked.connect(self.save_settings)
        layout.addWidget(save_button)

        self.setLayout(layout)

    def save_settings(self):
        config = {
            "db_host": self.ip_input.text(),
            "db_user": self.user_input.text(),
            "db_password": self.password_input.text(),
            "db_name": self.name_input.text()
        }
        with open("config/config.json", "w") as file:
            json.dump(config, file,ensure_ascii=False, indent=4)
        self.accept()
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QLabel, QLineEdit, QPushButton, QMessageBox

class InfoDialog(QDialog):
    def __init__(self, device_info, db_manager, barcode, parent=None):
        super().__init__(parent)
        self.setWindowTitle("设备操作与信息")
        self.db_manager = db_manager
        self.barcode = barcode
        self.selected_operation = None

        self.layout = QVBoxLayout(self)
        self.grid_layout = QGridLayout()
        self.button_layout = QHBoxLayout()
        # 中文字段和数据映射
        fields = {
            "资产编号": device_info[0],
            "用途": device_info[1],
            "资产分类(大类中文)": device_info[2],
            "资产分类(大类货物)": device_info[3],
            "资产分类(小类中文)": device_info[4],
            "资产分类(小类货物)": device_info[5],
            "品牌": device_info[6],
            "型号": device_info[7],
            "规格参数": device_info[8],
            # 按需补充所有字段
        }

        # 动态添加字段信息
        row = 0
        for name, value in fields.items():
            label = QLabel(name)
            value_label = QLabel(str(value) if value else "无数据")
            grid_layout.addWidget(label, row, 0)
            grid_layout.addWidget(value_label, row, 1)
            row += 1

        # 工号输入框
##        worker_label = QLabel("工号:")
##        self.worker_input = QLineEdit()
##        grid_layout.addWidget(worker_label, row, 0)
##        grid_layout.addWidget(self.worker_input, row, 1)

        # 按钮
        self.in_button = QPushButton("入库")
        self.out_button = QPushButton("出库")
        self.print_button = QPushButton("打印")
        self.submit_button = QPushButton("提交")
        button_layout.addWidget(self.in_button)
        button_layout.addWidget(self.out_button)
        button_layout.addWidget(self.print_button)
        button_layout.addWidget(self.submit_button)

        # Connect buttons to functions
        self.in_button.clicked.connect(self.handle_in_button)
        self.out_button.clicked.connect(self.handle_out_button)
        self.print_button.clicked.connect(self.handle_print_button)
        self.submit_button.clicked.connect(self.accept)

        # Combine layouts
        self.layout.addLayout(self.grid_layout)
        self.layout.addLayout(self.button_layout)
    def handle_in_button(self):
        # 入库逻辑
        print("入库操作")
    
    def handle_out_button(self):
        # 出库逻辑
        print("出库操作")

    def handle_print_button(self):
        # 打印逻辑
        print("打印操作")

        # 显示对话框
        self.show()

    def handle_operation(self, operation):
        self.selected_operation = operation
        if operation == "出库" and self.device_info_layout.isVisible():
            self.device_info_layout.setVisible(False)
            self.accept()
        elif not self.device_info_layout.isVisible():
            self.device_info_layout.setVisible(True)

    def save_changes(self):
        updated_info = [field.text() for field in self.device_info_fields.values()]
        success = self.db_manager.update_device_info(self.barcode, updated_info)

        if success:
            QMessageBox.information(self, "保存成功", "设备信息已更新。")
            self.accept()
        else:
            QMessageBox.warning(self, "保存失败", "更新设备信息时出错。")