chenkun 3 týždňov pred
rodič
commit
b8ae326200

+ 8 - 2
src/api/request.ts

@@ -49,10 +49,16 @@ request.interceptors.response.use(
     }
     
     // 业务错误
+    const errorMsg = message || '请求失败'
     if (!response.config.headers?.['Skip-Error-Message']) {
-      ElMessage.error(message || '请求失败')
+      ElMessage.error(errorMsg)
     }
-    return Promise.reject(new Error(message || '请求失败'))
+    const businessError = new Error(errorMsg)
+    // @ts-ignore
+    businessError.code = code
+    // @ts-ignore
+    businessError.isBusinessError = true
+    return Promise.reject(businessError)
   },
   async (error) => {
     const { response } = error

+ 29 - 86
src/views/basic-info/ConstructionPlan.vue

@@ -151,11 +151,6 @@
                   <el-icon><Delete /></el-icon>
                 </el-button>
               </el-tooltip>
-              <el-tooltip content="入库" placement="top">
-                <el-button link type="warning" @click="handleAction('ingest', scope.row)">
-                  <el-icon><Document /></el-icon>
-                </el-button>
-              </el-tooltip>
             </div>
           </template>
         </el-table-column>
@@ -176,11 +171,11 @@
 
     <!-- 新增/编辑对话框 -->
     <el-dialog v-model="formDialogVisible" :title="formTitle" width="800px">
-      <el-form :model="editForm" label-width="110px">
+      <el-form :model="editForm" :rules="formRules" ref="formRef" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="目标知识库">
-              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%">
+            <el-form-item label="目标知识库" prop="kb_id">
+              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%" :disabled="!!editForm.id">
                 <el-option
                   v-for="item in knowledgeBases"
                   :key="item.id"
@@ -191,8 +186,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="方案名称" required>
-              <el-input v-model="editForm.title" placeholder="请输入方案名称" />
+            <el-form-item label="方案名称" prop="title">
+              <el-input v-model="editForm.title" placeholder="请输入方案名称" :disabled="!!editForm.id" />
             </el-form-item>
           </el-col>
           
@@ -375,33 +370,6 @@
         </div>
       </div>
     </el-dialog>
-
-    <!-- 入库确认对话框 -->
-    <el-dialog v-model="ingestDialogVisible" title="文档入库" width="450px">
-      <el-form :model="ingestForm" label-width="100px">
-        <el-form-item label="选择知识库" required>
-          <el-select v-model="ingestForm.kb_id" placeholder="请选择知识库" style="width: 100%">
-            <el-option
-              v-for="item in knowledgeBases"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="切分方式" required>
-          <el-radio-group v-model="ingestForm.kb_method">
-            <el-radio label="length">按长度切分</el-radio>
-            <el-radio label="symbol">按符号切分</el-radio>
-            <el-radio label="parent_child">父子段切分</el-radio>
-          </el-radio-group>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <el-button @click="ingestDialogVisible = false">取消</el-button>
-        <el-button type="primary" @click="confirmIngest" :loading="ingesting">确认入库</el-button>
-      </template>
-    </el-dialog>
   </div>
 </template>
 
@@ -432,14 +400,17 @@ const previewLoading = ref(false)
 const previewUrl = ref('')
 const previewTitle = ref('')
 
-// 入库相关状态
-const ingestDialogVisible = ref(false)
-const ingesting = ref(false)
 const knowledgeBases = ref<any[]>([])
-const ingestForm = reactive({
-  kb_id: '',
-  kb_method: 'length'
-})
+
+const formRef = ref()
+const formRules = {
+  kb_id: [
+    { required: true, message: '请选择目标知识库', trigger: 'change' }
+  ],
+  title: [
+    { required: true, message: '请输入方案名称', trigger: 'blur' }
+  ]
+}
 
 // 动态列表字段存储
 const compilationBasisList = ref<string[]>([''])
@@ -635,6 +606,10 @@ const handleAction = async (action: string, row: any) => {
       editForm.id = row.id
       fileList.value = []
       formDialogVisible.value = true
+      // 清除之前的验证状态
+      if (formRef.value) {
+        formRef.value.clearValidate()
+      }
       break
     case 'delete':
       ElMessageBox.confirm('确定要删除该条信息吗?', '提示', {
@@ -654,11 +629,6 @@ const handleAction = async (action: string, row: any) => {
         }
       }).catch(() => {})
       break
-    case 'ingest':
-      currentItem.value = row
-      loadKnowledgeBases()
-      ingestDialogVisible.value = true
-      break
   }
 }
 
@@ -672,47 +642,12 @@ const loadKnowledgeBases = async () => {
     })
     if (res.code === 0) {
       knowledgeBases.value = res.data
-      if (knowledgeBases.value.length > 0 && !ingestForm.kb_id) {
-        ingestForm.kb_id = knowledgeBases.value[0].id
-      }
     }
   } catch (error) {
     console.error('获取知识库失败:', error)
   }
 }
 
-const confirmIngest = async () => {
-  if (!ingestForm.kb_id) {
-    ElMessage.warning('请选择知识库')
-    return
-  }
-  if (!currentItem.value || !currentItem.value.id) {
-    ElMessage.warning('未选中有效文档')
-    return
-  }
-  ingesting.value = true
-  try {
-    const res = await request.post<ApiResponse>('/api/v1/sample/documents/batch-enter', {
-      ids: [currentItem.value.id],
-      table_type: 'construction_plan',
-      kb_id: ingestForm.kb_id,
-      kb_method: ingestForm.kb_method
-    })
-    if (res.code === 0) {
-      ElMessage.success(res.message || '已加入入库队列')
-      ingestDialogVisible.value = false
-      loadData()
-    } else {
-      ElMessage.error(res.message || '入库失败')
-    }
-  } catch (error) {
-    console.error('入库失败:', error)
-    ElMessage.error('网络错误,请稍后重试')
-  } finally {
-    ingesting.value = false
-  }
-}
-
 const handleAdd = () => {
   loadKnowledgeBases()
   Object.keys(editForm).forEach(key => {
@@ -723,13 +658,21 @@ const handleAdd = () => {
   compilationBasisList.value = ['']
   fileList.value = []
   formDialogVisible.value = true
+  // 清除之前的验证状态
+  if (formRef.value) {
+    formRef.value.clearValidate()
+  }
 }
 
 const submitForm = async () => {
-  if (!editForm.title) {
-    ElMessage.warning('请输入标题')
+  if (!formRef.value) return
+  
+  try {
+    await formRef.value.validate()
+  } catch (error) {
     return
   }
+  
   submitting.value = true
   try {
     if (fileList.value.length > 0 && fileList.value[0].raw) {

+ 29 - 86
src/views/basic-info/Regulation.vue

@@ -117,11 +117,6 @@
                   <el-icon><Delete /></el-icon>
                 </el-button>
               </el-tooltip>
-              <el-tooltip content="入库" placement="top">
-                <el-button link type="warning" @click="handleAction('ingest', scope.row)">
-                  <el-icon><Document /></el-icon>
-                </el-button>
-              </el-tooltip>
             </div>
           </template>
         </el-table-column>
@@ -142,11 +137,11 @@
 
     <!-- 新增/编辑对话框 -->
     <el-dialog v-model="formDialogVisible" :title="formTitle" width="800px">
-      <el-form :model="editForm" label-width="110px">
+      <el-form :model="editForm" :rules="formRules" ref="formRef" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="目标知识库">
-              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%">
+            <el-form-item label="目标知识库" prop="kb_id">
+              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%" :disabled="!!editForm.id">
                 <el-option
                   v-for="item in knowledgeBases"
                   :key="item.id"
@@ -157,8 +152,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="文件名称" required>
-              <el-input v-model="editForm.title" placeholder="请输入文件名称" />
+            <el-form-item label="文件名称" prop="title">
+              <el-input v-model="editForm.title" placeholder="请输入文件名称" :disabled="!!editForm.id" />
             </el-form-item>
           </el-col>
 
@@ -287,33 +282,6 @@
         </div>
       </div>
     </el-dialog>
-
-    <!-- 入库确认对话框 -->
-    <el-dialog v-model="ingestDialogVisible" title="文档入库" width="450px">
-      <el-form :model="ingestForm" label-width="100px">
-        <el-form-item label="选择知识库" required>
-          <el-select v-model="ingestForm.kb_id" placeholder="请选择知识库" style="width: 100%">
-            <el-option
-              v-for="item in knowledgeBases"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="切分方式" required>
-          <el-radio-group v-model="ingestForm.kb_method">
-            <el-radio label="length">按长度切分</el-radio>
-            <el-radio label="symbol">按符号切分</el-radio>
-            <el-radio label="parent_child">父子段切分</el-radio>
-          </el-radio-group>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <el-button @click="ingestDialogVisible = false">取消</el-button>
-        <el-button type="primary" @click="confirmIngest" :loading="ingesting">确认入库</el-button>
-      </template>
-    </el-dialog>
   </div>
 </template>
 
@@ -344,14 +312,17 @@ const previewLoading = ref(false)
 const previewUrl = ref('')
 const previewTitle = ref('')
 
-// 入库相关状态
-const ingestDialogVisible = ref(false)
-const ingesting = ref(false)
 const knowledgeBases = ref<any[]>([])
-const ingestForm = reactive({
-  kb_id: '',
-  kb_method: 'length'
-})
+
+const formRef = ref()
+const formRules = {
+  kb_id: [
+    { required: true, message: '请选择目标知识库', trigger: 'change' }
+  ],
+  title: [
+    { required: true, message: '请输入文件名称', trigger: 'blur' }
+  ]
+}
 
 // 动态列表字段存储
 const fileList = ref<any[]>([])
@@ -520,6 +491,10 @@ const handleAction = async (action: string, row: any) => {
       editForm.id = row.id
       fileList.value = []
       formDialogVisible.value = true
+      // 清除之前的验证状态
+      if (formRef.value) {
+        formRef.value.clearValidate()
+      }
       break
     case 'delete':
       ElMessageBox.confirm('确定要删除该条信息吗?', '提示', {
@@ -539,11 +514,6 @@ const handleAction = async (action: string, row: any) => {
         }
       }).catch(() => {})
       break
-    case 'ingest':
-      currentItem.value = row
-      loadKnowledgeBases()
-      ingestDialogVisible.value = true
-      break
   }
 }
 
@@ -557,47 +527,12 @@ const loadKnowledgeBases = async () => {
     })
     if (res.code === 0) {
       knowledgeBases.value = res.data
-      if (knowledgeBases.value.length > 0 && !ingestForm.kb_id) {
-        ingestForm.kb_id = knowledgeBases.value[0].id
-      }
     }
   } catch (error) {
     console.error('获取知识库失败:', error)
   }
 }
 
-const confirmIngest = async () => {
-  if (!ingestForm.kb_id) {
-    ElMessage.warning('请选择知识库')
-    return
-  }
-  if (!currentItem.value || !currentItem.value.id) {
-    ElMessage.warning('未选中有效文档')
-    return
-  }
-  ingesting.value = true
-  try {
-    const res = await request.post<ApiResponse>('/api/v1/sample/documents/batch-enter', {
-      ids: [currentItem.value.id],
-      table_type: 'regulation',
-      kb_id: ingestForm.kb_id,
-      kb_method: ingestForm.kb_method
-    })
-    if (res.code === 0) {
-      ElMessage.success(res.message || '已加入入库队列')
-      ingestDialogVisible.value = false
-      loadData()
-    } else {
-      ElMessage.error(res.message || '入库失败')
-    }
-  } catch (error) {
-    console.error('入库失败:', error)
-    ElMessage.error('网络错误,请稍后重试')
-  } finally {
-    ingesting.value = false
-  }
-}
-
 const handleAdd = () => {
   loadKnowledgeBases()
   Object.keys(editForm).forEach(key => {
@@ -606,13 +541,21 @@ const handleAdd = () => {
   editForm.id = null
   fileList.value = []
   formDialogVisible.value = true
+  // 清除之前的验证状态
+  if (formRef.value) {
+    formRef.value.clearValidate()
+  }
 }
 
 const submitForm = async () => {
-  if (!editForm.title) {
-    ElMessage.warning('请输入标题')
+  if (!formRef.value) return
+  
+  try {
+    await formRef.value.validate()
+  } catch (error) {
     return
   }
+  
   submitting.value = true
   try {
     if (fileList.value.length > 0 && fileList.value[0].raw) {

+ 27 - 82
src/views/basic-info/Standard.vue

@@ -238,11 +238,6 @@
                   <el-icon><Delete /></el-icon>
                 </el-button>
               </el-tooltip>
-              <el-tooltip content="入库" placement="top">
-                <el-button link type="warning" @click="handleAction('ingest', scope.row)">
-                  <el-icon><Document /></el-icon>
-                </el-button>
-              </el-tooltip>
             </div>
           </template>
         </el-table-column>
@@ -263,11 +258,11 @@
 
     <!-- 新增/编辑对话框 -->
     <el-dialog v-model="formDialogVisible" :title="formTitle" width="800px">
-      <el-form :model="editForm" label-width="110px">
+      <el-form :model="editForm" :rules="formRules" ref="formRef" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="目标知识库">
-              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%">
+            <el-form-item label="目标知识库" prop="kb_id">
+              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%" :disabled="!!editForm.id">
                 <el-option
                   v-for="item in knowledgeBases"
                   :key="item.id"
@@ -278,8 +273,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="文档名称" required>
-              <el-input v-model="editForm.title" placeholder="请输入文档名称" />
+            <el-form-item label="文档名称" prop="title">
+              <el-input v-model="editForm.title" placeholder="请输入文档名称" :disabled="!!editForm.id" />
             </el-form-item>
           </el-col>
           
@@ -496,33 +491,6 @@
         </div>
       </div>
     </el-dialog>
-
-    <!-- 入库确认对话框 -->
-    <el-dialog v-model="ingestDialogVisible" title="文档入库" width="450px">
-      <el-form :model="ingestForm" label-width="100px">
-        <el-form-item label="选择知识库" required>
-          <el-select v-model="ingestForm.kb_id" placeholder="请选择知识库" style="width: 100%">
-            <el-option
-              v-for="item in knowledgeBases"
-              :key="item.id"
-              :label="item.name"
-              :value="item.id"
-            />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="切分方式" required>
-          <el-radio-group v-model="ingestForm.kb_method">
-            <el-radio label="length">按长度切分</el-radio>
-            <el-radio label="symbol">按符号切分</el-radio>
-            <el-radio label="parent_child">父子段切分</el-radio>
-          </el-radio-group>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <el-button @click="ingestDialogVisible = false">取消</el-button>
-        <el-button type="primary" @click="confirmIngest" :loading="ingesting">确认入库</el-button>
-      </template>
-    </el-dialog>
   </div>
 </template>
 
@@ -553,14 +521,18 @@ const previewLoading = ref(false)
 const previewUrl = ref('')
 const previewTitle = ref('')
 
-// 入库相关状态
-const ingestDialogVisible = ref(false)
+const formRef = ref()
+const formRules = {
+  kb_id: [
+    { required: true, message: '请选择目标知识库', trigger: 'change' }
+  ],
+  title: [
+    { required: true, message: '请输入文档名称', trigger: 'blur' }
+  ]
+}
+
 const ingesting = ref(false)
 const knowledgeBases = ref<any[]>([])
-const ingestForm = reactive({
-  kb_id: '',
-  kb_method: 'length'
-})
 
 // 动态列表字段存储
 const participatingUnitsList = ref<string[]>([''])
@@ -759,6 +731,9 @@ const handleAction = async (action: string, row: any) => {
       break
     case 'edit':
       loadKnowledgeBases()
+      if (formRef.value) {
+        formRef.value.clearValidate()
+      }
       Object.keys(editForm).forEach(key => {
         editForm[key] = row[key] || ''
       })
@@ -786,11 +761,6 @@ const handleAction = async (action: string, row: any) => {
         }
       }).catch(() => {})
       break
-    case 'ingest':
-      currentItem.value = row
-      loadKnowledgeBases()
-      ingestDialogVisible.value = true
-      break
   }
 }
 
@@ -813,40 +783,11 @@ const loadKnowledgeBases = async () => {
   }
 }
 
-const confirmIngest = async () => {
-  if (!ingestForm.kb_id) {
-    ElMessage.warning('请选择知识库')
-    return
-  }
-  if (!currentItem.value || !currentItem.value.id) {
-    ElMessage.warning('未选中有效文档')
-    return
-  }
-  ingesting.value = true
-  try {
-    const res = await request.post<ApiResponse>('/api/v1/sample/documents/batch-enter', {
-      ids: [currentItem.value.id],
-      table_type: 'standard',
-      kb_id: ingestForm.kb_id,
-      kb_method: ingestForm.kb_method
-    })
-    if (res.code === 0) {
-      ElMessage.success(res.message || '已加入入库队列')
-      ingestDialogVisible.value = false
-      loadData()
-    } else {
-      ElMessage.error(res.message || '入库失败')
-    }
-  } catch (error) {
-    console.error('入库失败:', error)
-    ElMessage.error('网络错误,请稍后重试')
-  } finally {
-    ingesting.value = false
-  }
-}
-
 const handleAdd = () => {
   loadKnowledgeBases()
+  if (formRef.value) {
+    formRef.value.clearValidate()
+  }
   Object.keys(editForm).forEach(key => {
     editForm[key] = ''
   })
@@ -859,10 +800,14 @@ const handleAdd = () => {
 }
 
 const submitForm = async () => {
-  if (!editForm.title) {
-    ElMessage.warning('请输入标题')
+  if (!formRef.value) return
+  
+  try {
+    await formRef.value.validate()
+  } catch (error) {
     return
   }
+  
   submitting.value = true
   try {
     if (fileList.value.length > 0 && fileList.value[0].raw) {

+ 102 - 24
src/views/documents/Index.vue

@@ -310,14 +310,32 @@
     
     <!-- 入库设置弹窗 -->
     <el-dialog v-model="ingestDialogVisible" title="入库设置" width="400px">
-      <el-form :model="ingestForm" label-width="100px">
-        <el-form-item label="切分方式">
+      <el-form :model="ingestForm" :rules="ingestRules" ref="ingestFormRef" label-width="100px">
+        <el-form-item label="切分方式" prop="kb_method">
           <el-select v-model="ingestForm.kb_method" placeholder="请选择切分方式" style="width: 100%">
             <el-option label="按长度切分" value="length" />
             <el-option label="按符号切分" value="symbol" />
             <el-option label="父子段切分" value="parent_child" />
           </el-select>
         </el-form-item>
+        <el-form-item label="切分长度" v-if="ingestForm.kb_method === 'length'">
+          <el-select v-model="ingestForm.chunk_size" placeholder="请选择切分长度" style="width: 100%">
+            <el-option label="200" :value="200" />
+            <el-option label="500" :value="500" />
+            <el-option label="800" :value="800" />
+            <el-option label="1000" :value="1000" />
+            <el-option label="1200" :value="1200" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="切分符号" v-if="ingestForm.kb_method === 'symbol'">
+          <el-select v-model="ingestForm.separator" placeholder="请选择切分符号" style="width: 100%">
+            <el-option label="句号 (。)" value="。" />
+            <el-option label="换行符 (\n)" value="\n" />
+            <el-option label="分号 (;)" value=";" />
+            <el-option label="感叹号 (!)" value="!" />
+            <el-option label="问号 (?)" value="?" />
+          </el-select>
+        </el-form-item>
       </el-form>
       <template #footer>
         <span class="dialog-footer">
@@ -344,8 +362,8 @@
 
     <!-- 上传文档对话框 -->
     <el-dialog v-model="uploadDialogVisible" title="上传文档" width="500px">
-      <el-form :model="uploadForm" label-width="120px">
-        <el-form-item label="基本信息类型" required>
+      <el-form :model="uploadForm" :rules="commonRules" ref="uploadFormRef" label-width="120px">
+        <el-form-item label="基本信息类型" prop="table_type">
           <el-select v-model="uploadForm.table_type" placeholder="请选择基本信息类型">
             <el-option label="施工标准规范" value="standard" />
             <el-option label="施工方案" value="construction_plan" />
@@ -353,8 +371,8 @@
             <el-option label="其他文档" value="other" />
           </el-select>
         </el-form-item>
-        <el-form-item label="目标知识库">
-          <el-select v-model="uploadForm.kb_id" placeholder="请选择目标知识库 (可选)" clearable style="width: 100%">
+        <el-form-item label="目标知识库" prop="kb_id">
+          <el-select v-model="uploadForm.kb_id" placeholder="请选择目标知识库">
             <el-option
               v-for="item in kbOptions"
               :key="item.value"
@@ -363,7 +381,7 @@
             />
           </el-select>
         </el-form-item>
-        <el-form-item label="文档标题" required>
+        <el-form-item label="文档标题" prop="title">
           <el-input v-model="uploadForm.title" placeholder="请输入文档标题" />
         </el-form-item>
         <el-form-item label="文档链接" v-if="false">
@@ -399,11 +417,11 @@
 
     <!-- 编辑文档对话框 -->
     <el-dialog v-model="editDialogVisible" :title="formTitle" width="800px">
-      <el-form :model="editForm" label-width="110px">
+      <el-form :model="editForm" :rules="commonRules" ref="editFormRef" label-width="110px">
         <el-row :gutter="20">
           <el-col :span="12">
-            <el-form-item label="目标知识库">
-              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" clearable style="width: 100%">
+            <el-form-item label="目标知识库" prop="kb_id">
+              <el-select v-model="editForm.kb_id" placeholder="请选择目标知识库" style="width: 100%" disabled>
                 <el-option
                   v-for="item in kbOptions"
                   :key="item.value"
@@ -414,8 +432,8 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item :label="titleLabel" required>
-              <el-input v-model="editForm.title" :placeholder="'请输入' + titleLabel" />
+            <el-form-item :label="titleLabel" prop="title">
+              <el-input v-model="editForm.title" :placeholder="'请输入' + titleLabel" disabled />
             </el-form-item>
           </el-col>
           
@@ -757,9 +775,33 @@ const previewDocType = ref('') // 'original' or 'md'
 const ingesting = ref(false)
 const ingestDialogVisible = ref(false)
 const ingestForm = reactive({
-  kb_method: 'length'
+  kb_method: 'length',
+  chunk_size: 500,
+  separator: '。'
 })
 
+const ingestRules = {
+  kb_method: [
+    { required: true, message: '请选择切分方式', trigger: 'change' }
+  ]
+}
+
+const ingestFormRef = ref()
+const uploadFormRef = ref()
+const editFormRef = ref()
+
+const commonRules = {
+  kb_id: [
+    { required: true, message: '请选择目标知识库', trigger: 'change' }
+  ],
+  title: [
+    { required: true, message: '请输入文档标题', trigger: 'blur' }
+  ],
+  table_type: [
+    { required: true, message: '请选择基本信息类型', trigger: 'change' }
+  ]
+}
+
 const isOfficeDoc = ref(false)
 const total = ref(0)
 const statistics = ref({
@@ -816,7 +858,7 @@ const level2Options = ['临建工程', '路基工程', '其他', '桥梁工程',
 const level3Options = ['/', 'TBM施工', '拌和站安、拆施工', '不良地质隧道施工', '常规桥梁', '挡土墙工程类', '辅助坑道施工', '复杂洞口工程施工', '钢筋加工场安、拆', '钢栈桥施工', '拱桥', '涵洞工程类', '滑坡体处理类', '路堤', '路堑', '其他', '深基坑', '隧道总体施工', '特殊结构隧道', '斜拉桥', '悬索桥']
 const level4Options = ['/', '挡土墙', '顶管', '断层破碎带及软弱围岩', '钢筋砼箱涵', '高填路堤', '抗滑桩', '其他', '软岩大变形隧道', '上部结构', '深基坑开挖与支护', '深挖路堑', '隧道TBM', '隧道进洞', '隧道竖井', '隧道斜井', '特种设备', '瓦斯隧道', '下部结构', '小净距隧道', '岩爆隧道', '岩溶隧道', '涌水突泥隧道', '桩基础']
 const documentTypeOptions = ['国家标准', '行业标准', '地方标准', '企业标准', '团体标准', '国际标准', '其他']
-const professionalFieldOptions = ['通用标准', '勘察钻探', '地基基础', '路基路面', '桥梁工程', '隧道工程', '交通工程', '港口航道', '铁路工程', '市政工程', '房建工程', '水利电力', '信息化', '试验检测', '安全环保']
+const professionalFieldOptions = ['法律法规','通用标准', '勘察钻探', '地基基础', '路基路面', '桥梁工程', '隧道工程', '交通工程', '港口航道', '铁路工程', '市政工程', '房建工程', '水利电力', '信息化', '试验检测', '安全环保']
 
 // 列表项管理
 const addListItem = (list: string[]) => {
@@ -994,14 +1036,23 @@ const confirmIngest = async () => {
     ElMessage.warning('请先选择要入库的文档')
     return
   }
+
+  if (!ingestFormRef.value) return
+  
+  try {
+    await ingestFormRef.value.validate()
+  } catch (error) {
+    return
+  }
   
   ingesting.value = true
   try {
     // 统一使用 batch-enter 接口
-    // 不再传递 kb_id,由后端根据 source_type 自动匹配
     const res = await request.post<ApiResponse>('/api/v1/sample/documents/batch-enter', {
       ids: selectedIds.value,
       kb_method: ingestForm.kb_method, // 使用用户选择的切分方式
+      chunk_size: ingestForm.chunk_size,
+      separator: ingestForm.separator,
       table_type: searchQuery.table_type // 传递当前的表类型上下文
     })
     
@@ -1011,12 +1062,11 @@ const confirmIngest = async () => {
       selectedIds.value = []
       ingestDialogVisible.value = false // 关闭弹窗
       fetchDocuments()
-    } else {
-      ElMessage.error(res.message || '入库失败')
     }
-  } catch (error) {
-    console.error('入库失败:', error)
-    ElMessage.error('网络错误,请稍后重试')
+  } catch (error: any) {
+    if (error !== 'cancel') {
+      console.error('入库失败:', error)
+    }
   } finally {
     ingesting.value = false
   }
@@ -1030,6 +1080,13 @@ const handleBatchEnter = async () => {
   
   // 不再使用 confirm,改为显示入库设置弹窗
   ingestForm.kb_method = 'length' // 重置为默认值
+  ingestForm.chunk_size = 500
+  ingestForm.separator = '。'
+  
+  if (ingestFormRef.value) {
+    ingestFormRef.value.clearValidate()
+  }
+  
   ingestDialogVisible.value = true
 }
 
@@ -1072,6 +1129,13 @@ const handleSingleEnter = async (doc: DocumentItem | null) => {
   
   selectedIds.value = [doc.id]
   ingestForm.kb_method = 'length' // 重置为默认值
+  ingestForm.chunk_size = 500
+  ingestForm.separator = '。'
+  
+  if (ingestFormRef.value) {
+    ingestFormRef.value.clearValidate()
+  }
+  
   ingestDialogVisible.value = true
 }
 
@@ -1290,13 +1354,19 @@ const handleUpload = () => {
   if (uploadRef.value) {
     uploadRef.value.clearFiles()
   }
+  if (uploadFormRef.value) {
+    uploadFormRef.value.clearValidate()
+  }
   loadKbOptions()
   uploadDialogVisible.value = true
 }
 
 const submitUpload = async () => {
-  if (!uploadForm.title) {
-    return ElMessage.warning('请输入文档标题')
+  if (!uploadFormRef.value) return
+  try {
+    await uploadFormRef.value.validate()
+  } catch (error) {
+    return
   }
   submitting.value = true
   try {
@@ -1353,6 +1423,10 @@ const handleEdit = async (row: DocumentItem) => {
       editForm.effective_end_date = data.effective_end_date || ''
       editForm.kb_id = data.kb_id || ''
       
+      if (editFormRef.value) {
+        editFormRef.value.clearValidate()
+      }
+      
       // 处理列表字段
       if (data.participating_units) {
         participatingUnitsList.value = data.participating_units.split(';').filter((i: string) => i.trim())
@@ -1386,8 +1460,11 @@ const handleEdit = async (row: DocumentItem) => {
 }
 
 const submitEdit = async () => {
-  if (!editForm.title) {
-    return ElMessage.warning('请输入文档标题')
+  if (!editFormRef.value) return
+  try {
+    await editFormRef.value.validate()
+  } catch (error) {
+    return
   }
   submitting.value = true
   try {
@@ -1540,6 +1617,7 @@ const openInNewWindow = () => {
 
 onMounted(() => {
   fetchDocuments()
+  loadKbOptions()
   // 5秒后开始第一次静默刷新,之后递归调用
   refreshTimer.value = window.setTimeout(refreshDocumentsSilently, 5000)
 })