* @package ai * @link https://www.zentao.net */ namespace zin; h::css(" .detail-view > .detail-body > .detail-main > .detail-sections:first-child > .detail-section {position: relative; z-index: 1;} .detail-view > .detail-body > .detail-main > .detail-sections:first-child > .detail-section:first-child {z-index: 2;} "); $generateAgents = function($agents) { $agentIds = array(); $agentCodes = array(); $agentList = explode(',', $agents); foreach($agentList as $agent) { $agent = trim($agent); if($agent === '') continue; if(strpos($agent, 'zt_') === 0) { $agentCodes[] = $agent; } elseif(is_numeric($agent)) { $agentIds[] = $agent; } } if(!empty($agentCodes)) { $codeAgents = $this->ai->getAgentsByCodes($agentCodes, 'active'); foreach($codeAgents as $codeAgent) $agentIds[] = $codeAgent->id; } return $agentIds; }; $promptMenuInject = function() use ($generateAgents) { if(isInModal()) return; $this->loadModel('ai'); if(!commonModel::hasPriv('ai', 'promptExecute')) return; $this->app->loadLang('ai'); $this->app->loadConfig('ai'); $module = $this->app->getModuleName(); $method = $this->app->getMethodName(); $isDocApp = $module === 'doc' && $method === 'app'; $useMethod = $method; if($isDocApp) $method = 'view'; $showOnList = in_array($module, ['product', 'project', 'projectstory', 'execution']) && in_array($useMethod, ['browse', 'story', 'task']); $isOtherDoc = $isDocApp && $this->app->tab != 'doc'; $showOnList = $showOnList || ($isOtherDoc); $isProjectStory = $module === 'product' && $useMethod === 'browse' && $this->app->tab == 'project'; if($showOnList) $method = 'view'; if($isOtherDoc || $isProjectStory) { $module = $this->app->tab; $useMethod = 'view'; } if(!isset($this->config->ai->menuPrint->locations[$module][$method])) return; $menuOptions = $this->config->ai->menuPrint->locations[$module][$method]; $prompts = $this->ai->getPromptsForUser($menuOptions->module); $prompts = $this->ai->filterPromptsForExecution($prompts, true); $btnName = $this->lang->ai->prompts->common; $promptIds = array_column($prompts, 'id'); $canAssign = !empty($this->config->enableAITeammate) && hasPriv('aiteammate', 'assignagent') && $this->config->edition != 'open'; $teammates = array(); if(!empty($prompts) && $canAssign) $teammates = $this->loadModel('aiteammate')->browse('0'); $showTeammates = array_filter($teammates, function($item) use ($promptIds, $generateAgents) { if(empty($item->agents)) return false; $agents = $generateAgents($item->agents); return !empty(array_intersect($promptIds, $agents)); }); if(!empty($showTeammates)) $showTeammates = array_values($showTeammates); $assignedBtnName = ''; if($canAssign) $assignedBtnName = sprintf($this->lang->ai->promptMenu->assignedTo, $this->lang->aiteammate->common); if($isDocApp && $this->app->tab == 'doc') { h::globalJS('window.docAIPrompts = ' . json_encode($prompts) . ";\n", 'window.docAIPromptLang = ' . json_encode(array('dropdownTitle' => $btnName, 'statuses' => $this->lang->ai->prompts->statuses)) . ";\n", 'window.docAITeammates = ' . json_encode($showTeammates) . ";\n", 'window.docAITeammateLang = ' . json_encode(array('dropdownTitle' => $assignedBtnName, 'nameLabel' => $this->lang->ai->promptMenu->assignedTo)) . ";\n"); return; } if($module === 'productplan' && $method === 'view') { /* 子计划不显示“拆分子计划智能体” */ $plan = data('plan'); if(is_object($plan) && $plan->parent > 0) { $prompts = array_filter($prompts, function($prompt) { return $prompt->module !== 'productplan' || $prompt->targetForm !== 'productplan.create'; }); } } if(empty($prompts)) return; $aiSuggestions = []; $isReleaseView = $module == 'release' && $method == 'view'; $className = $isReleaseView ? 'mt-1' : ''; $html = "