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

news2024/12/23 7:30:52

为了在现有的学生管理系统中增加**教师管理**、**班级管理**以及**角色和权限管理**,我们需要对数据库进行扩展,并相应地更新 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.coloradmin.cn/o/2264123.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTF_1

CTF_Show 萌新赛 1.签到题 <?php if(isset($_GET[url])){system("curl https://".$_GET[url].".ctf.show"); }else{show_source(__FILE__); }?> 和 AI 一起分析 1.if(isset($_GET[url]))检查GET请求中是否存在名为url的参数。 curl 2.curl…

[文献阅读] Unsupervised Deep Embedding for Clustering Analysis (无监督的深度嵌入式聚类)

文章目录 Abstract:摘要聚类深度聚类 KL散度深度嵌入式聚类(DEC)KL散度聚类软分配&#xff08;soft assignment&#xff09;KL散度损失训练编码器的初始化聚类中心的初始化 实验评估总结 Abstract: This week I read Unsupervised Deep Embedding for Clustering Analysis .It…

记录:virt-manager配置Ubuntu arm虚拟机

virt-manager&#xff08;Virtual Machine Manager&#xff09;是一个图形用户界面应用程序&#xff0c;通过libvirt管理虚拟机&#xff08;即作为libvirt的图形前端&#xff09; 因为要在Linux arm环境做测试&#xff0c;记录下virt-manager配置arm虚拟机的过程 先在VMWare中…

使用C语言编写UDP循环接收并打印消息的程序

使用C语言编写UDP循环接收并打印消息的程序 前提条件程序概述伪代码C语言实现编译和运行C改进之自由设定端口注意事项在本文中,我们将展示如何使用C语言编写一个简单的UDP服务器程序,该程序将循环接收来自指定端口的UDP消息,并将接收到的消息打印到控制台。我们将使用POSIX套…

Spring Boot 教程之三十六:实现身份验证

如何在 Spring Boot 中实现简单的身份验证&#xff1f; 在本文中&#xff0c;我们将学习如何使用 Spring设置和配置基本身份验证。身份验证是任何类型的安全性中的主要步骤之一。Spring 提供依赖项&#xff0c;即Spring Security&#xff0c;可帮助在 API 上建立身份验证。有很…

什么样的LabVIEW控制算自动控制?

自动控制是指系统通过预先设计的算法和逻辑&#xff0c;在无人工干预的情况下对被控对象的状态进行实时监测、决策和调整&#xff0c;达到预期目标的过程。LabVIEW作为一种图形化编程工具&#xff0c;非常适合开发自动控制系统。那么&#xff0c;什么样的LabVIEW控制算作“自动…

GFPS扩展技术原理(七)-音频切换消息流

音频切换消息流 Seeker和Provider通过消息流来同步音频切换能力&#xff0c;触发连接做切换&#xff0c;获取或设置音频切换偏好&#xff0c;通知连接状态等等。为此专门定义了音频切换消息流Message Group 为0x07&#xff0c;Message codes如下&#xff1a; MAC of Audio s…

视频直播点播平台EasyDSS与无人机技术的森林防火融合应用

随着科技的飞速发展&#xff0c;无人机技术以其独特的优势在各个领域得到了广泛应用&#xff0c;特别是在森林防火这一关键领域&#xff0c;EasyDSS视频平台与无人机技术的融合应用更是为传统森林防火手段带来很大的变化。 一、无人机技术在森林防火中的优势 ‌1、快速响应与高…

机器人路径规划和避障算法matlab仿真,分别对比贪婪搜索,最安全距离,RPM以及RRT四种算法

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1贪婪搜索算法原理 4.2最安全距离算法原理 4.3RPM 算法原理 4.4 RRT 算法原理 5.完整程序 1.程序功能描述 机器人路径规划和避障算法matlab仿真,分别对比贪婪搜索,最安全距离,RPM以及R…

【论文笔记】Visual Alignment Pre-training for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Visual Alignment Pre-tra…

【附源码】Electron Windows桌面壁纸开发中的 CommonJS 和 ES Module 引入问题以及 Webpack 如何处理这种兼容

背景 在尝试让 ChatGPT 自动开发一个桌面壁纸更改的功能时&#xff0c;发现引入了一个 wallpaper 库&#xff0c;这个库的入口文件是 index.js&#xff0c;但是 package.json 文件下的 type:"module"&#xff0c;这样造成了无论你使用 import from 还是 require&…

Apache解析漏洞(apache_parsingCVE-2017-15715)

apache_parsing 到浏览器中访问网站 http://8.155.8.239:81/ 我们写一个木马 1.php.jpg 我们将写好的木马上传 会得到我们上传文件的路径 我们访问一下 发现上传成功 发现木马运行成功&#xff0c;接下来使用蚁剑连接我们的图片马 获取 shell 成功 CVE-2013-454 我们还是到…

C++-----函数与库

数学中的函数与编程中的函数对比 数学中的函数 - 数学函数是一种映射关系&#xff0c;例如&#xff0c;函数\(y f(x)x^{2}\)&#xff0c;对于每一个输入值\(x\)&#xff0c;都有唯一确定的输出值\(y\)。它侧重于描述变量之间的数量关系&#xff0c;通常通过公式来表示这种关系…

带着国标充电器出国怎么办? 适配器模式(Adapter Pattern)

适配器模式&#xff08;Adapter Pattern&#xff09; 适配器模式适配器模式&#xff08;Adapter Pattern&#xff09;概述talk is cheap&#xff0c; show you my code总结 适配器模式 适配器模式&#xff08;Adapter Pattern&#xff09;是面向对象软件设计中的一种结构型设计…

SKETCHPAD——允许语言模型生成中间草图,在几何、函数、图算法和游戏策略等所有数学任务中持续提高基础模型的性能

概述 论文地址&#xff1a;https://arxiv.org/pdf/2406.09403 素描是一种应用广泛的有效工具&#xff0c;包括产生创意和解决问题。由于素描能直接传达无法用语言表达的视觉和空间信息&#xff0c;因此从古代岩画到现代建筑图纸&#xff0c;素描在世界各地被用于各种用途。儿童…

初等函数整理

1.幂函数 2.指数函数 3.对数函数

【C/C++】手搓项目中常用小工具:日志、sqlit数据库、Split切割、UUID唯一标识

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章将写到一些手搓常用工具&#xff0c;方便在项目中的使用&#xff0c;并且在手搓的过程中一些函数如&#xff1a;日志 宏中的__VA_ARGS__接收可变参…

路径规划之启发式算法之二十一:狼群算法(Wolf Pack Algorithm,WPA)

狼群算法(Wolf Pack Algorithm,WPA)是一种模拟狼群捕食行为及其猎物分配方式的群体智能优化算法。它由吴虎胜等人在2013年提出,算法采用了基于人工狼主体的自下而上的设计方法和基于职责分工的协作式搜索路径结构。它通过抽象狼群搜索、围攻以及更新换代的三种行为方式来实…

Linux下基于最新稳定版ESP-IDF5.3.2开发esp32s3入门任务创建【入门二】

继上一篇的hello world&#xff1a; 【Linux下基于最新稳定版ESP-IDF5.3.2开发esp32s3入门hello world输出【入门一】-CSDN博客】 这一篇我们开始任务的创建。 工程还是用上一篇的hello world作为模板&#xff0c;hello world就不再app_main函数中输出&#xff0c;改成在任务…

用音乐与自我对话 ——澄迈漓岛音乐节x草台回声

四季循环&#xff0c;昼夜往复&#xff0c;在相对恒定的日常中&#xff0c;音乐是扇打量世界又内观本心的双向窗户。难以描述的触动&#xff0c;透过音乐语言转换为温热且真实的吟唱&#xff0c;一次又一次记录与释放。 除却生浪主舞台中的声音玩具乐队以及STOLEN秘密行动&…