学生管理系统,增加教师管理,班级管理,角色功能权限管理

为了在现有的学生管理系统中增加**教师管理**、**班级管理**以及**角色和权限管理**,我们需要对数据库进行扩展,并相应地更新 Python 代码和用户界面。以下是详细的步骤和代码示例。

## 1. 数据库扩展

### 1.1 创建新表

#### 教师表 (`teachers`)

```sql
CREATE TABLE teachers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INT,
    gender VARCHAR(10),
    email VARCHAR(100),
    phone VARCHAR(20)
);
```

#### 班级表 (`classes`)

```sql
CREATE TABLE classes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    teacher_id INT,
    FOREIGN KEY (teacher_id) REFERENCES teachers(id) ON DELETE SET NULL
);
```

#### 学生表更新 (`students`)

为了将学生与班级关联,需要在 `students` 表中添加 `class_id` 字段。

```sql
ALTER TABLE students
ADD COLUMN class_id INT,
ADD FOREIGN KEY (class_id) REFERENCES classes(id) ON DELETE SET NULL;
```

#### 角色表 (`roles`)

```sql
CREATE TABLE roles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL UNIQUE
);
```

#### 权限表 (`permissions`)

```sql
CREATE TABLE permissions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL UNIQUE,
    description VARCHAR(255)
);
```

#### 角色权限关联表 (`role_permissions`)

```sql
CREATE TABLE role_permissions (
    role_id INT,
    permission_id INT,
    PRIMARY KEY (role_id, permission_id),
    FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
    FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
);
```

#### 用户表 (`users`)

假设系统有用户登录功能,可以创建 `users` 表。

```sql
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    password_hash VARCHAR(255) NOT NULL,
    role_id INT,
    FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE SET NULL
);
```

### 1.2 插入初始数据

```sql
-- 插入角色
INSERT INTO roles (name) VALUES ('管理员'), ('教师'), ('学生');

-- 插入权限
INSERT INTO permissions (name, description) VALUES
('add_student', '添加学生'),
('edit_student', '编辑学生'),
('delete_student', '删除学生'),
('view_student', '查看学生'),
('add_teacher', '添加教师'),
('edit_teacher', '编辑教师'),
('delete_teacher', '删除教师'),
('view_teacher', '查看教师'),
('add_class', '添加班级'),
('edit_class', '编辑班级'),
('delete_class', '删除班级'),
('view_class', '查看班级');

-- 关联角色与权限
INSERT INTO role_permissions (role_id, permission_id) VALUES
(1, 1), (1, 2), (1, 3), (1, 4),
(1, 5), (1, 6), (1, 7), (1, 8),
(1, 9), (1, 10), (1, 11), (1, 12),
(2, 1), (2, 4), (2, 5), (2, 8),
(3, 4);
```

## 2. 更新 Python 代码

### 2.1 数据库连接与基础模型

为了更好地管理数据库操作,建议使用 ORM(如 SQLAlchemy)或继续使用 PyMySQL。以下示例继续使用 PyMySQL,但建议考虑使用 ORM 以提高代码的可维护性。

### 2.2 添加教师管理功能

#### 教师管理界面

```python
    def __init__(self):
        # ... [初始化代码保持不变]
        self.add_teacher_button = QtWidgets.QPushButton("添加教师")
        self.edit_teacher_button = QtWidgets.QPushButton("编辑教师")
        self.delete_teacher_button = QtWidgets.QPushButton("删除教师")
        self.view_teacher_button = QtWidgets.QPushButton("查看教师")
        self.button_layout.addWidget(self.add_teacher_button)
        self.button_layout.addWidget(self.edit_teacher_button)
        self.button_layout.addWidget(self.delete_teacher_button)
        self.button_layout.addWidget(self.view_teacher_button)

        # 连接教师按钮信号
        self.add_teacher_button.clicked.connect(self.add_teacher)
        self.edit_teacher_button.clicked.connect(self.edit_teacher)
        self.delete_teacher_button.clicked.connect(self.delete_teacher)
        self.view_teacher_button.clicked.connect(self.view_teachers)

        # 教师表格
        self.teacher_table = QtWidgets.QTableWidget()
        self.teacher_table.setColumnCount(6)
        self.teacher_table.setHorizontalHeaderLabels(['ID', '姓名', '年龄', '性别', '邮箱', '电话'])
        self.layout.addWidget(self.teacher_table)
```

#### 添加教师

```python
    def add_teacher(self):
        dialog = QtWidgets.QDialog(self)
        dialog.setWindowTitle("添加教师")
        dialog_layout = QtWidgets.QVBoxLayout()
        form_layout = QtWidgets.QFormLayout()
        name_input = QtWidgets.QLineEdit()
        age_input = QtWidgets.QLineEdit()
        gender_input = QtWidgets.QLineEdit()
        email_input = QtWidgets.QLineEdit()
        phone_input = QtWidgets.QLineEdit()
        form_layout.addRow("姓名", name_input)
        form_layout.addRow("年龄", age_input)
        form_layout.addRow("性别", gender_input)
        form_layout.addRow("邮箱", email_input)
        form_layout.addRow("电话", phone_input)
        dialog_layout.addLayout(form_layout)

        button_layout = QtWidgets.QHBoxLayout()
        ok_button = QtWidgets.QPushButton("确定")
        cancel_button = QtWidgets.QPushButton("取消")
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)
        dialog_layout.addLayout(button_layout)

        dialog.setLayout(dialog_layout)

        def on_ok():
            name = name_input.text()
            age = age_input.text()
            gender = gender_input.text()
            email = email_input.text()
            phone = phone_input.text()
            if not name:
                QtWidgets.QMessageBox.warning(self, "输入错误", "姓名不能为空")
                return
            try:
                age = int(age)
            except ValueError:
                QtWidgets.QMessageBox.warning(self, "输入错误", "年龄必须是数字")
                return
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "INSERT INTO teachers (name, age, gender, email, phone) VALUES (%s, %s, %s, %s, %s)"
                        cursor.execute(sql, (name, age, gender, email, phone))
                    connection.commit()
                except pymysql.MySQLError as e:
                    print(f"插入错误: {e}")
                finally:
                    connection.close()
                self.view_teachers()
                dialog.close()

        def on_cancel():
            dialog.close()

        ok_button.clicked.connect(on_ok)
        cancel_button.clicked.connect(on_cancel)

        dialog.exec_()
```

#### 编辑教师

```python
    def edit_teacher(self):
        selected_items = self.teacher_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要编辑的教师")
            return
        row = selected_items[0].row()
        teacher_id = self.teacher_table.item(row, 0).text()
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT * FROM teachers WHERE id = %s"
                    cursor.execute(sql, (teacher_id,))
                    result = cursor.fetchone()
                connection.close()
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
                connection.close()
                return

            dialog = QtWidgets.QDialog(self)
            dialog.setWindowTitle("编辑教师")
            dialog_layout = QtWidgets.QVBoxLayout()
            form_layout = QtWidgets.QFormLayout()
            name_input = QtWidgets.QLineEdit(result[1])
            age_input = QtWidgets.QLineEdit(str(result[2]))
            gender_input = QtWidgets.QLineEdit(result[3])
            email_input = QtWidgets.QLineEdit(result[4])
            phone_input = QtWidgets.QLineEdit(result[5])
            form_layout.addRow("姓名", name_input)
            form_layout.addRow("年龄", age_input)
            form_layout.addRow("性别", gender_input)
            form_layout.addRow("邮箱", email_input)
            form_layout.addRow("电话", phone_input)
            dialog_layout.addLayout(form_layout)

            button_layout = QtWidgets.QHBoxLayout()
            ok_button = QtWidgets.QPushButton("确定")
            cancel_button = QtWidgets.QPushButton("取消")
            button_layout.addWidget(ok_button)
            button_layout.addWidget(cancel_button)
            dialog_layout.addLayout(button_layout)

            dialog.setLayout(dialog_layout)

            def on_ok():
                name = name_input.text()
                age = age_input.text()
                gender = gender_input.text()
                email = email_input.text()
                phone = phone_input.text()
                if not name:
                    QtWidgets.QMessageBox.warning(self, "输入错误", "姓名不能为空")
                    return
                try:
                    age = int(age)
                except ValueError:
                    QtWidgets.QMessageBox.warning(self, "输入错误", "年龄必须是数字")
                    return
                connection = get_db_connection()
                if connection:
                    try:
                        with connection.cursor() as cursor:
                            sql = "UPDATE teachers SET name = %s, age = %s, gender = %s, email = %s, phone = %s WHERE id = %s"
                            cursor.execute(sql, (name, age, gender, email, phone, teacher_id))
                        connection.commit()
                    except pymysql.MySQLError as e:
                        print(f"更新错误: {e}")
                    finally:
                        connection.close()
                    self.view_teachers()
                    dialog.close()

            def on_cancel():
                dialog.close()

            ok_button.clicked.connect(on_ok)
            cancel_button.clicked.connect(on_cancel)

            dialog.exec_()
```

#### 删除教师

```python
    def delete_teacher(self):
        selected_items = self.teacher_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要删除的教师")
            return
        row = selected_items[0].row()
        teacher_id = self.teacher_table.item(row, 0).text()
        reply = QtWidgets.QMessageBox.question(self, "确认删除", f"确定要删除教师 ID {teacher_id} 吗?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "DELETE FROM teachers WHERE id = %s"
                        cursor.execute(sql, (teacher_id,))
                    connection.commit()
                except pymysql.MySQLError as e:
                    print(f"删除错误: {e}")
                finally:
                    connection.close()
                self.view_teachers()
```

#### 查看教师

```python
    def view_teachers(self):
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT * FROM teachers"
                    cursor.execute(sql)
                    result = cursor.fetchall()
                    self.teacher_table.setRowCount(0)
                    for row_number, row_data in enumerate(result):
                        self.teacher_table.insertRow(row_number)
                        for column_number, data in enumerate(row_data):
                            self.teacher_table.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
            finally:
                connection.close()
```

### 2.3 添加班级管理功能

#### 班级管理界面

```python
    def __init__(self):
        # ... [初始化代码保持不变]
        self.add_class_button = QtWidgets.QPushButton("添加班级")
        self.edit_class_button = QtWidgets.QPushButton("编辑班级")
        self.delete_class_button = QtWidgets.QPushButton("删除班级")
        self.view_class_button = QtWidgets.QPushButton("查看班级")
        self.button_layout.addWidget(self.add_class_button)
        self.button_layout.addWidget(self.edit_class_button)
        self.button_layout.addWidget(self.delete_class_button)
        self.button_layout.addWidget(self.view_class_button)

        # 连接班级按钮信号
        self.add_class_button.clicked.connect(self.add_class)
        self.edit_class_button.clged.connect(self.edit_class)
        self.delete_class_button.clicked.connect(self.delete_class)
        self.view_class_button.clicked.connect(self.view_classes)

        # 班级表格
        self.class_table = QtWidgets.QTableWidget()
        self.class_table.setColumnCount(3)
        self.class_table.setHorizontalHeaderLabels(['ID', '班级名称', '教师'])
        self.layout.addWidget(self.class_table)
```

#### 添加班级

```python
    def add_class(self):
        dialog = QtWidgets.QDialog(self)
        dialog.setWindowTitle("添加班级")
        dialog_layout = QtWidgets.QVBoxLayout()
        form_layout = QtWidgets.QFormLayout()
        name_input = QtWidgets.QLineEdit()
        teacher_input = QtWidgets.QComboBox()
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT id, name FROM teachers"
                    cursor.execute(sql)
                    teachers = cursor.fetchall()
                    for teacher in teachers:
                        teacher_input.addItem(f"{teacher[1]} (ID: {teacher[0]})", teacher[0])
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
            finally:
                connection.close()
        form_layout.addRow("班级名称", name_input)
        form_layout.addRow("教师", teacher_input)
        dialog_layout.addLayout(form_layout)

        button_layout = QtWidgets.QHBoxLayout()
        ok_button = QtWidgets.QPushButton("确定")
        cancel_button = QtWidgets.QPushButton("取消")
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)
        dialog_layout.addLayout(button_layout)

        dialog.setLayout(dialog_layout)

        def on_ok():
            name = name_input.text()
            teacher_id = teacher_input.currentData()
            if not name:
                QtWidgets.QMessageBox.warning(self, "输入错误", "班级名称不能为空")
                return
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "INSERT INTO classes (name, teacher_id) VALUES (%s, %s)"
                        cursor.execute(sql, (name, teacher_id))
                    connection.commit()
                except pymysql.MySQLError as e:
                    print(f"插入错误: {e}")
                finally:
                    connection.close()
                self.view_classes()
                dialog.close()

        def on_cancel():
            dialog.close()

        ok_button.clicked.connect(on_ok)
        cancel_button.clicked.connect(on_cancel)

        dialog.exec_()
```

#### 编辑班级

```python
    def edit_class(self):
        selected_items = self.class_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要编辑的班级")
            return
        row = selected_items[0].row()
        class_id = self.class_table.item(row, 0).text()
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT * FROM classes WHERE id = %s"
                    cursor.execute(sql, (class_id,))
                    result = cursor.fetchone()
                connection.close()
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
                connection.close()
                return

            dialog = QtWidgets.QDialog(self)
            dialog.setWindowTitle("编辑班级")
            dialog_layout = QtWidgets.QVBoxLayout()
            form_layout = QtWidgets.QFormLayout()
            name_input = QtWidgets.QLineEdit(result[1])
            teacher_input = QtWidgets.QComboBox()
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "SELECT id, name FROM teachers"
                        cursor.execute(sql)
                        teachers = cursor.fetchall()
                        for teacher in teachers:
                            teacher_input.addItem(f"{teacher[1]} (ID: {teacher[0]})", teacher[0])
                        teacher_input.setCurrentIndex(teacher_input.findData(result[2]))
                except pymysql.MySQLError as e:
                    print(f"查询错误: {e}")
                finally:
                    connection.close()
            form_layout.addRow("班级名称", name_input)
            form_layout.addRow("教师", teacher_input)
            dialog_layout.addLayout(form_layout)

            button_layout = QtWidgets.QHBoxLayout()
            ok_button = QtWidgets.QPushButton("确定")
            cancel_button = QtWidgets.QPushButton("取消")
            button_layout.addWidget(ok_button)
            button_layout.addWidget(cancel_button)
            dialog_layout.addLayout(button_layout)

            dialog.setLayout(dialog_layout)

            def on_ok():
                name = name_input.text()
                teacher_id = teacher_input.currentData()
                if not name:
                    QtWidgets.QMessageBox.warning(self, "输入错误", "班级名称不能为空")
                    return
                connection = get_db_connection()
                if connection:
                    try:
                        with connection.cursor() as cursor:
                            sql = "UPDATE classes SET name = %s, teacher_id = %s WHERE id = %s"
                            cursor.execute(sql, (name, teacher_id, class_id))
                        connection.commit()
                    except pymysql.MySQLError as e:
                        print(f"更新错误: {e}")
                    finally:
                        connection.close()
                    self.view_classes()
                    dialog.close()

            def on_cancel():
                dialog.close()

            ok_button.clicked.connect(on_ok)
            cancel_button.clicked.connect(on_cancel)

            dialog.exec_()
```

#### 删除班级

```python
    def delete_class(self):
        selected_items = self.class_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要删除的班级")
            return
        row = selected_items[0].row()
        class_id = self.class_table.item(row, 0).text()
        reply = QtWidgets.QMessageBox.question(self, "确认删除", f"确定要删除班级 ID {class_id} 吗?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "DELETE FROM classes WHERE id = %s"
                        cursor.execute(sql, (class_id,))
                    connection.commit()
                except pymysql.MySQLError as e:
                    print(f"删除错误: {e}")
                finally:
                    connection.close()
                self.view_classes()
```

#### 查看班级

```python
    def view_classes(self):
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT classes.id, classes.name, teachers.name FROM classes LEFT JOIN teachers ON classes.teacher_id = teachers.id"
                    cursor.execute(sql)
                    result = cursor.fetchall()
                    self.class_table.setRowCount(0)
                    for row_number, row_data in enumerate(result):
                        self.class_table.insertRow(row_number)
                        for column_number, data in enumerate(row_data):
                            self.class_table.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
            finally:
                connection.close()
```

### 2.4 添加角色与权限管理

#### 角色管理界面

```python
    def __init__(self):
        # ... [初始化代码保持不变]
        self.add_role_button = QtWidgets.QPushButton("添加角色")
        self.edit_role_button = QtWidgets.QPushButton("编辑角色")
        self.delete_role_button = QtWidgets.QPushButton("删除角色")
        self.view_role_button = QtWidgets.QPushButton("查看角色")
        self.button_layout.addWidget(self.add_role_button)
        self.button_layout.addWidget(self.edit_role_button)
        self.button_layout.addWidget(self.delete_role_button)
        self.button_layout.addWidget(self.view_role_button)

        # 连接角色按钮信号
        self.add_role_button.clicked.connect(self.add_role)
        self.edit_role_button.clicked.connect(self.edit_role)
        self.delete_role_button.clicked.connect(self.delete_role)
        self.view_role_button.clicked.connect(self.view_roles)

        # 角色表格
        self.role_table = QtWidgets.QTableWidget()
        self.role_table.setColumnCount(2)
        self.role_table.setHorizontalHeaderLabels(['ID', '角色名称'])
        self.layout.addWidget(self.role_table)
```

#### 添加角色

```python
    def add_role(self):
        dialog = QtWidgets.QDialog(self)
        dialog.setWindowTitle("添加角色")
        dialog_layout = QtWidgets.QVBoxLayout()
        form_layout = QtWidgets.QFormLayout()
        name_input = QtWidgets.QLineEdit()
        form_layout.addRow("角色名称", name_input)
        dialog_layout.addLayout(form_layout)

        button_layout = QtWidgets.QHBoxLayout()
        ok_button = QtWidgets.QPushButton("确定")
        cancel_button = QtWidgets.QPushButton("取消")
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)
        dialog_layout.addLayout(button_layout)

        dialog.setLayout(dialog_layout)

        def on_ok():
            name = name_input.text()
            if not name:
                QtWidgets.QMessageBox.warning(self, "输入错误", "角色名称不能为空")
                return
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "INSERT INTO roles (name) VALUES (%s)"
                        cursor.execute(sql, (name,))
                    connection.commit()
                except pymysql.MySQLError as e:
                    print(f"插入错误: {e}")
                finally:
                    connection.close()
                self.view_roles()
                dialog.close()

        def on_cancel():
            dialog.close()

        ok_button.clicked.connect(on_ok)
        cancel_button.clicked.connect(on_cancel)

        dialog.exec_()
```

#### 编辑角色

```python
    def edit_role(self):
        selected_items = self.role_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要编辑的角色")
            return
        row = selected_items[0].row()
        role_id = self.role_table.item(row, 0).text()
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT name FROM roles WHERE id = %s"
                    cursor.execute(sql, (role_id,))
                    result = cursor.fetchone()
                connection.close()
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
                connection.close()
                return

            dialog = QtWidgets.QDialog(self)
            dialog.setWindowTitle("编辑角色")
            dialog_layout = QtWidgets.QVBoxLayout()
            form_layout = QtWidgets.QFormLayout()
            name_input = QtWidgets.QLineEdit(result[0])
            form_layout.addRow("角色名称", name_input)
            dialog_layout.addLayout(form_layout)

            button_layout = QtWidgets.QHBoxLayout()
            ok_button = QtWidgets.QPushButton("确定")
            cancel_button = QtWidgets.QPushButton("取消")
            button_layout.addWidget(ok_button)
            button_layout.addWidget(cancel_button)
            dialog_layout.addLayout(button_layout)

            dialog.setLayout(dialog_layout)

            def on_ok():
                name = name_input.text()
                if not name:
                    QtWidgets.QMessageBox.warning(self, "输入错误", "角色名称不能为空")
                    return
                connection = get_db_connection()
                if connection:
                    try:
                        with connection.cursor() as cursor:
                            sql = "UPDATE roles SET name = %s WHERE id = %s"
                            cursor.execute(sql, (name, role_id))
                        connection.commit()
                    except pymysql.MySQLError as e:
                        print(f"更新错误: {e}")
                    finally:
                        connection.close()
                    self.view_roles()
                    dialog.close()

            def on_cancel():
                dialog.close()

            ok_button.clicked.connect(on_ok)
            cancel_button.clicked.connect(on_cancel)

            dialog.exec_()
```

#### 删除角色

```python
    def delete_role(self):
        selected_items = self.role_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要删除的角色")
            return
        row = selected_items[0].row()
        role_id = self.role_table.item(row, 0).text()
        reply = QtWidgets.QMessageBox.question(self, "确认删除", f"确定要删除角色 ID {role_id} 吗?", QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "DELETE FROM roles WHERE id = %s"
                        cursor.execute(sql, (role_id,))
                    connection.commit()
                except pymysql.MySQLError as e:
                    print(f"删除错误: {e}")
                finally:
                    connection.close()
                self.view_roles()
```

#### 查看角色

```python
    def view_roles(self):
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT * FROM roles"
                    cursor.execute(sql)
                    result = cursor.fetchall()
                    self.role_table.setRowCount(0)
                    for row_number, row_data in enumerate(result):
                        self.role_table.insertRow(row_number)
                        for column_number, data in enumerate(row_data):
                            self.role_table.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
            finally:
                connection.close()
```

### 2.5 权限管理

权限管理通常与角色管理结合在一起。以下是一个简单的权限分配界面。

#### 权限分配界面

```python
    def __init__(self):
        # ... [初始化代码保持不变]
        self.assign_permission_button = QtWidgets.QPushButton("分配权限")
        self.button_layout.addWidget(self.assign_permission_button)

        # 连接权限分配按钮信号
        self.assign_permission_button.clicked.connect(self.assign_permission)

        # 权限表格
        self.permission_table = QtWidgets.QTableWidget()
        self.permission_table.setColumnCount(3)
        self.permission_table.setHorizontalHeaderLabels(['ID', '权限名称', '描述'])
        self.layout.addWidget(self.permission_table)
```

#### 分配权限

```python
    def assign_permission(self):
        selected_items = self.role_table.selectedItems()
        if not selected_items:
            QtWidgets.QMessageBox.warning(self, "选择错误", "请选择要分配权限的角色")
            return
        row = selected_items[0].row()
        role_id = self.role_table.item(row, 0).text()
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT id, name FROM permissions"
                    cursor.execute(sql)
                    permissions = cursor.fetchall()
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
                connection.close()
                return

            dialog = QtWidgets.QDialog(self)
            dialog.setWindowTitle("分配权限")
            dialog_layout = QtWidgets.QVBoxLayout()
            form_layout = QtWidgets.QFormLayout()
            permission_input = QtWidgets.QListWidget()
            for permission in permissions:
                item = QtWidgets.QListWidgetItem(f"{permission[1]}")
                item.setData(QtCore.Qt.UserRole, permission[0])
                permission_input.addItem(item)
            form_layout.addRow("权限", permission_input)
            dialog_layout.addLayout(form_layout)

            button_layout = QtWidgets.QHBoxLayout()
            ok_button = QtWidgets.QPushButton("确定")
            cancel_button = QtWidgets.QPushButton("取消")
            button_layout.addWidget(ok_button)
            button_layout.addWidget(cancel_button)
            dialog_layout.addLayout(button_layout)

            dialog.setLayout(dialog_layout)

            def on_ok():
                permission_ids = [item.data(QtCore.Qt.UserRole) for item in permission_input.selectedItems()]
                connection = get_db_connection()
                if connection:
                    try:
                        with connection.cursor() as cursor:
                            sql = "DELETE FROM role_permissions WHERE role_id = %s"
                            cursor.execute(sql, (role_id,))
                            if permission_ids:
                                sql = "INSERT INTO role_permissions (role_id, permission_id) VALUES (%s, %s)"
                                for permission_id in permission_ids:
                                    cursor.execute(sql, (role_id, permission_id))
                        connection.commit()
                    except pymysql.MySQLError as e:
                        print(f"更新错误: {e}")
                    finally:
                        connection.close()
                    self.view_roles()
                    self.view_permissions()
                    dialog.close()

            def on_cancel():
                dialog.close()

            ok_button.clicked.connect(on_ok)
            cancel_button.clicked.connect(on_cancel)

            dialog.exec_()
```

#### 查看权限

```python
    def view_permissions(self):
        connection = get_db_connection()
        if connection:
            try:
                with connection.cursor() as cursor:
                    sql = "SELECT * FROM permissions"
                    cursor.execute(sql)
                    result = cursor.fetchall()
                    self.permission_table.setRowCount(0)
                    for row_number, row_data in enumerate(result):
                        self.permission_table.insertRow(row_number)
                        for column_number, data in enumerate(row_data):
                            self.permission_table.setItem(row_number, column_number, QtWidgets.QTableWidgetItem(str(data)))
            except pymysql.MySQLError as e:
                print(f"查询错误: {e}")
            finally:
                connection.close()
```

## 3. 整合界面

为了更好地管理不同的功能模块,建议在主界面中添加标签页(Tabs),将学生、教师、班级、角色与权限分别放在不同的标签页中。

### 示例主界面

```python
    def __init__(self):
        super().__init__()
        self.setWindowTitle("综合管理系统")
        self.setGeometry(100, 100, 1000, 800)
        self.central_widget = QtWidgets.QTabWidget()
        self.setCentralWidget(self.central_widget)

        # 学生管理标签页
        student_tab = QtWidgets.QWidget()
        student_layout = QtWidgets.QVBoxLayout()
        student_tab.setLayout(student_layout)
        student_tab.setObjectName("学生管理")
        self.central_widget.addTab(student_tab, "学生管理")
        self.table = QtWidgets.QTableWidget()
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels(['ID', '姓名', '年龄', '性别', '邮箱', '电话'])
        student_layout.addWidget(self.table)

        # 教师管理标签页
        teacher_tab = QtWidgets.QWidget()
        teacher_layout = QtWidgets.QVBoxLayout()
        teacher_tab.setLayout(teacher_layout)
        teacher_tab.setObjectName("教师管理")
        self.central_widget.addTab(teacher_tab, "教师管理")
        self.teacher_table = QtWidgets.QTableWidget()
        self.teacher_table.setColumnCount(6)
        self.teacher_table.setHorizontalHeaderLabels(['ID', '姓名', '年龄', '性别', '邮箱', '电话'])
        teacher_layout.addWidget(self.teacher_table)

        # 班级管理标签页
        class_tab = QtWidgets.QWidget()
        class_layout = QtWidgets.QVBoxLayout()
        class_tab.setLayout(class_layout)
        class_tab.setObjectName("班级管理")
        self.central_widget.addTab(class_tab, "班级管理")
        self.class_table = QtWidgets.QTableWidget()
        self.class_table.setColumnCount(3)
        self.class_table.setHorizontalHeaderLabels(['ID', '班级名称', '教师'])
        class_layout.addWidget(self.class_table)

        # 角色管理标签页
        role_tab = QtWidgets.QWidget()
        role_layout = QtWidgets.QVBoxLayout()
        role_tab.setLayout(role_layout)
        role_tab.setObjectName("角色管理")
        self.central_widget.addTab(role_tab, "角色管理")
        self.role_table = QtWidgets.QTableWidget()
        self.role_table.setColumnCount(2)
        self.role_table.setHorizontalHeaderLabels(['ID', '角色名称'])
        role_layout.addWidget(self.role_table)

        # 权限管理标签页
        permission_tab = QtWidgets.QWidget()
        permission_layout = QtWidgets.QVBoxLayout()
        permission_tab.setLayout(permission_layout)
        permission_tab.setObjectName("权限管理")
        self.central_widget.addTab(permission_tab, "权限管理")
        self.permission_table = QtWidgets.QTableWidget()
        self.permission_table.setColumnCount(3)
        self.permission_table.setHorizontalHeaderLabels(['ID', '权限名称', '描述'])
        permission_layout.addWidget(self.permission_table)

        # 按钮布局
        self.button_layout = QtWidgets.QHBoxLayout()
        self.add_button = QtWidgets.QPushButton("添加")
        self.edit_button = QtWidgets.QPushButton("编辑")
        self.delete_button = QtWidgets.QPushButton("删除")
        self.view_button = QtWidgets.QPushButton("查看")
        self.button_layout.addWidget(self.add_button)
        self.button_layout.addWidget(self.edit_button)
        self.button_layout.addWidget(self.delete_button)
        self.button_layout.addWidget(self.view_button)
        self.layout = QtWidgets.QVBoxLayout()
        self.central_widget.currentChanged.connect(self.on_tab_changed)
        self.layout.addLayout(self.button_layout)
        self.layout.addWidget(self.table)
        self.layout.addWidget(self.teacher_table)
        self.layout.addWidget(self.class_table)
        self.layout.addWidget(self.role_table)
        self.layout.addWidget(self.permission_table)
        self.central_widget.setLayout(self.layout)

        # 连接按钮信号
        self.add_button.clicked.connect(self.on_add)
        self.edit_button.clicked.connect(self.on_edit)
        self.delete_button.clicked.connect(self.on_delete)
        self.view_button.clicked.connect(self.on_view)

    def on_tab_changed(self, index):
        if index == 0:
            self.view_students()
        elif index == 1:
            self.view_teachers()
        elif index == 2:
            self.view_classes()
        elif index == 3:
            self.view_roles()
        elif index == 4:
            self.view_permissions()

    def on_add(self):
        current_tab = self.central_widget.currentIndex()
        if current_tab == 0:
            self.add_student()
        elif current_tab == 1:
            self.add_teacher()
        elif current_tab == 2:
            self.add_class()
        elif current_tab == 3:
            self.add_role()
        elif current_tab == 4:
            self.assign_permission()

    def on_edit(self):
        current_tab = self.central_widget.currentIndex()
        if current_tab == 0:
            self.edit_student()
        elif current_tab == 1:
            self.edit_teacher()
        elif current_tab == 2:
            self.edit_class()
        elif current_tab == 3:
            self.edit_role()
        elif current_tab == 4:
            self.edit_permission()

    def on_delete(self):
        current_tab = self.central_widget.currentIndex()
        if current_tab == 0:
            self.delete_student()
        elif current_tab == 1:
            self.delete_teacher()
        elif current_tab == 2:
            self.delete_class()
        elif current_tab == 3:
            self.delete_role()
        elif current_tab == 4:
            self.delete_permission()

    def on_view(self):
        current_tab = self.central_widget.currentIndex()
        if current_tab == 0:
            self.view_students()
        elif current_tab == 1:
            self.view_teachers()
        elif current_tab == 2:
            self.view_classes()
        elif current_tab == 3:
            self.view_roles()
        elif current_tab == 4:
            self.view_permissions()
```

## 4. 权限控制

为了实现基于角色的权限控制,需要在应用启动时加载当前用户的角色和权限,并根据权限控制按钮的可用性。

### 示例代码

```python
    def __init__(self):
        # ... [初始化代码保持不变]
        self.current_user_role = None
        self.current_user_permissions = []

        # 登录逻辑
        self.login()

        # 根据权限控制按钮
        self.update_button_visibility()

    def login(self):
        # 简单的登录逻辑
        dialog = QtWidgets.QDialog(self)
        dialog.setWindowTitle("登录")
        dialog_layout = QtWidgets.QVBoxLayout()
        form_layout = QtWidgets.QFormLayout()
        username_input = QtWidgets.QLineEdit()
        password_input = QtWidgets.QLineEdit()
        password_input.setEchoMode(QtWidgets.QLineEdit.Password)
        form_layout.addRow("用户名", username_input)
        form_layout.addRow("密码", password_input)
        dialog_layout.addLayout(form_layout)

        button_layout = QtWidgets.QHBoxLayout()
        ok_button = QtWidgets.QPushButton("登录")
        cancel_button = QtWidgets.QPushButton("取消")
        button_layout.addWidget(ok_button)
        button_layout.addWidget(cancel_button)
        dialog_layout.addLayout(button_layout)

        dialog.setLayout(dialog_layout)

        def on_ok():
            username = username_input.text()
            password = password_input.text()
            connection = get_db_connection()
            if connection:
                try:
                    with connection.cursor() as cursor:
                        sql = "SELECT id, role_id FROM users WHERE username =

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/493919.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新版国标GB28181设备端Android版EasyGBD支持国标GB28181-2022,支持语音对讲,支持位置上报,开源在Github

经过近3个月的迭代开发,新版本的国标GB28181设备端EasyGBD安卓Android版终于在昨天发布到Github了,最新的EasyGBD支持了国标GB28181-2022版,还支持了语音对讲、位置上报、本地录像等功能,比原有GB28181-2016版的EasyGBD更加高效、…

YOLO-World:Real-Time Open-Vocabulary Object Detection

目录 摘要 Abstract YOLO-World 1 模型架构 1.1 Text Encoder 1.2 YOLO Backbone 2 RepVL-PAN 2.1 T-CSPLayer 2.2 I-Pooling Attention 2.3 预测 3 消融实验 3.1 预训练数据 3.2 RepVL-PAN的消融实验 3.3 文本编码器 4 效果展示 4.1 零样本 4.2 根据词汇表检…

MySQL -- 库的相关操作

目录 查看数据库 创建数据库 直接创建: 加约束条件 if not exists 字符集和校对规则 什么是字符集 什么是校对规则 校对规则的主要功能 校对规则的特性 查看指定的数据库使用的字符集和校对规则: 比较是否区分大小写字母差异 显示创建语句 …

【spring-cloud-gateway总结】

文章目录 什么是gateway如何导入gateway依赖路由配置gateway配置断路器导包配置 什么是gateway 在微服务架构中,gateway网关是一个服务,它作为系统的唯一入口点,处理所有的客户端请求,然后将这些请求路由到适当的服务。提供了几个…

mac iterm2 使用 lrzsz

前言 mac os 终端不支持使用 rz sz 上传下载文件,本文提供解决方法。 mac 上安装 brew install lrzsz两个脚本 注意:/usr/local/bin/iterm2-send-zmodem.sh 中的 sz命令路径要和你mac 上 sz 命令路径一致。 /usr/local/bin/iterm2-recv-zmodem.sh 中…

数智化医院分布式计算框架融合人工智能方向初步实现与能力转换浅析

人工智能中心计算机 一、引言 1.1 研究背景与意义 近年来,人工智能(Artificial Intelligence,AI)与大数据技术的迅猛发展为医疗行业带来了前所未有的变革机遇。医疗领域积累了海量的数据,如电子病历(Elec…

airflow docker 安装

mkdir -p /root/airflow cd /root/airflow && mkdir -p ./dags ./logs ./plugins ./configcd /root/airflow/ wget https://airflow.apache.org/docs/apache-airflow/2.10.4/docker-compose.yaml nano docker-compose.yamlAIRFLOW__CORE__LOAD_EXAMPLES: false #初始化…

【数据安全】如何保证其安全

数据安全风险 数字经济时代,数据已成为重要的生产要素。智慧城市、智慧政务的建设,正以数据为核心,推动城市管理的智能化和公共服务的优化。然而,公共数据开放共享与隐私保护之间的矛盾日益凸显,如何在确保数据安全的…

springboot463学生信息管理系统论文(论文+源码)_kaic

摘 要 使用旧方法对学生信息管理系统的信息进行系统化管理已经不再让人们信赖了,把现在的网络信息技术运用在学生信息管理系统的管理上面可以解决许多信息管理上面的难题,比如处理数据时间很长,数据存在错误不能及时纠正等问题。这次开发的学…

postman读取文件执行

要从文件获取的变量 text 在pre-request 中写从文件获取数据的脚本。脚本实现了,设置了text默认值,从文件读取text列,将text存入环境变量 //获取text参数 var text "济南天气"; if(data.text){ text data.text } pm.environment.…

我的个人博客正式上线了!

我的个人博客终于上线啦点此访问 经过一番折腾,我的个人博客终于上线啦!这是一个属于我自己的小天地,可以用来记录生活点滴、技术分享以及一些随想。 在这里,我想分享一下搭建博客的整个过程和心得体会。 为什么要搭建博客&…

摩尔信使MThings的逻辑控制功能范例

数值自增控制 数值自增/自减控制流程可广泛应用于生产线控制、工业机器人轨迹跟踪、输送带速度调整、空间环境模拟、炼油厂加热炉温度控制、啤酒和制药发酵过程控制、造纸机水分和基重控制以及多回路瞬态热流跟踪控制等多个领域,通过精确调整和优化关键参数&#xf…

高效处理PDF文件的终极工具:构建一个多功能PDF转换器

在日常工作中,处理PDF文件几乎是每个人都不可避免的任务。无论是从PDF中提取数据、合并多个PDF文件,还是处理文件中的敏感信息和图像,PDF文件的处理都可能成为繁琐且耗时的工作。如果你是数据分析师、工程师,或者从事文档管理的工…

ROS1入门教程3:自定义消息

一、新建项目 # 创建工作空间 mkdir -p demo3/src# 创建功能包 catkin_create_pkg demo roscpp rosmsg message_generation# 打开功能包 cd src/demo 二、创建自定义消息 # 创建消息目录 mkdir msg# 打开消息目录 cd msg# 创建消息文件 vim User.msg# 定义消息字段 string n…

《Java核心技术I》Swing的滑动条

滑动条 组合框在离散值中选择,滚动条从连续值中选择。 构造滑动条最常用方法:var slider new JSlider(min,max,initaValue); 如果忽略参数,最大值,最小值,初始值分别为0,100,50. 垂直滑动条,new JSlid…

STM32单片机使用CAN协议进行通信

CAN总线(控制器局域网总线) 理论知识 CAN总线是由BOSCH公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通信总线 CAN总线特征 两根通信线(CAN_H、CAN_L),线路少,无需共地差分信号通信&…

基础爬虫案例实战

我们已经学习了多进程、requests、正则表达式的基本用法,但还没有完整地实现过一个爬取案例。这一节,我们就来实现一个完整的网站爬虫,把前面学习的知识点串联起来,同时加深对这些知识点的理解。 准备工作 我们需要先做好如下准备工作。 安…

网络安全防范

实践内容 学习总结 PDR,$$P^2$$DR安全模型。 防火墙(Firewall): 网络访问控制机制,布置在网际间通信的唯一通道上。 不足:无法防护内部威胁,无法阻止非网络传播形式的病毒,安全策略…

【QSS样式表 - ⑤】:QLineEdit控件样式

文章目录 QLineEdit控件样式QSS示例1 - select-QSS示例2 - read-onlyQSS示例3 - echoModeQSS示例4 - 自定义密码模式 QLineEdit控件样式 常用属性 常用选择器 QSS示例1 - select- 代码: QLineEdit{selection-color: red;selection-background-color: yellow…

ScottPlot学习的常用笔记-02

ScottPlot学习的常用笔记-02 写在前面Why&Target:这里记一些杂项。上下文&背景 先记一下这几个小时的新收获先说一下,为什么可开发可视工具缩放的问题ScottPlot5.0起步.net Core: WinExe.Net Framework也是可以的 写在前面 Why&Target&…