upload project source code

This commit is contained in:
2026-04-30 18:49:43 +08:00
commit 9b394ba682
2277 changed files with 660945 additions and 0 deletions

View File

@@ -0,0 +1,904 @@
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
};