|
@@ -37,7 +37,7 @@
|
|
|
<div class="search-bar">
|
|
<div class="search-bar">
|
|
|
<el-input
|
|
<el-input
|
|
|
v-model="searchQuery.keyword"
|
|
v-model="searchQuery.keyword"
|
|
|
- placeholder="搜索文档标题、正文内容或标准号..."
|
|
|
|
|
|
|
+ placeholder="搜索文档名称..."
|
|
|
class="search-input"
|
|
class="search-input"
|
|
|
clearable
|
|
clearable
|
|
|
@keyup.enter="handleSearch"
|
|
@keyup.enter="handleSearch"
|
|
@@ -92,9 +92,14 @@
|
|
|
<el-icon v-else-if="getFileIcon(scope.row) === 'ppt'"><DataAnalysis /></el-icon>
|
|
<el-icon v-else-if="getFileIcon(scope.row) === 'ppt'"><DataAnalysis /></el-icon>
|
|
|
<el-icon v-else><Document /></el-icon>
|
|
<el-icon v-else><Document /></el-icon>
|
|
|
</div>
|
|
</div>
|
|
|
- <span class="file-name-link" @click="handleView(scope.row)">
|
|
|
|
|
- {{ scope.row.title }}{{ getFileExtension(scope.row) }}
|
|
|
|
|
- </span>
|
|
|
|
|
|
|
+ <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>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
@@ -127,20 +132,6 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
|
|
|
|
|
- <el-table-column prop="created_by" 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 label="修改时间" min-width="150" prop="updated_time">
|
|
|
|
|
- <template #default="scope">
|
|
|
|
|
- {{ formatDate(scope.row.updated_time) }}
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-table-column>
|
|
|
|
|
-
|
|
|
|
|
<el-table-column label="知识库" min-width="120">
|
|
<el-table-column label="知识库" min-width="120">
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
|
<el-tag size="small" effect="plain" :type="getKBTagType(scope.row.source_type)">
|
|
<el-tag size="small" effect="plain" :type="getKBTagType(scope.row.source_type)">
|
|
@@ -160,7 +151,21 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-table-column>
|
|
</el-table-column>
|
|
|
|
|
|
|
|
|
|
+ <el-table-column prop="created_by" 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="updated_by" 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">
|
|
<el-table-column label="操作" width="260" fixed="right" align="center">
|
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
@@ -230,7 +235,27 @@
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
<div v-loading="previewLoading" class="preview-content">
|
|
<div v-loading="previewLoading" class="preview-content">
|
|
|
- <div v-if="isHtmlPage && !previewLoading" class="preview-tip">
|
|
|
|
|
|
|
+ <!-- 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
|
|
<el-alert
|
|
|
title="网页预览提示"
|
|
title="网页预览提示"
|
|
|
type="info"
|
|
type="info"
|
|
@@ -240,7 +265,7 @@
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
<iframe
|
|
<iframe
|
|
|
- v-if="previewUrl"
|
|
|
|
|
|
|
+ v-if="previewUrl && !(isOfficeDoc && previewDocType === 'original')"
|
|
|
:src="proxyPreviewUrl"
|
|
:src="proxyPreviewUrl"
|
|
|
width="100%"
|
|
width="100%"
|
|
|
height="100%"
|
|
height="100%"
|
|
@@ -297,8 +322,8 @@
|
|
|
</template>
|
|
</template>
|
|
|
</el-upload>
|
|
</el-upload>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="文档内容">
|
|
|
|
|
- <el-input v-model="uploadForm.content" type="textarea" :rows="4" placeholder="请输入文档内容" />
|
|
|
|
|
|
|
+ <el-form-item label="文档备注">
|
|
|
|
|
+ <el-input v-model="uploadForm.note" type="textarea" :rows="4" placeholder="请输入文档备注" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
<template #footer>
|
|
<template #footer>
|
|
@@ -308,8 +333,8 @@
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
|
|
|
<!-- 编辑文档对话框 -->
|
|
<!-- 编辑文档对话框 -->
|
|
|
- <el-dialog v-model="editDialogVisible" title="编辑文档" width="600px">
|
|
|
|
|
- <el-form :model="editForm" label-width="110px">
|
|
|
|
|
|
|
+ <el-dialog v-model="editDialogVisible" title="编辑文档" width="700px">
|
|
|
|
|
+ <el-form :model="editForm" label-width="120px">
|
|
|
<el-divider content-position="left">基础信息</el-divider>
|
|
<el-divider content-position="left">基础信息</el-divider>
|
|
|
<el-form-item label="所属知识库" required>
|
|
<el-form-item label="所属知识库" required>
|
|
|
<el-select v-model="editForm.table_type" disabled placeholder="请选择知识库" style="width: 100%">
|
|
<el-select v-model="editForm.table_type" disabled placeholder="请选择知识库" style="width: 100%">
|
|
@@ -340,12 +365,12 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="文档类型">
|
|
|
|
|
|
|
+ <el-form-item label="文件类型">
|
|
|
<el-input v-model="editForm.document_type" placeholder="如:国家标准" />
|
|
<el-input v-model="editForm.document_type" placeholder="如:国家标准" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="有效性">
|
|
|
|
|
|
|
+ <el-form-item label="时效性">
|
|
|
<el-select v-model="editForm.validity" placeholder="请选择" style="width: 100%">
|
|
<el-select v-model="editForm.validity" placeholder="请选择" style="width: 100%">
|
|
|
<el-option label="现行" value="现行" />
|
|
<el-option label="现行" value="现行" />
|
|
|
<el-option label="已废止" value="已废止" />
|
|
<el-option label="已废止" value="已废止" />
|
|
@@ -361,17 +386,74 @@
|
|
|
|
|
|
|
|
<!-- 施工方案特有字段 -->
|
|
<!-- 施工方案特有字段 -->
|
|
|
<template v-else-if="editForm.table_type === 'work'">
|
|
<template v-else-if="editForm.table_type === 'work'">
|
|
|
- <el-form-item label="项目名称">
|
|
|
|
|
- <el-input v-model="editForm.project_name" placeholder="请输入项目名称" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="项目标段">
|
|
|
|
|
- <el-input v-model="editForm.project_section" placeholder="请输入项目标段" />
|
|
|
|
|
- </el-form-item>
|
|
|
|
|
- <el-form-item label="编制单位">
|
|
|
|
|
- <el-input v-model="editForm.issuing_authority" placeholder="请输入编制单位" />
|
|
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <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-row>
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <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" :label="item" :value="item" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="一级分类">
|
|
|
|
|
+ <el-input v-model="editForm.level_1_classification" disabled />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <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" :label="item" :value="item" />
|
|
|
|
|
+ </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" :label="item" :value="item" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <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" :label="item" :value="item" />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="编制单位">
|
|
|
|
|
+ <el-input v-model="editForm.issuing_authority" placeholder="请输入编制单位" />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-col>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ <el-row :gutter="20">
|
|
|
|
|
+ <el-col :span="12">
|
|
|
|
|
+ <el-form-item label="编制日期">
|
|
|
|
|
+ <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-row>
|
|
|
|
|
+ <el-form-item label="方案摘要">
|
|
|
|
|
+ <el-input v-model="editForm.plan_summary" type="textarea" :rows="3" placeholder="请输入方案摘要" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
- <el-form-item label="编制日期">
|
|
|
|
|
- <el-date-picker v-model="editForm.release_date" type="date" placeholder="选择日期" value-format="YYYY-MM-DD" style="width: 100%" />
|
|
|
|
|
|
|
+ <el-form-item label="编制依据">
|
|
|
|
|
+ <el-input v-model="editForm.compilation_basis" type="textarea" :rows="3" placeholder="请输入编制依据,多个依据请用逗号分隔" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -388,9 +470,9 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
- <el-divider content-position="left">文档正文</el-divider>
|
|
|
|
|
- <el-form-item label="文档内容">
|
|
|
|
|
- <el-input v-model="editForm.content" type="textarea" :rows="6" placeholder="请输入文档内容" />
|
|
|
|
|
|
|
+ <el-divider content-position="left">文档备注</el-divider>
|
|
|
|
|
+ <el-form-item label="文档备注">
|
|
|
|
|
+ <el-input v-model="editForm.note" type="textarea" :rows="6" placeholder="请输入文档备注" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
<template #footer>
|
|
<template #footer>
|
|
@@ -405,15 +487,34 @@
|
|
|
<el-descriptions-item label="名称">{{ currentDoc?.title }}</el-descriptions-item>
|
|
<el-descriptions-item label="名称">{{ currentDoc?.title }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="知识库">{{ getKnowledgeBaseName(currentDoc?.source_type) }}</el-descriptions-item>
|
|
<el-descriptions-item label="知识库">{{ getKnowledgeBaseName(currentDoc?.source_type) }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="上传人">{{ currentDoc?.created_by }}</el-descriptions-item>
|
|
<el-descriptions-item label="上传人">{{ currentDoc?.created_by }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="上传时间">{{ formatDate(currentDoc?.created_time || '') }}</el-descriptions-item>
|
|
|
|
|
|
|
+ <el-descriptions-item label="上传时间">{{ formatDate(currentDoc?.created_time) }}</el-descriptions-item>
|
|
|
<el-descriptions-item label="入库状态">
|
|
<el-descriptions-item label="入库状态">
|
|
|
<el-tag :type="isEntered(currentDoc?.whether_to_enter) ? 'success' : 'info'">
|
|
<el-tag :type="isEntered(currentDoc?.whether_to_enter) ? 'success' : 'info'">
|
|
|
{{ isEntered(currentDoc?.whether_to_enter) ? '已入库' : '未入库' }}
|
|
{{ isEntered(currentDoc?.whether_to_enter) ? '已入库' : '未入库' }}
|
|
|
</el-tag>
|
|
</el-tag>
|
|
|
</el-descriptions-item>
|
|
</el-descriptions-item>
|
|
|
- <el-descriptions-item label="内容摘要">
|
|
|
|
|
- <div class="content-preview">{{ currentDoc?.content || '暂无内容' }}</div>
|
|
|
|
|
|
|
+ <el-descriptions-item label="文档备注">
|
|
|
|
|
+ <div class="content-preview">{{ currentDoc?.note || '暂无备注' }}</div>
|
|
|
</el-descriptions-item>
|
|
</el-descriptions-item>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- 施工方案特有详情 -->
|
|
|
|
|
+ <template v-if="currentDoc?.source_type === 'work'">
|
|
|
|
|
+ <el-descriptions-item label="工程名称">{{ currentDoc?.project_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 class="content-preview">{{ currentDoc?.compilation_basis || '-' }}</div>
|
|
|
|
|
+ </el-descriptions-item>
|
|
|
|
|
+ </template>
|
|
|
</el-descriptions>
|
|
</el-descriptions>
|
|
|
<template #footer>
|
|
<template #footer>
|
|
|
<div class="detail-footer">
|
|
<div class="detail-footer">
|
|
@@ -465,6 +566,8 @@ const previewVisible = ref(false)
|
|
|
const previewLoading = ref(false)
|
|
const previewLoading = ref(false)
|
|
|
const previewTitle = ref('')
|
|
const previewTitle = ref('')
|
|
|
const previewUrl = ref('')
|
|
const previewUrl = ref('')
|
|
|
|
|
+const previewDocType = ref('') // 'original' or 'md'
|
|
|
|
|
+const isOfficeDoc = ref(false)
|
|
|
const total = ref(0)
|
|
const total = ref(0)
|
|
|
const statistics = ref({
|
|
const statistics = ref({
|
|
|
allTotal: 0,
|
|
allTotal: 0,
|
|
@@ -476,10 +579,10 @@ const currentDoc = ref<DocumentItem | null>(null)
|
|
|
|
|
|
|
|
const editForm = reactive({
|
|
const editForm = reactive({
|
|
|
id: '',
|
|
id: '',
|
|
|
- source_id: '',
|
|
|
|
|
title: '',
|
|
title: '',
|
|
|
- content: '',
|
|
|
|
|
|
|
+ note: '',
|
|
|
table_type: 'basis' as 'basis' | 'work' | 'job',
|
|
table_type: 'basis' as 'basis' | 'work' | 'job',
|
|
|
|
|
+ year: new Date().getFullYear(),
|
|
|
// 扩展字段 (子表特有属性)
|
|
// 扩展字段 (子表特有属性)
|
|
|
standard_no: '',
|
|
standard_no: '',
|
|
|
issuing_authority: '',
|
|
issuing_authority: '',
|
|
@@ -489,9 +592,21 @@ const editForm = reactive({
|
|
|
validity: '',
|
|
validity: '',
|
|
|
project_name: '',
|
|
project_name: '',
|
|
|
project_section: '',
|
|
project_section: '',
|
|
|
|
|
+ plan_category: '',
|
|
|
|
|
+ level_1_classification: '施工方案',
|
|
|
|
|
+ level_2_classification: '',
|
|
|
|
|
+ level_3_classification: '',
|
|
|
|
|
+ level_4_classification: '',
|
|
|
|
|
+ plan_summary: '',
|
|
|
|
|
+ compilation_basis: '',
|
|
|
file_url: ''
|
|
file_url: ''
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+const planCategoryOptions = ['超危大方案', '超危大方案较大II级', '超危大方案特大IV级', '超危大方案一般I级', '超危大方案重大III级', '危大方案', '一般方案']
|
|
|
|
|
+const level2Options = ['临建工程', '路基工程', '其他', '桥梁工程', '隧道工程']
|
|
|
|
|
+const level3Options = ['/', 'TBM施工', '拌和站安、拆施工', '不良地质隧道施工', '常规桥梁', '挡土墙工程类', '辅助坑道施工', '复杂洞口工程施工', '钢筋加工场安、拆', '钢栈桥施工', '拱桥', '涵洞工程类', '滑坡体处理类', '路堤', '路堑', '其他', '深基坑', '隧道总体施工', '特殊结构隧道', '斜拉桥', '悬索桥']
|
|
|
|
|
+const level4Options = ['/', '挡土墙', '顶管', '断层破碎带及软弱围岩', '钢筋砼箱涵', '高填路堤', '抗滑桩', '其他', '软岩大变形隧道', '上部结构', '深基坑开挖与支护', '深挖路堑', '隧道TBM', '隧道进洞', '隧道竖井', '隧道斜井', '特种设备', '瓦斯隧道', '下部结构', '小净距隧道', '岩爆隧道', '岩溶隧道', '涌水突泥隧道', '桩基础']
|
|
|
|
|
+
|
|
|
const currentTitle = computed(() => {
|
|
const currentTitle = computed(() => {
|
|
|
return '文档管理中心'
|
|
return '文档管理中心'
|
|
|
})
|
|
})
|
|
@@ -507,7 +622,7 @@ const searchQuery = reactive({
|
|
|
|
|
|
|
|
const uploadForm = reactive({
|
|
const uploadForm = reactive({
|
|
|
title: '',
|
|
title: '',
|
|
|
- content: '',
|
|
|
|
|
|
|
+ note: '',
|
|
|
file_url: '',
|
|
file_url: '',
|
|
|
table_type: 'basis' as 'basis' | 'work' | 'job',
|
|
table_type: 'basis' as 'basis' | 'work' | 'job',
|
|
|
year: new Date().getFullYear()
|
|
year: new Date().getFullYear()
|
|
@@ -533,7 +648,7 @@ const formatSimpleDate = (date: string | null) => {
|
|
|
return dayjs(date).format('YYYY-MM-DD')
|
|
return dayjs(date).format('YYYY-MM-DD')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const formatDate = (date: string, formatStr: string = 'YYYY-MM-DD HH:mm:ss') => {
|
|
|
|
|
|
|
+const formatDate = (date: string | undefined | null, formatStr: string = 'YYYY-MM-DD HH:mm:ss') => {
|
|
|
return date ? dayjs(date).format(formatStr) : '-'
|
|
return date ? dayjs(date).format(formatStr) : '-'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -621,56 +736,49 @@ const handleSelectionChange = (selection: DocumentItem[]) => {
|
|
|
const handleBatchEnter = async () => {
|
|
const handleBatchEnter = async () => {
|
|
|
if (selectedIds.value.length === 0) return
|
|
if (selectedIds.value.length === 0) return
|
|
|
|
|
|
|
|
- // 找出选中项中符合入库条件的:未入库 且 转换成功
|
|
|
|
|
- const selectedDocs = documents.value.filter(doc => selectedIds.value.includes(doc.id))
|
|
|
|
|
- const readyDocs = selectedDocs.filter(doc => !isEntered(doc.whether_to_enter) && doc.conversion_status === 2)
|
|
|
|
|
- const readyIds = readyDocs.map(doc => doc.id)
|
|
|
|
|
-
|
|
|
|
|
- if (readyIds.length === 0) {
|
|
|
|
|
- return ElMessage.warning('选中的文档中没有符合入库条件的(需转换成功且未入库)')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (readyIds.length < selectedIds.value.length) {
|
|
|
|
|
- try {
|
|
|
|
|
- await ElMessageBox.confirm(
|
|
|
|
|
- `选中的 ${selectedIds.value.length} 个文档中,仅有 ${readyIds.length} 个符合入库条件(已转换成功)。是否继续对这 ${readyIds.length} 个文档执行入库?`,
|
|
|
|
|
- '入库提示',
|
|
|
|
|
- {
|
|
|
|
|
- confirmButtonText: '继续入库',
|
|
|
|
|
- cancelButtonText: '取消',
|
|
|
|
|
- type: 'info'
|
|
|
|
|
- }
|
|
|
|
|
- )
|
|
|
|
|
- } catch {
|
|
|
|
|
- return
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
|
|
+ const ids = [...selectedIds.value]
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
- const res = await documentApi.batchEnter(readyIds)
|
|
|
|
|
|
|
+ const res = await documentApi.batchEnter(ids)
|
|
|
if (res.code === 0) {
|
|
if (res.code === 0) {
|
|
|
- ElMessage.success(res.message || '入库成功')
|
|
|
|
|
|
|
+ // 如果有详细详情(换行符标识),使用 MessageBox 显示
|
|
|
|
|
+ if (res.message && res.message.includes('\n')) {
|
|
|
|
|
+ ElMessageBox.alert(res.message, '入库结果', {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ customStyle: { 'white-space': 'pre-wrap' },
|
|
|
|
|
+ type: res.message.includes('失败') || res.message.includes('跳过') ? 'warning' : 'success'
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.success(res.message || '入库成功')
|
|
|
|
|
+ }
|
|
|
fetchDocuments()
|
|
fetchDocuments()
|
|
|
} else {
|
|
} else {
|
|
|
- ElMessage.error(res.message || '入库失败')
|
|
|
|
|
|
|
+ ElMessageBox.alert(res.message || '入库失败', '操作失败', {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ type: 'error'
|
|
|
|
|
+ })
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('批量入库失败:', error)
|
|
console.error('批量入库失败:', error)
|
|
|
- ElMessage.error('网络错误')
|
|
|
|
|
|
|
+ ElMessage.error('网络连接异常,请稍后重试')
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const handleSingleEnter = async (doc: DocumentItem | null) => {
|
|
const handleSingleEnter = async (doc: DocumentItem | null) => {
|
|
|
if (!doc) return
|
|
if (!doc) return
|
|
|
|
|
|
|
|
- if (doc.conversion_status !== 2) {
|
|
|
|
|
- return ElMessage.warning('该文档尚未转化完成,暂不允许入库')
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
try {
|
|
try {
|
|
|
const res = await documentApi.batchEnter([doc.id])
|
|
const res = await documentApi.batchEnter([doc.id])
|
|
|
if (res.code === 0) {
|
|
if (res.code === 0) {
|
|
|
- ElMessage.success('成功加入知识库')
|
|
|
|
|
|
|
+ if (res.message && res.message.includes('\n')) {
|
|
|
|
|
+ ElMessageBox.alert(res.message, '入库结果', {
|
|
|
|
|
+ confirmButtonText: '确定',
|
|
|
|
|
+ customStyle: { 'white-space': 'pre-wrap' },
|
|
|
|
|
+ type: res.message.includes('失败') || res.message.includes('跳过') ? 'warning' : 'success'
|
|
|
|
|
+ })
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.success(res.message || '入库成功')
|
|
|
|
|
+ }
|
|
|
detailDialogVisible.value = false
|
|
detailDialogVisible.value = false
|
|
|
fetchDocuments()
|
|
fetchDocuments()
|
|
|
} else {
|
|
} else {
|
|
@@ -678,7 +786,7 @@ const handleSingleEnter = async (doc: DocumentItem | null) => {
|
|
|
}
|
|
}
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
|
console.error('入库失败:', error)
|
|
console.error('入库失败:', error)
|
|
|
- ElMessage.error('入库失败')
|
|
|
|
|
|
|
+ ElMessage.error('入库异常')
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -891,7 +999,7 @@ const customUpload = async (options: any) => {
|
|
|
|
|
|
|
|
const handleUpload = () => {
|
|
const handleUpload = () => {
|
|
|
uploadForm.title = ''
|
|
uploadForm.title = ''
|
|
|
- uploadForm.content = ''
|
|
|
|
|
|
|
+ uploadForm.note = ''
|
|
|
uploadForm.file_url = ''
|
|
uploadForm.file_url = ''
|
|
|
uploadDialogVisible.value = true
|
|
uploadDialogVisible.value = true
|
|
|
}
|
|
}
|
|
@@ -921,9 +1029,8 @@ const handleEdit = async (row: DocumentItem) => {
|
|
|
if (res.code === 0 && res.data) {
|
|
if (res.code === 0 && res.data) {
|
|
|
const data = res.data
|
|
const data = res.data
|
|
|
editForm.id = data.id
|
|
editForm.id = data.id
|
|
|
- editForm.source_id = data.source_id
|
|
|
|
|
editForm.title = data.title
|
|
editForm.title = data.title
|
|
|
- editForm.content = data.content
|
|
|
|
|
|
|
+ editForm.note = data.note || ''
|
|
|
editForm.table_type = data.source_type
|
|
editForm.table_type = data.source_type
|
|
|
|
|
|
|
|
// 填充扩展字段
|
|
// 填充扩展字段
|
|
@@ -935,6 +1042,13 @@ const handleEdit = async (row: DocumentItem) => {
|
|
|
editForm.validity = data.validity || ''
|
|
editForm.validity = data.validity || ''
|
|
|
editForm.project_name = data.project_name || ''
|
|
editForm.project_name = data.project_name || ''
|
|
|
editForm.project_section = data.project_section || ''
|
|
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.file_url = data.file_url || ''
|
|
|
|
|
|
|
|
editDialogVisible.value = true
|
|
editDialogVisible.value = true
|
|
@@ -985,10 +1099,30 @@ const handleEditFromDetail = () => {
|
|
|
|
|
|
|
|
const handlePreview = (row: DocumentItem | null) => {
|
|
const handlePreview = (row: DocumentItem | null) => {
|
|
|
if (!row || !row.file_url) return
|
|
if (!row || !row.file_url) return
|
|
|
|
|
+ currentDoc.value = row
|
|
|
previewTitle.value = row.title
|
|
previewTitle.value = row.title
|
|
|
- previewUrl.value = row.file_url
|
|
|
|
|
|
|
+
|
|
|
|
|
+ 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
|
|
previewVisible.value = true
|
|
|
- previewLoading.value = true
|
|
|
|
|
|
|
+ // 如果是无法直接预览的 Office 文档,不需要等待 iframe 加载
|
|
|
|
|
+ if (isOfficeDoc.value && previewDocType.value === 'original') {
|
|
|
|
|
+ previewLoading.value = false
|
|
|
|
|
+ } else {
|
|
|
|
|
+ previewLoading.value = true
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const handleDownload = (row: DocumentItem) => {
|
|
const handleDownload = (row: DocumentItem) => {
|
|
@@ -1060,7 +1194,8 @@ const handleConvert = async (row: DocumentItem) => {
|
|
|
|
|
|
|
|
const openInNewWindow = () => {
|
|
const openInNewWindow = () => {
|
|
|
if (previewUrl.value) {
|
|
if (previewUrl.value) {
|
|
|
- window.open(previewUrl.value, '_blank')
|
|
|
|
|
|
|
+ // 优先尝试在新窗口打开代理后的链接,这有助于控制 Content-Disposition
|
|
|
|
|
+ window.open(proxyPreviewUrl.value, '_blank')
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1209,6 +1344,22 @@ onUnmounted(() => {
|
|
|
.file-icon-mini.excel { background-color: #f0f9eb; color: #67c23a; }
|
|
.file-icon-mini.excel { background-color: #f0f9eb; color: #67c23a; }
|
|
|
.file-icon-mini.ppt { background-color: #fff7e6; color: #e6a23c; }
|
|
.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 {
|
|
.file-name-link {
|
|
|
color: #409eff;
|
|
color: #409eff;
|
|
|
cursor: pointer;
|
|
cursor: pointer;
|
|
@@ -1458,11 +1609,27 @@ onUnmounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.preview-content {
|
|
.preview-content {
|
|
|
- height: 70vh;
|
|
|
|
|
|
|
+ height: 75vh;
|
|
|
display: flex;
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
flex-direction: column;
|
|
|
border: 1px solid #dcdfe6;
|
|
border: 1px solid #dcdfe6;
|
|
|
border-radius: 4px;
|
|
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 {
|
|
.preview-content iframe {
|