8 小时以前 16697df76d7b27ff65d229937b3f3ac4cc0e56a0
src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -244,6 +244,7 @@
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            :before-upload="beforeUpload"
            name="files"
            multiple
            :show-file-list="false"
            accept=".txt,.md,.docx,.xlsx,.xls,.pdf"
@@ -379,7 +380,7 @@
  getVectorStatus,
  reprocessVector,
  saveKnowledgeBaseFiles,
  deleteKnowledgeBaseFiles,
  deleteKnowledgeBaseFile,
  knowledgeChat
} from "@/api/collaborativeApproval/knowledgeBase.js";
import useUserStore from '@/store/modules/user';
@@ -624,21 +625,31 @@
const getList = () => {
  tableLoading.value = true;
  listKnowledgeBase({...page.value, ...searchForm.value})
  // ✅ GET请求使用params传参
  listKnowledgeBase({
    current: page.value.current,
    size: page.value.size,
    title: searchForm.value.title,
    type: searchForm.value.type
  })
  .then(res => {
    tableLoading.value = false;
    page.value.total = res.data.total;
    // 如果当前页数超过总页数,重置到第1页并重新查询
    // 如果当前页数超过总页数,重置到第1页并重新查询
    const maxPage = Math.ceil(res.data.total / page.value.size) || 1;
    if (page.value.current > maxPage && maxPage > 0) {
      page.value.current = 1;
      // 重新查询第1页数据
      return getList();
    }
    tableData.value = res.data.records;
  }).catch(err => {
    tableLoading.value = false;
  })
  .catch(err => {
    tableLoading.value = false;
    console.error("查询知识库列表失败:", err);
  });
};
// 分页处理
@@ -813,27 +824,47 @@
const submitForm = async () => {
  try {
    await formRef.value.validate();
    // ✅ POST请求使用data传参,明确参数结构
    const formData = {
      title: form.value.title,
      type: form.value.type,
      scenario: form.value.scenario || "",
      efficiency: form.value.efficiency || "",
      problem: form.value.problem,
      solution: form.value.solution,
      keyPoints: form.value.keyPoints || "",
      creator: form.value.creator || "",
      usageCount: form.value.usageCount || 0
    };
    if (dialogType.value === "add") {
      // 新增知识
      addKnowledgeBase({...form.value}).then(res => {
      addKnowledgeBase(formData).then(res => {
        if(res.code == 200){
          ElMessage.success("添加成功");
          closeKnowledgeDialog();
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
        console.error("添加知识库失败:", err);
        ElMessage.error(err.msg || "添加失败");
      });
    } else {
      updateKnowledgeBase({...form.value}).then(res => {
      // 更新知识 - 添加id参数
      updateKnowledgeBase({
        id: form.value.id,
        ...formData
      }).then(res => {
        if(res.code == 200){
          ElMessage.success("更新成功");
          closeKnowledgeDialog();
          getList();
        }
      }).catch(err => {
        ElMessage.error(err.msg);
      })
        console.error("更新知识库失败:", err);
        ElMessage.error(err.msg || "更新失败");
      });
    }
  } catch (error) {
    console.error("表单验证失败:", error);
@@ -847,19 +878,22 @@
    return;
  }
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "删除", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    // console.log(selectedIds.value);
    // ✅ DELETE请求使用data传递ID数组
    delKnowledgeBase(selectedIds.value).then(res => {
      if(res.code == 200){
        ElMessage.success("删除成功");
        selectedIds.value = [];
        getList();
      }
    })
    }).catch(err => {
      console.error("删除知识库失败:", err);
      ElMessage.error(err.msg || "删除失败");
    });
  }).catch(() => {
    // 用户取消
  });
@@ -963,9 +997,24 @@
// 上传成功
const handleUploadSuccess = (response, file) => {
  console.log("上传响应:", response);  // 调试日志
  if (response.code === 200) {
    uploadedBlobIds.value.push(response.data.id);
    // ✅ 后端返回的是 List<StorageBlobVO>,所以data是数组
    if (Array.isArray(response.data) && response.data.length > 0) {
      // 取数组第一个元素的id
      const blobId = response.data[0].id;
      if (blobId) {
        uploadedBlobIds.value.push(blobId);
    ElMessage.success(`文件 ${file.name} 上传成功`);
      } else {
        console.error("上传响应中未找到id:", response.data[0]);
        ElMessage.error("上传失败: 未获取到文件ID");
      }
    } else {
      console.error("上传响应格式错误:", response);
      ElMessage.error("上传失败: 响应格式错误");
    }
  } else {
    ElMessage.error(response.msg || "上传失败");
  }
@@ -978,22 +1027,30 @@
// 保存文件关联
const saveFiles = async () => {
  // 参数校验
  if (!currentKnowledgeBase.value?.id) {
    ElMessage.error("知识库信息异常");
    return;
  }
  if (uploadedBlobIds.value.length === 0) {
    ElMessage.warning("请先上传文件");
    return;
  }
  savingFiles.value = true;
  try {
    // ✅ POST请求使用data传参,明确参数结构
    await saveKnowledgeBaseFiles({
      knowledgeBaseId: currentKnowledgeBase.value.id,
      storageBlobIds: uploadedBlobIds.value
      knowledgeBaseId: currentKnowledgeBase.value.id,  // 知识库ID
      storageBlobIds: uploadedBlobIds.value             // 文件blob ID数组
    });
    ElMessage.success("文件关联保存成功,正在后台处理向量化");
    ElMessage.success("文件关联保存成功,正在后台处理向量化");
    uploadedBlobIds.value = [];
    // 延迟刷新文件列表,给后台处理时间
    // 延迟刷新文件列表,给后台处理时间
    setTimeout(() => {
      loadFileList();
    }, 1000);
@@ -1030,7 +1087,7 @@
const deleteFile = async (row) => {
  try {
    await ElMessageBox.confirm(
      "确定要删除该文件吗?删除后将无法恢复向量数据",
      "确定要删除该文件吗?删除后将无法恢复向量数据",
      "删除确认",
      {
        confirmButtonText: "确定",
@@ -1039,7 +1096,8 @@
      }
    );
    await deleteKnowledgeBaseFiles([row.id]);
    // ✅ DELETE请求使用data传递ID数组
    await deleteKnowledgeBaseFile([row.id]);  // 注意: row.id是向量记录ID,不是storageBlobId
    ElMessage.success("删除成功");
    loadFileList();
  } catch (error) {
@@ -1095,6 +1153,7 @@
// 发送消息
const sendMessage = async () => {
  // 参数校验
  if (!inputQuestion.value.trim()) {
    ElMessage.warning("请输入问题");
    return;
@@ -1121,18 +1180,11 @@
  scrollToBottom();
  try {
    // 流式请求
    const response = await fetch('/api/ai/knowledge/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + getToken()
      },
      body: JSON.stringify({
        knowledgeBaseId: currentKnowledgeBase.value.id,
        memoryId: memoryId.value,
        question: question
      })
    // ✅ 流式请求使用Fetch API
    const response = await knowledgeChat({
      knowledgeBaseId: currentKnowledgeBase.value.id,  // 知识库ID
      memoryId: memoryId.value,                         // 会话ID
      question: question                                // 用户问题
    });
    if (!response.ok) {
@@ -1140,7 +1192,7 @@
      throw new Error(errorText || '请求失败');
    }
    // 处理SSE流式响应
    // ✅ 后端返回 text/stream;charset=utf-8
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let aiContent = '';
@@ -1151,7 +1203,7 @@
      const { done, value } = await reader.read();
      if (done) break;
      const text = decoder.decode(value);
      const text = decoder.decode(value, { stream: true });  // ✅ 添加stream选项
      aiContent += text;
      messages.value[messages.value.length - 1].content = aiContent;