学生管理系统,增加教师管理,班级管理,角色功能权限管理
为了在现有的学生管理系统中增加**教师管理**、**班级管理**以及**角色和权限管理**,我们需要对数据库进行扩展,并相应地更新 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 =
相关文章:
学生管理系统,增加教师管理,班级管理,角色功能权限管理
为了在现有的学生管理系统中增加**教师管理**、**班级管理**以及**角色和权限管理**,我们需要对数据库进行扩展,并相应地更新 Python 代码和用户界面。以下是详细的步骤和代码示例。 ## 1. 数据库扩展 ### 1.1 创建新表 #### 教师表 (teachers) sql …...
Vue CLI 脚手架创建项目流程详解 (2)
更新 CLI 脚手架 确保你安装的是最新版本的 Vue CLI,以支持最新的特性及改进。你可以通过以下命令全局安装或更新 Vue CLI: npm install -g vue/cli创建 Vue 3.x 项目 启动创建向导 使用 vue create 命令来开始创建一个新的 Vue 项目: vue …...
LabVIEW机械故障诊断中的传感器选择
在机械设备故障诊断中,传感器是关键设备,用于采集设备运行状态的各种数据。常见的传感器类型和选择方法如下: 1. 振动传感器 用于检测设备运行中的振动特征,常见于旋转机械和轴承故障诊断。 加速度传感器:检测高频振…...
二叉树_堆
目录 一. 树(非线性结构) 1.1 树的概念与结构 1.2 树的表示 二. 二叉树 2.1 二叉树的概念与结构 2.2 特殊的二叉树 2.3 二叉树的存储结构 三. 实现顺序结构的二叉树 3.1 堆的概念与结构 一. 树(非线性结构) 1.1 树的概念与结构 概念ÿ…...
Java图片拼接
最近遇到一个挺离谱的功能,某个表单只让上传一张图,多图上传会使导出失败。跟开发沟通后表示,这个问题处理不了。我... 遂自己思考,能否以曲线救国的方式拯救一下,即不伤及代码之根本,又能解决燃眉之急。灵…...
使用qemu搭建armv7嵌入式开发环境
目录 目录 1 概述 2 环境准备 2.1 vexpress系列开发板介绍 2.2 安装工具 2.2.1 安装交叉工具链 2.2.2 安装qemu 2.2.3 安装其他工具 3 启动uboot 3.1 uboot下载与编译 3.1.1 下载 3.1.2 编译 3.2 使用qemu启动uboot 4 启动kernel 4.1 下载和编译kernel 4.1.1 下…...
新版国标GB28181设备端Android版EasyGBD支持国标GB28181-2022,支持语音对讲,支持位置上报,开源在Github
经过近3个月的迭代开发,新版本的国标GB28181设备端EasyGBD安卓Android版终于在昨天发布到Github了,最新的EasyGBD支持了国标GB28181-2022版,还支持了语音对讲、位置上报、本地录像等功能,比原有GB28181-2016版的EasyGBD更加高效、…...
Hashtable 描述及源码解析
目录 一、Hashtable的基本概念 二、Hashtable的源码解析 构造函数 哈希算法函数 处理哈希冲突 类定义和成员变量 构造方法 插入元素 查找元素 删除元素 扩容 Hashtable(哈希表)是一种非常重要的数据结构,它提供了快速的数据插入、删…...
clickhouse-数据库引擎
1、数据库引擎和表引擎 数据库引擎默认是Ordinary,在这种数据库下面的表可以是任意类型引擎。 生产环境中常用的表引擎是MergeTree系列,也是官方主推的引擎。 MergeTree是基础引擎,有主键索引、数据分区、数据副本、数据采样、删除和修改等功…...
深度学习之超分辨率算法——SRCNN
网络为基础卷积层 tensorflow 1.14 scipy 1.2.1 numpy 1.16 大概意思就是针对数据,我们先把图片按缩小因子照整数倍进行缩减为小图片,再针对小图片进行插值算法,获得还原后的低分辨率的图片作为标签。 main.py 配置文件 from model im…...
本机如何连接虚拟机MYSQL
要让本机(主机)连接到虚拟机上的 MySQL 数据库,你需要确保虚拟机和主机之间的网络连接正常,并且 MySQL 配置允许外部连接。以下是实现本机连接虚拟机 MySQL 的步骤: 步骤 1:确认虚拟机与本机的网络连接 确…...
mac 安装graalvm
Download GraalVM 上面链接选择jdk的版本 以及系统的环境下载graalvm的tar包 解压tar包 tar -xzf graalvm-jdk-<version>_macos-<architecture>.tar.gz 移入java的文件夹目录 sudo mv graalvm-jdk-<version> /Library/Java/JavaVirtualMachines 设置环境变…...
大模型日报 2024-12-19
大模型日报 2024-12-19 大模型资讯 标题:OpenAI发布季第十天:ChatGPT登陆电话、WhatsApp,你可以给ChatGPT真正打电话了 摘要:OpenAI于2024年12月18日发布了ChatGPT的新功能,用户可以通过电话和WhatsApp与ChatGPT进行互…...
【数据结构练习题】链表与LinkedList
顺序表与链表LinkedList 选择题链表面试题1. 删除链表中等于给定值 val 的所有节点。2. 反转一个单链表。3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。4. 输入一个链表,输出该链…...
使用 acme.sh 申请域名 SSL/TLS 证书完整指南
使用 acme.sh 申请域名 SSL/TLS 证书完整指南 简介为什么选择 acme.sh 和 ZeroSSL?前置要求安装过程 步骤一:安装 acme.sh步骤二:配置 ZeroSSL 证书申请 方法一:手动 DNS 验证(推荐新手使用)方法二…...
微信小程序开发入门
实现滚动 需要设置高度和边框 轮播图 差值表达式( {{表达式的值}} ),info数据要写到js文件的data数据中 小程序中常用的事件...
【LeetCode】9、回文数
【LeetCode】9、回文数 文章目录 一、数学: 除法和取模1.1 数学: 除法和取模 二、多语言解法 一、数学: 除法和取模 1.1 数学: 除法和取模 例如 15251, offset 也是五位数的 10000 先判断首1和尾1, 再变为 525, offset 变为 100 再判断首5和尾5, 再变为 2, offset 变为 1 整个…...
面试题整理9----谈谈对k8s的理解2
面试题整理9----谈谈对k8s的理解2 1. Service 资源1.1 ServiceClusterIPNodePortLoadBalancerIngressExternalName 1.2 Endpoints1.3 Ingress1.4 EndpointSlice1.5 IngressClass 2. 配置和存储资源2.1 ConfigMap2.2 Secret2.3 PersistentVolume2.4 PersistentVolumeClaim2.5 St…...
fpga系列 HDL:Quartus II PLL (Phase-Locked Loop) IP核 (Quartus II 18.0)
在 Quartus II 中使用 PLL (Phase-Locked Loop) 模块来将输入时钟分频或倍频,并生成多个相位偏移或频率不同的时钟信号: 1. 生成 PLL 模块 在 Quartus II 中: 打开 IP Components。 file:///C:/intelFPGA_lite/18.0/quartus/common/help/w…...
中国量子计算机领域的发展现状与展望
中国量子计算机领域的发展现状与展望 摘要 随着全球科技竞争的加剧,量子计算作为前沿技术领域备受瞩目。中国在量子计算机的研发方面取得了显著进展,本文将深入探讨中国量子计算机领域的现状、取得的成果、面临的挑战以及未来的发展方向,并…...
html(超文本标记语言)
声明! 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&…...
如何在Windows系统上安装和配置Maven
Maven是一个强大的构建和项目管理工具,广泛应用于Java项目的自动化构建、依赖管理、项目构建生命周期控制等方面。在Windows系统上安装Maven并配置环境变量,是开发者开始使用Maven的第一步。本文将详细介绍如何在Windows系统上安装和配置Maven࿰…...
基于Python Scrapy的豆瓣Top250电影爬虫程序
Scrapy安装 Python实现一个简单的爬虫程序(爬取图片)_python简单扒图脚本-CSDN博客 创建爬虫项目 创建爬虫项目: scrapy startproject test_spider 创建爬虫程序文件: >cd test_spider\test_spider\spiders >scrapy g…...
mysql,数据库数据备份
mysql 一.数据库备份概念1.备份分类2.备份策略3.备份三要素二.完全备份操作1.物理备份(还原),冷备份2.逻辑备份,温备份三.percona软件的xtrabackup工具备份(2备份,3还原),增量,差异1.percona软件安装2.增量备份(还原)3.差异备份四.binlog日志1.binlog日志概念2.查看binlog日志信…...
模仿elementui的Table,实现思路
vue2子组件使用render,给子子组件插槽传值 和elementui的Table一样使用render 在 Vue 2 中,子组件使用render函数向子子组件插槽传值可以通过以下步骤实现: 1、创建子组件 首先创建一个子组件,在子组件中使用render函数来渲染内容…...
Android Studio AI助手---Gemini
从金丝雀频道下载最新版 Android Studio,以利用所有这些新功能,并继续阅读以了解新增内容。 Gemini 现在可以编写、重构和记录 Android 代码 Gemini 不仅仅是提供指导。它可以编辑您的代码,帮助您快速从原型转向实现,实现常见的…...
大模型+安全实践之春天何时到来?
引子:距《在大模型实践旅途中摸了下上帝的脚指头》一文发布近一年,2024年笔者继续全情投入在大模型+安全上,深度参与了一些应用实践,包括安全大模型首次大规模应用在国家级攻防演习、部分项目的POC直到项目落地,也推动了一些场景安全大模型应用从0到3的孵化上市。这一年也…...
ACL技术---访问控制列表
是一种策略。 对于网络中的流量而言,通常有两种处理方式 允许 拒绝 ACL 的原理 配置了 ACL 的网络设备会根据事先设定好的报文匹配规则对经过该设备的报文进行匹配,然后对报 文执行预先设定好的处理动作。 ACL 的功能 访问控制:在设备…...
第25周:文献阅读
目录 摘要 Abstract 文献阅读 现有问题 提出方法 创新点 方法论 实验研究 数据集 数据预处理 仿真实验 评价指标 实验结果分析 总结 摘要 本篇论文提出了一种基于深度学习框架的风速预测方法——SSA-BiLSTM网络,旨在提高风速预测的精确性。研究使…...
BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出)
Matlab实现BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出) 目录 Matlab实现BiTCN-BiGRU基于双向时间卷积网络结合双向门控循环单元的数据多特征分类预测(多输入单输出)分类效果基本描述…...
docker数据卷
什么是数据卷? 在容器中是无法通过vi命令对一个容器中的资源做修改的,这个时候就需要通过数据卷将文件中的内容映射到宿主机,在宿主机修改的文件会更新到容器中,并且容器被删除后不会把数据卷删除,数据卷中的数据会被持…...
Linux下基于最新稳定版ESP-IDF5.3.2开发esp32s3入门任务间的通讯-信号量【入门三】
继续上一篇任务创建 【Linux下基于最新稳定版ESP-IDF5.3.2开发esp32s3入门任务创建【入门二】-CSDN博客】 今天要实现再创建一个任务。【二值和互斥都进行测试】 ①、通过任务A发送一个信号量,另一个任务得到信号量后再发送helloworld。 ②、两个任务通过互斥信…...
使用C#绘制具有平滑阴影颜色的曼德布洛特集分形
示例使用复数类在 C# 中轻松绘制曼德布洛特集分形解释了如何通过迭代方程绘制曼德布洛特集:...
Unittest01|TestCase
一、入门 1、新建测试文件 打开pycharm→左上角新建项目→选择项目路径→选择python解释器→创建→点击新建好的项目,右键新建python文件→测试文件(py文件)命名必须以test开头 2、创建测试用例 定义测试类:导入unittest模块→…...
Django实现异步视图asyncio请求
随着现代Web应用程序对性能和响应速度的需求不断增加,开发者们越来越倾向于采用异步编程来提升应用的效率和用户体验。在传统的Web开发框架中,通常采用同步请求方式,这意味着每一个请求都需要等待前一个请求完成后才能继续处理。对于高并发的请求,可能会出现性能瓶颈。而Dj…...
Apache Samza开源的分布式流处理框架
Apache Samza 是一个开源的分布式流处理框架,用于处理实时数据流和分布式任务。它最初由 LinkedIn 开发,并在 2014 年捐赠给 Apache 软件基金会。Samza 的设计目标是为开发人员提供一个易用、可靠、高效的流处理工具。以下是其关键特点和架构的简介: 核心特点 简单的编程模…...
Linux实验报告5-shell脚本编程进阶
目录 一:实验目的 二:实验内容 1 编写脚本,实现将当前目录中所有子目录的名称输出到屏幕上。 2 首先以你的姓氏的拼音为开头在当前用户的主目录下新建3个文件和2个子目录,如zi1,zi2,zi3以及子目录zi.d和…...
YOLO系列正传(四)YOLOv3论文精解(下)——损失函数推导与其他优化项
系列文章 YOLO系列基础 YOLO系列基础合集——小白也看得懂的论文精解-CSDN博客 YOLO系列正传 YOLO系列正传(一)类别损失与MSE损失函数、交叉熵损失函数-CSDN博客 YOLO系列正传(二)YOLOv3论文精解(上)——从FPN到darknet-53-C…...
【漏洞复现】CVE-2023-37461 Arbitrary File Writing
漏洞信息 NVD - cve-2023-37461 Metersphere is an opensource testing framework. Files uploaded to Metersphere may define a belongType value with a relative path like ../../../../ which may cause metersphere to attempt to overwrite an existing file in the d…...
【OpenCV计算机视觉】图像处理——平滑
本篇文章记录我学习【OpenCV】图像处理中关于“平滑”的知识点,希望我的分享对你有所帮助。 目录 一、什么是平滑处理 1、平滑的目的是什么? 2、常见的图像噪声 (1)椒盐噪声 编辑(2) 高斯噪声 &a…...
【java面向对象编程】第七弹----Object类、类变量与类方法
笔上得来终觉浅,绝知此事要躬行 🔥 个人主页:星云爱编程 🔥 所属专栏:javase 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 一、Object类 1.1equa…...
大模型微调---Prompt-tuning微调
目录 一、前言二、Prompt-tuning实战2.1、下载模型到本地2.2、加载模型与数据集2.3、处理数据2.4、Prompt-tuning微调2.5、训练参数配置2.6、开始训练 三、模型评估四、完整训练代码 一、前言 Prompt-tuning通过修改输入文本的提示(Prompt)来引导模型生…...
Connecting to Oracle 11g Database in Python
# encoding: utf-8 # 版权所有 2024 涂聚文有限公司 # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:python -m pip install oracledb # python -m pip install cx_Oracle --upgrade # pip install cx_Oracle # Autho…...
16.2、网络安全风险评估技术与攻击
目录 网络安全风险评估技术方法与工具 网络安全风险评估技术方法与工具 资产信息收集,可以通过调查表的形式把我们各类的资产信息进行一个统计和收集,掌握被评估对象的重要资产分布,进而分析这些资产关联的业务面临的安全威胁以及存在的安全…...
Windows脚本清理C盘缓存
方法一:使用power文件.ps1的文件 脚本功能 清理临时文件夹: 当前用户的临时文件夹(%Temp%)。系统临时文件夹(C:\Windows\Temp)。 清理 Windows 更新缓存: 删除 Windows 更新下载缓存࿰…...
ChromeOS 131 版本更新
ChromeOS 131 版本更新 1. ChromeOS Flex 自动注册 在 ChromeOS 131 中,ChromeOS Flex 的自动注册功能现已允许大规模部署 ChromeOS Flex 设备。与 ChromeOS 零接触注册类似,自动注册将通过组织管理员创建的注册令牌嵌入到 ChromeOS Flex 镜像中。这将…...
PDF24 Creator免费版
PDF点击上方"蓝字"关注我们 01、前言 >>> 官网:https://tools.pdf24.org/zh/creator PDF24 Creator完全免费,没有任何限制。企业也能免费用。 不可以,PDF24 Creator只能装在Windows系统上。目前不支持Linux和Mac。 PDF24…...
网络安全之访问控制
简介 同一分布式环境下,同一用户可能具有多个应用服务器的访问授权,同一应用服务器也有多个授权访问的用户,同一用户在一次事务中可能需要访问多个授权访问的应用服务器,应用服务器可能还需要对访问用户进行身份鉴别。为了实现这…...
vtie项目中使用到了TailwindCSS,如何打包成一个单独的CSS文件(优化、压缩)
在不依赖 Vite 或其他构建工具的情况下,使用 TailwindCSS CLI 快速生成独立的 CSS 文件是一种简单高效的方法,适合需要纯样式文件的场景。 这个项目中,使用到了tailwindCss, 需要把里面的样式打包出来,给其他项目用。 使用命令生…...
前端登录注册页面springboot+vue2全开发!
需求目标: 有“登录界面”和“注册界面”以及“功能操作界面”: 我们打开程序会自动进入“登录界面”,如果密码输入正确则直接进入“功能操作界面”,在“登录界面”我们可以点击注册进入“注册页面”,注册好了可以再跳…...