dev #1
@ -17,7 +17,10 @@ import { useRouter } from "vue-router";
|
||||
import type { AssistantResponseCard } from "@/types/conversation";
|
||||
import type { ReportCard } from "@/types/risk";
|
||||
|
||||
const props = defineProps<{ card: AssistantResponseCard }>();
|
||||
const props = defineProps<{
|
||||
card: AssistantResponseCard;
|
||||
canAppendReport?: boolean;
|
||||
}>();
|
||||
const router = useRouter();
|
||||
const emit = defineEmits<{
|
||||
generateReport: [card: ReportCard];
|
||||
@ -381,12 +384,13 @@ function generateReport() {
|
||||
|
||||
<div class="response-actions">
|
||||
<button
|
||||
v-if="card.type === 'solution' && canAppendReport"
|
||||
type="button"
|
||||
class="response-actions__primary"
|
||||
title="追加到当前风险报告"
|
||||
@click="generateReport"
|
||||
>
|
||||
<CheckCircle2 :size="14" />生成报告
|
||||
<CheckCircle2 :size="14" />追加到报告
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@ -47,6 +47,7 @@ const toolInput = ref("");
|
||||
const toolError = ref("");
|
||||
const toolFile = ref<File | null>(null);
|
||||
const expandedReplies = ref(new Set<number>());
|
||||
const primaryReportReady = ref(false);
|
||||
const assessmentFields = ref({
|
||||
category: "",
|
||||
specification: "",
|
||||
@ -116,15 +117,22 @@ onActivated(async () => {
|
||||
// MainLayout keeps this page alive. Returning from report/dashboard therefore
|
||||
// does not remount it, so explicitly reveal the newest message on re-entry.
|
||||
if (conversation.value?.messages.length) await scrollToBottom("auto");
|
||||
refreshPrimaryReportState();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => route.query.conversation,
|
||||
async () => {
|
||||
await openFromRoute();
|
||||
refreshPrimaryReportState();
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => conversation.value?.id,
|
||||
() => refreshPrimaryReportState(),
|
||||
);
|
||||
|
||||
async function usePrompt(value: string) {
|
||||
const current = prompt.value.trim();
|
||||
prompt.value = current ? `${current}\n${value}` : value;
|
||||
@ -356,6 +364,28 @@ function legacySolutionCards(result: RiskAssessmentResult): ReportCard[] {
|
||||
}));
|
||||
}
|
||||
|
||||
function isPrimaryRiskReport(
|
||||
report: RiskAssessmentResult | null,
|
||||
): report is RiskAssessmentResult {
|
||||
return Boolean(
|
||||
report &&
|
||||
(report.dimensionScores?.length ||
|
||||
report.factors?.length ||
|
||||
report.categoryWarning ||
|
||||
report.supplierFreq),
|
||||
);
|
||||
}
|
||||
|
||||
function refreshPrimaryReportState() {
|
||||
const conversationId = conversation.value?.id;
|
||||
primaryReportReady.value = Boolean(
|
||||
conversationId &&
|
||||
isPrimaryRiskReport(
|
||||
readConversationReport(conversationId, auth.user?.id),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function openReport(result: RiskAssessmentResult) {
|
||||
const conversationId = conversation.value?.id;
|
||||
if (!conversationId) return;
|
||||
@ -376,6 +406,7 @@ function openReport(result: RiskAssessmentResult) {
|
||||
}
|
||||
: cloneReport(result);
|
||||
writeConversationReport(conversationId, merged, auth.user?.id);
|
||||
primaryReportReady.value = true;
|
||||
void router.push({
|
||||
name: "report",
|
||||
query: { conversation: String(conversationId) },
|
||||
@ -384,27 +415,11 @@ function openReport(result: RiskAssessmentResult) {
|
||||
|
||||
function openSolutionReport(card: ReportCard) {
|
||||
const conversationId = conversation.value?.id;
|
||||
if (!conversationId) return;
|
||||
const current = conversation.value?.messages
|
||||
.slice()
|
||||
.reverse()
|
||||
.find((message) => message.riskResult)?.riskResult;
|
||||
if (!conversationId || card.type !== "solution" || !primaryReportReady.value)
|
||||
return;
|
||||
const stored = readConversationReport(conversationId, auth.user?.id);
|
||||
const sameReport = Boolean(
|
||||
current && stored && current.subjectId === stored.subjectId,
|
||||
);
|
||||
const base: RiskAssessmentResult =
|
||||
sameReport && stored
|
||||
? cloneReport(stored)
|
||||
: current
|
||||
? cloneReport(current)
|
||||
: stored || {
|
||||
subjectId: "AI 案例推理方案",
|
||||
score: 50,
|
||||
level: "medium",
|
||||
modelVersion: "ai-solution-card",
|
||||
factors: [],
|
||||
};
|
||||
if (!isPrimaryRiskReport(stored)) return;
|
||||
const base = cloneReport(stored);
|
||||
const existingCards = base.reportCards ?? [];
|
||||
const merged: RiskAssessmentResult = {
|
||||
...base,
|
||||
@ -571,6 +586,7 @@ async function scrollToBottom(behavior: "smooth" | "auto" = "smooth") {
|
||||
<AssistantResponseCard
|
||||
v-if="message.responseCard"
|
||||
:card="message.responseCard"
|
||||
:can-append-report="primaryReportReady"
|
||||
@generate-report="openSolutionReport"
|
||||
/>
|
||||
<time class="message-time">{{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user