2025-11-06 19:47:22 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<div class="knowledge-base-card">
|
|
|
|
|
|
<!-- 标题栏 -->
|
|
|
|
|
|
<div class="card-header">
|
|
|
|
|
|
<div class="header-left">
|
|
|
|
|
|
<a-button
|
|
|
|
|
|
@click="backToDatabase"
|
2025-12-10 19:42:58 +08:00
|
|
|
|
class="back-button"
|
2025-11-06 19:47:22 +08:00
|
|
|
|
shape="circle"
|
|
|
|
|
|
:icon="h(LeftOutlined)"
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
size="small"
|
|
|
|
|
|
></a-button>
|
|
|
|
|
|
<h3 class="card-title">{{ database.name || '数据库信息加载中' }}</h3>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="header-right">
|
2026-01-15 06:01:34 +08:00
|
|
|
|
<a-button type="text" size="small" @click="copyDatabaseId" title="复制知识库ID">
|
2025-12-24 13:17:12 +08:00
|
|
|
|
<template #icon>
|
|
|
|
|
|
<Copy :size="14" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</a-button>
|
2026-01-15 06:01:34 +08:00
|
|
|
|
<a-button @click="showEditModal" type="text" size="small">
|
2025-12-24 13:17:12 +08:00
|
|
|
|
<template #icon>
|
|
|
|
|
|
<Pencil :size="14" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</a-button>
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 卡片内容 -->
|
|
|
|
|
|
<div class="card-content">
|
|
|
|
|
|
<!-- 描述文本 -->
|
2025-12-10 19:42:58 +08:00
|
|
|
|
<div class="description">
|
|
|
|
|
|
<p class="description-text">{{ database.description || '暂无描述' }}</p>
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tags -->
|
|
|
|
|
|
<div class="tags-section">
|
2026-04-27 02:19:01 +08:00
|
|
|
|
<span class="card-tag" :class="'tag-' + getKbTypeColor(database.kb_type || 'lightrag')">
|
2025-11-06 19:47:22 +08:00
|
|
|
|
{{ getKbTypeLabel(database.kb_type || 'lightrag') }}
|
2026-04-27 02:19:01 +08:00
|
|
|
|
</span>
|
|
|
|
|
|
<span class="card-tag tag-blue">{{ database.embed_info?.name || 'N/A' }}</span>
|
|
|
|
|
|
<span class="card-tag tag-cyan">{{
|
2026-02-20 19:35:43 +08:00
|
|
|
|
chunkPresetLabelMap[database.additional_params?.chunk_preset_id || 'general'] || 'General'
|
2026-04-27 02:19:01 +08:00
|
|
|
|
}}</span>
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 编辑对话框 -->
|
|
|
|
|
|
<a-modal v-model:open="editModalVisible" title="编辑知识库信息">
|
|
|
|
|
|
<template #footer>
|
2026-01-15 06:01:34 +08:00
|
|
|
|
<a-button danger @click="deleteDatabase" style="margin-right: auto; margin-left: 0">
|
2025-12-24 13:17:12 +08:00
|
|
|
|
<template #icon>
|
2026-01-15 06:01:34 +08:00
|
|
|
|
<Trash2 :size="16" style="vertical-align: -3px; margin-right: 4px" />
|
2025-12-24 13:17:12 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
删除数据库
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</a-button>
|
|
|
|
|
|
<a-button key="back" @click="editModalVisible = false">取消</a-button>
|
|
|
|
|
|
<a-button key="submit" type="primary" @click="handleEditSubmit">确定</a-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<a-form :model="editForm" :rules="rules" ref="editFormRef" layout="vertical">
|
|
|
|
|
|
<a-form-item label="知识库名称" name="name" required>
|
|
|
|
|
|
<a-input v-model:value="editForm.name" placeholder="请输入知识库名称" />
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item label="知识库描述" name="description">
|
2025-12-18 21:01:25 +08:00
|
|
|
|
<AiTextarea
|
|
|
|
|
|
v-model="editForm.description"
|
|
|
|
|
|
:name="editForm.name"
|
2026-01-03 19:02:08 +08:00
|
|
|
|
:files="fileList"
|
2025-12-18 21:01:25 +08:00
|
|
|
|
placeholder="请输入知识库描述"
|
|
|
|
|
|
:rows="4"
|
|
|
|
|
|
/>
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</a-form-item>
|
2025-12-10 19:42:58 +08:00
|
|
|
|
|
2026-03-04 04:13:05 +08:00
|
|
|
|
<a-form-item
|
|
|
|
|
|
v-if="database.kb_type !== 'dify'"
|
|
|
|
|
|
label="自动生成问题"
|
|
|
|
|
|
name="auto_generate_questions"
|
|
|
|
|
|
>
|
2026-01-15 06:01:34 +08:00
|
|
|
|
<a-switch
|
|
|
|
|
|
v-model:checked="editForm.auto_generate_questions"
|
|
|
|
|
|
checked-children="开启"
|
|
|
|
|
|
un-checked-children="关闭"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<span style="margin-left: 8px; font-size: 12px; color: var(--gray-500)"
|
|
|
|
|
|
>上传文件后自动生成测试问题</span
|
|
|
|
|
|
>
|
2025-11-30 18:48:33 +08:00
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
2026-02-24 12:12:02 +08:00
|
|
|
|
<a-form-item v-if="database.kb_type !== 'dify'" name="chunk_preset_id">
|
2026-02-20 19:35:43 +08:00
|
|
|
|
<template #label>
|
|
|
|
|
|
<span class="chunk-preset-label">
|
|
|
|
|
|
分块策略
|
|
|
|
|
|
<a-tooltip :title="editPresetDescription">
|
|
|
|
|
|
<QuestionCircleOutlined class="chunk-preset-help-icon" />
|
|
|
|
|
|
</a-tooltip>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<a-select v-model:value="editForm.chunk_preset_id" :options="chunkPresetOptions" />
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
|
2026-02-24 12:12:02 +08:00
|
|
|
|
<template v-if="database.kb_type === 'dify'">
|
|
|
|
|
|
<a-form-item label="Dify API URL" name="dify_api_url">
|
2026-03-04 04:13:05 +08:00
|
|
|
|
<a-input
|
|
|
|
|
|
v-model:value="editForm.dify_api_url"
|
|
|
|
|
|
placeholder="例如: https://api.dify.ai/v1"
|
|
|
|
|
|
/>
|
2026-02-24 12:12:02 +08:00
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item label="Dify Token" name="dify_token">
|
2026-03-04 04:13:05 +08:00
|
|
|
|
<a-input-password
|
|
|
|
|
|
v-model:value="editForm.dify_token"
|
|
|
|
|
|
placeholder="请输入 Dify API Token"
|
|
|
|
|
|
/>
|
2026-02-24 12:12:02 +08:00
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<a-form-item label="Dataset ID" name="dify_dataset_id">
|
|
|
|
|
|
<a-input v-model:value="editForm.dify_dataset_id" placeholder="请输入 Dify dataset_id" />
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
2025-11-06 19:47:22 +08:00
|
|
|
|
<!-- 仅对 LightRAG 类型显示 LLM 配置 -->
|
|
|
|
|
|
<a-form-item v-if="database.kb_type === 'lightrag'" label="语言模型 (LLM)" name="llm_info">
|
|
|
|
|
|
<ModelSelectorComponent
|
|
|
|
|
|
:model_spec="llmModelSpec"
|
|
|
|
|
|
placeholder="请选择模型"
|
|
|
|
|
|
@select-model="handleLLMSelect"
|
2026-01-15 06:01:34 +08:00
|
|
|
|
style="width: 100%"
|
2025-11-06 19:47:22 +08:00
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item>
|
2026-01-20 02:14:51 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 共享配置(超级管理员可编辑,非共享时本部门管理员也可编辑) -->
|
|
|
|
|
|
<a-form-item v-if="canEditShareConfig" label="共享设置" name="share_config">
|
|
|
|
|
|
<a-form-item-rest>
|
|
|
|
|
|
<ShareConfigForm
|
|
|
|
|
|
ref="shareConfigFormRef"
|
|
|
|
|
|
:model-value="database.share_config"
|
|
|
|
|
|
:auto-select-user-dept="true"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</a-form-item-rest>
|
|
|
|
|
|
</a-form-item>
|
|
|
|
|
|
<!-- 非编辑状态下显示共享配置信息 -->
|
|
|
|
|
|
<a-form-item v-else-if="database.share_config" label="共享设置" name="share_config_readonly">
|
|
|
|
|
|
<div class="share-config-readonly">
|
|
|
|
|
|
<a-tag :color="database.share_config.is_shared !== false ? 'green' : 'blue'">
|
|
|
|
|
|
{{ database.share_config.is_shared !== false ? '全员共享' : '指定部门' }}
|
|
|
|
|
|
</a-tag>
|
|
|
|
|
|
<span v-if="database.share_config.is_shared === false" class="dept-names">
|
|
|
|
|
|
{{ getAccessibleDeptNames() }}
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</a-form-item>
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</a-form>
|
|
|
|
|
|
</a-modal>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2026-02-24 12:12:02 +08:00
|
|
|
|
import { ref, reactive, computed, h, onMounted } from 'vue'
|
2026-01-15 06:01:34 +08:00
|
|
|
|
import { useRouter } from 'vue-router'
|
|
|
|
|
|
import { useDatabaseStore } from '@/stores/database'
|
2026-01-20 02:14:51 +08:00
|
|
|
|
import { useUserStore } from '@/stores/user'
|
2026-05-04 08:25:23 +08:00
|
|
|
|
import {
|
|
|
|
|
|
getKbTypeLabel,
|
|
|
|
|
|
getKbTypeColor,
|
|
|
|
|
|
parseModelSpec,
|
|
|
|
|
|
buildDisplaySpec,
|
|
|
|
|
|
buildLlmInfoPayload
|
|
|
|
|
|
} from '@/utils/kb_utils'
|
2026-02-20 19:35:43 +08:00
|
|
|
|
import {
|
|
|
|
|
|
CHUNK_PRESET_OPTIONS,
|
|
|
|
|
|
CHUNK_PRESET_LABEL_MAP,
|
|
|
|
|
|
getChunkPresetDescription
|
|
|
|
|
|
} from '@/utils/chunk_presets'
|
2026-01-15 06:01:34 +08:00
|
|
|
|
import { message } from 'ant-design-vue'
|
2026-02-20 19:35:43 +08:00
|
|
|
|
import { LeftOutlined, QuestionCircleOutlined } from '@ant-design/icons-vue'
|
2026-01-15 06:01:34 +08:00
|
|
|
|
import { Pencil, Trash2, Copy } from 'lucide-vue-next'
|
2026-01-20 02:14:51 +08:00
|
|
|
|
import { departmentApi } from '@/apis/department_api'
|
2026-01-15 06:01:34 +08:00
|
|
|
|
import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue'
|
|
|
|
|
|
import AiTextarea from '@/components/AiTextarea.vue'
|
2026-01-20 02:14:51 +08:00
|
|
|
|
import ShareConfigForm from '@/components/ShareConfigForm.vue'
|
2026-01-15 06:01:34 +08:00
|
|
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
const store = useDatabaseStore()
|
2026-01-20 02:14:51 +08:00
|
|
|
|
const userStore = useUserStore()
|
2026-01-15 06:01:34 +08:00
|
|
|
|
|
|
|
|
|
|
const database = computed(() => store.database)
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
2026-01-20 02:14:51 +08:00
|
|
|
|
// 部门列表(用于显示部门名称)
|
|
|
|
|
|
const departments = ref([])
|
|
|
|
|
|
|
|
|
|
|
|
// 加载部门列表
|
|
|
|
|
|
const loadDepartments = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await departmentApi.getDepartments()
|
|
|
|
|
|
departments.value = res.departments || res || []
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.error('加载部门列表失败:', e)
|
|
|
|
|
|
departments.value = []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化时加载部门
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
loadDepartments()
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 获取可访问的部门名称
|
|
|
|
|
|
const getAccessibleDeptNames = () => {
|
|
|
|
|
|
const deptIds = database.value?.share_config?.accessible_departments || []
|
|
|
|
|
|
if (deptIds.length === 0) return '无'
|
|
|
|
|
|
return deptIds
|
|
|
|
|
|
.map((id) => {
|
|
|
|
|
|
const dept = departments.value.find((d) => d.id === id)
|
|
|
|
|
|
return dept?.name || `部门${id}`
|
|
|
|
|
|
})
|
|
|
|
|
|
.join('、')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 是否可以编辑共享配置
|
|
|
|
|
|
// 规则:1. 超级管理员可以编辑所有
|
|
|
|
|
|
// 2. 管理员也可以编辑(后端会验证权限)
|
|
|
|
|
|
const canEditShareConfig = computed(() => {
|
|
|
|
|
|
if (userStore.isSuperAdmin) {
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
// 管理员可以编辑共享配置,后端会验证权限
|
|
|
|
|
|
return userStore.isAdmin
|
|
|
|
|
|
})
|
|
|
|
|
|
|
2026-01-03 19:02:08 +08:00
|
|
|
|
const fileList = computed(() => {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
if (!database.value?.files) return []
|
|
|
|
|
|
return Object.values(database.value.files)
|
|
|
|
|
|
.map((f) => f.filename)
|
|
|
|
|
|
.filter(Boolean)
|
|
|
|
|
|
})
|
2026-01-03 19:02:08 +08:00
|
|
|
|
|
2025-11-06 19:47:22 +08:00
|
|
|
|
// 复制数据库ID
|
|
|
|
|
|
const copyDatabaseId = async () => {
|
|
|
|
|
|
if (!database.value.db_id) {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
message.warning('知识库ID为空')
|
|
|
|
|
|
return
|
2025-11-06 19:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
await navigator.clipboard.writeText(database.value.db_id)
|
|
|
|
|
|
message.success('知识库ID已复制到剪贴板')
|
2026-02-24 12:12:02 +08:00
|
|
|
|
} catch {
|
2025-11-06 19:47:22 +08:00
|
|
|
|
// 降级方案
|
2026-01-15 06:01:34 +08:00
|
|
|
|
const textArea = document.createElement('textarea')
|
|
|
|
|
|
textArea.value = database.value.db_id
|
|
|
|
|
|
document.body.appendChild(textArea)
|
|
|
|
|
|
textArea.select()
|
|
|
|
|
|
document.execCommand('copy')
|
|
|
|
|
|
document.body.removeChild(textArea)
|
|
|
|
|
|
message.success('知识库ID已复制到剪贴板')
|
2025-11-06 19:47:22 +08:00
|
|
|
|
}
|
2026-01-15 06:01:34 +08:00
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 返回数据库列表
|
|
|
|
|
|
const backToDatabase = () => {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
router.push('/database')
|
|
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
|
|
|
|
|
// 编辑相关逻辑(复用自 DatabaseHeader)
|
2026-01-15 06:01:34 +08:00
|
|
|
|
const editModalVisible = ref(false)
|
|
|
|
|
|
const editFormRef = ref(null)
|
2026-01-20 02:14:51 +08:00
|
|
|
|
const shareConfigFormRef = ref(null)
|
2025-11-06 19:47:22 +08:00
|
|
|
|
const editForm = reactive({
|
|
|
|
|
|
name: '',
|
|
|
|
|
|
description: '',
|
2025-11-30 18:48:33 +08:00
|
|
|
|
auto_generate_questions: false,
|
2026-02-20 19:35:43 +08:00
|
|
|
|
chunk_preset_id: 'general',
|
2025-11-06 19:47:22 +08:00
|
|
|
|
llm_info: {
|
2026-05-02 01:08:09 +08:00
|
|
|
|
model_spec: '',
|
2025-11-06 19:47:22 +08:00
|
|
|
|
provider: '',
|
|
|
|
|
|
model_name: ''
|
2026-02-24 12:12:02 +08:00
|
|
|
|
},
|
|
|
|
|
|
dify_api_url: '',
|
|
|
|
|
|
dify_token: '',
|
|
|
|
|
|
dify_dataset_id: ''
|
2026-01-15 06:01:34 +08:00
|
|
|
|
})
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
2026-02-20 19:35:43 +08:00
|
|
|
|
const chunkPresetOptions = CHUNK_PRESET_OPTIONS.map(({ label, value }) => ({ label, value }))
|
|
|
|
|
|
const chunkPresetLabelMap = CHUNK_PRESET_LABEL_MAP
|
|
|
|
|
|
const editPresetDescription = computed(() => getChunkPresetDescription(editForm.chunk_preset_id))
|
|
|
|
|
|
|
2025-11-06 19:47:22 +08:00
|
|
|
|
const rules = {
|
|
|
|
|
|
name: [{ required: true, message: '请输入知识库名称' }]
|
2026-01-15 06:01:34 +08:00
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
2026-01-20 02:14:51 +08:00
|
|
|
|
// 打开编辑弹窗
|
2025-11-06 19:47:22 +08:00
|
|
|
|
const showEditModal = () => {
|
2026-01-20 02:14:51 +08:00
|
|
|
|
console.log('[showEditModal] 被调用')
|
|
|
|
|
|
|
2026-01-15 06:01:34 +08:00
|
|
|
|
editForm.name = database.value.name || ''
|
|
|
|
|
|
editForm.description = database.value.description || ''
|
|
|
|
|
|
editForm.auto_generate_questions =
|
|
|
|
|
|
database.value.additional_params?.auto_generate_questions || false
|
2026-02-20 19:35:43 +08:00
|
|
|
|
editForm.chunk_preset_id = database.value.additional_params?.chunk_preset_id || 'general'
|
2026-02-24 12:12:02 +08:00
|
|
|
|
editForm.dify_api_url = database.value.additional_params?.dify_api_url || ''
|
|
|
|
|
|
editForm.dify_token = database.value.additional_params?.dify_token || ''
|
|
|
|
|
|
editForm.dify_dataset_id = database.value.additional_params?.dify_dataset_id || ''
|
2025-12-10 19:42:58 +08:00
|
|
|
|
|
2025-11-06 19:47:22 +08:00
|
|
|
|
// 如果是 LightRAG 类型,加载当前的 LLM 配置
|
|
|
|
|
|
if (database.value.kb_type === 'lightrag') {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
const llmInfo = database.value.llm_info || {}
|
2026-05-02 01:08:09 +08:00
|
|
|
|
editForm.llm_info.model_spec = llmInfo.model_spec || ''
|
2026-01-15 06:01:34 +08:00
|
|
|
|
editForm.llm_info.provider = llmInfo.provider || ''
|
|
|
|
|
|
editForm.llm_info.model_name = llmInfo.model_name || ''
|
2025-11-06 19:47:22 +08:00
|
|
|
|
}
|
2026-01-20 02:14:51 +08:00
|
|
|
|
|
2026-01-15 06:01:34 +08:00
|
|
|
|
editModalVisible.value = true
|
|
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
|
|
|
|
|
const handleEditSubmit = () => {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
editFormRef.value
|
|
|
|
|
|
.validate()
|
|
|
|
|
|
.then(async () => {
|
2026-01-20 02:14:51 +08:00
|
|
|
|
// 验证共享配置
|
|
|
|
|
|
if (shareConfigFormRef.value) {
|
|
|
|
|
|
const validation = shareConfigFormRef.value.validate()
|
|
|
|
|
|
if (!validation.valid) {
|
|
|
|
|
|
message.warning(validation.message)
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从 ShareConfigForm 组件直接获取当前值
|
|
|
|
|
|
let finalIsShared = true
|
|
|
|
|
|
let finalDeptIds = []
|
|
|
|
|
|
|
|
|
|
|
|
if (shareConfigFormRef.value) {
|
|
|
|
|
|
const formConfig = shareConfigFormRef.value.config
|
|
|
|
|
|
finalIsShared = formConfig.is_shared
|
|
|
|
|
|
finalDeptIds = formConfig.accessible_department_ids || []
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-22 00:28:43 +08:00
|
|
|
|
console.log(
|
|
|
|
|
|
'[handleEditSubmit] 直接从组件获取 - is_shared:',
|
|
|
|
|
|
finalIsShared,
|
|
|
|
|
|
'dept_ids:',
|
|
|
|
|
|
JSON.stringify(finalDeptIds)
|
|
|
|
|
|
)
|
2026-01-20 02:14:51 +08:00
|
|
|
|
|
2026-01-15 06:01:34 +08:00
|
|
|
|
const updateData = {
|
|
|
|
|
|
name: editForm.name,
|
|
|
|
|
|
description: editForm.description,
|
2026-02-24 12:12:02 +08:00
|
|
|
|
additional_params: {},
|
2026-01-20 02:14:51 +08:00
|
|
|
|
share_config: {
|
|
|
|
|
|
is_shared: finalIsShared,
|
|
|
|
|
|
accessible_departments: finalIsShared ? [] : finalDeptIds
|
2026-01-15 06:01:34 +08:00
|
|
|
|
}
|
2025-11-30 18:48:33 +08:00
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
2026-02-24 12:12:02 +08:00
|
|
|
|
if (database.value.kb_type === 'dify') {
|
|
|
|
|
|
if (
|
|
|
|
|
|
!editForm.dify_api_url?.trim() ||
|
|
|
|
|
|
!editForm.dify_token?.trim() ||
|
|
|
|
|
|
!editForm.dify_dataset_id?.trim()
|
|
|
|
|
|
) {
|
|
|
|
|
|
message.error('请完整填写 Dify API URL、Token 和 Dataset ID')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!editForm.dify_api_url.trim().endsWith('/v1')) {
|
|
|
|
|
|
message.error('Dify API URL 必须以 /v1 结尾')
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
updateData.additional_params = {
|
|
|
|
|
|
dify_api_url: editForm.dify_api_url.trim(),
|
|
|
|
|
|
dify_token: editForm.dify_token.trim(),
|
|
|
|
|
|
dify_dataset_id: editForm.dify_dataset_id.trim()
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
updateData.additional_params = {
|
|
|
|
|
|
auto_generate_questions: editForm.auto_generate_questions,
|
|
|
|
|
|
chunk_preset_id: editForm.chunk_preset_id || 'general'
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-22 00:28:43 +08:00
|
|
|
|
console.log(
|
|
|
|
|
|
'[handleEditSubmit] updateData.share_config:',
|
|
|
|
|
|
JSON.stringify(updateData.share_config)
|
|
|
|
|
|
)
|
2026-01-20 02:14:51 +08:00
|
|
|
|
|
2026-01-15 06:01:34 +08:00
|
|
|
|
// 如果是 LightRAG 类型,包含 llm_info
|
|
|
|
|
|
if (database.value.kb_type === 'lightrag') {
|
2026-05-04 08:12:54 +08:00
|
|
|
|
updateData.llm_info = buildLlmInfoPayload(editForm.llm_info)
|
2026-01-15 06:01:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await store.updateDatabaseInfo(updateData)
|
|
|
|
|
|
editModalVisible.value = false
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
|
console.error('表单验证失败:', err)
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
|
|
|
|
|
// LLM 模型选择处理
|
2026-05-02 01:08:09 +08:00
|
|
|
|
const llmModelSpec = computed(() => buildDisplaySpec(editForm.llm_info))
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
|
|
|
|
|
const handleLLMSelect = (spec) => {
|
2026-05-02 01:08:09 +08:00
|
|
|
|
const parsed = parseModelSpec(spec)
|
|
|
|
|
|
if (!parsed) return
|
|
|
|
|
|
Object.assign(editForm.llm_info, parsed)
|
2026-01-15 06:01:34 +08:00
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
|
|
|
|
|
|
const deleteDatabase = () => {
|
2026-01-15 06:01:34 +08:00
|
|
|
|
store.deleteDatabase()
|
|
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
|
|
.knowledge-base-card {
|
2025-11-23 01:39:44 +08:00
|
|
|
|
background: linear-gradient(120deg, var(--main-30) 0%, var(--gray-0) 100%);
|
2025-11-06 19:47:22 +08:00
|
|
|
|
border-radius: 12px;
|
|
|
|
|
|
border: 1px solid var(--gray-200);
|
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-20 02:14:51 +08:00
|
|
|
|
// 只读共享配置显示
|
|
|
|
|
|
.share-config-readonly {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 8px;
|
|
|
|
|
|
|
|
|
|
|
|
.dept-names {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: var(--gray-600);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-06 19:47:22 +08:00
|
|
|
|
.card-header {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
padding: 12px 16px;
|
|
|
|
|
|
|
|
|
|
|
|
.header-left {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
2025-12-10 19:42:58 +08:00
|
|
|
|
gap: 4px;
|
2025-11-06 19:47:22 +08:00
|
|
|
|
flex: 1;
|
|
|
|
|
|
min-width: 0;
|
2025-12-10 19:42:58 +08:00
|
|
|
|
|
|
|
|
|
|
button.back-button {
|
|
|
|
|
|
margin-left: -5px;
|
|
|
|
|
|
font-size: 10px;
|
|
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
|
color: var(--gray-800);
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
|
// flex: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.header-right {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
|
|
|
|
|
|
|
button {
|
2025-12-10 19:42:58 +08:00
|
|
|
|
color: var(--gray-500);
|
2025-11-06 19:47:22 +08:00
|
|
|
|
height: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
button:hover {
|
2025-12-10 19:42:58 +08:00
|
|
|
|
color: var(--gray-700);
|
2025-11-06 19:47:22 +08:00
|
|
|
|
background-color: var(--gray-100);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.card-content {
|
|
|
|
|
|
padding: 0 16px 16px 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.description {
|
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
|
|
|
|
|
|
|
.description-text {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: var(--gray-700);
|
|
|
|
|
|
line-height: 1.5;
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tags-section {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
flex-wrap: wrap;
|
2026-04-29 00:45:15 +08:00
|
|
|
|
gap: 4px;
|
2025-11-06 19:47:22 +08:00
|
|
|
|
}
|
2026-02-20 19:35:43 +08:00
|
|
|
|
|
|
|
|
|
|
.chunk-preset-label {
|
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.chunk-preset-help-icon {
|
|
|
|
|
|
color: var(--gray-500);
|
|
|
|
|
|
cursor: help;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
2025-11-06 19:47:22 +08:00
|
|
|
|
</style>
|