fix(frontend): load persisted case records
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user