<template>
  <div class="documents-container">
    <div class="header-section">
      <div class="title-info">
        <h2>{{ currentTitle }}</h2>
        <div class="statistics-bar">
          <span class="stat-item">
            <el-icon><Document /></el-icon>
            全部数据: <span class="stat-value">{{ statistics.allTotal }}</span>
          </span>
          <span class="stat-item">
            <el-icon><CircleCheck /></el-icon>
            已入库: <span class="stat-value success">{{ statistics.totalEntered }}</span>
          </span>
          <span class="stat-item" v-if="searchQuery.keyword || searchQuery.table_type || searchQuery.whether_to_enter !== null">
            <el-icon><Search /></el-icon>
            检索结果: <span class="stat-value">{{ total }}</span>
          </span>
        </div>
      </div>
      <div class="action-buttons">
        <el-button type="danger" :disabled="selectedIds.length === 0" @click="handleBatchDelete">
          <el-icon><Delete /></el-icon> 批量删除
        </el-button>
        <el-button type="info" :disabled="selectedIds.length === 0" @click="handleBatchClear">
          <el-icon><Refresh /></el-icon> 清空数据
        </el-button>
        <el-button type="warning" :disabled="selectedIds.length === 0" @click="handleBatchEnter">
          <el-icon><CircleCheck /></el-icon> 批量入库
        </el-button>
        <el-button type="primary" :disabled="selectedIds.length === 0" @click="handleBatchAddToTask">
          <el-icon><Tickets /></el-icon> 批量加入标注任务
        </el-button>
        <el-button type="success" class="upload-btn" @click="handleUpload">
          <el-icon><Upload /></el-icon> 上传文档
        </el-button>
      </div>
    </div>

    <!-- 板块切换 Tabs 移除，改为合并视图 -->

    <el-card class="search-card">
      <div class="search-bar">
        <el-input
          v-model="searchQuery.keyword"
          placeholder="搜索文档名称..."
          class="search-input"
          clearable
          @keyup.enter="handleSearch"
        >
          <template #prefix>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>

        <div class="filter-group">
          <el-select v-model="searchQuery.table_type" placeholder="基本信息类型" clearable class="filter-select">
            <el-option label="全部类型" :value="null" />
            <el-option label="施工标准规范" value="standard" />
            <el-option label="施工方案" value="construction_plan" />
            <el-option label="办公制度" value="regulation" />
            <el-option label="其他文档" value="other" />
          </el-select>

          <el-select v-model="searchQuery.whether_to_enter" placeholder="入库状态" clearable class="filter-select">
            <el-option label="全部入库状态" :value="null" />
            <el-option label="未入库" :value="0" />
            <el-option label="已入库" :value="1" />
          </el-select>

          <el-select v-model="searchQuery.conversion_status" placeholder="解析状态" clearable class="filter-select">
            <el-option label="全部解析状态" :value="null" />
            <el-option label="未转换" :value="0" />
            <el-option label="转换中" :value="1" />
            <el-option label="转换成功" :value="2" />
            <el-option label="转换失败" :value="3" />
          </el-select>

          <el-button type="primary" @click="handleSearch" class="search-btn">
            <el-icon><Filter /></el-icon> 检索
          </el-button>
        </div>
      </div>
    </el-card>

    <div class="content-section" v-loading="loading">
      <el-empty v-if="documents.length === 0" description="暂无文档数据" />
      <el-table 
        v-else 
        ref="multipleTableRef"
        :data="documents" 
        row-key="id"
        style="width: 100%" 
        border 
        stripe 
        size="small"
        @selection-change="handleSelectionChange"
        :row-class-name="tableRowClassName"
      >
        <el-table-column type="selection" width="40" :selectable="canSelect" :reserve-selection="true" />
        
        <el-table-column prop="title" label="文档名称" min-width="280" show-overflow-tooltip>
          <template #default="scope">
            <div class="file-info-cell">
              <div class="file-icon-mini" :class="getFileIconClass(scope.row)">
                <el-icon v-if="getFileIcon(scope.row) === 'pdf'"><Document /></el-icon>
                <el-icon v-else-if="getFileIcon(scope.row) === 'word'"><Document /></el-icon>
                <el-icon v-else-if="getFileIcon(scope.row) === 'excel'"><Grid /></el-icon>
                <el-icon v-else-if="getFileIcon(scope.row) === 'ppt'"><DataAnalysis /></el-icon>
                <el-icon v-else><Document /></el-icon>
              </div>
              <div class="file-info-content">
                <span class="file-name-link" @click="handleView(scope.row)">
                  {{ scope.row.title }}{{ getFileExtension(scope.row) }}
                </span>
                <span v-if="scope.row.note" class="file-note">
                  {{ scope.row.note }}
                </span>
              </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="转换状态" min-width="180">
          <template #default="scope">
            <div class="conversion-cell">
              <el-tooltip
                :content="scope.row.conversion_error"
                placement="top"
                :disabled="scope.row.conversion_status !== 3 || !scope.row.conversion_error"
              >
                <el-tag 
                  :type="getConversionStatusTag(scope.row)"
                  size="small"
                  effect="light"
                  class="status-tag"
                >
                  <el-icon v-if="scope.row.conversion_status === 3" style="vertical-align: middle; margin-right: 4px;">
                    <Warning />
                  </el-icon>
                  {{ getConversionStatusText(scope.row) }}
                </el-tag>
              </el-tooltip>
              
              <div class="converted-file-links" v-if="scope.row.conversion_status === 2">
                 <div class="converted-file-name" v-if="scope.row.md_url">
                   <el-link type="primary" :underline="false" @click="handleDownloadConverted(scope.row)">
                     <el-icon><Link /></el-icon> {{ scope.row.md_display_name || '下载 Markdown' }}
                   </el-link>
                 </div>
                 <div class="converted-file-name" v-if="scope.row.json_url">
                   <el-link type="success" :underline="false" @click="handleDownloadJson(scope.row)">
                     <el-icon><Link /></el-icon> {{ scope.row.json_display_name || '下载 JSON' }}
                   </el-link>
                 </div>
               </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column label="基本信息类型" min-width="120">
          <template #default="scope">
            <el-tag size="small" effect="plain" :type="getKBTagType(scope.row.source_type)">
              {{ getSourceTypeShortName(scope.row.source_type) }}
            </el-tag>
          </template>
        </el-table-column>

        <el-table-column label="所属知识库" min-width="150" show-overflow-tooltip>
          <template #default="scope">
            <span v-if="scope.row.kb_name" class="kb-name-tag">
              <el-icon><Tickets /></el-icon> {{ scope.row.kb_name }}
            </span>
            <span v-else class="text-info">未入库</span>
          </template>
        </el-table-column>

        <el-table-column prop="whether_to_enter" label="入库" width="80" align="center">
          <template #default="scope">
            <el-tooltip :content="isEntered(scope.row.whether_to_enter) ? '已入库' : '未入库'" placement="top">
              <el-icon :class="isEntered(scope.row.whether_to_enter) ? 'status-icon-success' : 'status-icon-info'">
                <CircleCheck v-if="isEntered(scope.row.whether_to_enter)" />
                <Warning v-else />
              </el-icon>
            </el-tooltip>
          </template>
        </el-table-column>
        <el-table-column prop="creator_name" label="上传人" min-width="100" show-overflow-tooltip />

        <el-table-column label="上传时间" min-width="150" prop="created_time">
          <template #default="scope">
            {{ formatDate(scope.row.created_time) }}
          </template>
        </el-table-column>

        <el-table-column prop="updater_name" label="修改人" min-width="100" show-overflow-tooltip />

        <el-table-column label="修改时间" min-width="150" prop="updated_time">
          <template #default="scope">
            {{ formatDate(scope.row.updated_time) }}
          </template>
        </el-table-column>

        <el-table-column label="操作" width="260" fixed="right" align="center">
          <template #default="scope">
            <div class="action-buttons">
              <el-tooltip content="编辑" placement="top">
                <el-button 
                  link 
                  type="primary" 
                  @click="handleEdit(scope.row)"
                  class="action-btn-icon"
                >
                  <el-icon><Edit /></el-icon>
                </el-button>
              </el-tooltip>
              
              <el-tooltip content="下载" placement="top" v-if="scope.row.file_url">
                <el-button 
                  link 
                  type="success" 
                  @click="handleDownload(scope.row)"
                  class="action-btn-icon"
                >
                  <el-icon><Download /></el-icon>
                </el-button>
              </el-tooltip>
              
              <el-tooltip 
                :content="scope.row.conversion_status === 1 ? '转换中' : (scope.row.conversion_status === 2 ? '重新转换' : '开始转换')" 
                placement="top"
              >
                <el-button 
                  link 
                  type="warning" 
                  @click="handleConvert(scope.row)"
                  :disabled="scope.row.conversion_status === 1"
                  class="action-btn-icon"
                >
                  <el-icon><Switch /></el-icon>
                </el-button>
              </el-tooltip>

              <el-tooltip content="删除" placement="top">
                <el-button 
                  link 
                  type="danger" 
                  @click="handleDelete(scope.row)"
                  class="action-btn-icon"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </el-tooltip>

              <el-tooltip content="入库" placement="top">
                <el-button 
                  link 
                  type="warning" 
                  @click="handleSingleEnter(scope.row)"
                  :disabled="isEntered(scope.row.whether_to_enter)"
                  class="action-btn-icon"
                >
                  <el-icon><CircleCheck /></el-icon>
                </el-button>
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
      </el-table>

    <!-- 文档预览对话框 -->
    <el-dialog v-model="previewVisible" :title="previewTitle" width="85%" top="5vh" custom-class="preview-dialog" @closed="previewUrl = ''">
      <template #header>
        <div class="dialog-header-custom">
          <span>{{ previewTitle }}</span>
          <div class="header-actions">
            <el-button type="primary" link @click="openInNewWindow">
              <el-icon><TopRight /></el-icon>在新窗口打开原链接
            </el-button>
          </div>
        </div>
      </template>
      <div v-loading="previewLoading" class="preview-content">
        <!-- Office 文档未转换提示 -->
        <div v-if="isOfficeDoc && previewDocType === 'original' && !previewLoading" class="unsupported-preview">
          <el-result
            icon="warning"
            title="该格式暂不支持直接预览"
            sub-title="Word/Excel/PPT 等 Office 文档需要转换后才能在浏览器中直接预览。"
          >
            <template #extra>
              <div class="unsupported-actions">
                <el-button type="primary" @click="handleConvert(currentDoc!)">
                  <el-icon><Switch /></el-icon> 立即转换
                </el-button>
                <el-button type="success" @click="handleDownload(currentDoc!)">
                  <el-icon><Download /></el-icon> 下载原文档
                </el-button>
              </div>
            </template>
          </el-result>
        </div>

        <div v-if="isHtmlPage && !previewLoading && !isOfficeDoc" class="preview-tip">
          <el-alert
            title="网页预览提示"
            type="info"
            description="由于外部网站的安全限制，某些网页可能无法在此处正常预览。如果显示异常，请点击右上角按钮在新窗口中查看。"
            show-icon
            :closable="false"
          />
        </div>
        <iframe 
          v-if="previewUrl && !(isOfficeDoc && previewDocType === 'original')" 
          :src="proxyPreviewUrl" 
          width="100%" 
          height="100%" 
          frameborder="0"
          allow="fullscreen"
          @load="previewLoading = false"
        ></iframe>
      </div>
    </el-dialog>
    
    <!-- 入库设置弹窗 -->
    <el-dialog v-model="ingestDialogVisible" title="入库设置" width="400px">
      <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">
          <el-button @click="ingestDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmIngest" :loading="ingesting">
            确认入库
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 加入任务设置弹窗 -->
    <el-dialog v-model="taskDialogVisible" title="加入标注任务" width="450px">
      <el-form :model="taskForm" :rules="taskRules" ref="taskFormRef" label-width="100px">
        <el-form-item label="项目名称" prop="project_name">
          <el-input v-model="taskForm.project_name" placeholder="请输入项目名称" clearable />
        </el-form-item>
        <el-form-item label="任务标签" prop="tags">
          <div class="tag-group">
            <el-tag
              v-for="(tag, index) in taskForm.selectedTags"
              :key="tag.id"
              closable
              @close="handleRemoveTag(index)"
              type="info"
              class="tag-item"
            >
              {{ tag.name }}
            </el-tag>
            <el-cascader
              :key="cascaderKey"
              v-model="tempTagValue"
              :options="tagTree"
              :props="{ checkStrictly: true, emitPath: false }"
              placeholder="添加标签"
              @change="handleAddTag"
              filterable
              clearable
              class="tag-adder"
            >
              <template #default="{ data }">
                <span>{{ data.label }}</span>
              </template>
            </el-cascader>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="taskDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmAddTask" :loading="taskAdding">
            确认加入
          </el-button>
        </span>
      </template>
    </el-dialog>

      <div class="pagination-container" v-if="total > 0">
        <el-pagination
          v-model:current-page="searchQuery.page"
          v-model:page-size="searchQuery.size"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 上传文档对话框 -->
    <el-dialog v-model="uploadDialogVisible" title="上传文档" width="500px">
      <el-form :model="uploadForm" :rules="commonRules" ref="uploadFormRef" label-width="120px" v-loading="uploadingFile" element-loading-text="正在上传文件到服务器...">
        <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" />
            <el-option label="办公制度" value="regulation" />
            <el-option label="其他文档" value="other" />
          </el-select>
        </el-form-item>
        <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"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="文档标题" prop="title">
          <el-input v-model="uploadForm.title" placeholder="请输入文档标题" />
        </el-form-item>
        <el-form-item label="文档链接" v-if="false">
          <el-input v-model="uploadForm.file_url" placeholder="请输入文档链接 (URL) 或通过下方上传文件" />
        </el-form-item>
        <el-form-item label="文件上传">
          <el-upload
            ref="uploadRef"
            class="upload-demo"
            action="#"
            :http-request="customUpload"
            :limit="1"
            :on-exceed="handleExceed"
            :before-upload="beforeUpload"
          >
            <el-button type="primary">点击上传</el-button>
            <template #tip>
              <div class="el-upload__tip">
                支持 PDF, Word, Excel, PPT, TXT 等文件，最大 50MB
              </div>
            </template>
          </el-upload>
        </el-form-item>
        <el-form-item label="文档备注">
          <el-input v-model="uploadForm.note" type="textarea" :rows="4" placeholder="请输入文档备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="uploadDialogVisible = false" :disabled="uploadingFile">取消</el-button>
        <el-button type="primary" @click="submitUpload" :loading="submitting" :disabled="uploadingFile">确定</el-button>
      </template>
    </el-dialog>

    <!-- 编辑文档对话框 -->
    <el-dialog v-model="editDialogVisible" :title="formTitle" width="800px">
      <el-form :model="editForm" :rules="commonRules" ref="editFormRef" label-width="110px">
        <el-row :gutter="20">
          <el-col :span="12">
            <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"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item :label="titleLabel" prop="title">
              <el-input v-model="editForm.title" :placeholder="'请输入' + titleLabel" disabled />
            </el-form-item>
          </el-col>
          
          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="英文名称">
              <el-input v-model="editForm.english_name" placeholder="请输入英文名称" />
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="* 标准编号">
              <el-input v-model="editForm.standard_no" placeholder="请输入标准编号" />
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item :label="'* ' + authorityLabel">
              <el-input v-model="editForm.issuing_authority" :placeholder="'请输入' + authorityLabel" />
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item :label="'* ' + dateLabel">
              <el-date-picker v-model="editForm.release_date" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%" />
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="* 实施日期">
              <el-date-picker v-model="editForm.implementation_date" type="date" placeholder="选择实施日期" value-format="YYYY-MM-DD" style="width: 100%" />
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard' || editForm.table_type === 'regulation'">
            <el-form-item :label="editForm.table_type === 'standard' ? '* 文件类型' : '文件类型'">
              <el-select v-model="editForm.document_type" placeholder="请选择文件类型" style="width: 100%">
                <el-option v-for="item in documentTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="* 专业领域">
              <el-select v-model="editForm.professional_field" placeholder="请选择专业领域" style="width: 100%">
                <el-option v-for="item in professionalFieldOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="* 时效性">
              <el-select v-model="editForm.validity" placeholder="请选择时效性" style="width: 100%">
                <el-option v-for="item in validityOptions" :key="item.value" :label="item.label" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="* 起草单位">
              <el-input v-model="editForm.drafting_unit" placeholder="请输入起草单位" />
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="* 批准部门">
              <el-input v-model="editForm.approving_department" placeholder="请输入批准部门" />
            </el-form-item>
          </el-col>

          <el-col :span="24" v-if="editForm.table_type === 'standard'">
            <el-form-item label="参编单位">
              <div v-for="(unit, index) in participatingUnitsList" :key="index" class="dynamic-input-row">
                <el-input v-model="participatingUnitsList[index]" placeholder="请输入参编单位" />
                <div class="row-actions">
                  <el-button :icon="Plus" circle size="small" @click="addListItem(participatingUnitsList)" />
                  <el-button :icon="Minus" circle size="small" type="danger" @click="removeListItem(participatingUnitsList, index)" v-if="participatingUnitsList.length > 1" />
                </div>
              </div>
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="工程阶段">
              <el-input v-model="editForm.engineering_phase" placeholder="请输入工程阶段" />
            </el-form-item>
          </el-col>

          <el-col :span="24" v-if="editForm.table_type === 'standard'">
            <el-form-item label="引用依据">
              <div v-for="(std, index) in referenceBasisList" :key="index" class="dynamic-input-row">
                <el-input v-model="referenceBasisList[index]" placeholder="请输入引用依据" />
                <div class="row-actions">
                  <el-button :icon="Plus" circle size="small" @click="addListItem(referenceBasisList)" />
                  <el-button :icon="Minus" circle size="small" type="danger" @click="removeListItem(referenceBasisList, index)" v-if="referenceBasisList.length > 1" />
                </div>
              </div>
            </el-form-item>
          </el-col>

          <el-col :span="12" v-if="editForm.table_type === 'standard'">
            <el-form-item label="来源链接">
              <el-input v-model="editForm.source_url" placeholder="请输入来源链接" />
            </el-form-item>
          </el-col>

          <template v-if="editForm.table_type === 'construction_plan'">
            <el-col :span="12">
              <el-form-item label="* 项目名称">
                <el-input v-model="editForm.project_name" placeholder="请输入项目名称" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="项目标段">
                <el-input v-model="editForm.project_section" placeholder="请输入项目标段" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="* 方案类别">
                <el-select v-model="editForm.plan_category" placeholder="请选择方案类别" style="width: 100%">
                  <el-option v-for="item in planCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="* 一级分类">
                <el-select v-model="editForm.level_1_classification" placeholder="请选择一级分类" style="width: 100%">
                  <el-option v-for="item in level1Options" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="* 二级分类">
                <el-select v-model="editForm.level_2_classification" placeholder="请选择二级分类" style="width: 100%">
                  <el-option v-for="item in level2Options" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="* 三级分类">
                <el-select v-model="editForm.level_3_classification" placeholder="请选择三级分类" style="width: 100%">
                  <el-option v-for="item in level3Options" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="* 四级分类">
                <el-select v-model="editForm.level_4_classification" placeholder="请选择四级分类" style="width: 100%">
                  <el-option v-for="item in level4Options" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="* 方案摘要">
                <el-input v-model="editForm.plan_summary" type="textarea" :rows="3" placeholder="请输入方案摘要" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="编制依据">
              <div v-for="(planStd, index) in compilationBasisList" :key="index" class="dynamic-input-row">
                <el-input v-model="compilationBasisList[index]" placeholder="请输入编制依据" />
                <div class="row-actions">
                  <el-button :icon="Plus" circle size="small" @click="addListItem(compilationBasisList)" />
                  <el-button :icon="Minus" circle size="small" type="danger" @click="removeListItem(compilationBasisList, index)" v-if="compilationBasisList.length > 1" />
                </div>
              </div>
            </el-form-item>
            </el-col>
          </template>

          <template v-if="editForm.table_type === 'regulation'">
            <el-col :span="12">
              <el-form-item label="生效日期">
                <el-date-picker v-model="editForm.effective_start_date" type="date" placeholder="选择生效日期" value-format="YYYY-MM-DD" style="width: 100%" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="失效日期">
                <el-date-picker v-model="editForm.effective_end_date" type="date" placeholder="选择失效日期" value-format="YYYY-MM-DD" style="width: 100%" />
              </el-form-item>
            </el-col>
          </template>

          <el-col :span="24">
            <el-form-item label="备注">
              <el-input v-model="editForm.note" type="textarea" :rows="2" placeholder="请输入备注" />
            </el-form-item>
          </el-col>

          <el-col :span="24">
            <el-form-item label="上传文件">
              <div class="file-info-edit">
                <el-tag type="info" size="large" class="file-tag">
                  <el-icon><Document /></el-icon>
                  <span>文件已锁定（编辑模式不可更改）</span>
                </el-tag>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button @click="editDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitEdit" :loading="submitting">确定</el-button>
      </template>
    </el-dialog>

    <!-- 文档详情对话框 -->
    <el-dialog v-model="detailDialogVisible" title="文档详情" width="600px">
      <el-descriptions :column="1" border>
        <el-descriptions-item label="名称">{{ currentDoc?.title }}</el-descriptions-item>
        <el-descriptions-item label="基本信息类型">{{ getSourceTypeName(currentDoc?.source_type) }}</el-descriptions-item>
        <el-descriptions-item label="上传人">{{ currentDoc?.creator_name || '-' }}</el-descriptions-item>
        <el-descriptions-item label="上传时间">{{ formatDate(currentDoc?.created_time) }}</el-descriptions-item>
        <el-descriptions-item label="最后修改人" v-if="currentDoc?.updater_name">{{ currentDoc?.updater_name }}</el-descriptions-item>
        <el-descriptions-item label="修改时间" v-if="currentDoc?.updated_time">{{ formatDate(currentDoc?.updated_time) }}</el-descriptions-item>
        <el-descriptions-item label="入库状态">
          <el-tag :type="isEntered(currentDoc?.whether_to_enter) ? 'success' : 'info'">
            {{ isEntered(currentDoc?.whether_to_enter) ? '已入库' : '未入库' }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="所属知识库" v-if="currentDoc?.kb_name">
          <span class="kb-name-tag">
            <el-icon><Tickets /></el-icon> {{ currentDoc.kb_name }}
          </span>
        </el-descriptions-item>
        <el-descriptions-item label="文档备注">
          <div class="content-preview">{{ currentDoc?.note || '暂无备注' }}</div>
        </el-descriptions-item>
        
        <!-- 施工标准规范特有详情 -->
        <template v-if="currentDoc?.source_type === 'standard'">
          <el-descriptions-item label="标准编号">{{ currentDoc?.standard_no || '-' }}</el-descriptions-item>
          <el-descriptions-item label="英文名称">{{ currentDoc?.english_name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="发布单位">{{ currentDoc?.issuing_authority || '-' }}</el-descriptions-item>
          <el-descriptions-item label="发布日期">{{ formatDate(currentDoc?.release_date) }}</el-descriptions-item>
          <el-descriptions-item label="实施日期">{{ formatDate(currentDoc?.implementation_date) }}</el-descriptions-item>
          <el-descriptions-item label="起草单位">{{ currentDoc?.drafting_unit || '-' }}</el-descriptions-item>
          <el-descriptions-item label="批准部门">{{ currentDoc?.approving_department || '-' }}</el-descriptions-item>
          <el-descriptions-item label="文件类型">{{ currentDoc?.document_type || '-' }}</el-descriptions-item>
          <el-descriptions-item label="专业领域">{{ currentDoc?.professional_field || '-' }}</el-descriptions-item>
          <el-descriptions-item label="时效性">{{ getValidityName(currentDoc?.validity) }}</el-descriptions-item>
          <el-descriptions-item label="参编单位">
            <div v-if="currentDoc?.participating_units">
              <div v-for="(unit, idx) in currentDoc.participating_units.split(';')" :key="idx">{{ unit }}</div>
            </div>
            <span v-else>-</span>
          </el-descriptions-item>
          <el-descriptions-item label="引用依据">
            <div v-if="currentDoc?.reference_basis">
              <div v-for="(std, idx) in currentDoc.reference_basis.split(';')" :key="idx">{{ std }}</div>
            </div>
            <span v-else>-</span>
          </el-descriptions-item>
          <el-descriptions-item label="来源 URL">{{ currentDoc?.source_url || '-' }}</el-descriptions-item>
          <el-descriptions-item label="工程阶段">{{ currentDoc?.engineering_phase || '-' }}</el-descriptions-item>
        </template>

        <!-- 施工方案特有详情 -->
        <template v-else-if="currentDoc?.source_type === 'construction_plan'">
          <el-descriptions-item label="工程名称">{{ currentDoc?.project_name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="英文名称">{{ currentDoc?.english_name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="工程标段">{{ currentDoc?.project_section || '-' }}</el-descriptions-item>
          <el-descriptions-item label="方案类别">{{ currentDoc?.plan_category || '-' }}</el-descriptions-item>
          <el-descriptions-item label="一级分类">{{ currentDoc?.level_1_classification || '-' }}</el-descriptions-item>
          <el-descriptions-item label="二级分类">{{ currentDoc?.level_2_classification || '-' }}</el-descriptions-item>
          <el-descriptions-item label="三级分类">{{ currentDoc?.level_3_classification || '-' }}</el-descriptions-item>
          <el-descriptions-item label="四级分类">{{ currentDoc?.level_4_classification || '-' }}</el-descriptions-item>
          <el-descriptions-item label="编制单位">{{ currentDoc?.issuing_authority || '-' }}</el-descriptions-item>
          <el-descriptions-item label="编制日期">{{ formatDate(currentDoc?.release_date) }}</el-descriptions-item>
          <el-descriptions-item label="方案摘要">
            <div class="content-preview">{{ currentDoc?.plan_summary || '-' }}</div>
          </el-descriptions-item>
          <el-descriptions-item label="编制依据">
            <div v-if="currentDoc?.compilation_basis">
              <div v-for="(planStd, idx) in currentDoc.compilation_basis.split(';')" :key="idx">{{ planStd }}</div>
            </div>
            <span v-else>-</span>
          </el-descriptions-item>
        </template>

        <!-- 办公制度特有详情 -->
        <template v-else-if="currentDoc?.source_type === 'regulation'">
          <el-descriptions-item label="发布部门">{{ currentDoc?.issuing_authority || '-' }}</el-descriptions-item>
          <el-descriptions-item label="英文名称">{{ currentDoc?.english_name || '-' }}</el-descriptions-item>
          <el-descriptions-item label="制度类型">{{ currentDoc?.document_type || '-' }}</el-descriptions-item>
          <el-descriptions-item label="发布日期">{{ formatDate(currentDoc?.release_date) }}</el-descriptions-item>
          <el-descriptions-item label="生效日期">{{ formatDate(currentDoc?.effective_start_date) }}</el-descriptions-item>
          <el-descriptions-item label="失效日期">{{ formatDate(currentDoc?.effective_end_date) }}</el-descriptions-item>
        </template>
      </el-descriptions>
      <template #footer>
        <div class="detail-footer">
          <div class="download-group" v-if="currentDoc">
            <el-button type="success" plain size="small" @click="handleDownload(currentDoc)" v-if="currentDoc.file_url">
              <el-icon><Download /></el-icon> 下载原文件
            </el-button>
            <el-button type="primary" plain size="small" @click="handleDownloadConverted(currentDoc)" v-if="currentDoc.md_url">
              <el-icon><Download /></el-icon> 下载 MD
            </el-button>
            <el-button type="warning" plain size="small" @click="handleDownloadJson(currentDoc)" v-if="currentDoc.json_url">
              <el-icon><Download /></el-icon> 下载 JSON
            </el-button>
          </div>
          <div class="action-group">
            <el-button @click="detailDialogVisible = false">关闭</el-button>
            <el-button type="primary" @click="handleEditFromDetail" v-if="currentDoc">
              <el-icon><Edit /></el-icon> 编辑文档
            </el-button>
            <el-button type="success" @click="handleSingleEnter(currentDoc)" v-if="currentDoc && !isEntered(currentDoc.whether_to_enter)">文档入库</el-button>
            <el-button type="primary" @click="handlePreview(currentDoc)" v-if="currentDoc?.file_url">预览原文档</el-button>
          </div>
        </div>
      </template>
    </el-dialog>


  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Filter, Upload, CircleCheck, Delete, Document, Warning, TopRight, Grid, DataAnalysis, Link, View, Switch, Edit, User, Download, Plus, Minus, Tickets, Refresh } from '@element-plus/icons-vue'
import request from '@/api/request'
import axios from 'axios'
import { downloadFile } from '@/utils/download'
import { getFileExtension } from '@/utils/file'
import { useAuthStore } from '@/stores/auth'
import dayjs from 'dayjs'
import type { ApiResponse } from '@/types/auth'
import { documentApi, type DocumentItem } from '@/api/document'
import { getKnowledgeBases } from '@/api/knowledge-base'
import { dictApi, type DictItem } from '@/api/dict'

// 接口定义已移至 @/api/document

// 状态变量
const loading = ref(false)
const uploadingFile = ref(false)
const submitting = ref(false)
const uploadRef = ref<any>(null)
const uploadDialogVisible = ref(false)
const editDialogVisible = ref(false)
const detailDialogVisible = ref(false)
const previewVisible = ref(false)
const previewLoading = ref(false)
const previewTitle = ref('')
const previewUrl = ref('')
const previewDocType = ref('') // 'original' or 'md'

// 入库相关状态
const ingesting = ref(false)
const ingestDialogVisible = ref(false)
const ingestForm = reactive({
  kb_method: 'length',
  chunk_size: 500,
  separator: '。'
})

// 任务相关状态
const taskAdding = ref(false)
const taskDialogVisible = ref(false)
const tempTagValue = ref<number | null>(null)
const cascaderKey = ref(0)
const taskForm = reactive({
  project_name: '',
  selectedTags: [] as { id: number, name: string }[]
})

// 标签相关
const tagTree = ref<any[]>([])

const handleAddTag = (val: any) => {
  if (!val) return
  const id = val
  const name = findTagName(tagTree.value, id)
  if (name && !taskForm.selectedTags.find(t => t.id === id)) {
    taskForm.selectedTags.push({ id, name })
  }
  // 清空选择器并增加 key 以强制重置 (清除搜索缓存等)
  tempTagValue.value = null
  cascaderKey.value++
}

const handleRemoveTag = (index: number) => {
  taskForm.selectedTags.splice(index, 1)
}

const findTagName = (nodes: any[], id: number): string | null => {
  for (const node of nodes) {
    if (node.value === id) return node.label
    if (node.children) {
      const name = findTagName(node.children, id)
      if (name) return name
    }
  }
  return null
}
const fetchTagTree = async () => {
  try {
    const res = await documentApi.getTagTree()
    if (res.code === 200) {
      tagTree.value = formatTagTree(res.data)
    }
  } catch (error) {
    console.error('获取标签树失败:', error)
  }
}

// 格式化标签树以适应 Cascader
const formatTagTree = (data: any[]) => {
  return data.map(node => ({
    value: node.id,
    label: node.name,
    children: node.children && node.children.length > 0 ? formatTagTree(node.children) : undefined
  }))
}

const taskRules = {
  project_name: [
    { required: true, message: '请输入项目名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ]
}

const taskFormRef = ref()
const ingestFormRef = ref()
const uploadFormRef = ref()
const editFormRef = ref()
const multipleTableRef = 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({
  allTotal: 0,
  totalEntered: 0
})
const authStore = useAuthStore()
const documents = ref<DocumentItem[]>([])
const currentDoc = ref<DocumentItem | null>(null)

const editForm = reactive({
  id: '',
  title: '',
  note: '',
  table_type: 'standard' as 'standard' | 'construction_plan' | 'regulation' | 'other',
  year: new Date().getFullYear(),
  // 扩展字段 (子表特有属性)
  standard_no: '',
  issuing_authority: '',
  release_date: '',
  document_type: '',
  professional_field: '',
  validity: '',
  project_name: '',
  project_section: '',
  plan_category: '',
  level_1_classification: '施工方案',
  level_2_classification: '',
  level_3_classification: '',
  level_4_classification: '',
  plan_summary: '',
  compilation_basis: '',
  file_url: '',
  // 补全缺失字段
  english_name: '',
  implementation_date: '',
  drafting_unit: '',
  approving_department: '',
  engineering_phase: '',
  participating_units: '',
  reference_basis: '',
  source_url: '',
  effective_start_date: '',
  effective_end_date: '',
  kb_id: ''
})

const participatingUnitsList = ref<string[]>([''])
const referenceBasisList = ref<string[]>([''])
const compilationBasisList = ref<string[]>([''])

// 字典选项（从字典表动态加载）
const documentTypeOptions = ref<Array<{ label: string, value: string }>>([])
const professionalFieldOptions = ref<Array<{ label: string, value: string }>>([])
const validityOptions = ref<Array<{ label: string, value: string }>>([])
const planCategoryOptions = ref<Array<{ label: string, value: string }>>([])
const level1Options = ref<Array<{ label: string, value: string }>>([])
const level2Options = ref<Array<{ label: string, value: string }>>([])
const level3Options = ref<Array<{ label: string, value: string }>>([])
const level4Options = ref<Array<{ label: string, value: string }>>([])

// 加载字典选项
const loadDictOptions = async () => {
  try {
    // 加载文件类型字典
    const fileTypeRes = await dictApi.getItemList({
      category_id: 'file_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (fileTypeRes.code === '000000' || fileTypeRes.code === 0) {
      documentTypeOptions.value = fileTypeRes.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载专业类型字典
    const professionalTypeRes = await dictApi.getItemList({
      category_id: 'professional_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (professionalTypeRes.code === '000000' || professionalTypeRes.code === 0) {
      professionalFieldOptions.value = professionalTypeRes.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载时效性字典
    const validityRes = await dictApi.getItemList({
      category_id: 'time_effect',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (validityRes.code === '000000' || validityRes.code === 0) {
      validityOptions.value = validityRes.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载施工方案类别字典
    const planTypeRes = await dictApi.getItemList({
      category_id: 'construction_plan_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (planTypeRes.code === '000000' || planTypeRes.code === 0) {
      planCategoryOptions.value = planTypeRes.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载一级分类字典
    const level1Res = await dictApi.getItemList({
      category_id: 'construction_plan_first_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (level1Res.code === '000000' || level1Res.code === 0) {
      level1Options.value = level1Res.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载二级分类字典
    const level2Res = await dictApi.getItemList({
      category_id: 'construction_plan_second_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (level2Res.code === '000000' || level2Res.code === 0) {
      level2Options.value = level2Res.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载三级分类字典
    const level3Res = await dictApi.getItemList({
      category_id: 'construction_plan_third_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (level3Res.code === '000000' || level3Res.code === 0) {
      level3Options.value = level3Res.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }

    // 加载四级分类字典
    const level4Res = await dictApi.getItemList({
      category_id: 'construction_plan_fourth_type',
      enable_flag: '1',
      page: 1,
      page_size: 100
    })
    if (level4Res.code === '000000' || level4Res.code === 0) {
      level4Options.value = level4Res.data.list.map((item: DictItem) => ({
        label: item.dict_name,
        value: item.dict_value
      }))
    }
  } catch (error) {
    console.error('加载字典选项失败:', error)
  }
}

// 列表项管理
const addListItem = (list: string[]) => {
  list.push('')
}

const removeListItem = (list: string[], index: number) => {
  if (list.length > 1) {
    list.splice(index, 1)
  } else {
    list[0] = ''
  }
}

const currentTitle = computed(() => {
  return '文档管理中心'
})

const formTitle = computed(() => {
  const typeMap: Record<string, string> = {
    standard: '施工标准规范',
    construction_plan: '施工方案',
    regulation: '办公制度',
    other: '其他文档'
  }
  return `编辑${typeMap[editForm.table_type] || ''}`
})

const titleLabel = computed(() => {
  if (editForm.table_type === 'standard') return '标准名称'
  if (editForm.table_type === 'construction_plan') return '方案名称'
  if (editForm.table_type === 'regulation') return '制度名称'
  return '文档名称'
})

const authorityLabel = computed(() => {
  if (editForm.table_type === 'standard') return '发布单位'
  if (editForm.table_type === 'construction_plan') return '编制单位'
  if (editForm.table_type === 'regulation') return '发布部门'
  return '发布机构'
})

const dateLabel = computed(() => {
  if (editForm.table_type === 'standard') return '发布日期'
  if (editForm.table_type === 'construction_plan') return '编制日期'
  if (editForm.table_type === 'regulation') return '发布日期'
  return '日期'
})

const selectedIds = ref<string[]>([])

const searchQuery = reactive({
  keyword: '',
  table_type: null as string | null,
  whether_to_enter: null as number | null,
  conversion_status: null as number | null,
  page: 1,
  size: 10
})

const uploadForm = reactive({
  title: '',
  note: '',
  file_url: '',
  table_type: 'standard' as 'standard' | 'construction_plan' | 'regulation' | 'other',
  year: new Date().getFullYear(),
  kb_id: ''
})

// 知识库列表
const kbOptions = ref<{ label: string, value: string }[]>([])
const loadKbOptions = async () => {
  try {
    const res = await getKnowledgeBases({ page_size: 100 })
    if (res.code === '000000' || res.code === 0) {
      kbOptions.value = res.data.map((item: any) => ({
        label: item.name,
        value: item.id
      }))
    }
  } catch (error) {
    console.error('加载知识库选项失败', error)
  }
}

// 计算属性
const proxyPreviewUrl = computed(() => {
  if (!previewUrl.value) return ''
  // 使用后端代理接口查看外部网页，附加 token 以通过认证
  let baseUrl = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'
  if (baseUrl.includes('localhost') && window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
    baseUrl = baseUrl.replace('localhost', window.location.hostname)
  }
  return `${baseUrl}/api/v1/sample/documents/proxy-view?url=${encodeURIComponent(previewUrl.value)}&token=${authStore.token}`
})

const isHtmlPage = computed(() => {
  if (!previewUrl.value) return false
  const url = previewUrl.value.toLowerCase()
  return url.includes('html') || url.includes('newgbinfo') || !url.split(/[?#]/)[0].includes('.')
})

// 方法
const formatSimpleDate = (date: string | null) => {
  if (!date) return '-'
  return dayjs(date).format('YYYY-MM-DD')
}

const formatDate = (date: string | undefined | null, formatStr: string = 'YYYY-MM-DD HH:mm:ss') => {
  return date ? dayjs(date).format(formatStr) : '-'
}



const getFileIcon = (row: DocumentItem) => {
  const ext = getFileExtension(row).replace('.', '').toLowerCase()
  if (['pdf'].includes(ext)) return 'pdf'
  if (['doc', 'docx'].includes(ext)) return 'word'
  if (['xls', 'xlsx'].includes(ext)) return 'excel'
  if (['ppt', 'pptx'].includes(ext)) return 'ppt'
  if (['html', 'htm'].includes(ext)) return 'html'
  return 'file'
}

const getFileIconClass = (row: DocumentItem) => {
  return `icon-${getFileIcon(row)}`
}

const getValidityName = (val: string | null | undefined) => {
  const names: Record<string, string> = {
    XH: '现行',
    FZ: '废止',
    SX: '试行'
  }
  return names[val || ''] || val || '-'
}

const getSourceTypeName = (sourceType: string | null | undefined) => {
  const names: Record<string, string> = {
    standard: '施工标准规范',
    construction_plan: '施工方案',
    regulation: '办公制度',
    other: '其他文档'
  }
  return names[sourceType || ''] || '未知类型'
}

const getSourceTypeShortName = (sourceType: string | null | undefined) => {
  const names: Record<string, string> = {
    standard: '标准规范',
    construction_plan: '施工方案',
    regulation: '办公制度',
    other: '其他'
  }
  return names[sourceType || ''] || '未知'
}

const getKBTagType = (sourceType: string | null | undefined) => {
  const types: Record<string, string> = {
    standard: 'primary',
    construction_plan: 'success',
    regulation: 'warning',
    other: 'info'
  }
  return types[sourceType || ''] || 'info'
}

// 为已入库或未转化的行添加特定类名
const tableRowClassName = ({ row }: { row: DocumentItem }) => {
  return ''
}

// 判断是否可以勾选（所有文档均可勾选，用于批量删除等操作）
const canSelect = (row: DocumentItem) => {
  return true
}

const handleSelectionChange = (selection: DocumentItem[]) => {
  selectedIds.value = selection.map(item => item.id)
}

const confirmIngest = async () => {
  if (selectedIds.value.length === 0) {
    ElMessage.warning('请先选择要入库的文档')
    return
  }

  if (!ingestFormRef.value) return
  
  try {
    await ingestFormRef.value.validate()
  } catch (error) {
    return
  }
  
  ingesting.value = true
  try {
    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
    })
    
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success(res.message || '已加入入库队列')
      selectedIds.value = []
      multipleTableRef.value?.clearSelection()
      ingestDialogVisible.value = false
      fetchDocuments()
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('入库失败:', error)
    }
  } finally {
    ingesting.value = false
  }
}

// 提取字段检查逻辑
const checkDocumentsCompleteness = async (ids: string[]) => {
  loading.value = true
  try {
    const detailPromises = ids.map(id => documentApi.getDetail(id))
    const detailResults = await Promise.all(detailPromises)
    const docs = detailResults.map(res => res.data)
    
    let isIncomplete = false
    let missingFields: string[] = []
    
    for (const doc of docs) {
      const type = doc.source_type || searchQuery.table_type
      
      if (type === 'standard') {
        const standardFields = [
          { key: 'standard_no', label: '标准编号' },
          { key: 'issuing_authority', label: '发布单位' },
          { key: 'release_date', label: '发布日期' },
          { key: 'implementation_date', label: '实施日期' },
          { key: 'document_type', label: '文件类型' },
          { key: 'professional_field', label: '专业领域' },
          { key: 'validity', label: '时效性' },
          { key: 'drafting_unit', label: '起草单位' },
          { key: 'approving_department', label: '批准部门' }
        ]
        for (const f of standardFields) {
          const val = doc[f.key as keyof typeof doc]
          if (val === null || val === undefined || (typeof val === 'string' && val.trim() === '')) {
            isIncomplete = true
            if (!missingFields.includes(f.label)) missingFields.push(f.label)
          }
        }
      } else if (type === 'construction_plan') {
        const planFields = [
          { key: 'issuing_authority', label: '编制单位' },
          { key: 'release_date', label: '编制日期' },
          { key: 'project_name', label: '项目名称' },
          { key: 'plan_category', label: '方案类型' },
          { key: 'level_1_classification', label: '一级分类' },
          { key: 'level_2_classification', label: '二级分类' },
          { key: 'level_3_classification', label: '三级分类' },
          { key: 'level_4_classification', label: '四级分类' },
          { key: 'plan_summary', label: '方案摘要' }
        ]
        for (const f of planFields) {
          const val = doc[f.key as keyof typeof doc]
          if (val === null || val === undefined || (typeof val === 'string' && val.trim() === '')) {
            isIncomplete = true
            if (!missingFields.includes(f.label)) missingFields.push(f.label)
          }
        }
      }
      if (isIncomplete && ids.length === 1) break
    }

    if (isIncomplete) {
      loading.value = false // 弹出确认框前先关闭 loading
      try {
        await ElMessageBox.confirm(
          '该文档基本信息其中某几个字段未补充完善，可能导致无法检索的问题，你是否继续？',
          '提示',
          {
            confirmButtonText: '继续',
            cancelButtonText: '取消',
            type: 'warning',
          }
        )
        return true
      } catch (error) {
        return false
      }
    }
    loading.value = false // 检查完成，关闭 loading
    return true
  } catch (error) {
    loading.value = false // 出错时也关闭 loading
    console.error('检查文档完善度失败:', error)
    ElMessage.error('检查文档完善度失败，请重试')
    return false
  } finally {
    // 确保 loading 在所有路径下都被正确关闭
    loading.value = false
  }
}

const handleBatchEnter = async () => {
  if (selectedIds.value.length === 0) {
    ElMessage.warning('请先选择要入库的文档')
    return
  }
  
  // 先检查字段完善度
  const canContinue = await checkDocumentsCompleteness(selectedIds.value)
  if (!canContinue) return

  // 校验通过后，显示入库设置弹窗
  ingestForm.kb_method = 'length'
  ingestForm.chunk_size = 500
  ingestForm.separator = '。'
  
  if (ingestFormRef.value) {
    ingestFormRef.value.clearValidate()
  }
  
  ingestDialogVisible.value = true
}

const handleBatchAddToTask = async () => {
  if (selectedIds.value.length === 0) {
    ElMessage.warning('请先选择要加入任务的文档')
    return
  }

  // 检查是否有未入库的数据
  const unenteredDocs = documents.value.filter(doc => selectedIds.value.includes(doc.id) && !isEntered(doc.whether_to_enter))
  if (unenteredDocs.length > 0) {
    ElMessage.warning(`选中数据中包含 ${unenteredDocs.length} 份未入库文档，只有已入库的文档可以加入标注任务。`)
    return
  }

  // 显示任务弹窗（填入项目名称和标签），不再进行字段检查
  taskForm.project_name = ''
  taskForm.selectedTags = []
  tempTagValue.value = null
  if (taskFormRef.value) {
    taskFormRef.value.clearValidate()
  }
  
  if (tagTree.value.length === 0) {
    await fetchTagTree()
  }
  
  taskDialogVisible.value = true
}

const confirmAddTask = async () => {
  if (!taskFormRef.value) return
  
  try {
    await taskFormRef.value.validate()
  } catch (error) {
    return
  }

  taskAdding.value = true
  try {
    const tags = taskForm.selectedTags.map(t => t.name)
    const res = await documentApi.batchAddToTask(selectedIds.value, taskForm.project_name, tags)

    if (res.code === '000000' || res.code === 0) {
      ElMessage.success(res.message || '操作成功')
      selectedIds.value = []
      multipleTableRef.value?.clearSelection()
      taskDialogVisible.value = false
      fetchDocuments()
    } else {
      ElMessage.error(res.message || '操作失败')
    }
  } catch (error: any) {
    console.error('批量加入任务失败:', error)
    ElMessage.error('操作失败')
  } finally {
    taskAdding.value = false
  }
}

const handleSingleEnter = async (doc: DocumentItem | null) => {
  if (!doc) return
  
  // 先检查字段完善度
  const canContinue = await checkDocumentsCompleteness([doc.id])
  if (!canContinue) return

  selectedIds.value = [doc.id]
  ingestForm.kb_method = 'length'
  ingestForm.chunk_size = 500
  ingestForm.separator = '。'
  
  if (ingestFormRef.value) {
    ingestFormRef.value.clearValidate()
  }
  
  ingestDialogVisible.value = true
}

const handleDelete = async (row: DocumentItem) => {
  if (isEntered(row.whether_to_enter)) {
    ElMessage.warning(`文档 "${row.title}" 已入库，请先执行“清空数据”操作后再删除。`)
    return
  }
  try {
    await ElMessageBox.confirm(
      `确定要删除文档 "${row.title}" 吗？此操作不可恢复。`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
    
    const res = await documentApi.batchDelete([row.id])
    
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success('删除成功')
      fetchDocuments()
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除文档失败:', error)
      ElMessage.error('删除失败')
    }
  }
}

const handleBatchDelete = async () => {
  if (selectedIds.value.length === 0) return
  
  // 检查是否有已入库的数据
  const enteredDocs = documents.value.filter(doc => selectedIds.value.includes(doc.id) && isEntered(doc.whether_to_enter))
  if (enteredDocs.length > 0) {
    ElMessage.warning(`选中数据中包含 ${enteredDocs.length} 份已入库文档，请先执行“清空数据”操作后再删除。`)
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要批量删除选中的 ${selectedIds.value.length} 条文档吗？此操作不可恢复。`,
      '确认批量删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
    
    const res = await documentApi.batchDelete(selectedIds.value)
    
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success(res.message || '批量删除成功')
      selectedIds.value = []
      multipleTableRef.value?.clearSelection()
      fetchDocuments()
    } else {
      ElMessage.error(res.message || '批量删除失败')
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      ElMessage.error('操作失败')
    }
  }
}

const handleBatchClear = async () => {
  if (selectedIds.value.length === 0) {
    ElMessage.warning('请先选择要清空数据的文档')
    return
  }

  // 过滤出已入库的文档
  const enteredIds = documents.value
    .filter(doc => selectedIds.value.includes(doc.id) && isEntered(doc.whether_to_enter))
    .map(doc => doc.id)
  
  if (enteredIds.length === 0) {
    ElMessage.info('所选文档均未入库，无需清空')
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要清空选中的 ${enteredIds.length} 份文档的知识库片段吗？清空后文档将变为“未入库”状态，且可以被删除。`,
      '确认清空数据',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    )
    
    loading.value = true
    const res = await documentApi.batchClear(enteredIds)
    
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success(res.message || '数据清空成功')
      selectedIds.value = []
      multipleTableRef.value?.clearSelection()
      fetchDocuments()
    } else {
      ElMessage.error(res.message || '数据清空失败')
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('清空数据失败:', error)
      ElMessage.error('操作失败')
    }
  } finally {
    loading.value = false
  }
}

const isEntered = (val: any) => {
  return val === 1 || val === true
}

const getConversionStatusTag = (row: DocumentItem) => {
  switch (row.conversion_status) {
    case 1: return 'warning'   // 转换中
    case 2: return 'success'   // 成功
    case 3: return 'danger'    // 失败
    default: return 'info'     // 未转换 (0)
  }
}

const getConversionStatusText = (row: DocumentItem) => {
  switch (row.conversion_status) {
    case 1: return '转换中'
    case 2: return '转换成功'
    case 3: return '转换失败'
    default: return '未转换'
  }
}

const fetchDocuments = async () => {
  loading.value = true
  try {
    const res = await documentApi.getList(searchQuery)
    if (res.code === '000000' || res.code === 0) {
      documents.value = res.data.items
      total.value = res.data.total
      statistics.value.allTotal = res.data.all_total || 0
      statistics.value.totalEntered = res.data.total_entered || 0
      
      // 自动检查是否需要开启轮询
      const hasConverting = documents.value.some(doc => doc.conversion_status === 1)
      if (hasConverting) {
        startPolling()
      } else {
        stopPolling()
      }
    }
  } catch (error) {
    console.error('获取文档列表失败:', error)
  } finally {
    loading.value = false
  }
}

const isRefreshing = ref(false)
const refreshTimer = ref<any>(null)

const startPolling = () => {
  if (refreshTimer.value === null) {
    refreshTimer.value = window.setTimeout(refreshDocumentsSilently, 5000)
  }
}

const stopPolling = () => {
  if (refreshTimer.value) {
    window.clearTimeout(refreshTimer.value)
    refreshTimer.value = null
  }
}

const refreshDocumentsSilently = async () => {
  if (isRefreshing.value) return
  isRefreshing.value = true
  try {
    const res = await documentApi.getList(searchQuery, true)
    if (res.code === '000000' || res.code === 0) {
      documents.value = res.data.items
      total.value = res.data.total
      statistics.value.allTotal = res.data.all_total || 0
      statistics.value.totalEntered = res.data.total_entered || 0
      
      // 检查是否还需要继续轮询
      const hasConverting = documents.value.some(doc => doc.conversion_status === 1)
      if (!hasConverting) {
        // 如果当前没有转换中的文档，不要立即停止，延迟一个周期再检查
        // 这样可以避免转换任务刚提交但状态还没更新到 1 的情况
        setTimeout(() => {
          const stillNoConverting = documents.value.some(doc => doc.conversion_status === 1)
          if (!stillNoConverting) {
            stopPolling()
          }
        }, 5000)
      }
    }
  } catch (error) {
    console.error('静默刷新失败:', error)
  } finally {
    isRefreshing.value = false
    // 如果没有手动停止，且组件未卸载，则安排下一次刷新
    if (refreshTimer.value !== null) {
      refreshTimer.value = window.setTimeout(refreshDocumentsSilently, 5000)
    }
  }
}

const handleSearch = () => {
  searchQuery.page = 1
  fetchDocuments()
}

const handleSizeChange = (val: number) => {
  searchQuery.size = val
  fetchDocuments()
}

const handleCurrentChange = (val: number) => {
  searchQuery.page = val
  fetchDocuments()
}

const beforeUpload = (file: File) => {
  const isLt50M = file.size / 1024 / 1024 < 50
  if (!isLt50M) {
    ElMessage.error('上传文件大小不能超过 50MB!')
    return false
  }
  return true
}

const handleExceed = () => {
  ElMessage.warning('只能上传一个文件，请先移除已上传的文件')
}

const customUpload = async (options: any) => {
  const { file, onSuccess, onError } = options
  try {
    uploadingFile.value = true
    // 1. 获取预签名 URL
    const res = await documentApi.getUploadUrl(file.name, file.type || 'application/octet-stream', uploadForm.table_type)

    if (res.code !== '000000' && res.code !== 0) {
      throw new Error(res.message || '获取上传链接失败')
    }

    const { upload_url, file_url } = res.data

    // 2. 直接上传到 MinIO (PUT 请求)
    await axios.put(upload_url, file, {
      headers: {
        'Content-Type': file.type || 'application/octet-stream'
      }
    })

    // 3. 上传成功，更新表单
    uploadForm.file_url = file_url
    if (!uploadForm.title) {
      // 如果标题为空，自动填充文件名（去掉后缀）
      uploadForm.title = file.name.replace(/\.[^/.]+$/, "")
    }
    
    ElMessage.success('文件上传成功')
    onSuccess(res.data)
  } catch (error: any) {
    console.error('文件上传失败:', error)
    ElMessage.error(error.message || '文件上传失败')
    onError(error)
  } finally {
    uploadingFile.value = false
  }
}

const handleUpload = () => {
  uploadForm.title = ''
  uploadForm.note = ''
  uploadForm.file_url = ''
  uploadForm.kb_id = ''
  if (uploadRef.value) {
    uploadRef.value.clearFiles()
  }
  if (uploadFormRef.value) {
    uploadFormRef.value.clearValidate()
  }
  loadKbOptions()
  uploadDialogVisible.value = true
}

const submitUpload = async () => {
  if (!uploadFormRef.value) return
  try {
    await uploadFormRef.value.validate()
  } catch (error) {
    return
  }
  submitting.value = true
  try {
    const res = await documentApi.add(uploadForm)
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success('上传成功')
      uploadDialogVisible.value = false
      fetchDocuments()
      // 上传后可能立即开始转换，启动轮询监控状态
      startPolling()
    }
  } catch (error) {
    console.error('上传失败:', error)
  } finally {
    submitting.value = false
  }
}

const handleEdit = async (row: DocumentItem) => {
  loadKbOptions()
  try {
    const res = await documentApi.getDetail(row.id)
    if ((res.code === '000000' || res.code === 0) && res.data) {
      const data = res.data
      editForm.id = data.id
      editForm.title = data.title
      editForm.note = data.note || ''
      editForm.table_type = data.source_type
      
      // 填充扩展字段
      editForm.standard_no = data.standard_no || ''
      editForm.issuing_authority = data.issuing_authority || ''
      editForm.release_date = data.release_date || ''
      editForm.document_type = data.document_type || ''
      editForm.professional_field = data.professional_field || ''
      editForm.validity = data.validity || ''
      editForm.project_name = data.project_name || ''
      editForm.project_section = data.project_section || ''
      editForm.plan_category = data.plan_category || ''
      editForm.level_1_classification = data.level_1_classification || '施工方案'
      editForm.level_2_classification = data.level_2_classification || ''
      editForm.level_3_classification = data.level_3_classification || ''
      editForm.level_4_classification = data.level_4_classification || ''
      editForm.plan_summary = data.plan_summary || ''
      editForm.compilation_basis = data.compilation_basis || ''
      editForm.file_url = data.file_url || ''
      
      // 填充新补全的字段
      editForm.english_name = data.english_name || ''
      editForm.implementation_date = data.implementation_date || ''
      editForm.drafting_unit = data.drafting_unit || ''
      editForm.approving_department = data.approving_department || ''
      editForm.engineering_phase = data.engineering_phase || ''
      editForm.source_url = data.source_url || ''
      editForm.effective_start_date = data.effective_start_date || ''
      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())
        if (participatingUnitsList.value.length === 0) participatingUnitsList.value = ['']
      } else {
        participatingUnitsList.value = ['']
      }
      
      if (data.reference_basis) {
        referenceBasisList.value = data.reference_basis.split(';').filter((i: string) => i.trim())
        if (referenceBasisList.value.length === 0) referenceBasisList.value = ['']
      } else {
        referenceBasisList.value = ['']
      }

      if (data.compilation_basis) {
        compilationBasisList.value = data.compilation_basis.split(';').filter((i: string) => i.trim())
        if (compilationBasisList.value.length === 0) compilationBasisList.value = ['']
      } else {
        compilationBasisList.value = ['']
      }
      
      editDialogVisible.value = true
    } else {
      ElMessage.error(res.message || '获取文档详情失败')
    }
  } catch (error) {
    console.error('获取文档详情失败:', error)
    ElMessage.error('获取文档详情失败')
  }
}

const submitEdit = async () => {
  if (!editFormRef.value) return
  try {
    await editFormRef.value.validate()
  } catch (error) {
    return
  }
  submitting.value = true
  try {
    // 将列表字段合并为分号分隔的字符串
    const payload: any = { 
      ...editForm,
      source_type: editForm.table_type 
    }
    
    if (editForm.table_type === 'standard') {
      payload.participating_units = participatingUnitsList.value.filter(i => i.trim()).join(';')
      payload.reference_basis = referenceBasisList.value.filter(i => i.trim()).join(';')
    } else if (editForm.table_type === 'construction_plan') {
      payload.compilation_basis = compilationBasisList.value.filter(i => i.trim()).join(';')
    }
    
    const res = await documentApi.edit(payload)
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success('更新成功')
      editDialogVisible.value = false
      fetchDocuments()
    }
  } catch (error) {
    console.error('编辑失败:', error)
  } finally {
    submitting.value = false
  }
}

const handleView = (row: DocumentItem) => {
  if (row.file_url) {
    handlePreview(row)
  } else {
    currentDoc.value = row
    detailDialogVisible.value = true
  }
}

const handleEditFromDetail = () => {
  if (currentDoc.value) {
    const doc = currentDoc.value
    detailDialogVisible.value = false
    handleEdit(doc)
  }
}

const handlePreview = (row: DocumentItem | null) => {
  if (!row || !row.file_url) return
  currentDoc.value = row
  previewTitle.value = row.title
  
  const ext = getFileExtension(row).toLowerCase()
  const officeExtensions = ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx']
  isOfficeDoc.value = officeExtensions.includes(ext)
  
  // 如果是 Office 文档且有转换后的 MD，优先预览 MD
  if (isOfficeDoc.value && row.md_url) {
    previewUrl.value = row.md_url
    previewDocType.value = 'md'
    previewTitle.value = `${row.title} (转换预览)`
  } else {
    previewUrl.value = row.file_url
    previewDocType.value = 'original'
  }
  
  previewVisible.value = true
  // 如果是无法直接预览的 Office 文档，不需要等待 iframe 加载
  if (isOfficeDoc.value && previewDocType.value === 'original') {
    previewLoading.value = false
  } else {
    previewLoading.value = true
  }
}

const handleDownload = (row: DocumentItem) => {
  if (row.file_url) {
    const ext = getFileExtension(row)
    const filename = row.title.endsWith(ext) ? row.title : `${row.title}${ext}`
    downloadFile(row.file_url, filename)
  } else {
    ElMessage.warning('该文档暂无下载链接')
  }
}

const handleDownloadConverted = (row: DocumentItem) => {
  if (row.md_url) {
    const filename = row.md_display_name || `${row.title}.md`
    downloadFile(row.md_url, filename)
  } else {
    ElMessage.warning('该文档暂无转换后的文件')
  }
}

const handleDownloadJson = (row: DocumentItem) => {
  if (row.json_url) {
    const filename = row.json_display_name || `${row.title}.json`
    downloadFile(row.json_url, filename)
  } else {
    ElMessage.warning('该文档暂无转换后的 JSON 文件')
  }
}

const handleConvert = async (row: DocumentItem) => {
  // 如果已经转换成功（status 为 2），弹出确认框
  if (row.conversion_status === 2) {
    try {
      await ElMessageBox.confirm(
        '该文档已经转换完成，再次转换将覆盖原转换后端文件，你继续吗？',
        '再次转换确认',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        }
      )
    } catch (error) {
      // 用户取消
      return
    }
  }

  try {
    // 乐观更新：设置状态为转换中
    row.conversion_status = 1
    row.conversion_error = undefined
    
    // 启动转换任务（静默刷新，不触发全局 loading）
    const res = await documentApi.convert(row.id)
    if (res.code === '000000' || res.code === 0) {
      ElMessage.success(res.message || '转换任务已启动')
      // 启动轮询以监控转换进度
      startPolling()
      // 触发一次静默刷新以更新状态
      refreshDocumentsSilently()
    } else {
      // 失败了恢复状态并刷新
      refreshDocumentsSilently()
    }
  } catch (error) {
    console.error('启动转换失败:', error)
    // 失败了恢复状态并刷新
    refreshDocumentsSilently()
  }
}

const openInNewWindow = () => {
  if (previewUrl.value) {
    // 优先尝试在新窗口打开代理后的链接，这有助于控制 Content-Disposition
    window.open(proxyPreviewUrl.value, '_blank')
  }
}

onMounted(() => {
  fetchDocuments()
  loadKbOptions()
  loadDictOptions()
})

onUnmounted(() => {
  if (refreshTimer.value) {
    window.clearTimeout(refreshTimer.value)
  }
  stopPolling()
})
</script>

<style scoped>
.tag-group {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  min-height: 32px;
}

.file-info-edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.file-tag {
  display: flex;
  align-items: center;
  gap: 5px;
  width: fit-content;
}

.tag-item {
  margin: 2px 0;
}

.tag-adder {
  width: 120px;
}

.documents-container {
  padding: 20px;
}

.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.title-info h2 {
  margin: 0;
  font-size: 24px;
  color: #303133;
}

.statistics-bar {
  display: flex;
  gap: 20px;
  margin-top: 8px;
}

.conversion-progress-wrapper {
  width: 100%;
  padding: 0 5px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.error-msg-text {
  font-size: 12px;
  color: #f56c6c;
  display: flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 2px;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  color: #606266;
}

.stat-item .el-icon {
  font-size: 16px;
  color: #909399;
}

.stat-value {
  font-weight: bold;
  color: #303133;
}

.stat-value.success {
  color: #67c23a;
}

.clickable-filename {
  color: #409eff;
  cursor: pointer;
  font-weight: 500;
  transition: color 0.2s;
}

.clickable-filename:hover {
  color: #66b1ff;
  text-decoration: underline;
}

.action-btn {
  padding: 4px 8px;
  height: auto;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.action-btn-icon {
  padding: 4px;
  height: 28px;
  width: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: all 0.2s;
}

.action-btn-icon:hover {
  background-color: #f5f7fa;
}

.action-btn-icon .el-icon {
  font-size: 16px;
}

.action-btn .el-icon {
  font-size: 14px;
}

.file-info-cell {
  display: flex;
  align-items: center;
  gap: 8px;
}

.file-icon-mini {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 4px;
  font-size: 14px;
}

.file-icon-mini.pdf { background-color: #fef0f0; color: #f56c6c; }
.file-icon-mini.word { background-color: #ecf5ff; color: #409eff; }
.file-icon-mini.excel { background-color: #f0f9eb; color: #67c23a; }
.file-icon-mini.ppt { background-color: #fff7e6; color: #e6a23c; }

.file-info-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow: hidden;
}

.file-note {
  font-size: 12px;
  color: #909399;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.2;
}

.file-name-link {
  color: #409eff;
  cursor: pointer;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.file-name-link:hover {
  text-decoration: underline;
}

.compact-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  line-height: 1.2;
}

.info-row {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: #606266;
}

.info-row.secondary {
  color: #909399;
  font-size: 11px;
}

.date-cell {
  display: flex;
  flex-direction: column;
  line-height: 1.2;
}

.time-mini {
  font-size: 11px;
  color: #909399;
}

.conversion-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 2px 0;
}

.status-tag {
  font-weight: 500;
  margin-bottom: 2px;
}

.converted-file-links {
  display: flex;
  flex-direction: column;
  gap: 0px;
  width: 100%;
}

.converted-file-name {
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.converted-file-name :deep(.el-link) {
  font-size: 12px;
  justify-content: flex-start;
}

.converted-file-name :deep(.el-link .el-icon) {
  margin-right: 4px;
}

.file-name-mini {
  font-size: 11px;
  color: #909399;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.status-icon-success { color: #67c23a; font-size: 18px; }
.status-icon-info { color: #909399; font-size: 18px; }

.upload-btn {
  background-color: #67c23a;
  border-color: #67c23a;
}

.search-card {
  margin-bottom: 20px;
  background-color: #f8f9fa;
}

.search-bar {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.search-input :deep(.el-input__wrapper) {
  padding: 8px 12px;
  font-size: 16px;
}

.filter-group {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

.filter-select {
  width: 200px;
}

.filter-select-year {
  width: 140px;
}

.search-btn {
  padding: 0 30px;
  height: 40px;
  font-size: 15px;
  font-weight: bold;
  margin-left: auto;
}

.content-section {
  background: #fff;
  border-radius: 4px;
  min-height: 400px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.dynamic-input-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  width: 100%;
}

.dynamic-input-row :deep(.el-input) {
  flex: 1;
}

.dynamic-input-row:last-child {
  margin-bottom: 0;
}

.row-actions {
  display: flex;
  gap: 5px;
  margin-left: 10px;
  flex-shrink: 0;
}

/* 文件信息单元格布局 */
.file-info-cell {
  display: flex;
  align-items: center;
  padding: 8px 0;
}

.file-icon-wrapper {
  position: relative;
  width: 40px;
  height: 48px;
  margin-right: 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  flex-shrink: 0;
  transition: transform 0.2s;
}

.file-icon-wrapper:hover {
  transform: scale(1.05);
}

.file-icon-wrapper .el-icon {
  font-size: 24px;
  margin-bottom: 2px;
  color: #fff;
}

.file-type-label {
  font-size: 10px;
  font-weight: bold;
  color: #fff;
  text-transform: uppercase;
}

/* 不同文件类型的背景色 */
.icon-pdf { background-color: #ff4d4f; }
.icon-word { background-color: #1890ff; }
.icon-excel { background-color: #52c41a; }
.icon-ppt { background-color: #fa8c16; }
.icon-html { background-color: #13c2c2; }
.icon-file { background-color: #8c8c8c; }

.file-text-content {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.file-name-title {
  font-size: 15px;
  font-weight: 500;
  color: #303133;
  margin-bottom: 4px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.2s;
}

.file-name-title:hover {
  color: #409eff;
}

.file-description-subtitle {
  font-size: 12px;
  color: #909399;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 操作按钮样式 */
.action-buttons {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 4px;
}

.dialog-header-custom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-right: 30px;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.preview-tip {
  margin-bottom: 15px;
}

.preview-content {
  height: 75vh;
  display: flex;
  flex-direction: column;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #f5f7fa;
  position: relative;
}

.unsupported-preview {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #fff;
}

.unsupported-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
}

.preview-content iframe {
  flex: 1;
  display: block;
}

:deep(.preview-dialog) {
  .el-dialog__body {
    padding: 10px 20px 20px;
  }
}

.kb-name-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--el-color-primary);
  font-weight: 500;
}

.text-info {
  color: var(--el-text-color-placeholder);
  font-size: 13px;
}
</style>
