185 lines
6.9 KiB
Vue
185 lines
6.9 KiB
Vue
<template>
|
||
<div class="page-stack">
|
||
<section class="page-toolbar">
|
||
<div>
|
||
<h1>知识库管理</h1>
|
||
<p>维护病例相关指南、课件和文档资料,支持上传 PDF 等附件。</p>
|
||
</div>
|
||
<div class="toolbar-actions">
|
||
<el-button :icon="Upload">批量上传</el-button>
|
||
<el-button :icon="Plus" type="primary" @click="openCreateDialog">新增知识库</el-button>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="filter-bar">
|
||
<el-input v-model="keyword" :prefix-icon="Search" clearable placeholder="搜索知识库名称/编号" />
|
||
<el-select v-model="category" clearable placeholder="分类">
|
||
<el-option label="临床指南" value="临床指南" />
|
||
<el-option label="教学课件" value="教学课件" />
|
||
<el-option label="诊疗规范" value="诊疗规范" />
|
||
<el-option label="病例资料" value="病例资料" />
|
||
</el-select>
|
||
<el-select v-model="status" clearable placeholder="状态">
|
||
<el-option label="已发布" value="已发布" />
|
||
<el-option label="整理中" value="整理中" />
|
||
<el-option label="草稿" value="草稿" />
|
||
</el-select>
|
||
<el-button :icon="Refresh" @click="resetFilters">重置</el-button>
|
||
</section>
|
||
|
||
<section class="data-section">
|
||
<el-table :data="filteredRows" row-key="id">
|
||
<el-table-column prop="id" label="编号" width="150" />
|
||
<el-table-column prop="name" label="知识库名称" min-width="220" />
|
||
<el-table-column prop="category" label="分类" width="120" />
|
||
<el-table-column prop="owner" label="负责人" width="120" />
|
||
<el-table-column label="附件" width="150">
|
||
<template #default="{ row }">
|
||
<el-tag type="info">{{ row.fileCount }} 个文件</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="updatedAt" label="更新时间" width="130" />
|
||
<el-table-column prop="status" label="状态" width="110">
|
||
<template #default="{ row }">
|
||
<el-tag :type="tagType(row.status)">{{ row.status }}</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="180" fixed="right">
|
||
<template #default>
|
||
<el-button link type="primary">编辑</el-button>
|
||
<el-button link type="primary">预览</el-button>
|
||
<el-button link type="danger">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</section>
|
||
|
||
<el-dialog v-model="dialogVisible" title="新增知识库" width="560px">
|
||
<el-form label-position="top">
|
||
<el-form-item label="知识库名称" required>
|
||
<el-input v-model="form.name" placeholder="例如:急诊胸痛诊疗资料库" />
|
||
</el-form-item>
|
||
<el-form-item label="分类">
|
||
<el-select v-model="form.category" placeholder="请选择分类">
|
||
<el-option label="临床指南" value="临床指南" />
|
||
<el-option label="教学课件" value="教学课件" />
|
||
<el-option label="诊疗规范" value="诊疗规范" />
|
||
<el-option label="病例资料" value="病例资料" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="简介">
|
||
<el-input v-model="form.description" type="textarea" :rows="3" placeholder="补充说明资料范围或适用病例" />
|
||
</el-form-item>
|
||
<el-form-item label="上传附件">
|
||
<el-upload
|
||
v-model:file-list="fileList"
|
||
drag
|
||
multiple
|
||
:auto-upload="false"
|
||
accept=".pdf,.doc,.docx,.ppt,.pptx,.txt"
|
||
>
|
||
<el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
||
<div class="el-upload__text">拖拽文件到此处,或点击选择</div>
|
||
<template #tip>
|
||
<div class="el-upload__tip">支持 PDF、Word、PPT、TXT,当前为本地选择演示。</div>
|
||
</template>
|
||
</el-upload>
|
||
</el-form-item>
|
||
</el-form>
|
||
<template #footer>
|
||
<el-button @click="dialogVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="createKnowledgeBase">保存</el-button>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, reactive, ref } from 'vue'
|
||
import { ElMessage } from 'element-plus'
|
||
import type { UploadUserFile } from 'element-plus'
|
||
import { Plus, Refresh, Search, Upload, UploadFilled } from '@element-plus/icons-vue'
|
||
|
||
interface KnowledgeBaseItem {
|
||
id: string
|
||
name: string
|
||
category: string
|
||
owner: string
|
||
fileCount: number
|
||
updatedAt: string
|
||
status: string
|
||
}
|
||
|
||
const keyword = ref('')
|
||
const category = ref('')
|
||
const status = ref('')
|
||
const dialogVisible = ref(false)
|
||
const fileList = ref<UploadUserFile[]>([])
|
||
|
||
const form = reactive({
|
||
name: '',
|
||
category: '临床指南',
|
||
description: ''
|
||
})
|
||
|
||
const rows = ref<KnowledgeBaseItem[]>([
|
||
{ id: 'KB-202606-001', name: '胸痛中心诊疗指南库', category: '临床指南', owner: '王内容', fileCount: 8, updatedAt: '2026-06-05', status: '已发布' },
|
||
{ id: 'KB-202606-002', name: '儿科发热问诊课件', category: '教学课件', owner: '李医生', fileCount: 5, updatedAt: '2026-06-03', status: '整理中' },
|
||
{ id: 'KB-202605-029', name: '糖尿病慢病随访规范', category: '诊疗规范', owner: '陈医生', fileCount: 12, updatedAt: '2026-05-28', status: '已发布' },
|
||
{ id: 'KB-202605-017', name: '神经内科病例资料包', category: '病例资料', owner: '王内容', fileCount: 3, updatedAt: '2026-05-21', status: '草稿' }
|
||
])
|
||
|
||
const filteredRows = computed(() =>
|
||
rows.value.filter(item => {
|
||
const matchKeyword = !keyword.value || item.name.includes(keyword.value) || item.id.includes(keyword.value)
|
||
const matchCategory = !category.value || item.category === category.value
|
||
const matchStatus = !status.value || item.status === status.value
|
||
return matchKeyword && matchCategory && matchStatus
|
||
})
|
||
)
|
||
|
||
function openCreateDialog() {
|
||
form.name = ''
|
||
form.category = '临床指南'
|
||
form.description = ''
|
||
fileList.value = []
|
||
dialogVisible.value = true
|
||
}
|
||
|
||
function createKnowledgeBase() {
|
||
if (!form.name.trim()) {
|
||
ElMessage.warning('请输入知识库名称')
|
||
return
|
||
}
|
||
|
||
rows.value.unshift({
|
||
id: createId(),
|
||
name: form.name.trim(),
|
||
category: form.category,
|
||
owner: '王内容',
|
||
fileCount: fileList.value.length,
|
||
updatedAt: new Date().toISOString().slice(0, 10),
|
||
status: fileList.value.length > 0 ? '整理中' : '草稿'
|
||
})
|
||
dialogVisible.value = false
|
||
ElMessage.success('知识库已添加')
|
||
}
|
||
|
||
function resetFilters() {
|
||
keyword.value = ''
|
||
category.value = ''
|
||
status.value = ''
|
||
}
|
||
|
||
function createId() {
|
||
const number = String(rows.value.length + 1).padStart(3, '0')
|
||
return `KB-202606-${number}`
|
||
}
|
||
|
||
function tagType(value: string) {
|
||
if (value === '已发布') return 'success'
|
||
if (value === '整理中') return 'warning'
|
||
return 'info'
|
||
}
|
||
</script>
|