提交 04628bc9 authored 作者: 张烨's avatar 张烨

feat:封装AI智能报告组件

上级 0204674d
<template>
<div class="view-box"
@mouseenter="handleMouseEnter"
@mouseleave="handleMouseLeave">
<AiButton />
<AiPane :aiContent="myParams.content" />
</div>
</template>
<script setup lang="ts" name="AiReport">
import {reactive} from "vue"
import AiButton from '@/components/base/Ai/AiButton/index.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue';
const myParams = reactive({
data: "",
content: "",
isState: false,
})
const onDataInfo = (event:any) => {
console.log("需要分析的数据", event);
myParams.isState = false;
myParams.data = JSON.stringify(event);
}
let controller = null;
let reader = null;
// 鼠标进入监听
const handleMouseEnter = async () => {
if (myParams.isState) return;
myParams.content = "正在生成...";
if (controller) controller.abort();
controller = new AbortController();
try {
const res = await fetch('/aiAnalysis/chart_interpretation', {
method: 'POST',
headers: {
"X-API-Key": "aircasKEY19491001",
'Content-Type': 'application/json',
},
body: JSON.stringify({ text: myParams.data }),
signal: controller.signal
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value, { stream: true });
const match = chunk.match(/"解读":\s*"([^"]*)"/);
if (match?.[1]) {
myParams.content = match[1];
myParams.isState = true;
return; // 获取到结果直接返回
}
}
myParams.content = "未获取到解读内容";
} catch (err) {
myParams.content = "系统异常,生成失败";
} finally {
reader?.cancel();
reader = null;
}
};
// 鼠标离开监听
const handleMouseLeave = () => {
controller?.abort();
reader?.cancel();
controller = null;
reader = null;
};
defineExpose({ onDataInfo })
</script>
<style scoped lang="scss">
.view-box {
position: absolute;
right: 0px;
bottom: 15px;
z-index: 2;
:deep(.ai-pane-wrapper) {
display: none;
}
:deep(.ai-button-wrapper) {
display: flex;
}
&:hover {
width: 100%;
bottom: 0px;
:deep(.ai-pane-wrapper) {
display: block;
}
:deep(.ai-button-wrapper) {
display: none;
}
}
}
</style>
\ No newline at end of file
...@@ -98,10 +98,7 @@ ...@@ -98,10 +98,7 @@
<div v-if="box5ChartData.title.length" style="width: 100%; height: 100%;" ref="box5Ref"></div> <div v-if="box5ChartData.title.length" style="width: 100%; height: 100%;" ref="box5Ref"></div>
</div> </div>
<TipTab text="数据来源:美国国际贸易委员会、商务部、贸易代表办公室官网" style="margin-top: 16px;" /> <TipTab text="数据来源:美国国际贸易委员会、商务部、贸易代表办公室官网" style="margin-top: 16px;" />
<div class="ai-pane"> <AiReport ref="refAiReport5"></AiReport>
<AiButton />
<AiPane :aiContent="aiContent.content5" />
</div>
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -123,10 +120,7 @@ ...@@ -123,10 +120,7 @@
<div v-if="box6Data.title.length" style="width: 100%; height: 100%;" id="box6Chart"></div> <div v-if="box6Data.title.length" style="width: 100%; height: 100%;" id="box6Chart"></div>
</div> </div>
<TipTab text="数据来源:美国国际贸易委员会、商务部、贸易代表办公室官网" style="padding-right: 50px;" /> <TipTab text="数据来源:美国国际贸易委员会、商务部、贸易代表办公室官网" style="padding-right: 50px;" />
<div class="ai-pane"> <AiReport ref="refAiReport6"></AiReport>
<AiButton />
<AiPane :aiContent="aiContent.content6" />
</div>
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -155,10 +149,7 @@ ...@@ -155,10 +149,7 @@
<div v-if="box7Data.data.length" style="width: 100%; height: 100%;" id="box7Chart"></div> <div v-if="box7Data.data.length" style="width: 100%; height: 100%;" id="box7Chart"></div>
</div> </div>
<TipTab :text="`数据来源:${box7TipText}`" style="margin-top: 10px;" /> <TipTab :text="`数据来源:${box7TipText}`" style="margin-top: 10px;" />
<div class="ai-pane"> <AiReport ref="refAiReport7"></AiReport>
<AiButton />
<AiPane :aiContent="aiContent.content7" />
</div>
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -180,10 +171,7 @@ ...@@ -180,10 +171,7 @@
<div v-if="box8Data.length" style="width: 100%; height: 100%;" ref="box8Ref"></div> <div v-if="box8Data.length" style="width: 100%; height: 100%;" ref="box8Ref"></div>
</div> </div>
<TipTab :text="`数据来源:${box8TipText}`" style="padding-right: 50px;" /> <TipTab :text="`数据来源:${box8TipText}`" style="padding-right: 50px;" />
<div class="ai-pane"> <AiReport ref="refAiReport8"></AiReport>
<AiButton />
<AiPane :aiContent="aiContent.content8" />
</div>
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -300,7 +288,7 @@ import CarouselItem301 from '@/views/marketAccessRestrictions/marketAccessHome/c ...@@ -300,7 +288,7 @@ import CarouselItem301 from '@/views/marketAccessRestrictions/marketAccessHome/c
import CarouselItem232 from '@/views/marketAccessRestrictions/marketAccessHome/com/CarouselItem232.vue'; import CarouselItem232 from '@/views/marketAccessRestrictions/marketAccessHome/com/CarouselItem232.vue';
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import { getDateBefore, getAIReport, getNearYearList } from "@/views/marketAccessRestrictions/utils/index.ts"; import { getDateBefore, getNearYearList } from "@/views/marketAccessRestrictions/utils/index.ts";
import router from "@/router"; import router from "@/router";
import { navigateToViewRiskSignal } from "@/utils/riskSignalOverviewNavigate"; import { navigateToViewRiskSignal } from "@/utils/riskSignalOverviewNavigate";
...@@ -308,8 +296,7 @@ import createLineChart from "@/views/marketAccessRestrictions/utils/baseLineChar ...@@ -308,8 +296,7 @@ import createLineChart from "@/views/marketAccessRestrictions/utils/baseLineChar
import createPieChart from "@/views/marketAccessRestrictions/utils/basePiechart.js"; import createPieChart from "@/views/marketAccessRestrictions/utils/basePiechart.js";
import getRadarChart from "./utils/radarChart"; import getRadarChart from "./utils/radarChart";
import getBarChart from "./utils/barChart1"; import getBarChart from "./utils/barChart1";
import AiButton from '@/components/base/Ai/AiButton/index.vue'; import AiReport from '@/views/marketAccessRestrictions/marketAccessHome/com/AiReport.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue';
import { getPersonSummaryInfo } from "@/api/common/index"; import { getPersonSummaryInfo } from "@/api/common/index";
import { import {
...@@ -332,15 +319,10 @@ import tipsTcon from "./assets/icons/tips-icon.png"; ...@@ -332,15 +319,10 @@ import tipsTcon from "./assets/icons/tips-icon.png";
const getCardClass = (code) => ['theme-card', `theme-${code}`] const getCardClass = (code) => ['theme-card', `theme-${code}`]
// 获取AI智能报告 // 获取AI智能报告
const aiContent = reactive({ const refAiReport5 = ref(null)
content5: "正在生成...", const refAiReport6 = ref(null)
content6: "正在生成...", const refAiReport7 = ref(null)
content7: "正在生成...", const refAiReport8 = ref(null)
content8: "正在生成...",
})
const onAIReport = (data, key) => {
getAIReport(data).then(res => { aiContent[key] = res })
}
const handleToPosi = id => { const handleToPosi = id => {
const element = document.getElementById(id); const element = document.getElementById(id);
...@@ -663,7 +645,6 @@ const hadleGetStatNum = async (event) => { ...@@ -663,7 +645,6 @@ const hadleGetStatNum = async (event) => {
} else { } else {
box5ChartData.value = transformAllData(res.data); box5ChartData.value = transformAllData(res.data);
} }
onAIReport({ type: "折线图", name: "数量变化趋势", data: res.data }, "content5")
} else { } else {
box5ChartData.value.title = []; box5ChartData.value.title = [];
box5ChartData.value.list = [ box5ChartData.value.list = [
...@@ -671,7 +652,6 @@ const hadleGetStatNum = async (event) => { ...@@ -671,7 +652,6 @@ const hadleGetStatNum = async (event) => {
{ name: "301调查", value: [] }, { name: "301调查", value: [] },
{ name: "232调查", value: [] } { name: "232调查", value: [] }
] ]
aiContent.content5 = "";
} }
} catch (error) { } catch (error) {
box5ChartData.value.title = []; box5ChartData.value.title = [];
...@@ -680,8 +660,8 @@ const hadleGetStatNum = async (event) => { ...@@ -680,8 +660,8 @@ const hadleGetStatNum = async (event) => {
{ name: "301调查", value: [] }, { name: "301调查", value: [] },
{ name: "232调查", value: [] } { name: "232调查", value: [] }
] ]
aiContent.content5 = "";
} }
refAiReport5.value?.onDataInfo({ type: "折线图", name: "数量变化趋势", data: box5ChartData.value })
nextTick(() => { createLineChart(box5Ref, box5ChartData.value) }) nextTick(() => { createLineChart(box5Ref, box5ChartData.value) })
}; };
...@@ -707,17 +687,11 @@ const handleGetStatArea = async () => { ...@@ -707,17 +687,11 @@ const handleGetStatArea = async () => {
const res = await getStatArea(params); const res = await getStatArea(params);
console.log("领域分布情况", res); console.log("领域分布情况", res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const arr = res.data.map(item => { const arr = res.data.map(item => item.areaname);
return item.areaname;
});
box6Data.value.title = [...new Set(arr)]; box6Data.value.title = [...new Set(arr)];
const arr1 = res.data.filter(item => { const arr1 = res.data.filter(item => item.sortname === "337调查");
return item.sortname === "337调查"; const arr1Name = arr1.map(item => item.areaname);
});
const arr1Name = arr1.map(item => {
return item.areaname;
});
box6Data.value.title.forEach((item, index) => { box6Data.value.title.forEach((item, index) => {
if (arr1Name.indexOf(item) > -1) { if (arr1Name.indexOf(item) > -1) {
const idx = arr1Name.indexOf(item); const idx = arr1Name.indexOf(item);
...@@ -727,12 +701,8 @@ const handleGetStatArea = async () => { ...@@ -727,12 +701,8 @@ const handleGetStatArea = async () => {
} }
}); });
const arr2 = res.data.filter(item => { const arr2 = res.data.filter(item => item.sortname === "232调查");
return item.sortname === "232调查"; const arr2Name = arr2.map(item => item.areaname);
});
const arr2Name = arr2.map(item => {
return item.areaname;
});
box6Data.value.title.forEach((item, index) => { box6Data.value.title.forEach((item, index) => {
if (arr2Name.indexOf(item) > -1) { if (arr2Name.indexOf(item) > -1) {
const idx = arr2Name.indexOf(item); const idx = arr2Name.indexOf(item);
...@@ -742,12 +712,8 @@ const handleGetStatArea = async () => { ...@@ -742,12 +712,8 @@ const handleGetStatArea = async () => {
} }
}); });
const arr3 = res.data.filter(item => { const arr3 = res.data.filter(item => item.sortname === "301调查");
return item.sortname === "301调查"; const arr3Name = arr3.map(item => item.areaname);
});
const arr3Name = arr3.map(item => {
return item.areaname;
});
box6Data.value.title.forEach((item, index) => { box6Data.value.title.forEach((item, index) => {
if (arr3Name.indexOf(item) > -1) { if (arr3Name.indexOf(item) > -1) {
const idx = arr3Name.indexOf(item); const idx = arr3Name.indexOf(item);
...@@ -756,14 +722,8 @@ const handleGetStatArea = async () => { ...@@ -756,14 +722,8 @@ const handleGetStatArea = async () => {
box6Data.value.data[2].value[index] = 0; box6Data.value.data[2].value[index] = 0;
} }
}); });
const numArr = res.data.map(item => item.AREACOUNT);
const numArr = res.data.map(item => {
return item.AREACOUNT;
});
box6Data.value.maxNum = Math.max(...numArr); box6Data.value.maxNum = Math.max(...numArr);
onAIReport({ type: "雷达图", name: "领域分布情况", data: res.data }, "content6")
} else { } else {
box6Data.value.title = []; box6Data.value.title = [];
box6Data.value.data = [ box6Data.value.data = [
...@@ -772,9 +732,17 @@ const handleGetStatArea = async () => { ...@@ -772,9 +732,17 @@ const handleGetStatArea = async () => {
{ name: "301调查", value: [] } { name: "301调查", value: [] }
]; ];
box6Data.value.maxNum = 0; box6Data.value.maxNum = 0;
aiContent.content6 = "";
} }
} catch (error) { } } catch (error) {
box6Data.value.title = [];
box6Data.value.data = [
{ name: "337调查", value: [] },
{ name: "232调查", value: [] },
{ name: "301调查", value: [] }
];
box6Data.value.maxNum = 0;
}
refAiReport6.value?.onDataInfo({ type: "雷达图", name: "领域分布情况", data: box6Data.value })
}; };
const handleBox6 = async () => { const handleBox6 = async () => {
await handleGetStatArea(); await handleGetStatArea();
...@@ -814,17 +782,15 @@ const handleGetBox7Data = async () => { ...@@ -814,17 +782,15 @@ const handleGetBox7Data = async () => {
box7Data.data = res.data.map(item => { box7Data.data = res.data.map(item => {
return item.NUM; return item.NUM;
}); });
onAIReport({ type: "柱状图", name: "国家分布情况", data: res.data }, "content7")
} else { } else {
box7Data.title = []; box7Data.title = [];
box7Data.data = []; box7Data.data = [];
aiContent.content7 = "";
} }
} catch (error) { } catch (error) {
box7Data.title = []; box7Data.title = [];
box7Data.data = []; box7Data.data = [];
aiContent.content7 = "";
} }
refAiReport7.value?.onDataInfo({ type: "柱状图", name: "国家分布情况", data: box7Data })
}; };
const handleBox7 = async () => { const handleBox7 = async () => {
...@@ -854,15 +820,13 @@ const handleGetBox8Data = async () => { ...@@ -854,15 +820,13 @@ const handleGetBox8Data = async () => {
console.log("结果分布情况", res); console.log("结果分布情况", res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
box8Data.value = res.data.map(item => ({ name: item.RESULTNAME, value: item.RESULTNUM })) box8Data.value = res.data.map(item => ({ name: item.RESULTNAME, value: item.RESULTNUM }))
onAIReport({ type: "环形图", name: "结果分布情况", data: res.data }, "content8")
} else { } else {
box8Data.value = [] box8Data.value = []
aiContent.content8 = "";
} }
} catch (error) { } catch (error) {
box8Data.value = [] box8Data.value = []
aiContent.content8 = "";
} }
refAiReport8.value?.onDataInfo({ type: "环形图", name: "结果分布情况", data: box8Data.value })
nextTick(() => { createPieChart(box8Ref, box8Data.value) }) nextTick(() => { createPieChart(box8Ref, box8Data.value) })
}; };
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论