按类型归并报告页面追加内容
This commit is contained in:
parent
343c04530c
commit
8ed60807f9
@ -34,6 +34,48 @@ const reportCards = computed<ReportCard[]>(
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
const reportData = computed(() => {
|
||||||
|
const cards = reportCards.value;
|
||||||
|
const unique = <T>(items: T[], key: (item: T) => string) => {
|
||||||
|
const seen = new Set<string>();
|
||||||
|
return items.filter((item) => {
|
||||||
|
const value = key(item);
|
||||||
|
if (seen.has(value)) return false;
|
||||||
|
seen.add(value);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const standards = unique(
|
||||||
|
[
|
||||||
|
...(report.value?.standardJudgment ?? []),
|
||||||
|
...cards.flatMap((card) => card.standards ?? []),
|
||||||
|
],
|
||||||
|
(item) => `${item.category}|${item.riskPoint}|${item.rule}|${item.status}`,
|
||||||
|
);
|
||||||
|
const similarCases = unique(
|
||||||
|
[
|
||||||
|
...(report.value?.similarCases ?? []),
|
||||||
|
...cards.flatMap((card) => card.similarCases ?? []),
|
||||||
|
],
|
||||||
|
(item) => `${item.caseId}|${item.date}|${item.product}|${item.problem ?? item.description}|${item.solution}`,
|
||||||
|
);
|
||||||
|
const suggestions = unique(
|
||||||
|
[
|
||||||
|
...(report.value?.aiSuggestions ?? []),
|
||||||
|
...cards.flatMap((card) => card.suggestions ?? []),
|
||||||
|
],
|
||||||
|
(item) => item,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
cards,
|
||||||
|
supplierCards: cards.filter((card) => card.type === "supplier"),
|
||||||
|
materialCards: cards.filter((card) => card.type === "material"),
|
||||||
|
solutionCards: cards.filter((card) => card.type === "solution"),
|
||||||
|
standards,
|
||||||
|
similarCases,
|
||||||
|
suggestions,
|
||||||
|
};
|
||||||
|
});
|
||||||
const dimensionRows = computed(() => {
|
const dimensionRows = computed(() => {
|
||||||
if (!report.value) return [];
|
if (!report.value) return [];
|
||||||
if (report.value.dimensionScores?.length) {
|
if (report.value.dimensionScores?.length) {
|
||||||
@ -208,7 +250,7 @@ function dimensionConclusion(item: {
|
|||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="report.supplierFreq?.supplierName">
|
<template v-if="report.supplierFreq?.supplierName || reportData.supplierCards.length">
|
||||||
<h2>三、供应商合作频次分析</h2>
|
<h2>三、供应商合作频次分析</h2>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@ -219,32 +261,55 @@ function dimensionConclusion(item: {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-if="report.supplierFreq.cooperationCount != null">
|
<tr v-if="report.supplierFreq?.cooperationCount != null">
|
||||||
<td>合作次数</td>
|
<td>合作次数</td>
|
||||||
<td>{{ report.supplierFreq.cooperationCount }} 次</td>
|
<td>{{ report.supplierFreq?.cooperationCount }} 次</td>
|
||||||
<td>近三年采购订单去重单据数</td>
|
<td>近三年采购订单去重单据数</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>异常次数</td>
|
<td>异常次数</td>
|
||||||
<td>{{ report.supplierFreq.anomalyCount ?? 0 }} 次</td>
|
<td>{{ report.supplierFreq?.anomalyCount ?? 0 }} 次</td>
|
||||||
<td>异常案例库统计</td>
|
<td>异常案例库统计</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="report.supplierFreq.alpha != null">
|
<tr v-if="report.supplierFreq?.alpha != null">
|
||||||
<td>频次风险系数</td>
|
<td>频次风险系数</td>
|
||||||
<td>×{{ report.supplierFreq.alpha.toFixed(2) }}</td>
|
<td>×{{ report.supplierFreq?.alpha?.toFixed(2) }}</td>
|
||||||
<td>α = 1.0 +(采购订单数 / 100)× 0.3,最高1.5</td>
|
<td>α = 1.0 +(采购订单数 / 100)× 0.3,最高1.5</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="report.supplierFreq.tier">
|
<tr v-if="report.supplierFreq?.tier">
|
||||||
<td>供应商层级</td>
|
<td>供应商层级</td>
|
||||||
<td>{{ report.supplierFreq.tier }}</td>
|
<td>{{ report.supplierFreq?.tier }}</td>
|
||||||
<td>{{ report.supplierFreq.suggestion }}</td>
|
<td>{{ report.supplierFreq?.suggestion }}</td>
|
||||||
|
</tr>
|
||||||
|
<template v-for="(card, cardIndex) in reportData.supplierCards" :key="`supplier-card-${cardIndex}`">
|
||||||
|
<tr v-if="card.supplierScore != null"><td>供应商得分</td><td>{{ card.supplierScore.toFixed(2) }} 分</td><td>供应商画像统计</td></tr>
|
||||||
|
<tr v-if="card.supplierBaseScore != null"><td>供应商基础分</td><td>{{ card.supplierBaseScore.toFixed(2) }} 分</td><td>供应商画像统计</td></tr>
|
||||||
|
<tr v-if="card.topProblems?.length"><td>高频问题</td><td>{{ card.topProblems.map((item) => `${item.name}(${item.count}次)`).join("、") }}</td><td>异常案例库统计</td></tr>
|
||||||
|
<tr v-if="card.note"><td>备注</td><td>{{ card.note }}</td><td>供应商画像统计</td></tr>
|
||||||
|
</template>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="reportData.materialCards.length">
|
||||||
|
<h2>四、物料风险分析</h2>
|
||||||
|
<table>
|
||||||
|
<thead><tr><th>物料/字段</th><th>分析结果</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(card, index) in reportData.materialCards" :key="`material-${index}`">
|
||||||
|
<td>{{ card.material || card.title }}</td>
|
||||||
|
<td>
|
||||||
|
<span v-if="card.anomalyCount != null">历史异常:{{ card.anomalyCount }} 条;</span>
|
||||||
|
<span v-if="card.frequentProblems?.length">常见问题:{{ card.frequentProblems.map((item) => `${item.name}(${item.count}次)`).join("、") }};</span>
|
||||||
|
<span v-if="card.suggestions?.length">建议:{{ card.suggestions.join(";") }}</span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<h2>四、相似案例匹配({{ report.similarCases?.length || 0 }} 条)</h2>
|
<h2>{{ reportData.materialCards.length ? "五" : "四" }}、相似案例匹配({{ reportData.similarCases.length }} 条)</h2>
|
||||||
<template v-if="report.similarCases?.length">
|
<template v-if="reportData.similarCases.length">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -256,7 +321,7 @@ function dimensionConclusion(item: {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
v-for="item in report.similarCases"
|
v-for="item in reportData.similarCases"
|
||||||
:key="`${item.date}-${item.product}-${item.problem}`"
|
:key="`${item.date}-${item.product}-${item.problem}`"
|
||||||
>
|
>
|
||||||
<td>{{ item.date || "未知" }}</td>
|
<td>{{ item.date || "未知" }}</td>
|
||||||
@ -271,11 +336,11 @@ function dimensionConclusion(item: {
|
|||||||
暂无相关案例,RAG 相似案例检索未返回匹配结果。
|
暂无相关案例,RAG 相似案例检索未返回匹配结果。
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2>五、预防建议</h2>
|
<h2>{{ reportData.materialCards.length ? "六" : "五" }}、预防建议</h2>
|
||||||
<ol>
|
<ol>
|
||||||
<li
|
<li
|
||||||
v-for="suggestion in report.aiSuggestions?.length
|
v-for="suggestion in reportData.suggestions.length
|
||||||
? report.aiSuggestions
|
? reportData.suggestions
|
||||||
: ['优先针对低分维度安排专项验证,并明确责任人与完成节点。']"
|
: ['优先针对低分维度安排专项验证,并明确责任人与完成节点。']"
|
||||||
:key="suggestion"
|
:key="suggestion"
|
||||||
>
|
>
|
||||||
@ -283,20 +348,30 @@ function dimensionConclusion(item: {
|
|||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<h2>六、AI 推理方案(无历史案例场景)</h2>
|
<h2>{{ reportData.materialCards.length ? "七" : "六" }}、AI 推理方案(无历史案例场景)</h2>
|
||||||
<p class="report-paragraph">
|
<p class="report-paragraph">
|
||||||
<template v-if="report.similarCases?.length">
|
<template v-if="reportData.similarCases.length">
|
||||||
本次评估已匹配
|
本次评估已匹配
|
||||||
{{ report.similarCases.length }}
|
{{ reportData.similarCases.length }}
|
||||||
条相似历史案例,当前采用历史案例与标准库双引擎结论,未单独触发无历史案例类比推理。
|
条相似历史案例,当前采用历史案例与标准库双引擎结论,未单独触发无历史案例类比推理。
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
当前未匹配到足够历史案例,系统将基于相似品类、相似物料生成类比方案,并结合判定标准库进行规则兜底;实际执行前需由产品和品控确认。
|
当前未匹配到足够历史案例,系统将基于相似品类、相似物料生成类比方案,并结合判定标准库进行规则兜底;实际执行前需由产品和品控确认。
|
||||||
</template>
|
</template>
|
||||||
</p>
|
</p>
|
||||||
|
<template v-if="reportData.solutionCards.length">
|
||||||
|
<section v-for="(card, index) in reportData.solutionCards" :key="`solution-${index}`" class="ai-solution-report">
|
||||||
|
<header><strong>{{ card.title }}</strong><span v-if="card.confidence">置信度:{{ card.confidence }}</span></header>
|
||||||
|
<p v-if="card.analysisBase"><b>分析基础:</b>{{ card.analysisBase }}</p>
|
||||||
|
<p v-if="card.standardFallbackEnabled"><b>标准兜底校验:</b>已启用(无直接历史案例)</p>
|
||||||
|
<ul v-if="card.risks?.length"><li v-for="risk in card.risks" :key="`${risk.title}-${risk.detail}`"><b>{{ risk.level }} · {{ risk.title }}:</b>{{ risk.detail }}</li></ul>
|
||||||
|
<ol v-if="card.suggestions?.length"><li v-for="suggestion in card.suggestions" :key="suggestion">{{ suggestion }}</li></ol>
|
||||||
|
<p v-if="card.warning" class="ai-solution-report__warning">{{ card.warning }}</p>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
<h2>七、标准判定结果</h2>
|
<h2>{{ reportData.materialCards.length ? "八" : "七" }}、标准判定结果</h2>
|
||||||
<template v-if="report.standardJudgment?.length">
|
<template v-if="reportData.standards.length">
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -308,7 +383,7 @@ function dimensionConclusion(item: {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
v-for="standard in report.standardJudgment"
|
v-for="standard in reportData.standards"
|
||||||
:key="`${standard.category}-${standard.riskPoint}`"
|
:key="`${standard.category}-${standard.riskPoint}`"
|
||||||
>
|
>
|
||||||
<td>{{ standard.category }} · {{ standard.riskPoint }}</td>
|
<td>{{ standard.category }} · {{ standard.riskPoint }}</td>
|
||||||
@ -324,41 +399,6 @@ function dimensionConclusion(item: {
|
|||||||
双引擎融合:历史异常经验引擎提供风险优先级,标准库提供可执行的检测阈值与验证任务。
|
双引擎融合:历史异常经验引擎提供风险优先级,标准库提供可执行的检测阈值与验证任务。
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<template v-if="reportCards.length">
|
|
||||||
<h2>八、追加卡片分析</h2>
|
|
||||||
<section
|
|
||||||
v-for="(card, index) in reportCards"
|
|
||||||
:key="`${card.type}-${card.title}-${index}`"
|
|
||||||
class="report-card-detail"
|
|
||||||
>
|
|
||||||
<header><strong>{{ card.title }}</strong><span>{{ card.type }}</span></header>
|
|
||||||
<p v-if="card.name || card.material || card.category"><b>分析对象:</b>{{ card.name || card.material || card.category }}</p>
|
|
||||||
<p v-if="card.partyType"><b>对象类型:</b>{{ card.partyType }}</p>
|
|
||||||
<p v-if="card.question"><b>原始问题:</b>{{ card.question }}</p>
|
|
||||||
<p v-if="card.anomalyCount != null"><b>历史异常:</b>{{ card.anomalyCount }} 条</p>
|
|
||||||
<p v-if="card.cooperationCount != null"><b>合作次数:</b>{{ card.cooperationCount }} 次</p>
|
|
||||||
<p v-if="card.frequencyBasis"><b>数据口径:</b>{{ card.frequencyBasis }}</p>
|
|
||||||
<p v-if="card.dataAvailable != null"><b>数据状态:</b>{{ card.dataAvailable ? "有匹配数据" : "暂无匹配数据" }}</p>
|
|
||||||
<p v-if="card.frequencyCoefficient != null"><b>频次系数:</b>×{{ card.frequencyCoefficient.toFixed(2) }}</p>
|
|
||||||
<p v-if="card.supplierBaseScore != null"><b>供应商基础分:</b>{{ card.supplierBaseScore.toFixed(2) }} 分</p>
|
|
||||||
<p v-if="card.supplierScore != null"><b>供应商得分:</b>{{ card.supplierScore.toFixed(2) }} 分</p>
|
|
||||||
<p v-if="card.tier"><b>层级:</b>{{ card.tier }}</p>
|
|
||||||
<p v-if="card.matchedCount != null"><b>匹配数量:</b>{{ card.matchedCount }} 条</p>
|
|
||||||
<p v-if="card.analysisBase"><b>分析基础:</b>{{ card.analysisBase }}</p>
|
|
||||||
<p v-if="card.confidence"><b>置信度:</b>{{ card.confidence }}</p>
|
|
||||||
<p v-if="card.standardFallbackEnabled"><b>标准兜底校验:</b>已启用(无直接历史案例)</p>
|
|
||||||
<p v-if="card.detectedValues?.length"><b>检测值:</b>{{ card.detectedValues.map((item) => `${item.name}:${item.value}`).join("、") }}</p>
|
|
||||||
<p v-if="card.topProblems?.length"><b>高频问题:</b>{{ card.topProblems.map((item) => `${item.name}(${item.count}次)`).join("、") }}</p>
|
|
||||||
<p v-if="card.frequentProblems?.length"><b>常见问题:</b>{{ card.frequentProblems.map((item) => `${item.name}(${item.count}次)`).join("、") }}</p>
|
|
||||||
<template v-if="card.standards?.length"><p><b>关联标准:</b></p><ul class="report-card-detail__standards"><li v-for="standard in card.standards" :key="`${standard.category}-${standard.riskPoint}`">{{ standard.category }} · {{ standard.riskPoint }}:{{ standard.rule }}({{ standard.source || "标准文件.xlsx" }})· {{ standard.status }}</li></ul></template>
|
|
||||||
<template v-if="card.similarCases?.length"><p><b>相似案例:</b></p><ul class="report-card-detail__standards"><li v-for="(item, caseIndex) in card.similarCases" :key="`${item.date || 'case'}-${caseIndex}`">{{ item.date || "日期未知" }} · {{ item.product || "未命名产品" }} · {{ item.problem || item.description || "异常问题未填写" }} → {{ item.solution || "解决方案未填写" }}<template v-if="item.similarity != null">(相似度 {{ Math.round(item.similarity * 100) }}%)</template></li></ul></template>
|
|
||||||
<ul v-if="card.risks?.length"><li v-for="risk in card.risks" :key="`${risk.title}-${risk.detail}`"><b>{{ risk.level }} · {{ risk.title }}:</b>{{ risk.detail }}</li></ul>
|
|
||||||
<ol v-if="card.suggestions?.length"><li v-for="suggestion in card.suggestions" :key="suggestion">{{ suggestion }}</li></ol>
|
|
||||||
<p v-if="card.note"><b>备注:</b>{{ card.note }}</p>
|
|
||||||
<p v-if="card.warning" class="report-card-detail__warning">{{ card.warning }}</p>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<footer class="report-footer">
|
<footer class="report-footer">
|
||||||
<span>编制:蝶雅风险预估系统</span
|
<span>编制:蝶雅风险预估系统</span
|
||||||
><span>生成时间:{{ generatedAt }}</span>
|
><span>生成时间:{{ generatedAt }}</span>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user