提交 2665249d authored 作者: 张烨's avatar 张烨

feat:市场准入限制-调查详情-图表增加ai智能报告

上级 0699980b
<template>
<div class="data-list">
<div class="data-item" v-for="(item, index) in props.list" :key="index">
<div class="item-head">
<div class="item-name">{{ `(${onNumToChinese(Number(index)+1)}). ${item.title}` }}</div>
<div class="button-box" @click="onNavigateTo()">
<div class="button-icon">
<img src="../assets/icons/open.png" alt="" />
</div>
<div class="button-text">跳转原文</div>
</div>
</div>
<Level2List :list="item.data"></Level2List>
</div>
</div>
</template>
<script setup lang="ts" name="Level2List">
import router from "@/router";
import { useRoute } from "vue-router";
import { onNumToChinese } from "@/views/marketAccessRestrictions/utils/index"
import Level2List from "@/views/marketAccessRestrictions/com/Level2List.vue";
const route = useRoute();
const props = defineProps({
list: {
type: Array as any,
default: () => ([])
},
})
const onNavigateTo = () => {
const page = router.resolve({
name: "MarketSingleReportOriginal",
query: { ...route.query }
});
window.open(page.href, "_blank");
}
</script>
<style scoped lang="scss">
.data-list {
margin-bottom: 16px;
border-top: 1px solid rgba(234, 236, 238, 1);
.data-item {
.item-head {
padding: 0 20px;
height: 48px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
background: rgba(247, 248, 249, 1);
display: flex;
align-items: center;
.item-name {
width: 20px;
flex: auto;
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: bold;
line-height: 30px;
color: var(--text-primary-80-color);
}
.button-box {
display: flex;
align-items: center;
margin-left: 50px;
cursor: pointer;
.button-icon {
width: 16px;
height: 16px;
font-size: 0;
margin-right: 4px;
img {
width: 100%;
height: 100%;
}
}
.button-text {
color: var(--color-primary-100);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 12px;
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="view-box">
<div class="item-info" v-for="(text, num) in props.list" :key="num">
<div class="item-num">{{ Number(num) + 1 }}.</div>
<div class="text-align-justify">{{ text }}</div>
</div>
</div>
</template>
<script setup lang="ts" name="Level2List">
const props = defineProps({
list: {
type: Array as any,
default: () => ([])
}
})
</script>
<style scoped lang="scss">
.view-box {
.item-info {
padding: 12px 20px 12px 50px;
color: rgba(59, 65, 75, 1);
font-family: Source Han Sans CN;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
position: relative;
.item-num {
position: absolute;
left: 26px;
top: 12px;
}
}
}
</style>
\ No newline at end of file
......@@ -2,36 +2,15 @@
<AnalysisBox :title="title" :showAllBtn="false" height="auto">
<el-empty v-if="!props.listData?.length" description="暂无数据" :image-size="200" />
<div v-else class="box-main">
<div class="data-list">
<div class="data-item" v-for="(item, index) in props.listData" :key="index">
<div class="item-head">
<div class="item-name">{{ `(${onNumToChinese(Number(index)+1)}). ${item.title}` }}</div>
<div class="button-box" @click="onNavigateTo()">
<div class="button-icon">
<img src="../assets/icons/open.png" alt="" />
</div>
<div class="button-text">跳转原文</div>
</div>
</div>
<div class="item-down">
<div class="item-info" v-for="(text, num) in item.data" :key="num">
<div class="item-num">{{ Number(num) + 1 }}.</div>
<div class="text-align-justify">{{ text }}</div>
</div>
</div>
</div>
</div>
<AiTips :tips="tips"></AiTips>
<Level1List :list="props.listData"></Level1List>
<!-- <AiTips :tips="tips"></AiTips> -->
</div>
</AnalysisBox>
</template>
<script setup lang="ts" name="SurveyConclusion">
import AiTips from "@/views/marketAccessRestrictions/com/AiTips.vue";
import { onNumToChinese } from "@/views/marketAccessRestrictions/utils/index"
import router from "@/router";
import { useRoute } from "vue-router";
const route = useRoute();
import Level1List from "@/views/marketAccessRestrictions/com/Level1List.vue";
const props = defineProps({
listData: {
......@@ -48,80 +27,10 @@ const props = defineProps({
}
})
const onNavigateTo = () => {
const page = router.resolve({
name: "MarketSingleReportOriginal",
query: { ...route.query }
});
window.open(page.href, "_blank");
}
</script>
<style scoped lang="scss">
.box-main {
padding: 0 22px 20px;
.data-list {
margin-bottom: 16px;
border-top: 1px solid rgba(234, 236, 238, 1);
.data-item {
.item-head {
padding: 0 20px;
height: 48px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
background: rgba(247, 248, 249, 1);
display: flex;
align-items: center;
.item-name {
width: 20px;
flex: auto;
font-family: Source Han Sans CN;
font-size: 18px;
font-weight: bold;
line-height: 30px;
color: var(--text-primary-80-color);
}
.button-box {
display: flex;
align-items: center;
margin-left: 50px;
cursor: pointer;
.button-icon {
width: 16px;
height: 16px;
font-size: 0;
margin-right: 4px;
img {
width: 100%;
height: 100%;
}
}
.button-text {
color: var(--color-primary-100);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 12px;
}
}
}
.item-info {
padding: 12px 20px 12px 50px;
color: rgba(59, 65, 75, 1);
font-family: Source Han Sans CN;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
position: relative;
.item-num {
position: absolute;
left: 26px;
top: 12px;
}
}
}
}
}
</style>
\ No newline at end of file
......@@ -2,19 +2,19 @@
<div class="box-text-box">
<div class="box-text-item">
<div class="box-text-left">{{ "启动时间:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.searchnum }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.progressdate }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查概括:" }}</div>
<div class="box-text-right two-line-ellipsis">{{ props.baseInfo.product }}</div>
<div class="box-text-right two-line-ellipsis">{{ props.baseInfo.investSummary }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查阶段:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.plaintiff }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investStage }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查范围:" }}</div>
<div class="box-text-right five-line-ellipsis">{{ props.baseInfo.defendant }}</div>
<div class="box-text-right five-line-ellipsis">{{ props.baseInfo.investScope }}</div>
</div>
</div>
</template>
......
......@@ -2,26 +2,25 @@
<div class="box-blue-box">
<div class="box-blue-name">
<div class="box-blue-time">{{ props.baseInfo.progressdate }}</div>
<div class="box-blue-time">{{ props.baseInfo.progressresult }}</div>
</div>
<div class="box-blue-text one-line-ellipsis">{{ props.baseInfo.progressdetails }}</div>
</div>
<div class="box-text-box">
<div class="box-text-item">
<div class="box-text-left">{{ "启动时间:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.searchnum }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investDate }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查对象:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.product }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investSubject }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "调查状态:" }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.plaintiff }}</div>
<div class="box-text-right one-line-ellipsis">{{ props.baseInfo.investStatus }}</div>
</div>
<div class="box-text-item">
<div class="box-text-left">{{ "请愿方:" }}</div>
<div class="box-text-right three-line-ellipsis">{{ props.baseInfo.product }}</div>
<div class="box-text-right three-line-ellipsis">{{ props.baseInfo.petitioner }}</div>
</div>
</div>
</template>
......
......@@ -658,9 +658,25 @@ const hadleGetStatNum = async (event) => {
box5ChartData.value = transformAllData(res.data);
}
onAIReport({ type: "折线图", name: "数量变化趋势", data: res.data }, "content5")
} else {
box5ChartData.value.title = [];
box5ChartData.value.list = [
{ name: "337调查", value: [] },
{ name: "301调查", value: [] },
{ name: "232调查", value: [] }
]
aiContent.content5 = "";
}
} catch (error) {}
nextTick(() => { createLineChart(box5Ref, box5ChartData.value, {unitY:"项"}) })
} catch (error) {
box5ChartData.value.title = [];
box5ChartData.value.list = [
{ name: "337调查", value: [] },
{ name: "301调查", value: [] },
{ name: "232调查", value: [] }
]
aiContent.content5 = "";
}
nextTick(() => { createLineChart(box5Ref, box5ChartData.value) })
};
// 领域分布情况
......@@ -777,7 +793,7 @@ const box7TipText = computed(() => {
const handleGetBox7Data = async () => {
const params = {
sortCode: box7SelectedSurvey.value,
year: box7SelectedYear.value
years: box7SelectedYear.value
};
try {
const res = await getSearchCountry(params);
......@@ -799,7 +815,9 @@ const handleGetBox7Data = async () => {
aiContent.content7 = "";
}
} catch (error) {
console.error("受调查国家分布error", error);
box7Data.title = [];
box7Data.data = [];
aiContent.content7 = "";
}
};
......@@ -833,9 +851,11 @@ const handleGetBox8Data = async () => {
onAIReport({ type: "环形图", name: "结果分布情况", data: res.data }, "content8")
} else {
box8Data.value = []
aiContent.content8 = "";
}
} catch (error) {
box8Data.value = []
aiContent.content8 = "";
}
nextTick(() => { createPieChart(box8Ref, box8Data.value, {labelType:1}) })
};
......
import { symbolCircle } from "d3";
import * as echarts from "echarts";
const getBarChart = (nameList, valueList) => {
......@@ -75,8 +74,7 @@ const getBarChart = (nameList, valueList) => {
barWidth: 20,
markPoint: {
symbol: 'circle',
symbolSize: 20,
symbolSize: 0,
data: (function () {
const data = [];
nameList.forEach((item, index) => {
......@@ -85,9 +83,7 @@ const getBarChart = (nameList, valueList) => {
xAxis: index,
yAxis: valueList[index],
symbol: `image://${item.img}`,
// symbolSize: [20, 20],
symbolSize: 20,
// symbolOffset: [0, 20],
symbolCircle: 20,
itemStyle: {
borderRadius: '50%',
......
......@@ -20,13 +20,15 @@
</div>
</div>
<div class="select-box">
<div class="paixu-btn" @click="handleSwithSort">
<div class="text">{{ "发布时间" }}</div>
<div class="icon2">
<img v-if="isSort" src="@/assets/icons/shengxu2.png" alt="" />
<img v-else src="@/assets/icons/jiangxu2.png" alt="" />
</div>
<el-select v-model="isSort" placeholder="发布时间" style="width: 166px">
<template #prefix>
<div style="display: flex; align-items: center; height: 100%">
<img src="@/assets/icons/jiangxu1.png" style="width: 14px; height: 14px" />
</div>
</template>
<el-option label="按发布时间降序" value="desc" />
<el-option label="按发布时间升序" value="asc" />
</el-select>
</div>
</div>
<div class="wrapper-main">
......@@ -95,11 +97,7 @@ const searchText = ref("");
const filterStage = ref("");
const filterParty = ref("");
const filterReason = ref("");
const isSort = ref(false); // false 降序
const handleSwithSort = () => {
isSort.value = !isSort.value;
};
const isSort = ref('desc'); // 降序
// 科技领域过滤
const surveyAreaList = ref([]);
......@@ -166,20 +164,17 @@ const handleFetchSurveyList = async () => {
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
caseStatus: filterStage.value,
keywords: searchText.value,
keywords: searchText.value || null,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
sortOrder: isSort.value
};
const res = await getSurveyList(params);
if (res.code === 200 && res.data) {
surveyInfoList.value = res.data.content;
totalDiscussNum.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取调查列表失败", error);
} finally {
} catch (error) {}
listLoading.value = false;
}
};
const handleCurrentChange = val => {
......@@ -241,30 +236,6 @@ onMounted(async () => {
}
}
}
.select-box {
.paixu-btn {
display: flex;
align-items: center;
gap: 8px;
height: 32px;
border: 1px solid #e6e7e8;
border-radius: 4px;
background: #fff;
cursor: pointer;
padding: 0 12px;
.text {
font-size: 14px;
color: #5f656c;
}
.icon2 {
width: 10px;
img {
width: 100%;
}
}
}
}
}
.wrapper-main {
......@@ -335,18 +306,26 @@ onMounted(async () => {
height: 48px;
display: flex;
align-items: center;
padding: 0 20px;
.icon {
width: 22px;
height: 18px;
margin-left: 19px;
img {
width: 100%;
height: 100%;
}
}
.title {
height: 26px;
margin-left: 12px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 20px;
font-weight: 700;
color: var(--color-main-active);
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
}
......
<template>
<div class="case-wrapper">
<div class="wrapper-header">
<div class="header-filters">
<div class="search-box">
<el-input v-model="searchText" style="width: 360px; height: 32px" placeholder="搜索调查案件" @keyup.enter="handleSearch" :suffix-icon="Search"></el-input>
</div>
<div class="select-box">
<div class="paixu-btn" @click="handleSwithSort">
<div class="icon1">
<img v-if="isSort" src="@/assets/icons/shengxu1.png" alt="" />
<img v-else src="@/assets/icons/jiangxu1.png" alt="" />
</div>
<div class="text">{{ "发布时间" }}</div>
<div class="icon2">
<img v-if="isSort" src="@/assets/icons/shengxu2.png" alt="" />
<img v-else src="@/assets/icons/jiangxu2.png" alt="" />
</div>
<div class="select-box">
<el-select v-model="isSort" placeholder="发布时间" style="width: 166px">
<template #prefix>
<div style="display: flex; align-items: center; height: 100%">
<img src="@/assets/icons/jiangxu1.png" style="width: 14px; height: 14px" />
</div>
</template>
<el-option label="按发布时间降序" value="desc" />
<el-option label="按发布时间升序" value="asc" />
</el-select>
</div>
</div>
<div class="wrapper-main">
......@@ -54,7 +54,7 @@
</div>
<SurveyHistory v-loading="listLoading" :surveyList="surveyInfoList"></SurveyHistory>
<div class="right-footer">
<div class="footer-left">{{ `共 ${totalDiscussNum}` }}</div>
<div class="footer-left">{{ `共${totalDiscussNum}项调查` }}</div>
<div class="footer-right">
<el-pagination @current-change="handleCurrentChange" :pageSize="pageSize" :current-page="currentPage" background layout="prev, pager, next" :total="totalDiscussNum" />
</div>
......@@ -70,10 +70,8 @@ import { Search } from "@element-plus/icons-vue";
import { getSearchAllArea, getSearchAllYear, getSurveyList } from "@/api/marketAccessRestrictions";
import SurveyHistory from "@/views/marketAccessRestrictions/com/SurveyHistory.vue"
const isSort = ref(true); // true 升序 false 倒序
const handleSwithSort = () => {
isSort.value = !isSort.value;
};
const searchText = ref(''); // 搜索文本
const isSort = ref('desc'); // 降序
// 科技领域过滤
const surveyAreaList = ref([]);
......@@ -139,20 +137,17 @@ const handleFetchSurveyList = async () => {
sortCode: "301",
publishYear: checkedYearList.value.join(',') || null,
Area: checkedAreaList.value.join(',') || null,
// keywords: searchText.value,
keywords: searchText.value || null,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
sortOrder: isSort.value
};
const res = await getSurveyList(params);
if (res.code === 200 && res.data) {
surveyInfoList.value = res.data.content;
totalDiscussNum.value = res.data.totalElements || 0;
}
} catch (error) {
console.error("获取调查列表失败", error);
} finally {
} catch (error) {}
listLoading.value = false;
}
};
const handleCurrentChange = (val) => {
......@@ -190,56 +185,24 @@ onMounted(async () => {
display: flex;
margin-bottom: 16px;
justify-content: space-between;
.header-filters {
display: flex;
gap: 16px;
align-items: center;
.search-box {
background-color: #fff;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
}
.select-box {
height: 32px;
box-sizing: border-box;
.paixu-btn {
.dropdown-filters {
display: flex;
width: 120px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
&:hover {
background: var(--color-bg-hover);
}
cursor: pointer;
.icon1 {
width: 11px;
height: 14px;
margin-top: 10px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 19px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
margin-top: 7px;
margin-left: 9px;
}
.icon2 {
width: 10px;
height: 5px;
margin-top: 5px;
margin-left: 13px;
img {
width: 100%;
height: 100%;
gap: 12px;
.filter-select {
width: 140px;
:deep(.el-input__wrapper) {
background-color: #fff;
}
}
}
......@@ -324,7 +287,7 @@ onMounted(async () => {
}
.title {
height: 26px;
margin-left: 19px;
margin-left: 12px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-style: Bold;
......
......@@ -26,7 +26,8 @@
<img src="@/assets/icons/jiangxu1.png" style="width: 14px; height: 14px" />
</div>
</template>
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" :value="item.value" />
<el-option label="按发布时间降序" value="desc" />
<el-option label="按发布时间升序" value="asc" />
</el-select>
</div>
</div>
......@@ -99,19 +100,7 @@ const searchText = ref("");
const filterStage = ref("");
const filterParty = ref("");
const filterReason = ref("");
const isSort = ref(false); // false 降序
const releaseTimeList = ref([
{
label: "按发布时间倒序",
value: false
},
{
label: "按发布时间升序",
value: true
}
]);
const isSort = ref('desc'); // 降序
// 科技领域过滤
const surveyAreaList = ref([]);
......@@ -203,18 +192,15 @@ const handleFetchSurveyList = async () => {
caseStatus: filterStage.value || null,
keywords: searchText.value || null,
sortField: "date",
sortOrder: isSort.value ? "asc" : "desc"
sortOrder: isSort.value
};
const res = await getSurveyList(params);
if (res.code === 200) {
surveyInfoList.value = res.data?.content || [];
totalDiscussNum.value = res.data?.totalElements || 0;
}
} catch (error) {
console.error("获取调查列表失败", error);
} finally {
} catch (error) {}
listLoading.value = false;
}
};
const handleCurrentChange = val => {
......@@ -278,33 +264,6 @@ onMounted(async () => {
}
}
}
.select-box {
.paixu-btn {
display: flex;
align-items: center;
gap: 8px;
height: 32px;
border: 1px solid #e6e7e8;
border-radius: 4px;
background: #fff;
cursor: pointer;
padding: 0 12px;
.text {
font-size: 14px;
color: #5f656c;
}
.icon2 {
width: 10px;
img {
width: 100%;
}
}
}
}
}
.wrapper-main {
......
......@@ -33,6 +33,10 @@
<div class="box-main">
<div class="box-head" ref="chart1"></div>
<TipTab text="美对华232调查案件的数量变化趋势,数据来源:美国商务部官网" style="margin-top: 16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content1" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -46,6 +50,10 @@
<div class="box-main">
<div class="box-head" ref="chart2"></div>
<TipTab text="美对华232调查案件的领域分布情况,数据来源:美国商务部官网" style="margin-top: -16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content2" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -61,6 +69,10 @@
<div class="box-main">
<div class="box-head" ref="chart3"></div>
<TipTab text="美对华232调查案件导致的关税变化分布,数据来源:美国商务部官网" style="margin-top: -16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content3" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -74,6 +86,10 @@
<div class="box-main">
<div class="box-head" ref="chart4"></div>
<TipTab text="美232调查所涉及的国家分布情况,数据来源:美国商务部官网" style="margin-top: -16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content4" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -92,8 +108,21 @@ import {
import createLineChart from "@/views/marketAccessRestrictions/utils/baseLineChart";
import createPieChart from "@/views/marketAccessRestrictions/utils/basePiechart.js";
import { getNearYearList } from "@/views/marketAccessRestrictions/utils/index.ts";
import AiButton from '@/components/base/Ai/AiButton/index.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue';
import { getNearYearList, getAIReport } from "@/views/marketAccessRestrictions/utils/index.ts";
const yearList = getNearYearList();
// 获取AI智能报告
const aiContent = reactive({
content1: "正在生成...",
content2: "正在生成...",
content3: "正在生成...",
content4: "正在生成...",
})
const onAIReport = (data, key) => {
getAIReport(data).then(res => { aiContent[key] = res })
}
// 数量统计
const totalCaseNum = ref(0)
......@@ -119,22 +148,23 @@ const box1Loading = ref(false);
const onStatNum = async (event) => {
if (event) activeName.value = event;
box1Loading.value = true;
let chart1Data = { title: [], list: [] };
let chartData = { title: [], list: [] };
try {
const res = await getStatNum({ sortCode: 232, searchStatus:activeName.value })
console.log('数量变化趋势', res);
if (res.code === 200 && res.data) {
chart1Data.title = res.data.map(item => item.searchYorM),
chart1Data.list = [{ name: "232调查", value: res.data.map(item => item.searchCount) }]
chartData.title = res.data.map(item => item.searchYorM),
chartData.list = [{ name: "232调查", value: res.data.map(item => item.searchCount) }]
} else {
chart1Data.title = [];
chart1Data.list = [];
chartData.title = [];
chartData.list = [];
}
} catch (error) {
chart1Data.title = [];
chart1Data.list = [];
chartData.title = [];
chartData.list = [];
}
nextTick(() => { createLineChart(chart1, chart1Data) });
onAIReport({ type: "折线图", name: "数量变化趋势", data: chartData }, "content1")
nextTick(() => { createLineChart(chart1, chartData) });
box1Loading.value = false;
}
......@@ -146,19 +176,20 @@ const box2Paarams = reactive({
const box2Loading = ref(false);
const handleGetStatArea = async () => {
box2Loading.value = true;
let chart2Data = []
let chartData = []
try {
const res = await getStatArea(box2Paarams);
console.log('领域分布情况', res);
if (res.code === 200 && res.data) {
chart2Data = res.data.map(item => ({ name: item.areaname, value: item.areacount }) );
chartData = res.data.map(item => ({ name: item.areaname, value: item.areacount }) );
} else {
chart2Data = [];
chartData = [];
}
} catch (error) {
chart2Data = [];
chartData = [];
}
nextTick(() => { createPieChart(chart2, chart2Data) });
onAIReport({ type: "环形图", name: "领域分布情况", data: chartData }, "content2")
nextTick(() => { createPieChart(chart2, chartData) });
box2Loading.value = false;
};
......@@ -170,24 +201,25 @@ const box3Paarams = reactive({
const box3Loading = ref(false);
const onSearchTariff = async () => {
box3Loading.value = true;
let chart3Data = []
let chartData = []
try {
const res = await getSearchTariff(box3Paarams);
console.log('关税变化分布', res);
if (res.code === 200 && res.data?.length) {
chart3Data = [
{ name: "税率25%+", value: res.data[0].TARIFF25 },
{ name: "税率11%-25%", value: res.data[0].TARIFF11 },
{ name: "税率1%-10%", value: res.data[0].TARIFF1 },
{ name: "税率0%", value: res.data[0].TARIFF0 },
if (res.code === 200 && res.data) {
chartData = [
{ name: "税率25%+", value: res.data.TARIFF25 },
{ name: "税率11%-25%", value: res.data.TARIFF11 },
{ name: "税率1%-10%", value: res.data.TARIFF1 },
{ name: "税率0%", value: res.data.TARIFF0 },
];
} else {
chart3Data = [];
chartData = [];
}
}catch (error) {
chart3Data = [];
chartData = [];
}
nextTick(() => { createPieChart(chart3, chart3Data) });
onAIReport({ type: "环形图", name: "关税变化分布", data: chartData }, "content3")
nextTick(() => { createPieChart(chart3, chartData) });
box3Loading.value = false;
}
......@@ -199,19 +231,20 @@ const box4Paarams = reactive({
const box4Loading = ref(false);
const handleGetSearchCountry = async () => {
box4Loading.value = true;
let chart4Data = []
let chartData = []
try {
const res = await getSearchCountry(box4Paarams);
console.log('国家分布情况', res);
if (res.code === 200 && res.data) {
chart4Data = res.data.map(item => ({ name: item.COUNTRY, value: item.NUM }) );
chartData = res.data.map(item => ({ name: item.COUNTRY, value: item.NUM }) );
} else {
chart4Data = []
chartData = []
}
} catch (error) {
chart4Data = []
chartData = []
}
nextTick(() => { createPieChart(chart4, chart4Data) });
onAIReport({ type: "环形图", name: "国家分布情况", data: chartData }, "content4")
nextTick(() => { createPieChart(chart4, chartData) });
box4Loading.value = false;
};
......@@ -312,10 +345,33 @@ onMounted(() => {
padding: 12px 30px 20px;
display: flex;
flex-direction: column;
position: relative;
.box-head {
height: 20px;
flex: auto;
}
.ai-pane {
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;
}
}
}
}
}
}
......
......@@ -9,6 +9,10 @@
<div class="box-main">
<div class="box-head" ref="box1Chart"></div>
<TipTab text="美对华301调查案件的数量变化趋势,数据来源:美国贸易代表办公室官网" style="margin-top: 16px" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content1" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -22,6 +26,10 @@
<div class="box-main">
<div class="box-head" id="box2Chart"></div>
<TipTab text="美301调查所涉及的国家分布情况,数据来源:美国贸易代表办公室官网" style="margin-top: 16px" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content2" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -32,6 +40,10 @@
<div class="box-main">
<div class="box-head" id="box3Chart"></div>
<TipTab text="美301调查方向及结果分布情况,数据来源:美国贸易代表办公室官网" style="margin-top: 16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content3" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -45,6 +57,10 @@
<div class="box-main">
<div class="box-head" ref="box4Chart"></div>
<TipTab text="美对华301调查案件的领域分布情况,数据来源:美国贸易代表办公室官网" style="margin-top: -16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content4" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -65,39 +81,52 @@ import {
} from "@/api/marketAccessRestrictions";
import createLineChart from "@/views/marketAccessRestrictions/utils/baseLineChart";
import createPieChart from "@/views/marketAccessRestrictions/utils/basePiechart.js";
import { getNearYearList } from "@/views/marketAccessRestrictions/utils/index.ts";
import AiButton from '@/components/base/Ai/AiButton/index.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue';
import { getNearYearList, getAIReport } from "@/views/marketAccessRestrictions/utils/index.ts";
const yearList = getNearYearList();
// 获取AI智能报告
const aiContent = reactive({
content1: "正在生成...",
content2: "正在生成...",
content3: "正在生成...",
content4: "正在生成...",
})
const onAIReport = (data, key) => {
getAIReport(data).then(res => { aiContent[key] = res })
}
const inProgressCount = ref(0);
const box1Chart = ref(null);
const box1ChartData = ref({
title: [],
list: []
});
const box1Loading = ref(false);
const handleGetStatNum = async () => {
box1Loading.value = true;
let chartData = { title: [], list: [] }
try {
const res = await getStatNum({ byYorM: "12", sortCode: "301" });
console.log('数量变化趋势', res)
if (res.code === 200 && res.data) {
const sortedData = res.data.sort((a, b) => parseInt(a.searchYorM) - parseInt(b.searchYorM));
box1ChartData.value.title = sortedData.map(item => item.searchYorM);
box1ChartData.value.list = [{ name: "301调查", value: sortedData.map(item => item.searchCount) }]
chartData.title = sortedData.map(item => item.searchYorM);
chartData.list = [{ name: "301调查", value: sortedData.map(item => item.searchCount) }]
inProgressCount.value = res.data.reduce((acc, cur) => acc + (cur.inSearchCount || 0), 0);
nextTick(() => { createLineChart(box1Chart, box1ChartData.value) })
} else {
chartData.title = []
chartData.list = []
inProgressCount.value = 0
}
} catch (error) {
console.error("获取调查年度数量趋势失败", error);
chartData.title = []
chartData.list = []
inProgressCount.value = 0
}
onAIReport({ type: "折线图", name: "数量变化趋势", data: chartData }, "content1")
nextTick(() => { createLineChart(box1Chart, chartData) })
box1Loading.value = false;
};
const box2ChartData = ref({
title: [],
data: []
});
const box2Paarams = reactive({
sortCode: 301,
years: '2025'
......@@ -105,69 +134,70 @@ const box2Paarams = reactive({
const box2Loading = ref(false);
const handleGetSearchCountry = async () => {
box2Loading.value = true;
let chartData = { title: [], data: [] }
try {
const res = await getSearchCountry(box2Paarams);
console.log('国家分布情况', res)
if (res.code === 200 && res.data) {
box2ChartData.value = {
title: res.data.map(item => ({
chartData.title = res.data.map(item => ({
img: item.COUNTRYIMAGE ? (item.COUNTRYIMAGE.startsWith("http") ? item.COUNTRYIMAGE : `http://${item.COUNTRYIMAGE}`) : "",
name: item.COUNTRY
})),
data: res.data.map(item => item.NUM)
};
const box2Chart = getBarChart(box2ChartData.value.title, box2ChartData.value.data);
setChart(box2Chart, "box2Chart");
}));
chartData.data = res.data.map(item => item.NUM)
} else {
chartData.title = []
chartData.data = []
}
} catch (error) {
console.error("获取受调查国家分布失败", error);
chartData.title = []
chartData.data = []
}
onAIReport({ type: "柱状图", name: "国家分布情况", data: chartData }, "content2")
nextTick(() => {
const box2Chart = getBarChart(chartData.title, chartData.data);
setChart(box2Chart, "box2Chart");
})
box2Loading.value = false;
};
const box3ChartData = ref({
nodes: [],
links: []
});
const box3Loading = ref(false);
const handleGetSearchDirection = async () => {
box3Loading.value = true;
let chartData = { nodes: [], links: [] }
try {
const res = await getSearchDirection({ sortCode: "301" });
console.log('调查方向及结果分布', res)
chartData.nodes = [];
chartData.links = [];
if (res.code === 200 && res.data) {
const nodes = [];
const links = [];
const nodeNames = new Set();
res.data.forEach(item => {
if (item.SEARCHDIRECTION) nodeNames.add(item.SEARCHDIRECTION);
if (item.SEARCHRESULT) nodeNames.add(item.SEARCHRESULT);
if (item.SEARCHDIRECTION && item.SEARCHRESULT) {
links.push({
chartData.links.push({
source: item.SEARCHDIRECTION,
target: item.SEARCHRESULT,
value: item.SEARCHCOUNT || 0
});
}
});
nodeNames.forEach(name => {
nodes.push({ name });
});
box3ChartData.value = { nodes, links };
const box3Chart = getSankeyChart(box3ChartData.value.nodes, box3ChartData.value.links);
setChart(box3Chart, "box3Chart");
nodeNames.forEach(name => { chartData.nodes.push({ name }) });
}
} catch (error) {
console.error("获取调查方向及结果分布失败", error);
chartData.nodes = [];
chartData.links = [];
}
onAIReport({ type: "桑基图", name: "调查方向及结果分布", data: chartData }, "content3")
nextTick(() => {
const box3Chart = getSankeyChart(chartData.nodes, chartData.links);
setChart(box3Chart, "box3Chart");
})
box3Loading.value = false;
};
const box4ChartData = ref([]);
const box4Chart = ref(null)
const box4Paarams = reactive({
sortCode: 301,
......@@ -176,18 +206,20 @@ const box4Paarams = reactive({
const box4Loading = ref(false);
const handleGetStatArea = async () => {
box4Loading.value = true;
let chartData = []
try {
const res = await getStatArea(box4Paarams);
console.log('领域分布情况', res)
if (res.code === 200 && res.data) {
box4ChartData.value = res.data.map(item => ({name: item.areaname, value: item.areacount}));
chartData = res.data.map(item => ({name: item.areaname, value: item.areacount}));
} else {
box4ChartData.value = []
chartData = []
}
} catch (error) {
box4ChartData.value = []
chartData = []
}
nextTick(() => { createPieChart(box4Chart, box4ChartData.value) })
onAIReport({ type: "环形图", name: "领域分布情况", data: chartData }, "content4")
nextTick(() => { createPieChart(box4Chart, chartData) })
box4Loading.value = false;
};
......@@ -223,10 +255,33 @@ onMounted(() => {
padding: 12px 30px 20px;
display: flex;
flex-direction: column;
position: relative;
.box-head {
height: 20px;
flex: auto;
}
.ai-pane {
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;
}
}
}
}
}
}
......
......@@ -4,10 +4,12 @@ const getBarChart = (nameList, valueList) => {
const option = {
tooltip: {},
grid: {
top: 40,
bottom: 0,
right: 26,
left: 12,
width: '100%',
height: '83%',
top: '15%',
right: '5%',
bottom: '2%',
left: '1%',
containLabel: true
},
yAxis: {
......@@ -37,9 +39,7 @@ const getBarChart = (nameList, valueList) => {
},
xAxis: {
type: 'category',
data: nameList.map(item => {
return item.name
}),
data: nameList.map(item => item.name),
axisLine: {
show: true,
lineStyle: {
......@@ -79,8 +79,7 @@ const getBarChart = (nameList, valueList) => {
const data = [];
nameList.forEach((item, index) => {
data.push({
name: 'icon',
// value: '',
name: `icon${index}`,
xAxis: index,
yAxis: valueList[index],
symbol: `image://${item.img}`,
......
......@@ -26,13 +26,17 @@
<AnalysisBox title="数量变化趋势">
<template #header-btn>
<div class="header-btn-box">
<ActionButton :type="box1Paarams.type === '01' ? 'active' : 'normal'" name="按年度" @click="handleGetStatNum('01')"></ActionButton>
<ActionButton :type="box1Paarams.type === '02' ? 'active' : 'normal'" name="按调查" @click="handleGetStatNum('02')"></ActionButton>
<ActionButton :type="box1Paarams.byYorM === '12' ? 'active' : 'normal'" name="按年度" @click="handleGetStatNum('12')"></ActionButton>
<ActionButton :type="box1Paarams.byYorM === '0' ? 'active' : 'normal'" name="按调查" @click="handleGetStatNum('0')"></ActionButton>
</div>
</template>
<div class="box-main">
<div class="box-head" ref="chart1"></div>
<TipTab text="美对华337调查案件的数量变化趋势,数据来源:美国国际贸易委员会官网" style="margin-top: 16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content1" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -46,6 +50,10 @@
<div class="box-main">
<div class="box-head" ref="chart2"></div>
<TipTab text="美对华337调查案件的领域分布情况,数据来源:美国国际贸易委员会官网" style="margin-top: -16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content2" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -77,6 +85,10 @@
<div class="map-box-right" id="chartMap"></div>
</div>
<TipTab text="美对华337调查案件的中国实体分布情况,数据来源:美国国际贸易委员会官网" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content3" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -90,6 +102,10 @@
<div class="box-main">
<div class="box-head" ref="chart4"></div>
<TipTab text="美对华337调查案件的调查结果分布情况,数据来源:美国国际贸易委员会官网" style="margin-top: -16px;" />
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="aiContent.content4" />
</div>
</div>
</AnalysisBox>
</div>
......@@ -101,14 +117,33 @@ import { ref, onMounted, nextTick, reactive } from "vue";
import setChart from "@/utils/setChart";
import TipTab from "@/components/base/TipTab/index.vue"
import { getStatCount, getStatcnOrgCount, getSearchResult, getStatArea, getStatNum } from "@/api/marketAccessRestrictions";
import {
getStatCount,
getStatcnOrgCount,
getSearchResult,
getStatArea,
getStatNum
} from "@/api/marketAccessRestrictions";
import createLineChart from "@/views/marketAccessRestrictions/utils/baseLineChart";
import createPieChart from "@/views/marketAccessRestrictions/utils/basePiechart.js";
import getBarChart from "./utils/barChart";
import getMapChart from "./utils/mapChart";
import { getNearYearList } from "@/views/marketAccessRestrictions/utils/index.ts";
import AiButton from '@/components/base/Ai/AiButton/index.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue';
import { getNearYearList, getAIReport } from "@/views/marketAccessRestrictions/utils/index.ts";
const yearList = getNearYearList();
// 获取AI智能报告
const aiContent = reactive({
content1: "正在生成...",
content2: "正在生成...",
content3: "正在生成...",
content4: "正在生成...",
})
const onAIReport = (data, key) => {
getAIReport(data).then(res => { aiContent[key] = res })
}
const provinceCoords = {
"北京": [116.46, 39.92],
......@@ -168,32 +203,32 @@ const handleGetStat = async () => {
const chart1 = ref(null);
const box1Paarams = reactive({
sortCode: 337,
type: '01',
byYorM: '12'
})
const box1Loading = ref(false);
const handleGetStatNum = async (type) => {
if (type) box1Paarams.type = type
if (type) box1Paarams.byYorM = type
box1Loading.value = true;
let chart1Data = { title: [], list: [] }
let chartData = { title: [], list: [] }
try {
const res = await getStatNum(box1Paarams);
console.log('数量变化趋势', res);
if (res.code === 200 && res.data) {
const sortedData = res.data.sort((a, b) => parseInt(a.searchYorM) - parseInt(b.searchYorM));
chart1Data.title = sortedData.map(item => item.searchYorM);
chart1Data.list = [
chartData.title = sortedData.map(item => item.searchYorM);
chartData.list = [
{ name: "调查数量", value: sortedData.map(item => item.searchCount) }
];
} else {
chart1Data.title = [];
chart1Data.list = [];
chartData.title = [];
chartData.list = [];
}
} catch (error) {
chart1Data.title = [];
chart1Data.list = [];
chartData.title = [];
chartData.list = [];
}
nextTick(() => { createLineChart(chart1, chart1Data) });
onAIReport({ type: "折线图", name: "数量变化趋势", data: chartData }, "content1")
nextTick(() => { createLineChart(chart1, chartData) });
box1Loading.value = false;
};
......@@ -205,19 +240,20 @@ const box2Paarams = reactive({
const box2Loading = ref(false);
const handleGetStatArea = async () => {
box2Loading.value = true;
let chart2Data = []
let chartData = []
try {
const res = await getStatArea(box2Paarams);
console.log('领域分布情况', res);
if (res.code === 200 && res.data) {
chart2Data = res.data.map(item => ({ name: item.areaname, value: item.areacount }));
chartData = res.data.map(item => ({ name: item.areaname, value: item.areacount }));
} else {
chart2Data = [];
chartData = [];
}
} catch (error) {
chart2Data = [];
chartData = [];
}
nextTick(() => { createPieChart(chart2, chart2Data) });
onAIReport({ type: "环形图", name: "领域分布情况", data: chartData }, "content2")
nextTick(() => { createPieChart(chart2, chartData) });
box2Loading.value = false;
};
......@@ -231,23 +267,24 @@ const box3Loading = ref(false);
const handleGetStatcnOrgCount = async () => {
box3Loading.value = true;
if (box3Paarams.type === "01") {
let chart3Data = { name: [], value: [] }
let chartData = { name: [], value: [] }
try {
const res = await getStatcnOrgCount(box3Paarams);
console.log('中国实体分布情况', res);
if (res.code === 200 && res.data) {
chart3Data.name = res.data.map(item => item.ORGNAME)
chart3Data.value = res.data.map(item => item.ORGCOUNT)
chartData.name = res.data.map(item => item.ORGNAME)
chartData.value = res.data.map(item => item.ORGCOUNT)
} else {
chart3Data.name = [];
chart3Data.value = [];
chartData.name = [];
chartData.value = [];
}
} catch (error) {
chart3Data.name = [];
chart3Data.value = [];
chartData.name = [];
chartData.value = [];
}
onAIReport({ type: "柱状图", name: "中国实体分布情况", data: chartData }, "content3")
nextTick(() => {
let chart3 = getBarChart(chart3Data.name, chart3Data.value);
let chart3 = getBarChart(chartData.name, chartData.value);
setChart(chart3, "chart3");
});
} else if (box3Paarams.type === "02") {
......@@ -268,6 +305,7 @@ const handleGetStatcnOrgCount = async () => {
} catch (error) {
mapData.value = [];
}
onAIReport({ type: "地图", name: "中国实体分布情况", data: mapData.value }, "content3")
nextTick(() => {
let chartMap = getMapChart(mapData.value);
setChart(chartMap, "chartMap");
......@@ -284,19 +322,20 @@ const box4Paarams = reactive({
const box4Loading = ref(false);
const handleGetSearchResult = async () => {
box4Loading.value = true;
let chart4Data = []
let chartData = []
try {
const res = await getSearchResult(box4Paarams);
console.log('调查结果分布', res);
if (res.code === 200 && res.data) {
chart4Data = res.data.map(item => ({ name: item.RESULTNAME, value: item.RESULTNUM }));
chartData = res.data.map(item => ({ name: item.RESULTNAME, value: item.RESULTNUM }));
} else {
chart4Data = [];
chartData = [];
}
} catch (error) {
chart4Data = [];
chartData = [];
}
nextTick(() => { createPieChart(chart4, chart4Data) });
onAIReport({ type: "环形图", name: "调查结果分布", data: chartData }, "content4")
nextTick(() => { createPieChart(chart4, chartData) });
box4Loading.value = false;
};
......@@ -397,10 +436,33 @@ onMounted(() => {
padding: 12px 30px 20px;
display: flex;
flex-direction: column;
position: relative;
.box-head {
height: 20px;
flex: auto;
}
.ai-pane {
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;
}
}
}
}
}
}
......
......@@ -2,10 +2,8 @@
<div class="wrapper">
<AnalysisBox title="行业背景" :showAllBtn="false" height="auto">
<div class="box1-main">
<div class="data-list">
<div class="data-item" v-for="(bg, index) in bgList" :key="index">{{ bg.title }}</div>
</div>
<AiTips tips="钒作为被美国列为对经济与国家安全至关重要且供应链易受中断的关键矿产,广泛应用于国防、关键基础设施等多个领域,美国钒产业以二次生产为主、产业高度集中且依赖进口原料,同时通过征收反倾销税、加征关税及签订国际合作协议等方式管控钒进口。"></AiTips>
<Level2List :list="bgList"></Level2List>
<!-- <AiTips tips="钒作为被美国列为对经济与国家安全至关重要且供应链易受中断的关键矿产,广泛应用于国防、关键基础设施等多个领域,美国钒产业以二次生产为主、产业高度集中且依赖进口原料,同时通过征收反倾销税、加征关税及签订国际合作协议等方式管控钒进口。"></AiTips> -->
</div>
</AnalysisBox>
<SurveyConclusion title="市场需求" :listData="demandList" tips="美国钒市场年均表观消费量约 8590 吨且进口依赖度超 80%,需求主要集中在钢铁产业(占 90%),钛产业和非冶金领域各占 5%,2020 年受新冠疫情冲击需求下滑;全球钒需求以钢铁产业为主(90%-93%),中国是最大消费国,航空航天领域需求稳定、钒液流电池为新兴增长点,化工领域提供稳定补充。"></SurveyConclusion>
......@@ -26,13 +24,12 @@
</div>
<div class="item-down">
<div class="content-item" v-for="(val, idx) in item.data" :key="idx">
<div class="content-item-title">{{val.title }}</div>
<div class="content-item-title">{{val.TITLE }}</div>
<div class="content-item-info">
<div class="desc">{{ val.info.desc }}</div>
<div class="info-bill" v-if="val.info.bill">
<div class="info-bill-box">
<Level2List :list="val.CONTENT"></Level2List>
<div class="info-bill-box" v-if="val.BILLNAME && val.BILLID" @click="onNavigateToBill(val)">
<div class="info-bill-left">{{ "法案" }}</div>
<div class="info-bill-center">{{ val.info.bill }}</div>
<div class="info-bill-center">{{ val.BILLNAME }}</div>
<div class="info-bill-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
......@@ -42,8 +39,7 @@
</div>
</div>
</div>
</div>
<AiTips tips="美国为降低盟友及自身在钕铁硼磁体价值链对中国的依赖、保障国家安全,一方面推动关键矿物多边及双边合作,另一方面通过支持相关税收抵免法案、分配额外资金等立法与政策举措,强化稀土及非稀土磁体相关国内供应链建设。"></AiTips>
<!-- <AiTips tips="美国为降低盟友及自身在钕铁硼磁体价值链对中国的依赖、保障国家安全,一方面推动关键矿物多边及双边合作,另一方面通过支持相关税收抵免法案、分配额外资金等立法与政策举措,强化稀土及非稀土磁体相关国内供应链建设。"></AiTips> -->
</div>
</AnalysisBox>
</div>
......@@ -56,6 +52,7 @@ import router from "@/router";
import { getReportAnalyze } from "@/api/marketAccessRestrictions/index.js";
import SurveyConclusion from "@/views/marketAccessRestrictions/com/SurveyConclusion.vue";
import AiTips from "@/views/marketAccessRestrictions/com/AiTips.vue";
import Level2List from "@/views/marketAccessRestrictions/com/Level2List.vue";
const route = useRoute();
const searchId = route.query.searchId || "232";
......@@ -77,11 +74,8 @@ const onNavigateTo = () => {
const getData = async () => {
// 行业背景
getReportAnalyze({ searchId, type: "01" }).then((res) => {
if (res.data) {
bgList.value = res.data.map((item) => ({
title: item.CONTENT
}));
}
console.log('行业背景', res)
if (res.data) bgList.value = res.data.flatMap(item => item.CONTENT);
});
// 市场需求
......@@ -90,7 +84,7 @@ const getData = async () => {
demandList.value = res.data.map(item => {
return {
title: item.TITLE,
data: item.CONTENT?.split(/\r\n|\n/).filter(line => line.trim()) || [],
data: item.CONTENT || [],
};
});
}
......@@ -102,7 +96,7 @@ const getData = async () => {
supplyList.value = res.data.map(item => {
return {
title: item.TITLE,
data: item.CONTENT?.split(/\r\n|\n/).filter(line => line.trim()) || [],
data: item.CONTENT || [],
};
});
}
......@@ -114,7 +108,7 @@ const getData = async () => {
box4List.value = res.data.map(item => {
return {
title: item.TITLE,
data: item.CONTENT?.split(/\r\n|\n/).filter(line => line.trim()) || [],
data: item.CONTENT || [],
};
});
}
......@@ -122,11 +116,21 @@ const getData = async () => {
// 调查建议
getReportAnalyze({ searchId, type: "05" }).then((res) => {
if (res.data) {
console.log('调查建议', res)
if (res.code==200 && res.data) {
suggestionList.value = groupSuggestionData(res.data);
}
});
};
// 跳转科技法案详情页
const onNavigateToBill = (item) => {
window.sessionStorage.setItem("curTabName", item.BILLNAME);
const route = router.resolve({
path: "/billLayout",
query: { billId: item.BILLID }
});
window.open(route.href, "_blank");
};
const groupSuggestionData = (data) => {
const groups = {};
......@@ -135,13 +139,7 @@ const groupSuggestionData = (data) => {
if (!groups[groupTitle]) {
groups[groupTitle] = [];
}
groups[groupTitle].push({
title: item.TITLE,
info: {
desc: item.CONTENT,
bill: item.BILLNAME
}
});
groups[groupTitle].push(item);
});
return Object.keys(groups).map((title) => ({
title,
......@@ -165,22 +163,6 @@ onMounted(() => {
.box1-main {
padding: 0 22px 20px;
.data-list {
margin-bottom: 16px;
border-top: 1px solid rgba(234, 236, 238, 1);
.data-item {
letter-spacing: 1px;
padding: 12px 20px 12px 40px;
color: rgba(59, 65, 75, 1);
font-family: Source Han Sans CN;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
border-bottom: 1px solid rgba(234, 236, 238, 1);
}
}
}
.box5-main {
......@@ -233,7 +215,7 @@ onMounted(() => {
margin-bottom: 10px;
.content-item {
.content-item-title {
padding: 12px 23px 12px 44px;
padding: 12px 23px 12px 30px;
box-sizing: border-box;
border-bottom: 1px solid rgba(234, 236, 238, 1);
color: rgba(59, 65, 75, 1);
......@@ -245,26 +227,17 @@ onMounted(() => {
text-align: justify;
}
.content-item-info {
padding: 12px 23px 12px 44px;
box-sizing: border-box;
border-bottom: 1px solid rgba(234, 236, 238, 1);
.desc {
color: rgba(59, 65, 75, 1);
font-family: Source Han Sans CN;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
padding-left: 15px;
:deep(.item-info) {
padding-left: 70px;
.item-num {
left: 46px;
}
}
.info-bill {
border-radius: 4px;
display: inline-block;
background: rgba(246, 250, 255, 1);
.info-bill-box {
display: flex;
margin-top: 4px;
cursor: pointer;
margin: 10px 44px;
display: inline-flex;
height: 32px;
border-radius: 4px;
background: rgba(246, 250, 255, 1);
......@@ -297,7 +270,6 @@ onMounted(() => {
.info-bill-right {
width: 20px;
height: 20px;
cursor: pointer;
img {
width: 100%;
height: 100%;
......@@ -309,6 +281,5 @@ onMounted(() => {
}
}
}
}
}
</style>
\ No newline at end of file
......@@ -235,8 +235,6 @@ onMounted(() => {
font-size: 16px;
font-weight: 700;
line-height: 24px;
margin-top: 3px;
margin-bottom: 3px;
}
.box1-item-right {
width: 346px;
......
......@@ -19,7 +19,7 @@
<div class="icon">
<img src="./assets/images/icon1.png" alt="" />
</div>
<div class="text">{{ (baseInfo.SEARCHORG || '-') + " >" }}</div>
<div class="text" style="cursor: pointer;" @click="onNavigateToORG()">{{ (baseInfo.SEARCHORG || '-') + " >" }}</div>
</div>
</div>
<div class="box1-item">
......@@ -46,7 +46,7 @@
<div class="box1-item-right3">
<template v-if="baseInfo.AdminstrativeData && baseInfo.AdminstrativeData.length">
<div v-for="(item, index) in baseInfo.AdminstrativeData" :key="index">
{{ item.ORDERNAME + " >" }}
<div style="cursor: pointer;" @click="onNavigateToDecree(item)">{{ item.ORDERNAME + " >" }}</div>
</div>
</template>
<template v-else>-</template>
......@@ -88,22 +88,7 @@
</div>
</div>
<div class="box3-main2" v-else>
<div class="box3-main2-item" v-for="(item, index) in box3Data2" :key="index">
<div class="box3-main2-item-header">
<div class="title">{{ item.title }}</div>
<div class="more" >
<div class="icon">
<img src="./assets/images/open-active.png" alt="" />
</div>
<div class="text" @click="onNavigateTo()">{{ "跳转原文" }}</div>
</div>
</div>
<div class="box3-main2-item-content">
<div class="item" v-for="(val, idx) in item.data" :key="idx">
{{ idx+1 + "." + val.content }}
</div>
</div>
</div>
<Level1List :list="box3Data2"></Level1List>
</div>
</div>
</AnalysisBox>
......@@ -123,6 +108,7 @@ import {
} from "@/api/marketAccessRestrictions";
import RelatedEvent from "@/views/marketAccessRestrictions/com/RelatedEvent.vue";
import SurveyAffiche from "@/views/marketAccessRestrictions/com/SurveyAffiche.vue";
import Level1List from "@/views/marketAccessRestrictions/com/Level1List.vue";
const route = useRoute();
......@@ -136,10 +122,19 @@ const handleClickBox3Btn = btn => {
box3BtnActive.value = btn;
};
const onNavigateTo = () => {
// 跳转到机构详情页
const onNavigateToORG = () => {
const page = router.resolve({
name: "MarketSingleReportOriginal",
query: { ...route.query }
path: "/institution",
query: { id: baseInfo.value.SEARCHORGID }
});
window.open(page.href, "_blank");
}
// 跳转到政令详情页
const onNavigateToDecree = (item) => {
const page = router.resolve({
path: "/decreeLayout",
query: { id: item.ORDERID }
});
window.open(page.href, "_blank");
}
......@@ -191,26 +186,23 @@ const box3Data1 = ref([]);
const handleGetSearchContext = async () => {
try {
const res = await getSearchContext({ searchId: route.query.searchId });
console.log('事件脉络', res.data)
console.log('事件脉络', res)
if(res.code === 200) box3Data1.value = res.data;
} catch (error) {
console.error("获取事件脉络失败", error);
}
} catch (error) {}
}
// 报复性措施
const box3Data2 = ref([]);
const handleGetSearchMeasures = async () => {
try {
const res = await getSearchMeasures({ searchId: route.query.searchId });
console.log('报复性措施', res)
if(res.code === 200 && res.data) {
box3Data2.value = res.data.map(item => ({
title: item.TITLE,
data: [{ content: item.CONTENT }]
data: typeof(item.CONTENT)=='array' ? item.CONTENT : [item.CONTENT]
}));
}
} catch (error) {
console.error("获取报复性措施失败", error);
}
} catch (error) {}
};
onMounted(() => {
handleGetSearchBlurb();
......@@ -254,8 +246,6 @@ onMounted(() => {
font-size: 16px;
font-weight: 700;
line-height: 24px;
margin-top: 3px;
margin-bottom: 3px;
}
.box1-item-right {
width: 346px;
......
......@@ -42,10 +42,10 @@
<AnalysisBox title="原告信息" :showAllBtn="false" height="auto">
<div class="box2-main">
<div class="data-head">
<div class="data-icon">{{ baseInfo.ORGNAME?.substring(0, 3) }}</div>
<div class="data-icon">{{ baseInfo.orgAbb }}</div>
<div class="data-right">
<div class="data-name">{{ baseInfo.ORGNAME }}</div>
<div class="data-desc">{{ "" }}</div>
<div class="data-name">{{ baseInfo.orgNameEn }}</div>
<div class="data-desc">{{ baseInfo.ORGNAME }}</div>
</div>
</div>
<div class="data-text">{{ baseInfo.ORGBLURB || '-' }}</div>
......@@ -110,7 +110,7 @@ const handleGetSearchBlurb = async () => {
if (data.defendantOrg) {
const groups = {};
data.defendantOrg.forEach(item => {
const companyName = item.COMPANYNAME || "其他相关企业";
const companyName = item.COMPANYNAM || "其他相关企业";
if (!groups[companyName]) {
groups[companyName] = {
title: companyName + (companyName !== "其他" ? "及相关企业" : ""),
......@@ -118,7 +118,7 @@ const handleGetSearchBlurb = async () => {
};
}
groups[companyName].companyList.push({
name: item.COMNAME,
name: item.COMNAM,
logo: "" // API 不提供 logo
});
});
......@@ -276,8 +276,6 @@ onMounted(() => {
font-size: 16px;
font-weight: 700;
line-height: 24px;
margin-top: 3px;
margin-bottom: 3px;
}
.box1-item-right {
width: 346px;
......
......@@ -93,7 +93,7 @@ const createLineChart = (chartDom, data, option={}) => {
{
type: 'value',
position: 'left',
name: option.unitY || "数量",
name: "项",
nameLocation: 'end',
nameGap: 12,
nameTextStyle: {
......
......@@ -14,7 +14,7 @@ const formatLabel = (node, type) => {
const name = truncateLabel(node.name, 6)
return `{name|${name}}\n{time|${ node.percent||0}%}`
}
return `{name|${node.name}} {time|${ node.percent||0}%}\n`
return `{name|${node.name}} {time| ${node.value}${ node.percent||0}%}\n`
}
const createPieChart = (chartDom, data=[], option={}) => {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论