feat: 移除冗余的AI任务和项目生成逻辑,优化代码结构

This commit is contained in:
kuaifan 2025-11-08 20:45:21 +00:00
parent 0deb3113b5
commit 0434bde16f
8 changed files with 2 additions and 700 deletions

View File

@ -3024,115 +3024,6 @@ class ProjectController extends AbstractController
return Base::retSuccess('复制成功', $data);
}
/**
* @api {post} api/project/task/ai_generate 使用 AI 助手生成任务
*
* @apiDescription 需要token身份使用AI根据用户输入和上下文信息生成任务标题和详细描述
* @apiVersion 1.0.0
* @apiGroup project
* @apiName task__ai_generate
*
* @apiParam {String} content 用户输入的任务描述(必填)
* @apiParam {String} [current_title] 当前已有的任务标题(用于优化改进)
* @apiParam {String} [current_content] 当前已有的任务内容HTML格式用于优化改进
* @apiParam {String} [template_name] 选中的任务模板名称
* @apiParam {String} [template_content] 选中的任务模板内容HTML格式
* @apiParam {Boolean} [has_owner] 是否已设置负责人
* @apiParam {Boolean} [has_time_plan] 是否已设置计划时间
* @apiParam {String} [priority_level] 任务优先级等级名称
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
* @apiSuccess {String} data.title AI 生成的任务标题
* @apiSuccess {String} data.content AI 生成的任务内容HTML 格式)
* @apiSuccess {Array} data.subtasks 当任务较复杂时生成的子任务名称列表
*/
public function task__ai_generate()
{
User::auth();
// 获取用户输入的任务描述
$content = Request::input('content');
if (empty($content)) {
return Base::retError('任务描述不能为空');
}
// 获取上下文信息
$context = [
'current_title' => Request::input('current_title', ''),
'current_content' => Request::input('current_content', ''),
'template_name' => Request::input('template_name', ''),
'template_content' => Request::input('template_content', ''),
'has_owner' => boolval(Request::input('has_owner', false)),
'has_time_plan' => boolval(Request::input('has_time_plan', false)),
'priority_level' => Request::input('priority_level', ''),
];
// 如果当前内容是HTML格式转换为markdown
if (!empty($context['current_content'])) {
$context['current_content'] = Base::html2markdown($context['current_content']);
}
if (!empty($context['template_content'])) {
$context['template_content'] = Base::html2markdown($context['template_content']);
}
$result = AI::generateTask($content, $context);
if (Base::isError($result)) {
return Base::retError('生成任务失败', $result);
}
return Base::retSuccess('生成任务成功', $result['data']);
}
/**
* @api {post} api/project/ai/generate 使用 AI 助手生成项目
*
* @apiDescription 需要token身份根据需求说明自动生成项目名称及任务列表
* @apiVersion 1.0.0
* @apiGroup project
* @apiName ai__generate
*
* @apiParam {String} content 项目需求或背景描述(必填)
* @apiParam {String} [current_name] 当前草拟的项目名称
* @apiParam {Array|String} [current_columns] 已有任务列表(数组或以逗号/换行分隔的字符串)
* @apiParam {Array} [template_examples] 可参考的模板示例,格式:[ {name: 模板名, columns: [列表...] }, ... ]
*
* @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述)
* @apiSuccess {Object} data 返回数据
* @apiSuccess {String} data.name AI 生成的项目名称
* @apiSuccess {Array} data.columns AI 生成的任务列表名称数组
*/
public function ai__generate()
{
User::auth();
$content = trim((string)Request::input('content', ''));
if ($content === '') {
return Base::retError('项目需求描述不能为空');
}
$templateExamples = Request::input('template_examples', []);
if (!is_array($templateExamples)) {
$templateExamples = [];
} else {
$templateExamples = array_slice($templateExamples, 0, 6);
}
$context = [
'current_name' => Request::input('current_name', ''),
'current_columns' => Request::input('current_columns', []),
'template_examples' => $templateExamples,
];
$result = AI::generateProject($content, $context);
if (Base::isError($result)) {
return Base::retError('生成项目失败', $result);
}
return Base::retSuccess('生成项目成功', $result['data']);
}
/**
* @api {get} api/project/flow/list 工作流列表
*

View File

@ -318,244 +318,6 @@ class AI
return $result;
}
/**
* 通过 openAI 生成任务标题和描述
* @param string $text 用户提供的提示词
* @param array $context 上下文信息
* @return array
*/
public static function generateTask($text, $context = [])
{
// 构建上下文提示信息
$contextPrompt = self::buildTaskContextPrompt($context);
$post = json_encode([
"model" => "gpt-5-mini",
"reasoning_effort" => "minimal",
"messages" => [
[
"role" => "system",
"content" => <<<EOF
你是一个专业的任务管理专家,擅长将想法和需求转化为清晰、可执行的项目任务。
任务生成要求:
1. 根据输入内容分析并生成合适的任务标题和详细描述
2. 标题要简洁明了准确概括任务核心目标长度控制在8-30个字符
3. 描述需覆盖任务背景、具体要求、交付标准、风险提示等关键信息
4. 描述内容使用Markdown格式合理组织标题、列表、加粗等结构
5. 内容需适配项目管理系统,表述专业、逻辑清晰,并与用户输入语言保持一致
6. 优先遵循用户在输入中给出的风格、长度或复杂度要求默认情况下将详细描述控制在120-200字内如用户要求简单或简短则控制在80-120字内
7. 当任务具有多个执行步骤、阶段或协作角色时,请拆解出 2-6 个关键子任务;如无必要,可返回空数组
8. 子任务应聚焦单一可执行动作名称控制在8-30个字符内,避免重复和含糊表述
返回格式要求:
必须严格按照以下 JSON 结构返回,禁止输出额外文字或 Markdown 代码块标记;即使某项为空,也保留对应字段:
{
"title": "任务标题",
"content": "任务的详细描述内容使用Markdown格式根据实际情况组织结构",
"subtasks": [
"子任务名称1",
"子任务名称2"
]
}
内容格式建议(非强制):
- 可以使用标题、列表、加粗等Markdown格式
- 可以包含任务背景、具体要求、验收标准等部分
- 根据任务性质灵活组织内容结构
- 仅在确有必要时生成子任务,并确保每个子任务都是独立、可执行、便于追踪的动作
- 若用户明确要求简洁或简单,保持描述紧凑,避免添加冗余段落或重复信息
上下文信息处理指南:
- 如果已有标题和内容,优先考虑优化改进而非完全重写
- 如果使用了任务模板,严格按照模板的结构和格式要求生成
- 如果已设置负责人或时间计划,在任务描述中体现相关要求
- 根据优先级等级调整任务的紧急程度和详细程度
注意事项:
- 标题要体现任务的核心动作和目标
- 描述要包含足够的细节让执行者理解任务
- 如果涉及技术开发,要明确技术要求和实现方案
- 如果涉及设计,要说明设计要求和期望效果
- 如果涉及测试,要明确测试范围和验收标准
EOF
],
[
"role" => "user",
"content" => $contextPrompt . "\n\n请根据以上上下文并结合以下提示词生成一个完整的项目任务(包含标题和详细描述):\n\n" . $text
]
],
]);
$ai = new self($post);
$ai->setTimeout(60);
$res = $ai->request();
if (Base::isError($res)) {
return Base::retError("任务生成失败", $res);
}
// 清理可能的markdown代码块标记
$content = $res['data'];
$content = preg_replace('/^\s*```json\s*/', '', $content);
$content = preg_replace('/\s*```\s*$/', '', $content);
if (empty($content)) {
return Base::retError("任务生成结果为空");
}
// 解析JSON
$parsedData = Base::json2array($content);
if (!$parsedData || !isset($parsedData['title']) || !isset($parsedData['content'])) {
return Base::retError("任务生成格式错误", $content);
}
$title = trim($parsedData['title']);
$markdownContent = trim($parsedData['content']);
$rawSubtasks = $parsedData['subtasks'] ?? [];
if (empty($title) || empty($markdownContent)) {
return Base::retError("生成的任务标题或内容为空", $parsedData);
}
$subtasks = [];
if (is_array($rawSubtasks)) {
foreach ($rawSubtasks as $raw) {
if (is_array($raw)) {
$name = trim($raw['title'] ?? $raw['name'] ?? '');
} else {
$name = trim($raw);
}
if (!empty($name)) {
$subtasks[] = $name;
}
if (count($subtasks) >= 8) {
break;
}
}
}
return Base::retSuccess("success", [
'title' => $title,
'content' => Base::markdown2html($markdownContent), // 将 Markdown 转换为 HTML
'subtasks' => $subtasks
]);
}
/**
* 通过 openAI 生成项目名称与任务列表
* @param string $text 用户提供的提示词
* @param array $context 上下文信息
* @return array
*/
public static function generateProject($text, $context = [])
{
$text = trim((string)$text);
if ($text === '') {
return Base::retError("项目提示词不能为空");
}
$context['current_name'] = trim($context['current_name'] ?? '');
$context['current_columns'] = self::normalizeProjectColumns($context['current_columns'] ?? []);
if (!empty($context['template_examples']) && is_array($context['template_examples'])) {
$examples = [];
foreach ($context['template_examples'] as $item) {
$name = trim($item['name'] ?? '');
$columns = self::normalizeProjectColumns($item['columns'] ?? []);
if (empty($columns)) {
continue;
}
$examples[] = [
'name' => $name,
'columns' => $columns,
];
if (count($examples) >= 6) {
break;
}
}
$context['template_examples'] = $examples;
} else {
$context['template_examples'] = [];
}
$contextPrompt = self::buildProjectContextPrompt($context);
$post = json_encode([
"model" => "gpt-5-mini",
"reasoning_effort" => "minimal",
"messages" => [
[
"role" => "system",
"content" => <<<EOF
你是一名资深的项目规划顾问,帮助团队快速搭建符合需求的项目。
生成要求:
1. 产出一个简洁、有辨识度的项目名称不超过18个汉字或36个字符
2. 给出 3 - 8 个项目任务列表,用于看板列或阶段分组
3. 任务列表名称保持 4 - 12 个字符,聚焦阶段或责任划分,避免冗长描述
4. 结合用户描述的业务特征,必要时可包含里程碑或交付节点
5. 尽量参考上下文提供的现有内容或模板,不要与之完全重复
输出格式:
必须严格返回 JSON禁止携带额外说明或 Markdown 代码块,结构如下:
{
"name": "项目名称",
"columns": ["列表1", "列表2", "列表3"]
}
校验标准:
- 列表名称应当互不重复且语义明确
- 若上下文包含已有名称或列表,请在此基础上迭代优化
EOF
],
[
"role" => "user",
"content" => ($contextPrompt ? $contextPrompt . "\n\n" : "") . "请根据以上信息,并结合以下提示词生成适合的项目名称和任务列表:\n\n" . $text
],
],
]);
$ai = new self($post);
$ai->setTimeout(45);
$res = $ai->request();
if (Base::isError($res)) {
return Base::retError("项目生成失败", $res);
}
$content = $res['data'];
$content = preg_replace('/^\s*```json\s*/', '', $content);
$content = preg_replace('/\s*```\s*$/', '', $content);
if (empty($content)) {
return Base::retError("项目生成结果为空");
}
$parsedData = Base::json2array($content);
if (!$parsedData || !isset($parsedData['name'])) {
return Base::retError("项目生成格式错误", $content);
}
$name = trim($parsedData['name']);
$columns = self::normalizeProjectColumns($parsedData['columns'] ?? []);
if ($name === '') {
return Base::retError("生成的项目名称为空", $parsedData);
}
if (empty($columns)) {
$columns = $context['current_columns'];
}
return Base::retSuccess("success", [
'name' => $name,
'columns' => $columns,
]);
}
/**
* 对工作汇报内容进行分析
* @param Report $report
@ -685,194 +447,6 @@ class AI
]);
}
/**
* 构建任务生成的上下文提示信息
* @param array $context 上下文信息
* @return string
*/
private static function buildTaskContextPrompt($context)
{
$prompts = [];
// 当前任务信息
if (!empty($context['current_title']) || !empty($context['current_content'])) {
$prompts[] = "## 当前任务信息";
if (!empty($context['current_title'])) {
$prompts[] = "当前标题:" . $context['current_title'];
}
if (!empty($context['current_content'])) {
$prompts[] = "当前内容:" . $context['current_content'];
}
$prompts[] = "请在此基础上优化改进,而不是完全重写。";
}
// 任务模板信息
if (!empty($context['template_name']) || !empty($context['template_content'])) {
$prompts[] = "## 任务模板要求";
if (!empty($context['template_name'])) {
$prompts[] = "模板名称:" . $context['template_name'];
}
if (!empty($context['template_content'])) {
$prompts[] = "模板内容结构:" . $context['template_content'];
}
$prompts[] = "请严格按照此模板的结构和格式要求生成内容。";
}
// 项目状态信息
$statusInfo = [];
if (!empty($context['has_owner'])) {
$statusInfo[] = "已设置负责人";
}
if (!empty($context['has_time_plan'])) {
$statusInfo[] = "已设置计划时间";
}
if (!empty($context['priority_level'])) {
$statusInfo[] = "优先级:" . $context['priority_level'];
}
if (!empty($statusInfo)) {
$prompts[] = "## 任务状态";
$prompts[] = implode("", $statusInfo);
$prompts[] = "请在任务描述中体现相应的要求和约束。";
}
return empty($prompts) ? "" : implode("\n", $prompts);
}
private static function buildProjectContextPrompt($context)
{
$prompts = [];
if (!empty($context['current_name']) || !empty($context['current_columns'])) {
$prompts[] = "## 当前项目草稿";
if (!empty($context['current_name'])) {
$prompts[] = "已有名称:" . $context['current_name'];
}
if (!empty($context['current_columns'])) {
$prompts[] = "现有任务列表:" . implode("", $context['current_columns']);
}
$prompts[] = "请在此基础上进行优化和补充。";
}
if (!empty($context['template_examples'])) {
$prompts[] = "## 常用模板示例";
foreach ($context['template_examples'] as $example) {
$line = '';
if (!empty($example['name'])) {
$line .= $example['name'] . "";
}
$line .= implode("", $example['columns']);
$prompts[] = "- " . $line;
}
$prompts[] = "可以借鉴以上结构,但要结合用户需求生成更贴合的方案。";
}
return empty($prompts) ? "" : implode("\n", $prompts);
}
public static function messageSystemPrompt()
{
return <<<EOF
你是一名专业的沟通助手,协助用户编写得体、清晰且具行动指向的即时消息。
写作要求:
1. 根据用户提供的需求与上下文生成完整消息,语气需符合业务沟通场景,保持真诚、礼貌且高效
2. 默认使用简洁的短段落,可使用 Markdown 基础格式(加粗、列表、引用)增强结构,但不要输出代码块或 JSON
3. 如果上下文包含引用信息或草稿,请在消息中自然呼应相关要点
4. 如无特别说明,将消息长度控制在 60-180 字;若需更短或更长,遵循用户描述
5. 如需提出行动或问题,请明确表达,避免含糊
输出规范:
- 仅返回可直接发送的消息内容
- 禁止在内容前后添加额外说明、标签或引导语
EOF;
}
public static function buildMessageContextPrompt($context)
{
$prompts = [];
if (!empty($context['dialog_name']) || !empty($context['dialog_type']) || !empty($context['group_type'])) {
$prompts[] = "## 会话信息";
if (!empty($context['dialog_name'])) {
$prompts[] = "名称:" . Base::cutStr($context['dialog_name'], 60);
}
if (!empty($context['dialog_type'])) {
$typeMap = ['group' => '群聊', 'user' => '单聊'];
$prompts[] = "类型:" . ($typeMap[$context['dialog_type']] ?? $context['dialog_type']);
}
if (!empty($context['group_type'])) {
$prompts[] = "分类:" . Base::cutStr($context['group_type'], 60);
}
}
if (!empty($context['members']) && is_array($context['members'])) {
$members = array_slice(array_filter($context['members']), 0, 10);
if (!empty($members)) {
$prompts[] = "## 会话成员";
$prompts[] = implode("", array_map(fn($name) => Base::cutStr($name, 30), $members));
}
}
if (!empty($context['recent_messages']) && is_array($context['recent_messages'])) {
$prompts[] = "## 最近消息";
foreach ($context['recent_messages'] as $item) {
$sender = Base::cutStr(trim($item['sender'] ?? ''), 40) ?: '成员';
$summary = Base::cutStr(trim($item['summary'] ?? ''), 120);
if ($summary !== '') {
$prompts[] = "- {$sender}{$summary}";
}
}
}
if (!empty($context['quote_summary'])) {
$prompts[] = "## 引用消息";
$quoteUser = Base::cutStr(trim($context['quote_user'] ?? ''), 40);
$quoteText = Base::cutStr(trim($context['quote_summary']), 200);
if ($quoteUser !== '') {
$prompts[] = "{$quoteUser}{$quoteText}";
} else {
$prompts[] = $quoteText;
}
}
if (!empty($context['current_draft'])) {
$prompts[] = "## 当前草稿";
$prompts[] = Base::cutStr(trim($context['current_draft']), 200);
}
return empty($prompts) ? "" : implode("\n", $prompts);
}
private static function normalizeProjectColumns($columns)
{
if (is_string($columns)) {
$columns = preg_split('/[\n\r,;|]/u', $columns);
}
$normalized = [];
if (is_array($columns)) {
foreach ($columns as $item) {
if (is_array($item)) {
$item = $item['name'] ?? $item['title'] ?? reset($item);
}
$item = trim((string)$item);
if ($item === '') {
continue;
}
$item = mb_substr($item, 0, 30);
if (!in_array($item, $normalized)) {
$normalized[] = $item;
}
if (count($normalized) >= 8) {
break;
}
}
}
return $normalized;
}
/**
* 通过 openAI 生成职场笑话、心灵鸡汤
* @param bool $noCache 是否禁用缓存

View File

@ -1956,8 +1956,6 @@ API请求的基础URL路径如果没有请留空
Grok是由xAI开发的生成式人工智能聊天机器人旨在通过实时回答用户问题来提供帮助。
Ollama 是一个轻量级、可扩展的框架,旨在让用户能够在本地机器上构建和运行大型语言模型。
AI 列表
AI 设置
思考中...
请先填写 Base URL
@ -2224,7 +2222,6 @@ AI 正在生成分析...
最后更新:
暂无 AI 分析,点击右侧按钮生成。
AI 整理汇报
整理结果预览
应用到汇报
请先填写汇报内容
AI 未返回整理内容

View File

@ -27899,30 +27899,6 @@
"id": "Ollama adalah kerangka kerja ringan dan skalabel yang dirancang untuk memungkinkan pengguna membangun dan menjalankan model bahasa besar pada mesin lokal.",
"ru": "Ollama - это легкий, масштабируемый фреймворк, разработанный для того, чтобы пользователи могли создавать и запускать крупные языковые модели на локальных машинах."
},
{
"key": "AI 列表",
"zh": "",
"zh-CHT": "AI 列表",
"en": "AI List",
"ko": "AI 목록",
"ja": "AIリスト",
"de": "KI-Liste",
"fr": "Liste d'IA",
"id": "Daftar AI",
"ru": "Список AI"
},
{
"key": "AI 设置",
"zh": "",
"zh-CHT": "AI 設置",
"en": "AI Settings",
"ko": "AI 설정",
"ja": "AI設定",
"de": "KI-Einstellungen",
"fr": "Paramètres de l'IA",
"id": "Pengaturan AI",
"ru": "Настройки AI"
},
{
"key": "思考中...",
"zh": "",

View File

@ -155,62 +155,6 @@
</div>
</Modal>
<!--AI BOT-->
<DrawerOverlay v-model="aibotShow" placement="right" :size="720">
<template v-if="aibotShow" #title>
{{ $L('AI 列表') }}
</template>
<template v-if="aibotShow" #more>
<a href="javascript:void(0)" @click="applyClick({value: 'robot-setting'}, 'openai')" v-if="userIsAdmin">{{ $L('机器人设置') }}</a>
</template>
<div v-if="aibotShow" class="ivu-modal-wrap-apply">
<div class="ivu-modal-wrap-apply-body full-body">
<ul class="ivu-modal-wrap-ul">
<li v-for="(item, key) in aibotList" :key="key">
<div class="modal-item-img">
<img :src="item.src">
</div>
<div class="modal-item-info">
<div class="modal-item-name">
<h4>{{ item.label }}</h4>
<div v-if="item.tag" class="modal-item-tag" @click="applyClick({value: 'robot-setting'}, item.value)">
{{ item.tag }}
<em v-if="item.tags.length > 1">+{{ item.tags.length - 1 }}</em>
</div>
</div>
<p class="modal-item-desc" @click="openDetail(item.desc)">{{ item.desc }}</p>
<div class="modal-item-btns">
<Button icon="md-chatbubbles" :loading="aibotDialogSearchLoad == item.value" @click="onGoToChat(item.value)">{{ $L('开始聊天') }}</Button>
<Button v-if="userIsAdmin" icon="md-settings" @click="applyClick({value: 'robot-setting'}, item.value)">{{ $L('设置') }}</Button>
</div>
</div>
</li>
</ul>
</div>
</div>
</DrawerOverlay>
<!--AI BOT 设置-->
<DrawerOverlay v-model="aibotSettingShow" placement="right" :size="950">
<template v-if="aibotSettingShow" #title>
{{ $L('AI 设置') }}
</template>
<div v-if="aibotSettingShow" class="ivu-modal-wrap-apply">
<div class="ivu-modal-wrap-apply-body">
<Tabs v-model="aibotTabAction" :animated="false" class="ai-tabs">
<TabPane v-for="(item, key) in aibotList" :key="key" :label="item.label" :name="item.value">
<div class="aibot-setting">
<SystemAibot
v-if="aibotTabAction == item.value"
:type="item.value"
@on-update-setting="handleAITags"/>
</div>
</TabPane>
</Tabs>
</div>
</div>
</DrawerOverlay>
<!--签到-->
<DrawerOverlay v-model="signInShow" placement="right" :size="500">
<template v-if="signInShow" #title>
@ -347,7 +291,6 @@
import {mapGetters, mapState} from "vuex";
import DrawerOverlay from "../../components/DrawerOverlay";
import UserSelect from "../../components/UserSelect";
import SystemAibot from "./setting/components/SystemAibot";
import SystemCheckin from "./setting/components/SystemCheckin";
import Checkin from "./setting/checkin";
import SystemMeeting from "./setting/components/SystemMeeting";
@ -357,16 +300,14 @@ import SystemEmailSetting from "./setting/components/SystemEmailSetting";
import SystemAppPush from "./setting/components/SystemAppPush";
import SystemAiAssistant from "./setting/components/SystemAiAssistant";
import emitter from "../../store/events";
import {AIBotList, AIModelNames} from "../../utils/ai";
import ImgUpload from "../../components/ImgUpload.vue";
import {webhookEventOptions} from "../../utils/other";
import {webhookEventOptions} from "../../utils/webhook";
export default {
components: {
ImgUpload,
UserSelect,
DrawerOverlay,
SystemAibot,
SystemCheckin,
Checkin,
SystemMeeting,
@ -388,12 +329,6 @@ export default {
mybotModifyLoad: 0,
webhookEventOptions,
//
aibotShow: false,
aibotList: AIBotList,
aibotSettingShow: false,
aibotTabAction: "openai",
aibotDialogSearchLoad: "",
//
signInShow: false,
signInSettingShow: false,
//
@ -445,7 +380,6 @@ export default {
{value: "recent", label: "最近打开", sort: 47},
{value: "report", label: "工作报告", sort: 50},
{value: "mybot", label: "我的机器人", sort: 55},
{value: "robot", label: "AI 机器人", sort: 60, show: this.microAppsIds.includes('ai')},
{value: "signin", label: "签到打卡", sort: 70},
{value: "meeting", label: "在线会议", sort: 80},
{value: "createGroup", label: "创建群组", sort: 85},
@ -560,14 +494,6 @@ export default {
case 'mybot-del':
this.delMybot(params);
break;
case 'robot':
this.getAITags();
this.aibotShow = true;
break;
case 'robot-setting':
this.aibotTabAction = params;
this.aibotSettingShow = true;
break;
case 'signin':
this.signInShow = true;
break;
@ -677,65 +603,6 @@ export default {
this.mybotModifyLoad--;
});
},
// AI
getAITags() {
this.$store.dispatch("call", {
url: 'system/setting/aibot_models',
}).then(({data}) => {
this.handleAITags(data);
});
},
// AI
handleAITags(data) {
for (let key in data) {
const match = key.match(/^(.*?)_models$/);
if (match) {
const value = match[1];
this.aibotList.map(h => {
if (h.value == value) {
const items = AIModelNames(data[key])
h.tags = items.map(item => item.label);
h.tag = data[key.slice(0, -1)];
items.some(item => {
if (item.value == h.tag) {
h.tag = item.label;
return true;
}
})
}
});
}
}
},
//
onGoToChat(type) {
let dialogId = 0;
this.cacheDialogs.some(h => {
if (h.email == `ai-${type}@bot.system`) {
dialogId = h.id;
return true;
}
})
if (dialogId) {
this.$store.dispatch("openDialog", dialogId)
return
}
//
this.aibotDialogSearchLoad = type;
this.$store.dispatch("call", {
url: 'users/search/ai',
data: {type},
}).then(({data}) => {
this.$store.dispatch("openDialogUserid", data.userid).catch(({msg}) => {
$A.modalError(msg)
}).finally(_ => {
this.aibotDialogSearchLoad = '';
});
}).catch(({msg}) => {
this.aibotDialogSearchLoad = '';
$A.messageError(msg || '机器人暂未开启');
});
},
//
onMeeting(name) {
switch (name) {

View File

@ -690,7 +690,7 @@ import emitter from "../../../store/events";
import Forwarder from "./Forwarder/index.vue";
import {throttle} from "lodash";
import transformEmojiToHtml from "../../../utils/emoji";
import {webhookEventOptions} from "../../../utils/other";
import {webhookEventOptions} from "../../../utils/webhook";
export default {
name: "DialogWrapper",

View File

@ -42,8 +42,6 @@ const AINormalizeJsonContent = (content) => {
return null;
}
const AIBotList = []
const AIBotMap = {
openai: "ChatGPT",
claude: "Claude",
@ -327,7 +325,6 @@ const PROJECT_AI_SYSTEM_PROMPT = `你是一名资深的项目规划顾问,帮
export {
AIModelNames,
AINormalizeJsonContent,
AIBotList,
AIBotMap,
AISystemConfig,
MESSAGE_AI_SYSTEM_PROMPT,