Files
FendxPHP/scripts/check-database.ps1
Lawson 2782d765fb feat(database): 添加用户角色权限系统及相关监控功能
- 创建用户表(users)包含基本信息和认证字段
- 创建角色表(roles)用于权限控制
- 创建权限表(permissions)定义系统权限
- 创建用户角色关联表(user_roles)建立用户与角色关系
- 创建角色权限关联表(role_permissions)建立角色与权限关系
- 创建迁移记录表(migrations)追踪数据库变更
- 添加AdminController提供管理员面板功能
- 实现系统监控、配置管理、缓存清理等功能
- 添加AOP切面编程支持的各种通知类型
- 实现告警管理AlertManager支持多渠道告警
- 添加文档注解接口规范
2026-04-08 17:00:28 +08:00

467 lines
13 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FendxPHP 数据库检查 PowerShell 脚本
# 用法: .\scripts\check-database.ps1 [选项]
param(
[Parameter(Mandatory=$false)]
[ValidateSet("check", "fix", "migrate", "seed", "help")]
[string]$Action = "check"
)
# 颜色输出函数
function Write-ColorOutput {
param(
[string]$Message,
[ConsoleColor]$Color = "White"
)
Write-Host $Message -ForegroundColor $Color
}
function Write-Info {
param([string]$Message)
Write-ColorOutput "[INFO] $Message" -Color Cyan
}
function Write-Success {
param([string]$Message)
Write-ColorOutput "[SUCCESS] $Message" -Color Green
}
function Write-Warning {
param([string]$Message)
Write-ColorOutput "[WARNING] $Message" -Color Yellow
}
function Write-Error {
param([string]$Message)
Write-ColorOutput "[ERROR] $Message" -Color Red
}
# 加载环境配置
function Load-Environment {
$envFile = Join-Path $PSScriptRoot "..\.env"
if (Test-Path $envFile) {
Write-Info "加载环境配置: $envFile"
Get-Content $envFile | ForEach-Object {
if ($_ -match '^([^=]+)=(.*)$' -and -not $_.StartsWith('#')) {
$name = $matches[1].Trim()
$value = $matches[2].Trim()
[Environment]::SetEnvironmentVariable($name, $value, "Process")
}
}
} else {
Write-Warning "环境配置文件不存在: $envFile"
}
}
# 测试MySQL客户端
function Test-MySQLClient {
try {
$result = & mysql --version 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Success "MySQL客户端可用"
return $true
}
} catch {
# 忽略错误
}
Write-Warning "MySQL客户端不可用尝试使用Docker"
return $false
}
# 测试数据库连接
function Test-DatabaseConnection {
$dbHost = if ($env:DB_HOST) { $env:DB_HOST } else { "localhost" }
$dbPort = if ($env:DB_PORT) { $env:DB_PORT } else { "3306" }
$dbDatabase = if ($env:DB_DATABASE) { $env:DB_DATABASE } else { "fendx_php" }
$dbUsername = if ($env:DB_USERNAME) { $env:DB_USERNAME } else { "root" }
$dbPassword = if ($env:DB_PASSWORD) { $env:DB_PASSWORD } else { "" }
$config = @{
Host = $dbHost
Port = $dbPort
Database = $dbDatabase
Username = $dbUsername
Password = $dbPassword
}
Write-Info "检查数据库连接..."
Write-Info " 主机: $($config.Host):$($config.Port)"
Write-Info " 数据库: $($config.Database)"
Write-Info " 用户名: $($config.Username)"
# 尝试使用MySQL客户端
if (Test-MySQLClient) {
try {
& mysql -h $config.Host -P $config.Port -u $config.Username -p$config.Password -e "SELECT 1" 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Success "数据库连接成功"
return @{ Success = $true; Config = $config }
}
} catch {
# 忽略错误
}
}
# 尝试使用Docker
if (Get-Command docker -ErrorAction SilentlyContinue) {
return Test-DockerDatabaseConnection $config
}
Write-Error "数据库连接失败"
return @{ Success = $false }
}
# 测试Docker数据库连接
function Test-DockerDatabaseConnection {
param($config)
Write-Info "尝试使用Docker连接数据库..."
# 检查Docker是否运行
try {
& docker info >$null 2>&1
if ($LASTEXITCODE -ne 0) {
Write-Error "Docker未运行"
return @{ Success = $false }
}
} catch {
Write-Error "Docker未运行"
return @{ Success = $false }
}
# 检查MySQL容器
$containerName = "fendx-mysql-test"
$container = & docker ps --filter "name=$containerName" --format "table {{.Names}}\t{{.Status}}" | Select-Object -Skip 1
if (-not $container -or $container -notlike "*Up*") {
Write-Warning "MySQL容器未运行尝试启动..."
& docker-compose -f docker-compose.test.yml up -d mysql-test
# 等待启动
Write-Info "等待MySQL启动..."
$maxAttempts = 30
$attempt = 0
while ($attempt -lt $maxAttempts) {
try {
& docker exec $containerName mysqladmin ping -h localhost --silent >$null 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Success "MySQL启动成功"
break
}
} catch {
# 忽略错误
}
$attempt++
Write-Host "." -NoNewline
Start-Sleep -Seconds 2
}
if ($attempt -eq $maxAttempts) {
Write-Error "MySQL启动超时"
& docker-compose -f docker-compose.test.yml logs mysql-test
return @{ Success = $false }
}
}
# 测试连接
try {
& docker exec $containerName mysql -u test -ptest -e "SELECT 1" >$null 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Success "Docker数据库连接成功"
return @{ Success = $true; Config = $config; Docker = $true }
}
} catch {
# 忽略错误
}
Write-Error "Docker数据库连接失败"
return @{ Success = $false }
}
# 检查数据库是否存在
function Test-DatabaseExists {
param($Config, [switch]$UseDocker)
$database = $Config.Database
if ($UseDocker) {
Write-Info "检查数据库是否存在 (Docker)..."
$result = & docker exec fendx-mysql-test mysql -u test -ptest -e "SHOW DATABASES LIKE '$database'" 2>$null
if ($result -match $database) {
Write-Success "数据库 '$database' 存在"
return $true
}
} else {
Write-Info "检查数据库是否存在..."
$result = & mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password -e "SHOW DATABASES LIKE '$database'" 2>$null
if ($result -match $database) {
Write-Success "数据库 '$database' 存在"
return $true
}
}
Write-Warning "数据库 '$database' 不存在"
return $false
}
# 创建数据库
function New-Database {
param($Config, [switch]$UseDocker)
$database = $Config.Database
Write-Info "创建数据库 '$database'..."
if ($UseDocker) {
$sql = "CREATE DATABASE IF NOT EXISTS `$database` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
& docker exec fendx-mysql-test mysql -u test -ptest -e $sql >$null 2>&1
} else {
$sql = "CREATE DATABASE IF NOT EXISTS `$database` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
& mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password -e $sql >$null 2>&1
}
if ($LASTEXITCODE -eq 0) {
Write-Success "数据库创建成功"
return $true
} else {
Write-Error "数据库创建失败"
return $false
}
}
# 检查表结构
function Get-DatabaseTables {
param($Config, [switch]$UseDocker)
Write-Info "检查数据库表..."
if ($UseDocker) {
$tables = & docker exec fendx-mysql-test mysql -u test -ptest $Config.Database -e "SHOW TABLES" 2>$null
} else {
$tables = & mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password $Config.Database -e "SHOW TABLES" 2>$null
}
if (-not $tables -or $tables.Split("`n").Length -le 1) {
Write-Warning "数据库中没有表"
Write-Info "建议运行迁移命令:"
Write-Info " php bin/console migrate:run"
return
}
Write-Success "数据库表列表:"
$tableList = $tables.Split("`n") | Where-Object { $_ -and $_ -notmatch "Tables_in_" }
foreach ($table in $tableList) {
if ($table.Trim()) {
$count = Get-TableRecordCount $table $Config $UseDocker
Write-Host " - $table ($count 条记录)"
}
}
}
# 获取表记录数
function Get-TableRecordCount {
param($Table, $Config, [switch]$UseDocker)
if ($UseDocker) {
$result = & docker exec fendx-mysql-test mysql -u test -ptest $Config.Database -e "SELECT COUNT(*) FROM `$Table`" 2>$null
} else {
$result = & mysql -h $Config.Host -P $Config.Port -u $Config.Username -p$Config.Password $Config.Database -e "SELECT COUNT(*) FROM `$Table`" 2>$null
}
if ($result -match '\d+') {
return [int]$matches[0]
}
return 0
}
# 运行数据库迁移
function Invoke-DatabaseMigration {
param([switch]$UseDocker)
Write-Info "运行数据库迁移..."
if ($UseDocker) {
& docker-compose -f docker-compose.test.yml exec -T app php bin/console migrate:run
} else {
& php bin/console migrate:run
}
if ($LASTEXITCODE -eq 0) {
Write-Success "数据库迁移完成"
return $true
} else {
Write-Error "数据库迁移失败"
return $false
}
}
# 填充测试数据
function Invoke-DatabaseSeed {
param([switch]$UseDocker)
Write-Info "填充测试数据..."
if ($UseDocker) {
& docker-compose -f docker-compose.test.yml exec -T app php bin/console migrate:seed
} else {
& php bin/console migrate:seed
}
if ($LASTEXITCODE -eq 0) {
Write-Success "测试数据填充完成"
return $true
} else {
Write-Error "测试数据填充失败"
return $false
}
}
# 完整检查
function Invoke-FullCheck {
Write-Info "开始完整数据库检查..."
Write-Host "==================================================" -ForegroundColor Cyan
# 加载环境配置
Load-Environment
# 测试数据库连接
$connectionResult = Test-DatabaseConnection
if (-not $connectionResult.Success) {
Write-Host "`n💡 解决建议:" -ForegroundColor Yellow
Write-Host " 1. 检查数据库服务是否启动" -ForegroundColor White
Write-Host " 2. 验证数据库连接配置" -ForegroundColor White
Write-Host " 3. 确认用户权限正确" -ForegroundColor White
return
}
$config = $connectionResult.Config
$useDocker = $connectionResult.Docker
Write-Host "`n--------------------------------------------------" -ForegroundColor Cyan
# 检查数据库是否存在
if (-not (Test-DatabaseExists $config -UseDocker:$useDocker)) {
Write-Host "`n🔧 尝试创建数据库..." -ForegroundColor Yellow
if (New-Database $config -UseDocker:$useDocker) {
Write-Success "数据库已创建,请运行迁移命令:"
Write-Info " php bin/console migrate:run"
}
return
}
Write-Host "`n--------------------------------------------------" -ForegroundColor Cyan
# 检查表结构
Get-DatabaseTables $config -UseDocker:$useDocker
Write-Host "`n==================================================" -ForegroundColor Cyan
Write-Success "数据库检查完成"
}
# 修复数据库
function Repair-Database {
Write-Info "开始修复数据库..."
# 加载环境配置
Load-Environment
# 测试数据库连接
$connectionResult = Test-DatabaseConnection
if (-not $connectionResult.Success) {
Write-Error "数据库连接失败,无法修复"
return
}
$config = $connectionResult.Config
$useDocker = $connectionResult.Docker
# 创建数据库
if (-not (Test-DatabaseExists $config -UseDocker:$useDocker)) {
New-Database $config -UseDocker:$useDocker
}
# 运行迁移
Invoke-DatabaseMigration -UseDocker:$useDocker
# 填充数据
Invoke-DatabaseSeed -UseDocker:$useDocker
Write-Success "数据库修复完成"
}
# 显示帮助
function Show-Help {
Write-Host @"
FendxPHP (PowerShell)
: .\scripts\check-database.ps1 []
:
check ()
fix
migrate
seed
help
:
.\scripts\check-database.ps1 #
.\scripts\check-database.ps1 check #
.\scripts\check-database.ps1 fix #
.\scripts\check-database.ps1 migrate #
.\scripts\check-database.ps1 seed #
"@ -ForegroundColor White
}
# 主函数
function Main {
Write-Host "🚀 FendxPHP 数据库检查 (PowerShell)" -ForegroundColor Green
Write-Host "==================================================" -ForegroundColor Cyan
switch ($Action.ToLower()) {
"check" {
Invoke-FullCheck
}
"fix" {
Repair-Database
}
"migrate" {
Load-Environment
$connectionResult = Test-DatabaseConnection
if ($connectionResult.Success) {
Invoke-DatabaseMigration -UseDocker:$connectionResult.Docker
}
}
"seed" {
Load-Environment
$connectionResult = Test-DatabaseConnection
if ($connectionResult.Success) {
Invoke-DatabaseSeed -UseDocker:$connectionResult.Docker
}
}
"help" {
Show-Help
}
default {
Write-Error "未知选项: $Action"
Show-Help
exit 1
}
}
}
# 运行主函数
try {
Main
} catch {
Write-Error "脚本执行失败: $($_.Exception.Message)"
exit 1
}