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

600 lines
25 KiB
JavaScript
Raw Permalink 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 { h as ElButton, aj as refresh_default, ak as plus_default, aa as delete_default, al as ElTable, am as ElTableColumn, q as ElTag, r as ElText, ay as view_default, ao as vLoading, ap as ElPagination, T as ElCard, w as ElForm, x as ElFormItem, y as ElInput, aq as ElSelect, ar as ElOption, a1 as ElUpload, az as upload_default, v as ElDialog, a3 as ElDescriptions, a4 as ElDescriptionsItem, E as ElMessage, D as ElMessageBox } from "./element-plus.CkEW9frc.js";
import { a as KB_STATUS_MAP, K as KnowledgeBaseAPI } from "./knowledge_base.CHSLq1jf.js";
import { E as EmbeddingConfigAPI } from "./ai_config.BnEV7HHL.js";
import { J as defineComponent, t as onMounted, S as openBlock, _ as createElementBlock, $ as createVNode, a0 as withCtx, a1 as createBaseVNode, o as unref, a9 as createTextVNode, a6 as withDirectives, T as createBlock, aa as toDisplayString, a8 as createCommentVNode, H as Fragment, ay as renderList, r as ref, ak as reactive } from "./.pnpm.BW3P1y8f.js";
import { _ as _export_sfc } from "./_plugin-vue_export-helper.1tPrXgE0.js";
import "./index.CMd5bD1r.js";
import "./codemirror.CvJAcn2d.js";
const _hoisted_1 = { class: "app-container" };
const _hoisted_2 = { class: "table-toolbar" };
const _hoisted_3 = {
key: 0,
class: "embedding-info"
};
const _hoisted_4 = { class: "config-name" };
const _sfc_main = /* @__PURE__ */ defineComponent({
...{
name: "KnowledgeBase",
inheritAttrs: false
},
__name: "index",
setup(__props) {
const loading = ref(false);
const tableData = ref([]);
const total = ref(0);
const selection = ref([]);
const queryParams = reactive({
page_no: 1,
page_size: 10,
name: void 0,
kb_status: void 0
});
const embeddingOptions = ref([]);
const uploadRef = ref();
const fileList = ref([]);
async function loadData() {
loading.value = true;
try {
const res = await KnowledgeBaseAPI.list(queryParams);
tableData.value = res.data.data.items;
total.value = res.data.data.total;
} finally {
loading.value = false;
}
}
async function loadEmbeddingOptions() {
try {
const res = await EmbeddingConfigAPI.list({ page_no: 1, page_size: 100 });
embeddingOptions.value = res.data.data.items;
} catch (error) {
console.error("加载向量化配置失败", error);
}
}
function handleSelectionChange(rows) {
selection.value = rows;
}
function getStatusType(status) {
var _a;
return ((_a = KB_STATUS_MAP[status]) == null ? void 0 : _a.type) || "info";
}
const dialogVisible = ref(false);
const dialogTitle = ref("新增知识库");
const formRef = ref();
const formData = reactive({
id: void 0,
name: void 0,
embedding_config_id: void 0,
description: void 0
});
const formRules = {
name: [{ required: true, message: "请输入知识库名称", trigger: "blur" }]
};
function handleAdd() {
dialogTitle.value = "新增知识库";
const defaultEmbedding = embeddingOptions.value.find((item) => item.is_default === 1);
Object.assign(formData, {
id: void 0,
name: void 0,
embedding_config_id: defaultEmbedding == null ? void 0 : defaultEmbedding.id,
description: void 0
});
fileList.value = [];
dialogVisible.value = true;
}
async function handleSubmit() {
var _a;
await ((_a = formRef.value) == null ? void 0 : _a.validate());
const files = fileList.value.map((f) => f.raw).filter(Boolean);
await KnowledgeBaseAPI.create(formData, files);
ElMessage.success("创建成功");
dialogVisible.value = false;
loadData();
}
function handleExceed() {
ElMessage.warning("最多只能上传10个文件");
}
async function handleDelete(row) {
await ElMessageBox.confirm("确定删除该知识库吗?删除后相关向量数据也将被删除。", "警告", { type: "warning" });
await KnowledgeBaseAPI.delete([row.id]);
ElMessage.success("删除成功");
loadData();
}
async function handleBatchDelete() {
await ElMessageBox.confirm(`确定删除选中的${selection.value.length}个知识库吗?`, "警告", { type: "warning" });
const ids = selection.value.map((item) => item.id);
await KnowledgeBaseAPI.delete(ids);
ElMessage.success("删除成功");
loadData();
}
const detailVisible = ref(false);
const detailData = ref({});
async function handleDetail(row) {
try {
const res = await KnowledgeBaseAPI.detail(row.id);
detailData.value = res.data.data;
detailVisible.value = true;
} catch (error) {
console.error("获取详情失败", error);
}
}
async function handleRetry(row) {
await ElMessageBox.confirm("确定重新向量化该知识库吗?", "提示", { type: "info" });
await KnowledgeBaseAPI.retry(row.id);
ElMessage.success("已启动重新向量化");
loadData();
}
onMounted(() => {
loadData();
loadEmbeddingOptions();
});
return (_ctx, _cache) => {
const _component_el_button = ElButton;
const _component_el_table_column = ElTableColumn;
const _component_el_tag = ElTag;
const _component_el_text = ElText;
const _component_el_table = ElTable;
const _component_el_pagination = ElPagination;
const _component_el_card = ElCard;
const _component_el_input = ElInput;
const _component_el_form_item = ElFormItem;
const _component_el_option = ElOption;
const _component_el_select = ElSelect;
const _component_el_upload = ElUpload;
const _component_el_form = ElForm;
const _component_el_dialog = ElDialog;
const _component_el_descriptions_item = ElDescriptionsItem;
const _component_el_descriptions = ElDescriptions;
const _directive_loading = vLoading;
return openBlock(), createElementBlock("div", _hoisted_1, [
createVNode(_component_el_card, null, {
header: withCtx(() => [..._cache[9] || (_cache[9] = [
createBaseVNode("div", { class: "card-header" }, [
createBaseVNode("span", null, "知识库管理")
], -1)
])]),
default: withCtx(() => [
createBaseVNode("div", _hoisted_2, [
createVNode(_component_el_button, {
icon: unref(refresh_default),
onClick: loadData
}, {
default: withCtx(() => [..._cache[10] || (_cache[10] = [
createTextVNode("刷新", -1)
])]),
_: 1
}, 8, ["icon"]),
createVNode(_component_el_button, {
type: "primary",
icon: unref(plus_default),
onClick: handleAdd
}, {
default: withCtx(() => [..._cache[11] || (_cache[11] = [
createTextVNode("新增知识库", -1)
])]),
_: 1
}, 8, ["icon"]),
createVNode(_component_el_button, {
type: "danger",
icon: unref(delete_default),
disabled: selection.value.length === 0,
onClick: handleBatchDelete
}, {
default: withCtx(() => [..._cache[12] || (_cache[12] = [
createTextVNode("批量删除", -1)
])]),
_: 1
}, 8, ["icon", "disabled"])
]),
withDirectives((openBlock(), createBlock(_component_el_table, {
data: tableData.value,
onSelectionChange: handleSelectionChange
}, {
default: withCtx(() => [
createVNode(_component_el_table_column, {
type: "selection",
width: "50"
}),
createVNode(_component_el_table_column, {
prop: "name",
label: "知识库名称",
"min-width": "150"
}),
createVNode(_component_el_table_column, {
label: "向量化配置",
"min-width": "200"
}, {
default: withCtx(({ row }) => [
row.embedding_config ? (openBlock(), createElementBlock("div", _hoisted_3, [
createVNode(_component_el_tag, {
size: "small",
type: row.embedding_config.embedding_type === 0 ? "primary" : "success"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(row.embedding_config.embedding_type === 0 ? "本地" : "远程"), 1)
]),
_: 2
}, 1032, ["type"]),
createBaseVNode("span", _hoisted_4, toDisplayString(row.embedding_config.name), 1)
])) : (openBlock(), createBlock(_component_el_text, {
key: 1,
type: "info"
}, {
default: withCtx(() => [..._cache[13] || (_cache[13] = [
createTextVNode("未配置", -1)
])]),
_: 1
}))
]),
_: 1
}),
createVNode(_component_el_table_column, {
prop: "collection_name",
label: "集合名称",
"min-width": "180",
"show-overflow-tooltip": ""
}),
createVNode(_component_el_table_column, {
prop: "document_count",
label: "文档数",
width: "100",
align: "center"
}),
createVNode(_component_el_table_column, {
prop: "vector_count",
label: "向量数",
width: "100",
align: "center"
}),
createVNode(_component_el_table_column, {
prop: "kb_status",
label: "状态",
width: "100",
align: "center"
}, {
default: withCtx(({ row }) => [
createVNode(_component_el_tag, {
type: getStatusType(row.kb_status)
}, {
default: withCtx(() => {
var _a;
return [
createTextVNode(toDisplayString(((_a = unref(KB_STATUS_MAP)[row.kb_status]) == null ? void 0 : _a.label) || "未知"), 1)
];
}),
_: 2
}, 1032, ["type"])
]),
_: 1
}),
createVNode(_component_el_table_column, {
prop: "description",
label: "备注",
"min-width": "150",
"show-overflow-tooltip": ""
}),
createVNode(_component_el_table_column, {
prop: "created_time",
label: "创建时间",
width: "170"
}),
createVNode(_component_el_table_column, {
label: "操作",
width: "180",
fixed: "right"
}, {
default: withCtx(({ row }) => [
row.kb_status === 3 ? (openBlock(), createBlock(_component_el_button, {
key: 0,
type: "warning",
link: "",
icon: unref(refresh_default),
onClick: ($event) => handleRetry(row)
}, {
default: withCtx(() => [..._cache[14] || (_cache[14] = [
createTextVNode("重试", -1)
])]),
_: 1
}, 8, ["icon", "onClick"])) : createCommentVNode("", true),
createVNode(_component_el_button, {
type: "primary",
link: "",
icon: unref(view_default),
onClick: ($event) => handleDetail(row)
}, {
default: withCtx(() => [..._cache[15] || (_cache[15] = [
createTextVNode("详情", -1)
])]),
_: 1
}, 8, ["icon", "onClick"]),
createVNode(_component_el_button, {
type: "danger",
link: "",
icon: unref(delete_default),
onClick: ($event) => handleDelete(row)
}, {
default: withCtx(() => [..._cache[16] || (_cache[16] = [
createTextVNode("删除", -1)
])]),
_: 1
}, 8, ["icon", "onClick"])
]),
_: 1
})
]),
_: 1
}, 8, ["data"])), [
[_directive_loading, loading.value]
]),
createVNode(_component_el_pagination, {
"current-page": queryParams.page_no,
"onUpdate:currentPage": _cache[0] || (_cache[0] = ($event) => queryParams.page_no = $event),
"page-size": queryParams.page_size,
"onUpdate:pageSize": _cache[1] || (_cache[1] = ($event) => queryParams.page_size = $event),
total: total.value,
"page-sizes": [10, 20, 50, 100],
layout: "total, sizes, prev, pager, next, jumper",
onSizeChange: loadData,
onCurrentChange: loadData
}, null, 8, ["current-page", "page-size", "total"])
]),
_: 1
}),
createVNode(_component_el_dialog, {
modelValue: dialogVisible.value,
"onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => dialogVisible.value = $event),
title: dialogTitle.value,
width: "600px",
"destroy-on-close": ""
}, {
footer: withCtx(() => [
createVNode(_component_el_button, {
onClick: _cache[6] || (_cache[6] = ($event) => dialogVisible.value = false)
}, {
default: withCtx(() => [..._cache[19] || (_cache[19] = [
createTextVNode("取消", -1)
])]),
_: 1
}),
createVNode(_component_el_button, {
type: "primary",
onClick: handleSubmit
}, {
default: withCtx(() => [..._cache[20] || (_cache[20] = [
createTextVNode("确定", -1)
])]),
_: 1
})
]),
default: withCtx(() => [
createVNode(_component_el_form, {
ref_key: "formRef",
ref: formRef,
model: formData,
rules: formRules,
"label-width": "100px"
}, {
default: withCtx(() => [
createVNode(_component_el_form_item, {
label: "知识库名称",
prop: "name"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: formData.name,
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => formData.name = $event),
placeholder: "请输入知识库名称"
}, null, 8, ["modelValue"])
]),
_: 1
}),
createVNode(_component_el_form_item, {
label: "向量化配置",
prop: "embedding_config_id"
}, {
default: withCtx(() => [
createVNode(_component_el_select, {
modelValue: formData.embedding_config_id,
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => formData.embedding_config_id = $event),
placeholder: "请选择向量化配置",
style: { "width": "100%" },
clearable: ""
}, {
default: withCtx(() => [
(openBlock(true), createElementBlock(Fragment, null, renderList(embeddingOptions.value, (item) => {
return openBlock(), createBlock(_component_el_option, {
key: item.id,
label: `${item.name} (${item.embedding_type === 0 ? "本地" : "远程"} - ${item.model_name})`,
value: item.id
}, null, 8, ["label", "value"]);
}), 128))
]),
_: 1
}, 8, ["modelValue"])
]),
_: 1
}),
!formData.id ? (openBlock(), createBlock(_component_el_form_item, {
key: 0,
label: "上传文件",
prop: "files"
}, {
default: withCtx(() => [
createVNode(_component_el_upload, {
ref_key: "uploadRef",
ref: uploadRef,
"file-list": fileList.value,
"onUpdate:fileList": _cache[4] || (_cache[4] = ($event) => fileList.value = $event),
"auto-upload": false,
limit: 10,
multiple: "",
accept: ".txt,.pdf,.doc,.docx,.md",
"on-exceed": handleExceed
}, {
tip: withCtx(() => [..._cache[18] || (_cache[18] = [
createBaseVNode("div", { class: "el-upload__tip" }, "支持 txt、pdf、doc、docx、md 格式最多上传10个文件", -1)
])]),
default: withCtx(() => [
createVNode(_component_el_button, {
type: "primary",
icon: unref(upload_default)
}, {
default: withCtx(() => [..._cache[17] || (_cache[17] = [
createTextVNode("选择文件", -1)
])]),
_: 1
}, 8, ["icon"])
]),
_: 1
}, 8, ["file-list"])
]),
_: 1
})) : createCommentVNode("", true),
createVNode(_component_el_form_item, {
label: "备注",
prop: "description"
}, {
default: withCtx(() => [
createVNode(_component_el_input, {
modelValue: formData.description,
"onUpdate:modelValue": _cache[5] || (_cache[5] = ($event) => formData.description = $event),
type: "textarea",
rows: 3,
placeholder: "请输入备注"
}, null, 8, ["modelValue"])
]),
_: 1
})
]),
_: 1
}, 8, ["model"])
]),
_: 1
}, 8, ["modelValue", "title"]),
createVNode(_component_el_dialog, {
modelValue: detailVisible.value,
"onUpdate:modelValue": _cache[8] || (_cache[8] = ($event) => detailVisible.value = $event),
title: "知识库详情",
width: "700px"
}, {
default: withCtx(() => [
createVNode(_component_el_descriptions, {
column: 2,
border: ""
}, {
default: withCtx(() => [
createVNode(_component_el_descriptions_item, { label: "知识库名称" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.name), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, { label: "状态" }, {
default: withCtx(() => [
createVNode(_component_el_tag, {
type: getStatusType(detailData.value.kb_status)
}, {
default: withCtx(() => {
var _a;
return [
createTextVNode(toDisplayString(((_a = unref(KB_STATUS_MAP)[detailData.value.kb_status]) == null ? void 0 : _a.label) || "未知"), 1)
];
}),
_: 1
}, 8, ["type"])
]),
_: 1
}),
createVNode(_component_el_descriptions_item, {
label: "向量化配置",
span: 2
}, {
default: withCtx(() => [
detailData.value.embedding_config ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
createVNode(_component_el_tag, {
size: "small",
type: detailData.value.embedding_config.embedding_type === 0 ? "primary" : "success"
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.embedding_config.embedding_type === 0 ? "本地" : "远程"), 1)
]),
_: 1
}, 8, ["type"]),
createTextVNode(" " + toDisplayString(detailData.value.embedding_config.name) + " (" + toDisplayString(detailData.value.embedding_config.model_name) + ") ", 1)
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
createTextVNode("未配置")
], 64))
]),
_: 1
}),
createVNode(_component_el_descriptions_item, {
label: "ChromaDB集合名称",
span: 2
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.collection_name), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, { label: "文档数量" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.document_count), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, { label: "向量数量" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.vector_count), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, {
label: "备注",
span: 2
}, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.description || "-"), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, { label: "创建时间" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.created_time), 1)
]),
_: 1
}),
createVNode(_component_el_descriptions_item, { label: "更新时间" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.updated_time), 1)
]),
_: 1
}),
detailData.value.error_message ? (openBlock(), createBlock(_component_el_descriptions_item, {
key: 0,
label: "错误信息",
span: 2
}, {
default: withCtx(() => [
createVNode(_component_el_text, { type: "danger" }, {
default: withCtx(() => [
createTextVNode(toDisplayString(detailData.value.error_message), 1)
]),
_: 1
})
]),
_: 1
})) : createCommentVNode("", true)
]),
_: 1
})
]),
_: 1
}, 8, ["modelValue"])
]);
};
}
});
const index = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-c71b4110"]]);
export {
index as default
};