Files
zhgh_zjipc/jmeter/prepare-brand-activity-users.ps1
2026-11-03 17:57:19 +08:00

133 lines
4.5 KiB
PowerShell

param(
[ValidateRange(1, 1300)]
[int]$UserCount = 1300,
[ValidateSet("AllScope", "Authorized")]
[string]$PermissionMode = "AllScope",
[ValidatePattern("^[0-9a-fA-F]{32}$")]
[string]$ActivityId = "11619eee67574256ad8ccc8a16630023",
[string]$OutputFile = (Join-Path $PSScriptRoot "data\brand-activity-users.csv"),
[string]$ApplicationConfig = (Join-Path $PSScriptRoot "..\src\main\resources\application.yaml")
)
$ErrorActionPreference = "Stop"
function Get-YamlScalar {
param(
[string[]]$Lines,
[string]$Name
)
$matchedLine = $Lines | Where-Object { $_ -match ("^\s*" + [regex]::Escape($Name) + "\s*:\s*(.+?)\s*$") } | Select-Object -First 1
if (-not $matchedLine) {
throw "未在 application.yaml 中找到配置项:$Name"
}
return ([regex]::Match($matchedLine, "^\s*[^:]+:\s*(.+?)\s*$")).Groups[1].Value.Trim('"', "'")
}
if (-not (Test-Path -LiteralPath $ApplicationConfig)) {
throw "找不到应用配置文件:$ApplicationConfig"
}
$mysqlCommand = Get-Command mysql -ErrorAction SilentlyContinue
if (-not $mysqlCommand) {
throw "未找到 mysql 命令,请先把 MySQL 客户端 bin 目录加入 PATH。"
}
$configLines = Get-Content -LiteralPath $ApplicationConfig -Encoding UTF8
$jdbcUrl = Get-YamlScalar -Lines $configLines -Name "url"
$dbUser = Get-YamlScalar -Lines $configLines -Name "username"
$dbPassword = Get-YamlScalar -Lines $configLines -Name "password"
$jdbcMatch = [regex]::Match($jdbcUrl, "jdbc:mysql://(?<host>[^:/?]+)(:(?<port>\d+))?/(?<database>[^?]+)")
if (-not $jdbcMatch.Success) {
throw "无法解析 JDBC 地址:$jdbcUrl"
}
$dbHost = $jdbcMatch.Groups["host"].Value
$dbPort = if ($jdbcMatch.Groups["port"].Success) { $jdbcMatch.Groups["port"].Value } else { "3306" }
$database = $jdbcMatch.Groups["database"].Value
# 仅导出活动范围内、账号未禁用且尚未报名的人员;不读取密码、身份证号、手机号等敏感字段。
$permissionCondition = if ($PermissionMode -eq "Authorized") {
@"
AND EXISTS (
SELECT 1
FROM sys_user_role ur
JOIN sys_role_menu rm ON rm.roleId = ur.roleId
JOIN sys_menu m ON m.id = rm.menuId
WHERE ur.userId = u.id
AND m.permission IN ('trainSignUp.apply', 'h5.trainSignUp.apply')
)
"@
} else {
""
}
$query = @"
SELECT
u.loginname,
CASE WHEN EXISTS (
SELECT 1
FROM sys_user_role ur
JOIN sys_role_menu rm ON rm.roleId = ur.roleId
JOIN sys_menu m ON m.id = rm.menuId
WHERE ur.userId = u.id
AND m.permission IN ('trainSignUp.apply', 'h5.trainSignUp.apply')
) THEN 1 ELSE 0 END AS expectedAuthorized
FROM train_sign_up_activity a
JOIN activity_user_scope aus ON aus.groupId = a.activityGroupId
JOIN sys_user u ON u.id = aus.userId
LEFT JOIN train_sign_up_user su ON su.activityId = a.id AND su.userId = u.id
WHERE a.id = '$ActivityId'
AND u.disabled = 0
AND u.loginname IS NOT NULL
AND u.loginname <> ''
AND su.id IS NULL
$permissionCondition
GROUP BY u.id, u.loginname
ORDER BY expectedAuthorized DESC, u.loginname
LIMIT $UserCount;
"@
$previousMysqlPassword = $env:MYSQL_PWD
try {
$env:MYSQL_PWD = $dbPassword
$rows = @(& $mysqlCommand.Source --batch --raw --skip-column-names -h $dbHost -P $dbPort -u $dbUser $database -e $query)
if ($LASTEXITCODE -ne 0) {
throw "查询压测人员失败,mysql 退出码:$LASTEXITCODE"
}
} finally {
$env:MYSQL_PWD = $previousMysqlPassword
}
$users = @($rows | Where-Object { $_ -and $_.Trim() } | ForEach-Object {
$columns = $_ -split "`t", 2
[pscustomobject]@{
loginname = $columns[0]
expectedAuthorized = $columns[1]
}
})
if ($users.Count -lt $UserCount) {
throw "符合条件的人员只有 $($users.Count) 人,少于要求的 $UserCount 人。PermissionMode=$PermissionMode"
}
$outputDirectory = Split-Path -Parent $OutputFile
if (-not (Test-Path -LiteralPath $outputDirectory)) {
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
}
$users | Export-Csv -LiteralPath $OutputFile -NoTypeInformation -Encoding UTF8 -UseQuotes Always
$authorizedCount = @($users | Where-Object { $_.expectedAuthorized -eq "1" }).Count
$unauthorizedCount = $users.Count - $authorizedCount
Write-Host "已生成 UTF-8 用户文件:$OutputFile"
Write-Host "总人数:$($users.Count),具备报名权限:$authorizedCount,无报名权限:$unauthorizedCount"
if ($unauthorizedCount -gt 0) {
Write-Warning "无报名权限的线程仍会访问报名接口,但会被权限校验拒绝。"
}