fix(frontend): load persisted case records

This commit is contained in:
2026-07-14 05:05:49 +08:00
parent 153382cb57
commit 307f524499
2 changed files with 119 additions and 2 deletions
+92 -2
View File
@@ -87,17 +87,48 @@
<el-table-column prop="time" label="时间" width="130" />
<el-table-column prop="owner" label="负责人" width="120" />
<el-table-column prop="summary" label="摘要" min-width="300" />
<el-table-column label="操作" width="90" fixed="right">
<template #default="{ row }">
<el-button link type="danger" :disabled="!row.caseId" @click="openCaseDetail(row)">详情</el-button>
</template>
</el-table-column>
</el-table>
</section>
<el-dialog v-model="detailVisible" title="案例详情" width="720px">
<template v-if="caseDetail">
<div class="detail-meta">{{ caseDetail.time }} · {{ caseDetail.owner }} · {{ caseDetail.status }} · {{ caseDetail.fileName }}</div>
<div class="detail-block">
<strong>原始转写</strong>
<p>{{ caseDetail.transcript || '暂无转写内容' }}</p>
</div>
<div class="detail-block">
<strong>案例摘要</strong>
<p>{{ caseDetail.summary || '暂无案例摘要' }}</p>
</div>
<el-alert title="当前版本提供转写、摘要和状态详情;视频样片、学习点与主管点评待正式媒体和业务字段接入。" type="info" :closable="false" />
</template>
<el-empty v-else description="暂无详情" />
</el-dialog>
</div>
</template>
<script setup name="KnowledgeCases" lang="ts">
import { DocumentChecked, FolderChecked, Microphone, Tickets } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { computed, ref } from 'vue';
import { computed, onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { curateKnowledgeCase, organizeKnowledgeCase, uploadCaseAudio, type CaseRecord, type CaseSummaryItem, type CaseTag } from '@/api/aihr/case';
import {
curateKnowledgeCase,
getCaseDetail,
getCaseRecords,
organizeKnowledgeCase,
uploadCaseAudio,
type CaseDetailResponse,
type CaseRecord,
type CaseSummaryItem,
type CaseTag
} from '@/api/aihr/case';
const router = useRouter();
@@ -114,6 +145,9 @@ const apiSummary = ref<CaseSummaryItem[]>([]);
const apiTags = ref<CaseTag[]>([]);
const apiRecord = ref<CaseRecord | null>(null);
const apiSampleHint = ref('');
const recordsLoading = ref(false);
const detailVisible = ref(false);
const caseDetail = ref<CaseDetailResponse | null>(null);
const displayFileName = computed(() => apiFileName.value || '未选择文件');
const displayTranscript = computed(() => apiTranscript.value || '暂无转写结果');
@@ -170,6 +204,7 @@ const pipeline = computed(() => [
const baseRecords = [
{
caseId: '',
title: '车库积水投诉处理',
type: '投诉处理',
status: '已入库',
@@ -178,6 +213,7 @@ const baseRecords = [
summary: '确认车位、派工排水、群内同步进度,业主确认问题解决。'
},
{
caseId: '',
title: '催缴沟通争议化解',
type: '催缴沟通',
status: '待审核',
@@ -186,6 +222,7 @@ const baseRecords = [
summary: '业主质疑服务质量,管家先回应服务问题再说明缴费安排。'
},
{
caseId: '',
title: '夜间噪音投诉跟进',
type: '邻里纠纷',
status: '整理中',
@@ -197,6 +234,30 @@ const baseRecords = [
const records = ref([...baseRecords]);
async function loadCaseRecords() {
recordsLoading.value = true;
try {
const { data } = await getCaseRecords();
records.value = data ?? [];
} catch {
records.value = [...baseRecords];
ElMessage.warning('案例列表接口暂不可用,当前展示演示记录');
} finally {
recordsLoading.value = false;
}
}
async function openCaseDetail(record: CaseRecord) {
if (!record.caseId) return;
try {
const { data } = await getCaseDetail(record.caseId);
caseDetail.value = data;
detailVisible.value = true;
} catch {
ElMessage.error('案例详情加载失败');
}
}
async function handleAudioPicked(event: Event) {
const input = event.target as HTMLInputElement;
const file = input.files?.[0];
@@ -281,6 +342,7 @@ async function storeCase() {
if (apiRecord.value && !records.value.some((item) => item.title === apiRecord.value?.title)) {
records.value.unshift(apiRecord.value);
}
await loadCaseRecords();
ElMessage.success('案例已由后端 API 入库,可用于训练复用');
} catch {
apiMode.value = 'error';
@@ -289,6 +351,10 @@ async function storeCase() {
ElMessage.error('后端案例入库 API 不可用');
}
}
onMounted(() => {
void loadCaseRecords();
});
</script>
<style lang="scss" scoped>
@@ -524,6 +590,30 @@ async function storeCase() {
}
}
.detail-meta {
margin-bottom: 16px;
color: #657184;
font-size: 13px;
}
.detail-block {
margin-bottom: 16px;
padding: 14px;
border-radius: 10px;
background: #f7f8fb;
strong {
color: #162033;
}
p {
margin: 8px 0 0;
color: #445064;
line-height: 1.65;
white-space: pre-wrap;
}
}
.record-table {
border: 1px solid #edf0f5;
border-radius: 8px;