feat(admin): 添加用户管理相关文件

添加用户管理视图、API和状态管理文件
This commit is contained in:
张翔
2026-03-28 14:37:29 +08:00
commit 08ea5fbe98
1643 changed files with 255646 additions and 0 deletions
@@ -0,0 +1,355 @@
import os
import subprocess
from typing import Optional
from pathlib import Path
import shutil
class ReportHelper:
"""测试报告辅助工具类"""
def __init__(
self,
allure_results_dir: str = "reports/allure-results",
allure_report_dir: str = "reports/allure-report",
html_report_dir: str = "reports/html",
):
"""初始化报告辅助工具
Args:
allure_results_dir: Allure测试结果目录
allure_report_dir: Allure报告输出目录
html_report_dir: HTML报告输出目录
"""
self.allure_results_dir = allure_results_dir
self.allure_report_dir = allure_report_dir
self.html_report_dir = html_report_dir
self._ensure_directories()
def _ensure_directories(self) -> None:
"""确保报告目录存在"""
Path(self.allure_results_dir).mkdir(parents=True, exist_ok=True)
Path(self.allure_report_dir).mkdir(parents=True, exist_ok=True)
Path(self.html_report_dir).mkdir(parents=True, exist_ok=True)
def generate_allure_report(self, clean: bool = True) -> bool:
"""生成Allure测试报告
Args:
clean: 是否清理旧的报告
Returns:
是否生成成功
"""
try:
if clean and os.path.exists(self.allure_report_dir):
shutil.rmtree(self.allure_report_dir)
Path(self.allure_report_dir).mkdir(parents=True, exist_ok=True)
command = [
"allure",
"generate",
self.allure_results_dir,
"-o",
self.allure_report_dir,
"--clean",
]
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode == 0:
print(f"Allure报告生成成功: {self.allure_report_dir}")
return True
else:
print(f"Allure报告生成失败: {result.stderr}")
return False
except FileNotFoundError:
print("Allure命令未找到,请先安装Allure: brew install allure")
return False
except Exception as e:
print(f"生成Allure报告时发生错误: {str(e)}")
return False
def open_allure_report(self) -> bool:
"""打开Allure测试报告
Returns:
是否打开成功
"""
try:
if not os.path.exists(self.allure_report_dir):
print(f"Allure报告目录不存在: {self.allure_report_dir}")
return False
command = ["allure", "open", self.allure_report_dir]
subprocess.Popen(command)
print(f"Allure报告已打开: {self.allure_report_dir}")
return True
except FileNotFoundError:
print("Allure命令未找到,请先安装Allure: brew install allure")
return False
except Exception as e:
print(f"打开Allure报告时发生错误: {str(e)}")
return False
def serve_allure_report(self, port: int = 8080) -> bool:
"""启动Allure报告服务器
Args:
port: 服务器端口
Returns:
是否启动成功
"""
try:
if not os.path.exists(self.allure_report_dir):
print(f"Allure报告目录不存在: {self.allure_report_dir}")
return False
command = ["allure", "serve", self.allure_report_dir, "-p", str(port)]
subprocess.Popen(command)
print(f"Allure报告服务器已启动: http://localhost:{port}")
return True
except FileNotFoundError:
print("Allure命令未找到,请先安装Allure: brew install allure")
return False
except Exception as e:
print(f"启动Allure报告服务器时发生错误: {str(e)}")
return False
def get_html_report_path(self) -> str:
"""获取HTML报告路径
Returns:
HTML报告路径
"""
html_files = list(Path(self.html_report_dir).glob("*.html"))
if html_files:
return str(html_files[0])
return os.path.join(self.html_report_dir, "report.html")
def open_html_report(self) -> bool:
"""打开HTML测试报告
Returns:
是否打开成功
"""
try:
report_path = self.get_html_report_path()
if not os.path.exists(report_path):
print(f"HTML报告文件不存在: {report_path}")
return False
import webbrowser
webbrowser.open(f"file://{os.path.abspath(report_path)}")
print(f"HTML报告已打开: {report_path}")
return True
except Exception as e:
print(f"打开HTML报告时发生错误: {str(e)}")
return False
def clean_allure_results(self) -> bool:
"""清理Allure测试结果
Returns:
是否清理成功
"""
try:
if os.path.exists(self.allure_results_dir):
shutil.rmtree(self.allure_results_dir)
Path(self.allure_results_dir).mkdir(parents=True, exist_ok=True)
print(f"Allure测试结果已清理: {self.allure_results_dir}")
return True
return False
except Exception as e:
print(f"清理Allure测试结果时发生错误: {str(e)}")
return False
def clean_allure_report(self) -> bool:
"""清理Allure报告
Returns:
是否清理成功
"""
try:
if os.path.exists(self.allure_report_dir):
shutil.rmtree(self.allure_report_dir)
Path(self.allure_report_dir).mkdir(parents=True, exist_ok=True)
print(f"Allure报告已清理: {self.allure_report_dir}")
return True
return False
except Exception as e:
print(f"清理Allure报告时发生错误: {str(e)}")
return False
def clean_html_report(self) -> bool:
"""清理HTML报告
Returns:
是否清理成功
"""
try:
if os.path.exists(self.html_report_dir):
shutil.rmtree(self.html_report_dir)
Path(self.html_report_dir).mkdir(parents=True, exist_ok=True)
print(f"HTML报告已清理: {self.html_report_dir}")
return True
return False
except Exception as e:
print(f"清理HTML报告时发生错误: {str(e)}")
return False
def clean_all_reports(self) -> bool:
"""清理所有报告
Returns:
是否清理成功
"""
success = True
success = self.clean_allure_results() and success
success = self.clean_allure_report() and success
success = self.clean_html_report() and success
if success:
print("所有报告已清理")
return success
def get_report_summary(self) -> dict:
"""获取报告摘要信息
Returns:
报告摘要字典
"""
summary = {
"allure_results_dir": self.allure_results_dir,
"allure_report_dir": self.allure_report_dir,
"html_report_dir": self.html_report_dir,
"allure_results_exists": os.path.exists(self.allure_results_dir),
"allure_report_exists": os.path.exists(self.allure_report_dir),
"html_report_exists": os.path.exists(self.html_report_dir),
"html_report_path": self.get_html_report_path(),
}
return summary
def archive_report(self, archive_name: str, archive_dir: str = "reports/archives") -> bool:
"""归档报告
Args:
archive_name: 归档名称
archive_dir: 归档目录
Returns:
是否归档成功
"""
try:
Path(archive_dir).mkdir(parents=True, exist_ok=True)
timestamp = subprocess.run(
["date", "+%Y%m%d_%H%M%S"], capture_output=True, text=True
).stdout.strip()
archive_path = os.path.join(archive_dir, f"{archive_name}_{timestamp}")
if os.path.exists(self.allure_report_dir):
shutil.copytree(self.allure_report_dir, os.path.join(archive_path, "allure"))
if os.path.exists(self.html_report_dir):
shutil.copytree(self.html_report_dir, os.path.join(archive_path, "html"))
print(f"报告已归档到: {archive_path}")
return True
except Exception as e:
print(f"归档报告时发生错误: {str(e)}")
return False
def get_allure_history(self) -> list:
"""获取Allure历史记录
Returns:
历史记录列表
"""
history_dir = os.path.join(self.allure_report_dir, "history")
if not os.path.exists(history_dir):
return []
history = []
for item in os.listdir(history_dir):
item_path = os.path.join(history_dir, item)
if os.path.isdir(item_path):
history.append(
{
"name": item,
"path": item_path,
"modified": os.path.getmtime(item_path),
}
)
return sorted(history, key=lambda x: x["modified"], reverse=True)
def generate_combined_report(self) -> bool:
"""生成组合报告(Allure + HTML
Returns:
是否生成成功
"""
success = True
allure_success = self.generate_allure_report()
success = allure_success and success
html_report_path = self.get_html_report_path()
if os.path.exists(html_report_path):
print(f"HTML报告路径: {html_report_path}")
return success
def validate_allure_installation(self) -> bool:
"""验证Allure是否已安装
Returns:
Allure是否已安装
"""
try:
result = subprocess.run(["allure", "--version"], capture_output=True, text=True)
if result.returncode == 0:
print(f"Allure版本: {result.stdout.strip()}")
return True
return False
except FileNotFoundError:
print("Allure未安装")
return False
except Exception as e:
print(f"验证Allure安装时发生错误: {str(e)}")
return False
def get_test_statistics(self) -> Optional[dict]:
"""获取测试统计信息(需要Allure已安装)
Returns:
测试统计信息字典
"""
try:
if not self.validate_allure_installation():
return None
command = ["allure", "report", "list"]
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode != 0:
return None
return {
"total": 0,
"passed": 0,
"failed": 0,
"broken": 0,
"skipped": 0,
"unknown": 0,
}
except Exception as e:
print(f"获取测试统计信息时发生错误: {str(e)}")
return None