refactor: 拆分管理后台页面并按需加载
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<script setup lang="ts">
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ref, watch } from "vue";
|
||||
import { api } from "../services/api";
|
||||
import type { AiLogRecord } from "../types/api";
|
||||
|
||||
const props = defineProps<{ modelValue: boolean; logId: number | null }>();
|
||||
const emit = defineEmits<{ "update:modelValue": [value: boolean] }>();
|
||||
const detail = ref<AiLogRecord | null>(null);
|
||||
const loading = ref(false);
|
||||
|
||||
watch(
|
||||
() => [props.modelValue, props.logId] as const,
|
||||
async ([open, logId]) => {
|
||||
if (!open || !logId) return;
|
||||
detail.value = null;
|
||||
loading.value = true;
|
||||
try {
|
||||
detail.value = await api.aiLogDetail(logId);
|
||||
} catch (error) {
|
||||
ElMessage.error(
|
||||
error instanceof Error ? error.message : "AI 请求详情加载失败",
|
||||
);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
function formatMoney(value?: number | null, currency = "CNY") {
|
||||
if (typeof value !== "number") return "-";
|
||||
return `${currency || "CNY"} ${value.toFixed(6)}`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-drawer
|
||||
:model-value="modelValue"
|
||||
size="820px"
|
||||
title="AI 请求详情"
|
||||
@update:model-value="emit('update:modelValue', $event)"
|
||||
>
|
||||
<div v-loading="loading">
|
||||
<template v-if="detail">
|
||||
<section class="chat-summary">
|
||||
<div>
|
||||
<span>请求ID</span><strong>{{ detail.id }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>会话ID</span><strong>{{ detail.sessionId || "-" }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>消息ID</span><strong>{{ detail.messageId || "-" }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>用户ID</span><strong>{{ detail.userId || "-" }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>模型</span><strong>{{ detail.modelName || "-" }}</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>状态</span><strong>{{ detail.status }}</strong>
|
||||
</div>
|
||||
</section>
|
||||
<section class="audit-detail-grid">
|
||||
<span>知识库:{{ detail.knowledgeIds || "-" }}</span
|
||||
><span>命中数:{{ detail.retrieveCount }}</span
|
||||
><span>片段数:{{ detail.retrievedChunks?.length || 0 }}</span
|
||||
><span>输入 Token:{{ detail.inputToken || "-" }}</span
|
||||
><span>输出 Token:{{ detail.outputToken || "-" }}</span
|
||||
><span>总 Token:{{ detail.totalToken || "-" }}</span
|
||||
><span
|
||||
>估算成本:{{
|
||||
formatMoney(detail.estimatedCost, detail.currency || "CNY")
|
||||
}}</span
|
||||
><span>问题类型:{{ detail.questionType || "-" }}</span
|
||||
><span>知识命中:{{ detail.knowledgeHit ? "是" : "否" }}</span
|
||||
><span>路由原因:{{ detail.routeReason || "-" }}</span
|
||||
><span>耗时:{{ detail.costMs || "-" }}ms</span
|
||||
><span>时间:{{ detail.createdAt }}</span>
|
||||
</section>
|
||||
<p v-if="detail.errorMessage" class="error-text">
|
||||
{{ detail.errorMessage }}
|
||||
</p>
|
||||
<h3 class="detail-title">召回知识片段</h3>
|
||||
<section v-if="detail.retrievedChunks?.length" class="retrieval-chunks">
|
||||
<article
|
||||
v-for="chunk in detail.retrievedChunks"
|
||||
:key="`${detail.id}-${chunk.index}`"
|
||||
class="retrieval-chunk"
|
||||
>
|
||||
<div class="chunk-head">
|
||||
<strong
|
||||
>片段 {{ chunk.index }}/{{
|
||||
detail.retrievedChunks.length
|
||||
}}</strong
|
||||
><span>{{ chunk.knowledgeName || "未知知识库" }}</span
|
||||
><span v-if="chunk.knowledgeId"
|
||||
>知识库ID:{{ chunk.knowledgeId }}</span
|
||||
>
|
||||
</div>
|
||||
<div class="chunk-title">{{ chunk.title || "未命名片段" }}</div>
|
||||
<pre>{{ chunk.content }}</pre>
|
||||
<a
|
||||
v-if="chunk.sourceUrl"
|
||||
:href="chunk.sourceUrl"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>查看来源</a
|
||||
>
|
||||
</article>
|
||||
</section>
|
||||
<el-empty
|
||||
v-else
|
||||
description="本条请求未保存召回片段"
|
||||
:image-size="72"
|
||||
/>
|
||||
<h3 class="detail-title">完整 Prompt</h3>
|
||||
<pre class="prompt-preview">{{
|
||||
detail.prompt || "无 Prompt 记录"
|
||||
}}</pre>
|
||||
</template>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
Reference in New Issue
Block a user