| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- <template>
- <div class="report-unknown admin-page">
- <el-card>
- <div slot="header">
- <span>未知报告审核</span>
- <div style="float: right; display: flex; gap: 10px;">
- <el-select v-model="statusFilter" size="small" style="width: 140px;" @change="fetchClusters">
- <el-option label="全部" value="" />
- <el-option label="收集" value="collecting" />
- <el-option label="可生成" value="ready" />
- <el-option label="已生成" value="generated" />
- </el-select>
- </div>
- </div>
- <el-table :data="clusters" v-loading="loading" border stripe>
- <el-table-column prop="id" label="ID" width="60" />
- <el-table-column prop="clusterKey" label="聚类键" width="140" />
- <el-table-column prop="reportCount" label="报告数" width="80" />
- <el-table-column label="状态" width="100">
- <template slot-scope="{ row }">
- <el-tag :type="statusType(row.status)" size="small">{{ statusText(row.status) }}</el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="generatedTypeId" label="生成类型" width="140" />
- <el-table-column prop="updatedAt" label="更新时间" width="180" />
- <el-table-column label="操作" width="160" fixed="right">
- <template slot-scope="{ row }">
- <el-button size="mini" type="primary" @click="handleDetail(row)">详情</el-button>
- <el-button v-if="row.status === 'ready'" size="mini" type="success" @click="handleGenerate(row)">生成类型</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- <!-- 详情对话框 -->
- <el-dialog :visible.sync="detailVisible" title="聚类详情" width="750px" :close-on-click-modal="false">
- <template v-if="currentCluster">
- <el-descriptions :column="2" border size="small">
- <el-descriptions-item label="聚类键">{{ currentCluster.clusterKey }}</el-descriptions-item>
- <el-descriptions-item label="报告数">{{ currentCluster.reportCount }}</el-descriptions-item>
- <el-descriptions-item label="状态">{{ statusText(currentCluster.status) }}</el-descriptions-item>
- <el-descriptions-item label="生成类型">{{ currentCluster.generatedTypeId || '—' }}</el-descriptions-item>
- </el-descriptions>
- <h4>公共文本特征</h4>
- <pre class="detail-pre">{{ currentCluster.commonSignatures }}</pre>
- <h4>LLM 解析模板</h4>
- <pre class="detail-pre">{{ formatJson(currentCluster.llmTemplate) }}</pre>
- <h4>聚类内报告</h4>
- <el-table :data="uploads" v-loading="uploadLoading" border size="small">
- <el-table-column prop="id" label="ID" width="60" />
- <el-table-column prop="fileUrl" label="文件" min-width="200" />
- <el-table-column prop="uploadedAt" label="上传时间" width="180" />
- </el-table>
- </template>
- </el-dialog>
- </div>
- </template>
- <script>
- import { getUnknownClusters, getClusterUploads, generateTypeFromCluster } from '@/api/reportParser'
- export default {
- name: 'ReportUnknownCluster',
- data() {
- return {
- loading: false, uploadLoading: false,
- clusters: [], statusFilter: '',
- detailVisible: false, currentCluster: null,
- uploads: [],
- }
- },
- mounted() { this.fetchClusters() },
- methods: {
- async fetchClusters() {
- this.loading = true
- try {
- const res = await getUnknownClusters({ page: 1, size: 50, status: this.statusFilter })
- this.clusters = res.data?.records || res.data || []
- } catch (e) { this.$message.error('加载失败') }
- this.loading = false
- },
- statusType(status) {
- return { collecting: 'info', ready: 'warning', generated: 'success', imported: 'success' }[status] || 'info'
- },
- statusText(status) {
- return { collecting: '收集', ready: '可生成', generated: '已生成', imported: '已导入' }[status] || status
- },
- formatJson(str) {
- if (!str) return ''
- try { return JSON.stringify(JSON.parse(str), null, 2) } catch (e) { return str }
- },
- async handleDetail(row) {
- this.currentCluster = row
- this.detailVisible = true
- this.uploads = []
- this.uploadLoading = true
- try {
- const res = await getClusterUploads({ clusterId: row.id })
- this.uploads = res.data || []
- } catch (e) { this.$message.error('加载报告失败') }
- this.uploadLoading = false
- },
- handleGenerate(row) {
- this.$confirm('确认为此聚类生成报告类型?将创建待审核的报告类型和指纹规则。', '提示', { type: 'warning' })
- .then(async () => {
- try {
- const res = await generateTypeFromCluster({ clusterId: row.id })
- this.$message.success('已生成类型: ' + (res.data?.typeId || ''))
- this.fetchClusters()
- } catch (e) { this.$message.error('生成失败') }
- }).catch(() => {})
- },
- }
- }
- </script>
- <style scoped>
- .detail-pre {
- background: #f5f7fa;
- border: 1px solid #e4e7ed;
- border-radius: 4px;
- padding: 10px;
- max-height: 300px;
- overflow: auto;
- font-size: 12px;
- white-space: pre-wrap;
- word-break: break-all;
- }
- </style>
|