Files
----/后端源码/yifan.action-ai.cn/index/js/index.Cn8BFTsV.js

905 lines
36 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Z as ElRadioButton, P as ElRadioGroup, ao as vLoading, x as ElFormItem, aq as ElSelect, ar as ElOption, y as ElInput, as as ElSlider, h as ElButton, at as aim_default, aa as delete_default, ad as chat_dot_round_default, i as ElIcon, ae as user_default, ai as promotion_default, au as video_pause_default, w as ElForm, v as ElDialog, E as ElMessage, D as ElMessageBox } from "./element-plus.CkEW9frc.js";
import { J as defineComponent, ej as MarkdownIt, t as onMounted, S as openBlock, _ as createElementBlock, a1 as createBaseVNode, $ as createVNode, a0 as withCtx, H as Fragment, ay as renderList, o as unref, T as createBlock, a9 as createTextVNode, aa as toDisplayString, a6 as withDirectives, a8 as createCommentVNode, a3 as normalizeClass, a_ as withKeys, aw as withModifiers, r as ref, j as computed, ak as reactive, n as nextTick, el as HighlightJS } from "./.pnpm.BW3P1y8f.js";
import { l as httpRequest, A as Auth } from "./index.CMd5bD1r.js";
import { A as AIProviderAPI } from "./ai_config.BnEV7HHL.js";
import { K as KnowledgeBaseAPI } from "./knowledge_base.CHSLq1jf.js";
import { _ as _export_sfc } from "./_plugin-vue_export-helper.1tPrXgE0.js";
import "./codemirror.CvJAcn2d.js";
const API_PATH = "/application/ai/model";
const AI_MODEL_TYPES = {
enterprise_naming: "企业起名",
enterprise_renaming: "企业改名",
enterprise_scoring: "企业测名",
enterprise_scoring_trial: "企业测名试用",
personal_naming: "个人起名",
personal_renaming: "个人改名",
personal_scoring: "个人测名",
personal_scoring_trial: "个人测名试用"
};
const AI_MODEL_TYPE_GROUPS = {
enterprise: {
label: "企业服务",
types: ["enterprise_naming", "enterprise_renaming", "enterprise_scoring", "enterprise_scoring_trial"]
},
personal: {
label: "个人服务",
types: ["personal_naming", "personal_renaming", "personal_scoring", "personal_scoring_trial"]
}
};
const AIModelConfigAPI = {
// 获取模型配置详情(如果不存在会自动创建默认配置)
detail(modelType) {
return httpRequest({
url: `${API_PATH}/detail/${modelType}`,
method: "get"
});
},
// 列表查询
list(query) {
return httpRequest({
url: `${API_PATH}/list`,
method: "get",
params: query
});
},
// 更新配置
update(modelType, body) {
return httpRequest({
url: `${API_PATH}/update/${modelType}`,
method: "put",
data: body
});
},
// 获取可用模型列表
getAvailableModels(providerId) {
return httpRequest({
url: `${API_PATH}/available-models/${providerId}`,
method: "get"
});
},
// 获取训练对话记录
getMessages(modelType) {
return httpRequest({
url: `${API_PATH}/messages/${modelType}`,
method: "get"
});
},
// 删除单条训练对话记录
deleteMessage(messageId) {
return httpRequest({
url: `${API_PATH}/message/${messageId}`,
method: "delete"
});
},
// 清空训练对话记录
clearMessages(modelType) {
return httpRequest({
url: `${API_PATH}/messages/${modelType}`,
method: "delete"
});
},
// 训练对话(流式输出)
async chat(data, signal) {
const baseURL = void 0;
const token = Auth.getAccessToken();
return fetch(`${baseURL}${API_PATH}/chat`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": token ? `Bearer ${token}` : ""
},
body: JSON.stringify(data),
signal
});
},
// 起名测试(非流式,一次性返回)
test(data) {
return httpRequest({
url: `${API_PATH}/test`,
method: "post",
data
});
}
};
const _hoisted_1 = { class: "ai-model-container" };
const _hoisted_2 = { class: "config-panel" };
const _hoisted_3 = { class: "model-type-selector" };
const _hoisted_4 = { class: "category-tabs" };
const _hoisted_5 = { class: "type-tabs" };
const _hoisted_6 = { class: "chat-panel" };
const _hoisted_7 = { class: "panel-header" };
const _hoisted_8 = { class: "header-actions" };
const _hoisted_9 = {
key: 0,
class: "welcome-screen"
};
const _hoisted_10 = { class: "welcome-content" };
const _hoisted_11 = {
key: 1,
class: "messages-list"
};
const _hoisted_12 = { class: "message-content" };
const _hoisted_13 = { class: "message-header" };
const _hoisted_14 = ["innerHTML"];
const _hoisted_15 = { class: "message-avatar" };
const _hoisted_16 = { class: "message-avatar" };
const _hoisted_17 = { class: "message-content" };
const _hoisted_18 = { class: "message-header" };
const _hoisted_19 = ["innerHTML"];
const _hoisted_20 = {
key: 0,
class: "message-item assistant"
};
const _hoisted_21 = { class: "message-avatar" };
const _hoisted_22 = { class: "message-content" };
const _hoisted_23 = { class: "message-body" };
const _hoisted_24 = ["innerHTML"];
const _hoisted_25 = {
key: 1,
class: "typing-indicator"
};
const _hoisted_26 = { class: "chat-input" };
const _hoisted_27 = { class: "input-wrapper" };
const _hoisted_28 = { class: "test-dialog-content" };
const _hoisted_29 = {
key: 0,
class: "test-result"
};
const _hoisted_30 = ["innerHTML"];
const _sfc_main = /* @__PURE__ */ defineComponent({
...{
name: "AIModel",
inheritAttrs: false
},
__name: "index",
setup(__props) {
const md = new MarkdownIt({
html: true,
linkify: true,
typographer: true,
breaks: true,
highlight(str, lang) {
if (lang && HighlightJS.getLanguage(lang)) {
try {
return `<pre class="hljs"><code>${HighlightJS.highlight(str, { language: lang, ignoreIllegals: true }).value}</code></pre>`;
} catch {
}
}
return `<pre class="hljs"><code>${md.utils.escapeHtml(str)}</code></pre>`;
}
});
const currentCategory = ref("enterprise");
const currentModelType = ref("enterprise_naming");
const currentGroupTypes = computed(() => {
return AI_MODEL_TYPE_GROUPS[currentCategory.value].types;
});
function getShortLabel(typeKey) {
const label = AI_MODEL_TYPES[typeKey];
return label.replace(/^企业|个人/, "");
}
function handleCategoryChange() {
const firstType = AI_MODEL_TYPE_GROUPS[currentCategory.value].types[0];
currentModelType.value = firstType;
handleModelTypeChange();
}
const configFormRef = ref();
const configForm = reactive({
provider_id: void 0,
model_name: void 0,
system_prompt: "",
temperature: 1,
knowledge_base_ids: []
});
const originalConfig = ref({});
const configLoading = ref(false);
const saveLoading = ref(false);
const messagesLoading = ref(false);
const providerList = ref([]);
const availableModels = ref([]);
const knowledgeBaseList = ref([]);
const messages = ref([]);
const inputMessage = ref("");
const currentResponse = ref("");
const isGenerating = ref(false);
const messagesContainer = ref();
const abortController = ref(null);
const showTestDialog = ref(false);
const testInput = ref("");
const testResult = ref("");
const testLoading = ref(false);
async function loadProviderList() {
try {
const res = await AIProviderAPI.list({ page_no: 1, page_size: 100 });
providerList.value = res.data.data.items;
} catch (error) {
console.error("加载供应商列表失败", error);
}
}
async function loadKnowledgeBaseList() {
try {
const res = await KnowledgeBaseAPI.list({ page_no: 1, page_size: 100, kb_status: 2 });
knowledgeBaseList.value = res.data.data.items;
} catch (error) {
console.error("加载知识库列表失败", error);
}
}
async function loadModelConfig() {
configLoading.value = true;
try {
const res = await AIModelConfigAPI.detail(currentModelType.value);
const data = res.data.data;
Object.assign(configForm, {
provider_id: data.provider_id,
model_name: data.model_name,
system_prompt: data.system_prompt || "",
temperature: data.temperature ?? 1,
knowledge_base_ids: data.knowledge_base_ids || []
});
originalConfig.value = { ...configForm };
if (data.provider_id) {
await loadAvailableModels(data.provider_id);
}
} catch (error) {
console.error("加载模型配置失败", error);
} finally {
configLoading.value = false;
}
}
async function loadAvailableModels(providerId) {
try {
console.log("[DEBUG] 加载模型列表供应商ID:", providerId);
const res = await AIModelConfigAPI.getAvailableModels(providerId);
console.log("[DEBUG] API 响应:", res.data);
availableModels.value = res.data.data || [];
console.log("[DEBUG] 更新后的模型列表:", availableModels.value);
} catch (error) {
console.error("加载可用模型列表失败", error);
availableModels.value = [];
}
}
async function loadMessages() {
messagesLoading.value = true;
try {
const res = await AIModelConfigAPI.getMessages(currentModelType.value);
messages.value = res.data.data;
scrollToBottom();
} catch (error) {
console.error("加载训练对话记录失败", error);
} finally {
messagesLoading.value = false;
}
}
async function handleProviderChange(providerId) {
console.log("[DEBUG] 供应商变化新ID:", providerId);
configForm.model_name = void 0;
availableModels.value = [];
if (providerId) {
await loadAvailableModels(providerId);
}
}
async function handleModelTypeChange() {
await Promise.all([loadModelConfig(), loadMessages()]);
}
async function handleSaveConfig() {
saveLoading.value = true;
try {
await AIModelConfigAPI.update(currentModelType.value, configForm);
originalConfig.value = { ...configForm };
ElMessage.success("配置保存成功");
} catch (error) {
console.error("保存配置失败", error);
ElMessage.error("保存配置失败");
} finally {
saveLoading.value = false;
}
}
function isConfigChanged() {
return JSON.stringify(configForm) !== JSON.stringify(originalConfig.value);
}
async function handleSendMessage() {
var _a;
const message = inputMessage.value.trim();
if (!message || isGenerating.value) return;
const configChanged = isConfigChanged();
inputMessage.value = "";
isGenerating.value = true;
currentResponse.value = "";
const tempUserMessageId = -Date.now();
const userMessage = {
id: tempUserMessageId,
model_config_id: 0,
role: "user",
content: message,
created_time: (/* @__PURE__ */ new Date()).toISOString(),
updated_time: (/* @__PURE__ */ new Date()).toISOString()
};
messages.value.push(userMessage);
scrollToBottom();
try {
const chatData = {
model_type: currentModelType.value,
message,
config_changed: configChanged,
config_data: configChanged ? configForm : void 0
};
abortController.value = new AbortController();
const response = await AIModelConfigAPI.chat(chatData, abortController.value.signal);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const reader = (_a = response.body) == null ? void 0 : _a.getReader();
if (!reader) {
throw new Error("无法获取响应流");
}
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
currentResponse.value += chunk;
scrollToBottom();
}
if (configChanged) {
originalConfig.value = { ...configForm };
}
if (currentResponse.value) {
const assistantMessage = {
id: -Date.now() - 1,
model_config_id: 0,
role: "assistant",
content: currentResponse.value,
created_time: (/* @__PURE__ */ new Date()).toISOString(),
updated_time: (/* @__PURE__ */ new Date()).toISOString()
};
messages.value.push(assistantMessage);
}
} catch (error) {
if (error.name === "AbortError") {
console.log("用户中断了生成");
if (currentResponse.value) {
const assistantMessage = {
id: -Date.now() - 1,
model_config_id: 0,
role: "assistant",
content: currentResponse.value + "\n\n*[已停止生成]*",
created_time: (/* @__PURE__ */ new Date()).toISOString(),
updated_time: (/* @__PURE__ */ new Date()).toISOString()
};
messages.value.push(assistantMessage);
}
} else {
console.error("发送消息失败", error);
const errorMessage = {
id: -Date.now() - 1,
model_config_id: 0,
role: "assistant",
content: "发送消息失败,请检查配置和网络连接",
created_time: (/* @__PURE__ */ new Date()).toISOString(),
updated_time: (/* @__PURE__ */ new Date()).toISOString()
};
messages.value.push(errorMessage);
}
} finally {
currentResponse.value = "";
isGenerating.value = false;
abortController.value = null;
scrollToBottom();
}
}
function handleStopGenerate() {
if (abortController.value) {
abortController.value.abort();
}
}
async function handleTest() {
const text = testInput.value.trim();
if (!text || testLoading.value) return;
testLoading.value = true;
testResult.value = "";
try {
const res = await AIModelConfigAPI.test({
model_type: currentModelType.value,
text
});
testResult.value = res.data.data;
} catch (error) {
console.error("起名测试失败", error);
ElMessage.error("测试失败,请检查配置和网络连接");
} finally {
testLoading.value = false;
}
}
function handleTestDialogClosed() {
testInput.value = "";
testResult.value = "";
}
async function handleDeleteMessage(messageId) {
try {
await ElMessageBox.confirm("确定删除这条对话记录吗?", "提示", {
type: "warning"
});
await AIModelConfigAPI.deleteMessage(messageId);
messages.value = messages.value.filter((m) => m.id !== messageId);
ElMessage.success("删除成功");
} catch (error) {
if (error !== "cancel") {
console.error("删除消息失败", error);
}
}
}
async function handleClearMessages() {
try {
await ElMessageBox.confirm("确定清空所有对话记录吗?此操作不可恢复。", "提示", {
type: "warning"
});
await AIModelConfigAPI.clearMessages(currentModelType.value);
messages.value = [];
ElMessage.success("对话已清空");
} catch (error) {
if (error !== "cancel") {
console.error("清空对话失败", error);
}
}
}
function processThinkTags(content) {
if (!content) return "";
const thinkRegex = /<think>([\s\S]*?)<\/think>/g;
return content.replace(thinkRegex, (_, thinkContent) => {
const escapedContent = md.render(thinkContent.trim());
return `<details class="think-block"><summary><span class="think-icon">💭</span> 思考过程</summary><div class="think-content">${escapedContent}</div></details>`;
});
}
function formatMessage(content) {
if (!content) return "";
const processedContent = processThinkTags(content);
if (processedContent !== content) {
const parts = content.split(/<think>[\s\S]*?<\/think>/g);
const thinkMatches = content.match(/<think>[\s\S]*?<\/think>/g) || [];
let result = "";
for (let i = 0; i < parts.length; i++) {
result += md.render(parts[i]);
if (thinkMatches[i]) {
const thinkContent = thinkMatches[i].replace(/<\/?think>/g, "").trim();
result += `<details class="think-block"><summary><span class="think-icon">💭</span> 思考过程</summary><div class="think-content">${md.render(thinkContent)}</div></details>`;
}
}
return result;
}
return md.render(content);
}
function scrollToBottom() {
nextTick(() => {
if (messagesContainer.value) {
messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
}
});
}
onMounted(async () => {
await Promise.all([loadProviderList(), loadKnowledgeBaseList()]);
await Promise.all([loadModelConfig(), loadMessages()]);
});
return (_ctx, _cache) => {
const _component_el_radio_button = ElRadioButton;
const _component_el_radio_group = ElRadioGroup;
const _component_el_option = ElOption;
const _component_el_select = ElSelect;
const _component_el_form_item = ElFormItem;
const _component_el_input = ElInput;
const _component_el_slider = ElSlider;
const _component_el_button = ElButton;
const _component_el_form = ElForm;
const _component_el_icon = ElIcon;
const _component_el_dialog = ElDialog;
const _directive_loading = vLoading;
return openBlock(), createElementBlock("div", _hoisted_1, [
createBaseVNode("div", _hoisted_2, [
_cache[13] || (_cache[13] = createBaseVNode("div", { class: "panel-header" }, [
createBaseVNode("h3", null, "模型配置")
], -1)),
createBaseVNode("div", _hoisted_3, [
createBaseVNode("div", _hoisted_4, [
createVNode(_component_el_radio_group, {
modelValue: currentCategory.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => currentCategory.value = $event),
onChange: handleCategoryChange
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(AI_MODEL_TYPE_GROUPS), (group, key) => {
return openBlock(), createBlock(_component_el_radio_button, {
key,
value: key
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(group.label), 1)
]),
_: 2
}, 1032, ["value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue"])
]),
createBaseVNode("div", _hoisted_5, [
createVNode(_component_el_radio_group, {
modelValue: currentModelType.value,
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => currentModelType.value = $event),
onChange: handleModelTypeChange
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(currentGroupTypes), (typeKey) => {
return openBlock(), createBlock(_component_el_radio_button, {
key: typeKey,
value: typeKey
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(getShortLabel(typeKey)), 1)
]),
_: 2
}, 1032, ["value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue"])
])
]),
withDirectives((openBlock(), createBlock(_component_el_form, {
ref_key: "configFormRef",
ref: configFormRef,
model: configForm,
"label-position": "top",
class: "config-form"
}, {
default: withCtx(() => [
createVNode(_component_el_form_item, { label: "AI供应商" }, {
default: withCtx(() => [
createVNode(_component_el_select, {
modelValue: configForm.provider_id,
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => configForm.provider_id = $event),
placeholder: "请选择AI供应商",
style: { "width": "100%" },
onChange: handleProviderChange
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(providerList.value, (provider) => {
return openBlock(), createBlock(_component_el_option, {
key: provider.id,
label: provider.name,
value: provider.id || ""
}, null, 8, ["label", "value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, { label: "模型" }, {
default: withCtx(() => [
createVNode(_component_el_select, {
modelValue: configForm.model_name,
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => configForm.model_name = $event),
placeholder: "请选择或输入模型名称",
style: { "width": "100%" },
disabled: !configForm.provider_id,
filterable: "",
"allow-create": "",
"default-first-option": ""
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(availableModels.value, (model) => {
return openBlock(), createBlock(_component_el_option, {
key: model.id,
label: model.name,
value: model.id
}, null, 8, ["label", "value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue", "disabled"])
]),
_: 1
}),
createVNode(_component_el_form_item, { label: "系统提示词" }, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: configForm.system_prompt,
"onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => configForm.system_prompt = $event),
type: "textarea",
rows: 6,
placeholder: "请输入系统提示词"
}, null, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, { label: "模型温度" }, {
default: withCtx(() => [
createVNode(_component_el_slider, {
modelValue: configForm.temperature,
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => configForm.temperature = $event),
min: 0,
max: 2,
step: 0.1,
"show-input": "",
"show-input-controls": false,
"input-size": "small"
}, null, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, { label: "关联知识库" }, {
default: withCtx(() => [
createVNode(_component_el_select, {
modelValue: configForm.knowledge_base_ids,
"onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => configForm.knowledge_base_ids = $event),
multiple: "",
placeholder: "请选择关联的知识库",
style: { "width": "100%" }
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(knowledgeBaseList.value, (kb) => {
return openBlock(), createBlock(_component_el_option, {
key: kb.id,
label: kb.name,
value: kb.id || ""
}, null, 8, ["label", "value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, null, {
default: withCtx(() => [
createVNode(_component_el_button, {
type: "primary",
loading: saveLoading.value,
onClick: handleSaveConfig,
style: { "width": "100%" }
}, {
default: withCtx(() => [..._cache[12] || (_cache[12] = [
createTextVNode(" 保存配置 ", -1)
])]),
_: 1
}, 8, ["loading"])
]),
_: 1
})
]),
_: 1
}, 8, ["model"])), [
[_directive_loading, configLoading.value]
])
]),
createBaseVNode("div", _hoisted_6, [
createBaseVNode("div", _hoisted_7, [
createBaseVNode("h3", null, "对话训练 - " + toDisplayString(unref(AI_MODEL_TYPES)[currentModelType.value]), 1),
createBaseVNode("div", _hoisted_8, [
createVNode(_component_el_button, {
text: "",
icon: unref(aim_default),
onClick: _cache[7] || (_cache[7] = ($event) => showTestDialog.value = true)
}, {
default: withCtx(() => [..._cache[14] || (_cache[14] = [
createTextVNode(" 起名测试 ", -1)
])]),
_: 1
}, 8, ["icon"]),
messages.value.length > 0 ? (openBlock(), createBlock(_component_el_button, {
key: 0,
text: "",
icon: unref(delete_default),
onClick: handleClearMessages
}, {
default: withCtx(() => [..._cache[15] || (_cache[15] = [
createTextVNode(" 清空对话 ", -1)
])]),
_: 1
}, 8, ["icon"])) : createCommentVNode("", true)
])
]),
createBaseVNode("div", {
ref_key: "messagesContainer",
ref: messagesContainer,
class: "chat-messages"
}, [
messages.value.length === 0 && !messagesLoading.value ? (openBlock(), createElementBlock("div", _hoisted_9, [
createBaseVNode("div", _hoisted_10, [
createVNode(_component_el_icon, { size: "48" }, {
default: withCtx(() => [
createVNode(unref(chat_dot_round_default))
]),
_: 1
}),
createBaseVNode("h2", null, toDisplayString(unref(AI_MODEL_TYPES)[currentModelType.value]) + "训练", 1),
_cache[16] || (_cache[16] = createBaseVNode("p", null, "通过与AI对话来训练和优化模型效果", -1))
])
])) : withDirectives((openBlock(), createElementBlock("div", _hoisted_11, [
(openBlock(true), createElementBlock(Fragment, null, renderList(messages.value, (message) => {
return openBlock(), createElementBlock("div", {
key: message.id,
class: normalizeClass(["message-item", message.role])
}, [
message.role === "user" ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
createBaseVNode("div", _hoisted_12, [
createBaseVNode("div", _hoisted_13, [
createVNode(_component_el_button, {
text: "",
size: "small",
icon: unref(delete_default),
class: "delete-btn",
onClick: ($event) => handleDeleteMessage(message.id)
}, null, 8, ["icon", "onClick"]),
_cache[17] || (_cache[17] = createBaseVNode("span", { class: "sender-name" }, "用户", -1))
]),
createBaseVNode("div", {
class: "message-body",
innerHTML: formatMessage(message.content)
}, null, 8, _hoisted_14)
]),
createBaseVNode("div", _hoisted_15, [
createVNode(_component_el_icon, null, {
default: withCtx(() => [
createVNode(unref(user_default))
]),
_: 1
})
])
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
createBaseVNode("div", _hoisted_16, [
createVNode(_component_el_icon, null, {
default: withCtx(() => [
createVNode(unref(chat_dot_round_default))
]),
_: 1
})
]),
createBaseVNode("div", _hoisted_17, [
createBaseVNode("div", _hoisted_18, [
_cache[18] || (_cache[18] = createBaseVNode("span", { class: "sender-name" }, "AI", -1)),
createVNode(_component_el_button, {
text: "",
size: "small",
icon: unref(delete_default),
class: "delete-btn",
onClick: ($event) => handleDeleteMessage(message.id)
}, null, 8, ["icon", "onClick"])
]),
createBaseVNode("div", {
class: "message-body",
innerHTML: formatMessage(message.content)
}, null, 8, _hoisted_19)
])
], 64))
], 2);
}), 128)),
isGenerating.value ? (openBlock(), createElementBlock("div", _hoisted_20, [
createBaseVNode("div", _hoisted_21, [
createVNode(_component_el_icon, null, {
default: withCtx(() => [
createVNode(unref(chat_dot_round_default))
]),
_: 1
})
]),
createBaseVNode("div", _hoisted_22, [
_cache[20] || (_cache[20] = createBaseVNode("div", { class: "message-header" }, [
createBaseVNode("span", { class: "sender-name" }, "AI")
], -1)),
createBaseVNode("div", _hoisted_23, [
currentResponse.value ? (openBlock(), createElementBlock("span", {
key: 0,
innerHTML: formatMessage(currentResponse.value)
}, null, 8, _hoisted_24)) : (openBlock(), createElementBlock("span", _hoisted_25, [..._cache[19] || (_cache[19] = [
createBaseVNode("span", null, null, -1),
createBaseVNode("span", null, null, -1),
createBaseVNode("span", null, null, -1)
])]))
])
])
])) : createCommentVNode("", true)
])), [
[_directive_loading, messagesLoading.value]
])
], 512),
createBaseVNode("div", _hoisted_26, [
createBaseVNode("div", _hoisted_27, [
createVNode(_component_el_input, {
modelValue: inputMessage.value,
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => inputMessage.value = $event),
type: "textarea",
rows: 1,
autosize: { minRows: 1, maxRows: 4 },
placeholder: "输入消息进行训练...",
disabled: isGenerating.value,
onKeydown: withKeys(withModifiers(handleSendMessage, ["exact", "prevent"]), ["enter"])
}, null, 8, ["modelValue", "disabled", "onKeydown"]),
!isGenerating.value ? (openBlock(), createBlock(_component_el_button, {
key: 0,
type: "primary",
icon: unref(promotion_default),
disabled: !inputMessage.value.trim(),
circle: "",
onClick: handleSendMessage
}, null, 8, ["icon", "disabled"])) : (openBlock(), createBlock(_component_el_button, {
key: 1,
type: "danger",
icon: unref(video_pause_default),
circle: "",
onClick: handleStopGenerate
}, null, 8, ["icon"]))
]),
_cache[21] || (_cache[21] = createBaseVNode("div", { class: "input-hint" }, " 按 Enter 发送消息Shift + Enter 换行 ", -1))
])
]),
createVNode(_component_el_dialog, {
modelValue: showTestDialog.value,
"onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => showTestDialog.value = $event),
title: "起名测试",
width: "600px",
"close-on-click-modal": false,
onClosed: handleTestDialogClosed
}, {
footer: withCtx(() => [
createVNode(_component_el_button, {
onClick: _cache[10] || (_cache[10] = ($event) => showTestDialog.value = false)
}, {
default: withCtx(() => [..._cache[23] || (_cache[23] = [
createTextVNode("关闭", -1)
])]),
_: 1
}),
createVNode(_component_el_button, {
type: "primary",
loading: testLoading.value,
disabled: !testInput.value.trim(),
onClick: handleTest
}, {
default: withCtx(() => [..._cache[24] || (_cache[24] = [
createTextVNode(" 提交测试 ", -1)
])]),
_: 1
}, 8, ["loading", "disabled"])
]),
default: withCtx(() => [
createBaseVNode("div", _hoisted_28, [
createVNode(_component_el_form, { "label-position": "top" }, {
default: withCtx(() => [
createVNode(_component_el_form_item, { label: "测试内容" }, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: testInput.value,
"onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => testInput.value = $event),
type: "textarea",
rows: 4,
placeholder: "请输入要测试的内容...",
disabled: testLoading.value
}, null, 8, ["modelValue", "disabled"])
]),
_: 1
})
]),
_: 1
}),
testResult.value ? (openBlock(), createElementBlock("div", _hoisted_29, [
_cache[22] || (_cache[22] = createBaseVNode("div", { class: "result-header" }, [
createBaseVNode("span", null, "测试结果")
], -1)),
createBaseVNode("div", {
class: "result-content",
innerHTML: formatMessage(testResult.value)
}, null, 8, _hoisted_30)
])) : createCommentVNode("", true)
])
]),
_: 1
}, 8, ["modelValue"])
]);
};
}
});
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-b7d6e58d"]]);
export {
index as default
};