feat: add Batch Workstation & Ambiguity User Resolver dialog with Dry-Run preview and multi-parameter controls
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
# Modules\UserResolverService.ps1
|
||||
# ==============================================================================
|
||||
# User Multi-Input Resolver & Ambiguity (동명이인) Detection Service
|
||||
# ==============================================================================
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
줄바꿈, 쉼표, 세미콜론, 탭(엑셀 복사본)으로 입력된 다중 사용자 텍스트를 파싱하고,
|
||||
Active Directory 및 DB에서 검색하여 [정상 매칭], [동명이인 중복], [미발견]으로 분류합니다.
|
||||
#>
|
||||
|
||||
function Parse-MultiUserInput {
|
||||
param([string]$RawInput)
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($RawInput)) {
|
||||
return @()
|
||||
}
|
||||
|
||||
# 쉼표, 세미콜론, 줄바꿈, 탭, 공백 등 모든 구분자로 분리
|
||||
$tokens = $RawInput -split "[\r\n,;\t]+" | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }
|
||||
return @($tokens | Select-Object -Unique)
|
||||
}
|
||||
|
||||
function Resolve-UsersWithAmbiguityCheck {
|
||||
param(
|
||||
[string[]]$Tokens,
|
||||
[object]$Config = $null
|
||||
)
|
||||
|
||||
# 기본 AD 사용자 풀 (Live 모드 시 실제 AD 검색 가능, 현재는 풍부한 샘플 풀 + 동명이인 포함)
|
||||
$allPool = @(
|
||||
[PSCustomObject]@{ SamAccountName = "gdhong"; DisplayName = "홍길동"; Department = "클라우드인프라팀"; Title = "수석"; Mail = "gdhong@corp.local"; EmpId = "EMP1001" },
|
||||
[PSCustomObject]@{ SamAccountName = "gdhong_sales"; DisplayName = "홍길동"; Department = "영업1팀"; Title = "과장"; Mail = "gdhong_sales@corp.local"; EmpId = "EMP1099" }, # 홍길동 동명이인!
|
||||
[PSCustomObject]@{ SamAccountName = "cskim"; DisplayName = "김철수"; Department = "데이터플랫폼팀"; Title = "책임 (DBA)"; Mail = "cskim@corp.local"; EmpId = "EMP1002" },
|
||||
[PSCustomObject]@{ SamAccountName = "cskim_dev"; DisplayName = "김철수"; Department = "프론트엔드개발팀"; Title = "선임"; Mail = "cskim_dev@corp.local"; EmpId = "EMP1088" }, # 김철수 동명이인!
|
||||
[PSCustomObject]@{ SamAccountName = "yylee"; DisplayName = "이영희"; Department = "보안관제팀"; Title = "책임"; Mail = "yylee@corp.local"; EmpId = "EMP1003" },
|
||||
[PSCustomObject]@{ SamAccountName = "mschoi"; DisplayName = "최민수"; Department = "개발운영팀"; Title = "선임"; Mail = "mschoi@corp.local"; EmpId = "EMP1004" },
|
||||
[PSCustomObject]@{ SamAccountName = "jhbak"; DisplayName = "박지훈"; Department = "시스템관리팀"; Title = "팀장"; Mail = "jhbak@corp.local"; EmpId = "EMP1005" },
|
||||
[PSCustomObject]@{ SamAccountName = "swjung"; DisplayName = "정수원"; Department = "인사기획팀"; Title = "차장"; Mail = "swjung@corp.local"; EmpId = "EMP1006" }
|
||||
)
|
||||
|
||||
$resolvedResults = [System.Collections.Generic.List[PSCustomObject]]::new()
|
||||
|
||||
foreach ($token in $Tokens) {
|
||||
# 1. SamAccountName 정확 일치 우선 검색
|
||||
$matchById = @($allPool | Where-Object { $_.SamAccountName -ieq $token })
|
||||
if ($matchById.Count -eq 1) {
|
||||
$u = $matchById[0]
|
||||
$resolvedResults.Add([PSCustomObject]@{
|
||||
InputToken = $token
|
||||
Status = "정상 매칭"
|
||||
StatusBadge = "#10B981" # Green
|
||||
IsAmbiguous = $false
|
||||
IsResolved = $true
|
||||
IsSelected = $true
|
||||
SamAccountName = $u.SamAccountName
|
||||
DisplayName = $u.DisplayName
|
||||
Department = $u.Department
|
||||
Title = $u.Title
|
||||
EmpId = $u.EmpId
|
||||
CandidateCount = 1
|
||||
Note = "ID($token) 정확 일치"
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
# 2. 이름(DisplayName) 일치 검색 (동명이인 판정)
|
||||
$matchByName = @($allPool | Where-Object { $_.DisplayName -ieq $token -or $_.DisplayName -like "*$token*" })
|
||||
if ($matchByName.Count -eq 1) {
|
||||
$u = $matchByName[0]
|
||||
$resolvedResults.Add([PSCustomObject]@{
|
||||
InputToken = $token
|
||||
Status = "단일 매칭"
|
||||
StatusBadge = "#10B981" # Green
|
||||
IsAmbiguous = $false
|
||||
IsResolved = $true
|
||||
IsSelected = $true
|
||||
SamAccountName = $u.SamAccountName
|
||||
DisplayName = $u.DisplayName
|
||||
Department = $u.Department
|
||||
Title = $u.Title
|
||||
EmpId = $u.EmpId
|
||||
CandidateCount = 1
|
||||
Note = "이름($token) 단일 사용자 확인"
|
||||
})
|
||||
}
|
||||
elseif ($matchByName.Count -gt 1) {
|
||||
# 동명이인 다수 발견! -> 각 후보자별로 개별 행 생성하여 운영자가 라디오/체크로 선택하도록 함
|
||||
foreach ($cand in $matchByName) {
|
||||
$resolvedResults.Add([PSCustomObject]@{
|
||||
InputToken = $token
|
||||
Status = "동명이인 확인필요"
|
||||
StatusBadge = "#F59E0B" # Amber / Warning
|
||||
IsAmbiguous = $true
|
||||
IsResolved = $false
|
||||
IsSelected = $false # 운영자 확인 전까지 미선택
|
||||
SamAccountName = $cand.SamAccountName
|
||||
DisplayName = $cand.DisplayName
|
||||
Department = $cand.Department
|
||||
Title = $cand.Title
|
||||
EmpId = $cand.EmpId
|
||||
CandidateCount = $matchByName.Count
|
||||
Note = "동명이인 $($matchByName.Count)명 중 1명 [부서: $($cand.Department) 확인필요]"
|
||||
})
|
||||
}
|
||||
}
|
||||
else {
|
||||
# 미발견
|
||||
$resolvedResults.Add([PSCustomObject]@{
|
||||
InputToken = $token
|
||||
Status = "미발견 (계정 없음)"
|
||||
StatusBadge = "#EF4444" # Red
|
||||
IsAmbiguous = $false
|
||||
IsResolved = $false
|
||||
IsSelected = $false
|
||||
SamAccountName = "-"
|
||||
DisplayName = $token
|
||||
Department = "-"
|
||||
Title = "-"
|
||||
EmpId = "-"
|
||||
CandidateCount = 0
|
||||
Note = "AD 및 DB에서 해당 ID/이름을 찾을 수 없음"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return $resolvedResults.ToArray()
|
||||
}
|
||||
Reference in New Issue
Block a user