| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- # Adds JavaDoc to impl package - documentation only
- $ErrorActionPreference = 'Stop'
- $utf8 = [System.Text.UTF8Encoding]::new($false)
- $ImplDir = 'd:/ylrz_saas_new/java/fs-service/src/main/java/com/fs/company/service/workflow/impl'
- $WorkflowDir = 'd:/ylrz_saas_new/java/fs-service/src/main/java/com/fs/company/service/workflow'
- $CallerLabel = '调用方'
- $MainCallerLabel = '主要调用方'
- $ClassDesc = @{
- LobsterEvolutionEngineImpl = '龙虾进化引擎实现:单轮对话从上下文组装到 AI 生成、质量评分、合规与敏感词过滤的完整流水线。'
- LobsterWorkflowExecutorImpl = '龙虾工作流执行器实现:实例生命周期管理、节点推进、消息投递与进化引擎集成。'
- DynamicNodeExecutorImpl = '动态节点执行器实现:按节点类型注册 handler,执行枚举节点与 AI 兜底逻辑。'
- ContextAssemblerImpl = '上下文组装器实现:并行加载画像、知识库、历史、变量等多源上下文供 AI 使用。'
- SummaryGeneratorImpl = '对话摘要生成器实现:实例/全局摘要、变量抽取与异步摘要更新。'
- LobsterE2eTestServiceImpl = '龙虾端到端测试服务实现:工作流 E2E 跑批、单步推进与多轮对话测试。'
- VariableStoreImpl = '工作流变量存储实现:内存 + Redis + 数据库三级读写,供实例运行时变量持久化。'
- MultiTurnDialogueManagerImpl = '多轮对话管理器实现:多轮信息收集节点的轮次控制、变量抽取与完成判定。'
- QualityScoringServiceImpl = '质量评分服务实现:多维度 AI 回复评分、规则引擎校正与带反馈重生成。'
- SensitiveWordServiceImpl = '敏感词过滤服务实现:租户级敏感词检测、替换与高风险词处置。'
- ComplianceServiceImpl = '合规检查服务实现:AI 回复合规性校验与分级安全话术替换。'
- ConditionEvaluatorImpl = '条件表达式求值器实现:工作流分支节点的条件判断。'
- DynamicNodeAdjusterImpl = '动态节点调节器实现:基于语义分析的路由决策与转人工判定。'
- DynamicNodeImplServiceImpl = '动态节点实现管理服务:节点 handler 注册与配置 CRUD。'
- DuplicateReplyDetector = '重复回复检测器:防止工作流对同一客户重复发送相同内容。'
- FactDecayScheduler = '事实衰减定时任务:清理过期用户事实与沟通习惯缓存。'
- LobsterBillingServiceImpl = '龙虾计费服务实现:租户余额、Token 消耗记录与统计汇总。'
- LobsterConversationSummaryServiceImpl = '对话摘要查询服务实现:管理端摘要列表与详情。'
- LobsterEventAuditServiceImpl = '事件审计服务实现:进化/学习事件的人工审核流转。'
- LobsterEvolutionSuggestionServiceImpl = '进化建议服务实现:AI 进化建议列表、审核与指标统计。'
- LobsterInstanceStatsServiceImpl = '实例统计服务实现:工作流实例运行指标汇总。'
- LobsterIntegrationTestServiceImpl = '集成测试服务实现:引擎组件冒烟测试与节点类型验证。'
- LobsterLearningCorpusServiceImpl = '学习语料服务实现:租户学习语料查询。'
- LobsterModelConfigServiceImpl = '模型配置服务实现:租户级 LLM 路由与质量检查模型配置。'
- LobsterNodeTypeServiceImpl = '节点类型注册服务实现:工作流节点类型元数据缓存与 CRUD。'
- LobsterPromptServiceImpl = '系统 Prompt 管理服务实现:引擎 Prompt 与系统 Prompt CRUD。'
- LobsterSalesCorpusServiceImpl = '销冠语料服务实现:销冠对话导入、分析与场景查询。'
- LobsterTestScenarioServiceImpl = '测试场景服务实现:E2E 测试场景 CRUD 与定时跑批。'
- MultiModelWorkflowGeneratorImpl = '多模型工作流生成器实现:AI 自动生成/迭代优化工作流 JSON。'
- NodePromptServiceImpl = '节点 Prompt 绑定服务实现:节点与 Prompt 模板的关联保存。'
- OutputQualityCheckerImpl = '输出质量检查器实现:生成内容的基础质量校验与纠正。'
- PendingAuditKnowledgeServiceImpl = '待审核知识服务实现:低质量问答入库审核与晋升知识库。'
- ProfileEnrichmentService = '用户画像富化服务:基于行为数据异步更新客户画像。'
- PromptManagerImpl = 'Prompt 管理器实现:节点/全局 Prompt 读取与持久化。'
- QualityScoreRuleEngine = '质量评分规则引擎:静态规则校正、创意场景加分与合规否决。'
- ReplaceWordServiceImpl = '违禁词/易错词替换服务实现:按租户加载替换词表并应用。'
- SemanticTakeoverDetectorImpl = '语义接管检测器实现:检测客户要求转人工或 AI 主动转接意图。'
- ToolCallFrameworkImpl = '工具调用框架实现:解析 AI 工具调用并执行订单/SMS 等内置工具。'
- VariableSubstitutionEngineImpl = '变量替换引擎实现:模板占位符替换与变量抽取。'
- WorkflowTemplateAdminServiceImpl = '工作流模板管理服务实现:模板列表、节点保存与发布查询。'
- }
- $Callers = @{
- LobsterWorkflowExecutor = @('LobsterInboundService','WorkflowTriggerScheduler','LobsterTaskDispatchService','LobsterWorkflowExecController','LobsterTravelValidationServiceImpl')
- LobsterEvolutionEngine = @('LobsterWorkflowExecutorImpl','LobsterQwEvolutionBridge','LobsterTravelValidationServiceImpl','LobsterPayWorkflowBridge')
- DynamicNodeExecutor = @('LobsterWorkflowExecutorImpl','LobsterTravelValidationServiceImpl','LobsterEngineController','LobsterAdminController','LobsterIntegrationTestServiceImpl')
- ContextAssembler = @('LobsterEvolutionEngineImpl','MultiTurnDialogueManagerImpl','ChannelPluginService')
- SummaryGenerator = @('LobsterEvolutionEngineImpl','ContextAssemblerImpl','MultiTurnDialogueManagerImpl','LobsterTravelValidationServiceImpl','LobsterEngineHealthService')
- VariableStore = @('LobsterEvolutionEngineImpl','LobsterWorkflowExecutorImpl','TriggerOrchestratorImpl','LobsterScheduleService','ContextAssemblerImpl')
- MultiTurnDialogueManager = @('LobsterEvolutionEngineImpl','LobsterWorkflowExecutorImpl')
- QualityScoringService = @('LobsterEvolutionEngineImpl','DynamicNodeExecutorImpl','LobsterTravelValidationServiceImpl','LobsterE2eTestServiceImpl','TenantLearningEngineImpl')
- SensitiveWordService = @('LobsterEvolutionEngineImpl','MultiTurnDialogueManagerImpl','LobsterTravelValidationServiceImpl','LobsterCompanyConfigService','LobsterEngineHealthService')
- LobsterE2eTestService = @('LobsterE2eController','LobsterAdminController','LobsterTravelValidationServiceImpl','LobsterTestScenarioServiceImpl')
- ComplianceService = @('LobsterEvolutionEngineImpl','MultiTurnDialogueManagerImpl','LobsterWorkflowExecController')
- ConditionEvaluator = @('LobsterWorkflowExecutorImpl')
- DynamicNodeAdjuster = @('LobsterEvolutionEngineImpl')
- PromptManager = @('LobsterEvolutionEngineImpl','LobsterWorkflowExecutorImpl','DynamicNodeExecutorImpl','MultiTurnDialogueManagerImpl')
- ToolCallFramework = @('LobsterEvolutionEngineImpl')
- ReplaceWordService = @('LobsterEvolutionEngineImpl','LobsterCompanyConfigService')
- VariableSubstitutionEngine = @('LobsterWorkflowExecutorImpl','LobsterEvolutionEngineImpl')
- SemanticTakeoverDetector = @('DynamicNodeAdjusterImpl','LobsterInboundReplyOrchestrator')
- OutputQualityChecker = @('DynamicNodeExecutorImpl')
- MultiModelWorkflowGenerator = @('LobsterIntegrationTestServiceImpl','LobsterAdminController')
- PendingAuditKnowledgeService = @('TenantLearningEngineImpl','LobsterLearningPersistenceService')
- ProfileEnrichmentService = @('LobsterEvolutionEngineImpl')
- QualityScoreRuleEngine = @('QualityScoringServiceImpl')
- DuplicateReplyDetector = @('LobsterWorkflowExecutorImpl')
- FactDecayScheduler = @('Spring 定时调度')
- LobsterBillingServiceImpl = @('LobsterAdminController','LobsterPlatformAdminController','LobsterTokenStatsController')
- LobsterIntegrationTestServiceImpl = @('LobsterEngineController','LobsterAdminController')
- WorkflowTemplateAdminServiceImpl = @('LobsterAdminController')
- ILobsterSalesCorpusService = @('LobsterAdminController','LobsterSalesCorpusController','LobsterPlatformAdminController')
- ILobsterEvolutionSuggestionService = @('LobsterAdminController')
- ILobsterInstanceStatsService = @('LobsterAdminController')
- ILobsterPromptService = @('LobsterPromptController')
- LobsterModelConfigService = @('LobsterAdminController','LobsterModelRouteController')
- LobsterNodeTypeService = @('LobsterIntegrationTestServiceImpl','DynamicNodeExecutorImpl')
- LobsterTestScenarioService = @('LobsterE2eController','LobsterAdminController')
- DynamicNodeImplService = @('LobsterE2eController','LobsterAdminController')
- INodePromptService = @('WorkflowTemplateAdminServiceImpl')
- ILobsterEventAuditService = @('LobsterEventAuditController','LobsterAdminController')
- ILobsterConversationSummaryService = @('LobsterAdminController')
- ILobsterLearningCorpusService = @('LobsterAdminController')
- }
- function Get-Callers([string]$ClassName) {
- $keys = @($ClassName, ($ClassName -replace 'Impl$',''))
- if (-not $keys[1].StartsWith('I')) { $keys += 'I' + $keys[1] }
- foreach ($k in $keys) {
- if ($Callers.ContainsKey($k)) { return $Callers[$k] }
- }
- return @('Spring 容器注入调用')
- }
- function Format-Callers([string[]]$list) {
- return (($list | ForEach-Object { "{@code $_}" }) -join '、')
- }
- function Parse-InterfaceMethods([string]$ClassName) {
- $iface = $ClassName -replace 'Impl$',''
- $files = @(
- (Join-Path $WorkflowDir "$iface.java"),
- (Join-Path $WorkflowDir "I$iface.java")
- )
- $methods = @{}
- foreach ($f in $files) {
- if (-not (Test-Path $f)) { continue }
- $text = [System.IO.File]::ReadAllText($f, $utf8)
- $matches = [regex]::Matches($text, '/\*\*([\s\S]*?)\*/\s*(?:@[\w.]+\s*)*[\w<>,\[\]\s.?]+\s+(\w+)\s*\([^)]*\)\s*;')
- foreach ($m in $matches) {
- $lines = $m.Groups[1].Value -split "`n" | ForEach-Object { $_ -replace '^\s*\*\s?','' } | Where-Object { $_ -and $_ -notmatch '^\s*@(param|return)' }
- if ($lines.Count -gt 0) { $methods[$m.Groups[2].Value] = $lines[0].Trim() }
- }
- }
- return $methods
- }
- function Method-Purpose([string]$ClassName, [string]$MethodName, $ifaceMethods) {
- if ($ifaceMethods.ContainsKey($MethodName)) { return $ifaceMethods[$MethodName] }
- $map = @{
- init='初始化组件(注册 handler、加载缓存等)。'
- evolve='执行单轮对话进化流水线,生成 AI 回复及下一节点。'
- enrichWithDynamicNode='AI 动态生成并插入个性化工作流节点。'
- learnCustomerHabit='从本轮交互学习客户沟通习惯并写入 habit 表。'
- startWorkflow='启动新的工作流实例并执行首节点。'
- executeNextNode='接收客户回复并推进工作流到下一节点。'
- execute='执行指定类型的动态节点 handler。'
- processDialogue='处理多轮对话节点的一轮交互。'
- scoreWithRetry='质量评分并在不达标时带反馈重生成。'
- filterSensitiveWords='过滤文本中的敏感词并替换。'
- enrichProfile='多渠道融合 CRM/标签/交互数据并写入用户画像表。'
- detectTakeover='检测客户是否要求转人工接管。'
- detectAITransfer='检测 AI 是否应主动转接人工。'
- cleanupExpiredFacts='定时清理过期事实与习惯数据。'
- }
- if ($map.ContainsKey($MethodName)) { return $map[$MethodName] }
- if ($MethodName.StartsWith('get') -and $MethodName.Length -gt 3) { return "获取$($MethodName.Substring(3))。" }
- if ($MethodName.StartsWith('is') -and $MethodName.Length -gt 2) { return "判断是否$($MethodName.Substring(2))。" }
- if ($MethodName.StartsWith('list')) { return "查询$($MethodName.Substring(4))列表。" }
- return "$MethodName 的公共入口。"
- }
- function Has-JavadocBefore {
- param([Parameter(Mandatory)][AllowEmptyCollection()][string[]]$Lines, [Parameter(Mandatory)][int]$Idx)
- if ($null -eq $Lines -or $Lines.Count -eq 0 -or $Idx -le 0) { return $false }
- $j = $Idx - 1
- while ($j -ge 0 -and $Lines[$j].Trim() -eq '') { $j-- }
- if ($j -ge 0 -and $Lines[$j].Trim().EndsWith('*/')) { return $true }
- return $false
- }
- function Has-CallerInJavadoc {
- param([Parameter(Mandatory)][AllowEmptyCollection()][string[]]$Lines, [Parameter(Mandatory)][int]$Idx)
- if ($null -eq $Lines -or $Lines.Count -eq 0 -or $Idx -le 0) { return $false }
- $j = $Idx - 1
- while ($j -ge 0) {
- $t = $Lines[$j].Trim()
- if ($t.StartsWith('/**')) { break }
- if ($t.Contains($CallerLabel)) { return $true }
- $j--
- }
- return $false
- }
- function Make-MethodDoc([string]$ClassName, [string]$MethodName, $ifaceMethods, [string]$indent) {
- $purpose = Method-Purpose $ClassName $MethodName $ifaceMethods
- $callers = Format-Callers (Get-Callers $ClassName)
- return @(
- "$indent/**",
- "$indent * $purpose",
- "$indent * <p>${CallerLabel}:$callers。",
- "$indent */"
- )
- }
- function Make-ClassDoc([string]$ClassName) {
- $desc = if ($ClassDesc.ContainsKey($ClassName)) { $ClassDesc[$ClassName] } else { "$ClassName:workflow impl 包 Spring 服务实现。" }
- $callers = Format-Callers (Get-Callers $ClassName)
- return @(
- '/**',
- " * $desc",
- " * <p>${MainCallerLabel}:$callers。",
- ' */'
- )
- }
- function Process-File([string]$FilePath) {
- $className = [System.IO.Path]::GetFileNameWithoutExtension($FilePath)
- if ($className -eq 'package-info') { return $false }
- $lines = [System.Collections.Generic.List[string]]::new()
- [System.IO.File]::ReadAllLines($FilePath, $utf8) | ForEach-Object { [void]$lines.Add($_) }
- $ifaceMethods = Parse-InterfaceMethods $className
- $classIdx = -1
- for ($i = 0; $i -lt $lines.Count; $i++) {
- if ($lines[$i] -match "public\s+(?:final\s+)?class\s+$className\b") { $classIdx = $i; break }
- }
- if ($classIdx -lt 0) { return $false }
- $modified = $false
- $hasClassDoc = $false
- $j = $classIdx - 1
- while ($j -ge 0 -and ($lines[$j].Trim().StartsWith('@') -or $lines[$j].Trim() -eq '')) { $j-- }
- if ($j -ge 0 -and ($lines[$j].Trim().StartsWith('/**') -or $lines[$j].Trim().EndsWith('*/'))) { $hasClassDoc = $true }
- $lineArr = @($lines.ToArray())
- if (-not $hasClassDoc) {
- $insertAt = $classIdx
- while ($insertAt -gt 0 -and ($lines[$insertAt-1].Trim().StartsWith('@') -or $lines[$insertAt-1].Trim() -eq '')) { $insertAt-- }
- $doc = Make-ClassDoc $className
- for ($d = $doc.Count - 1; $d -ge 0; $d--) { $lines.Insert($insertAt, $doc[$d]) }
- $classIdx += $doc.Count
- $modified = $true
- } elseif (-not (Has-CallerInJavadoc -Lines $lineArr -Idx $classIdx)) {
- $j = $classIdx - 1
- while ($j -ge 0 -and ($lines[$j].Trim().StartsWith('@') -or $lines[$j].Trim() -eq '')) { $j-- }
- if ($j -ge 0 -and $lines[$j].Trim() -eq '*/') {
- $callers = Format-Callers (Get-Callers $className)
- $lines.Insert($j, " * <p>${MainCallerLabel}:$callers。")
- $modified = $true
- }
- }
- $lineArr = @($lines.ToArray())
- $out = [System.Collections.Generic.List[string]]::new()
- $skipUntil = -1
- for ($i = 0; $i -lt $lines.Count; $i++) {
- if ($i -le $skipUntil) { continue }
- $line = $lines[$i]
- $stripped = $line.Trim()
- if ($stripped -eq '@Override' -and ($i+1) -lt $lines.Count -and $lines[$i+1].Trim() -match '^public\s+') {
- if (-not (Has-JavadocBefore -Lines $lineArr -Idx $i)) {
- $mm = [regex]::Match($lines[$i+1], '\b(\w+)\s*\(')
- if ($mm.Success) {
- $indent = if ($line -match '^(\s*)') { $Matches[1] } else { ' ' }
- Make-MethodDoc $className $mm.Groups[1].Value $ifaceMethods $indent | ForEach-Object { [void]$out.Add($_) }
- $modified = $true
- }
- } elseif (-not (Has-CallerInJavadoc -Lines $lineArr -Idx $i)) {
- $j = $i - 1
- while ($j -ge 0 -and $lines[$j].Trim() -ne '*/') { $j-- }
- if ($j -ge 0) {
- $indent = if ($lines[$j] -match '^(\s*)') { $Matches[1] } else { ' ' }
- $callers = Format-Callers (Get-Callers $className)
- [void]$out.Insert($out.Count, "$indent * <p>${CallerLabel}:$callers。")
- $modified = $true
- }
- }
- [void]$out.Add($line)
- continue
- }
- if ($stripped -match '^public\s+(?!class\b|interface\b|enum\b|static\s+class\b)' -and -not $stripped.StartsWith('@')) {
- if (-not (Has-JavadocBefore -Lines $lineArr -Idx $i)) {
- $combined = $stripped
- $k = $i
- while ($combined -notmatch '[;{]' -and $k+1 -lt $lines.Count) { $k++; $combined += ' ' + $lines[$k].Trim() }
- $mm = [regex]::Match($combined, '\b(\w+)\s*\(')
- if ($mm.Success -and $mm.Groups[1].Value -notin @('if','for','while','switch','catch')) {
- $indent = if ($line -match '^(\s*)') { $Matches[1] } else { ' ' }
- Make-MethodDoc $className $mm.Groups[1].Value $ifaceMethods $indent | ForEach-Object { [void]$out.Add($_) }
- $modified = $true
- }
- } elseif (-not (Has-CallerInJavadoc -Lines $lineArr -Idx $i)) {
- $j = $i - 1
- while ($j -ge 0 -and $lines[$j].Trim() -ne '*/') { $j-- }
- if ($j -ge 0) {
- $indent = if ($lines[$j] -match '^(\s*)') { $Matches[1] } else { ' ' }
- $callers = Format-Callers (Get-Callers $className)
- [void]$out.Insert($out.Count, "$indent * <p>${CallerLabel}:$callers。")
- $modified = $true
- }
- }
- }
- [void]$out.Add($line)
- }
- if ($modified) {
- [System.IO.File]::WriteAllLines($FilePath, $out, $utf8)
- }
- return $modified
- }
- $modified = @()
- if ($MyInvocation.InvocationName -ne '.') {
- Get-ChildItem $ImplDir -Filter *.java | Sort-Object Name | ForEach-Object {
- if (Process-File $_.FullName) {
- $modified += $_.Name
- Write-Host "MODIFIED: $($_.Name)"
- } else {
- Write-Host "SKIP: $($_.Name)"
- }
- }
- Write-Host "Total modified: $($modified.Count)"
- }
|