ReportAutoLearn.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <div class="report-autolearn admin-page">
  3. <el-card>
  4. <div slot="header">
  5. <span>报告自学习</span>
  6. <div style="float: right;">
  7. <el-button size="small" @click="fetchClusters" icon="el-icon-refresh">刷新</el-button>
  8. </div>
  9. </div>
  10. <el-alert title='自学习机制:当同一类型的未知报告积累到3份后,系统自动标记为"可生成"状态,管理员可在此生成报告类型和指纹规则。' type='info' :closable='false' show-icon style='margin-bottom: 16px;' />
  11. <el-table :data="clusters" v-loading="loading" border stripe>
  12. <el-table-column prop="id" label="ID" width="60" />
  13. <el-table-column prop="clusterKey" label="聚类键" width="140" />
  14. <el-table-column prop="reportCount" label="报告数" width="80" />
  15. <el-table-column label="状态" width="100">
  16. <template slot-scope="{ row }">
  17. <el-tag :type="row.status === 'ready' ? 'warning' : 'success'" size="small">
  18. {{ row.status === 'ready' ? '可生成' : '已生成' }}
  19. </el-tag>
  20. </template>
  21. </el-table-column>
  22. <el-table-column prop="generatedTypeId" label="类型ID" width="140" />
  23. <el-table-column prop="updatedAt" label="更新时间" width="180" />
  24. <el-table-column label="操作" width="180" fixed="right">
  25. <template slot-scope="{ row }">
  26. <el-button size="mini" type="primary" @click="handleDetail(row)">详情</el-button>
  27. <el-button v-if="row.status === 'ready'" size="mini" type="success" @click="handleGenerate(row)">生成类型</el-button>
  28. <el-button v-if="row.status === 'generated'" size="mini" type="primary" @click="handleViewType(row)" plain>查看类型</el-button>
  29. </template>
  30. </el-table-column>
  31. </el-table>
  32. </el-card>
  33. <el-dialog :visible.sync="detailVisible" title="聚类详情" width="750px">
  34. <template v-if="currentCluster">
  35. <el-descriptions :column="2" border size="small">
  36. <el-descriptions-item label="聚类键">{{ currentCluster.clusterKey }}</el-descriptions-item>
  37. <el-descriptions-item label="报告数">{{ currentCluster.reportCount }}</el-descriptions-item>
  38. <el-descriptions-item label="状态">{{ currentCluster.status === 'ready' ? '可生成' : '已生成' }}</el-descriptions-item>
  39. <el-descriptions-item label="类型ID">{{ currentCluster.generatedTypeId || '—' }}</el-descriptions-item>
  40. </el-descriptions>
  41. <h4>公共文本特征</h4>
  42. <pre class="detail-pre">{{ currentCluster.commonSignatures }}</pre>
  43. <h4>LLM 解析模板</h4>
  44. <pre class="detail-pre">{{ formatJson(currentCluster.llmTemplate) }}</pre>
  45. </template>
  46. </el-dialog>
  47. </div>
  48. </template>
  49. <script>
  50. import { getUnknownClusters, generateTypeFromCluster } from '@/api/reportParser'
  51. export default {
  52. name: 'ReportAutoLearn',
  53. data() {
  54. return {
  55. loading: false,
  56. clusters: [],
  57. detailVisible: false,
  58. currentCluster: null,
  59. }
  60. },
  61. mounted() { this.fetchClusters() },
  62. methods: {
  63. async fetchClusters() {
  64. this.loading = true
  65. try {
  66. const res = await getUnknownClusters({ page: 1, size: 50 })
  67. this.clusters = (res.data?.records || res.data || []).filter(
  68. c => c.status === 'ready' || c.status === 'generated')
  69. } catch (e) { this.$message.error('加载失败') }
  70. this.loading = false
  71. },
  72. formatJson(str) {
  73. if (!str) return ''
  74. try { return JSON.stringify(JSON.parse(str), null, 2) } catch (e) { return str }
  75. },
  76. handleDetail(row) {
  77. this.currentCluster = row
  78. this.detailVisible = true
  79. },
  80. handleGenerate(row) {
  81. this.$confirm('确认为此聚类生成报告类型和指纹规则?生成后需在"报告类型管理"中审核启用。', '提示', { type: 'warning' })
  82. .then(async () => {
  83. try {
  84. const res = await generateTypeFromCluster({ clusterId: row.id })
  85. this.$message.success('已生成类型: ' + (res.data?.typeId || ''))
  86. this.fetchClusters()
  87. } catch (e) { this.$message.error('生成失败') }
  88. }).catch(() => {})
  89. },
  90. handleViewType(row) {
  91. this.$router.push('/report-types')
  92. },
  93. }
  94. }
  95. </script>
  96. <style scoped>
  97. .detail-pre {
  98. background: #f5f7fa;
  99. border: 1px solid #e4e7ed;
  100. border-radius: 4px;
  101. padding: 10px;
  102. max-height: 300px;
  103. overflow: auto;
  104. font-size: 12px;
  105. white-space: pre-wrap;
  106. word-break: break-all;
  107. }
  108. </style>