提交 47d49701 authored 作者: 张烨's avatar 张烨

feat:市场准入限制-对接232数据统计页面接口

上级 002c3693
...@@ -39,6 +39,18 @@ export function getStatNum(params) { ...@@ -39,6 +39,18 @@ export function getStatNum(params) {
}) })
} }
// 查询关税税率
/**
* @param {byYorM}
*/
export function getSearchTariff(params) {
return request({
method: 'GET',
url: `/api/marketsearchDetails/getSearchTariff`,
params
})
}
// 制裁领域分布 // 制裁领域分布
/** /**
* @param {years} * @param {years}
......
...@@ -88,9 +88,9 @@ ...@@ -88,9 +88,9 @@
<div class="box-echart-main"> <div class="box-echart-main">
<div class="box-echart-content"> <div class="box-echart-content">
<el-empty v-if="!box5ChartData.title.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" /> <el-empty v-if="!box5ChartData.title.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" />
<div v-if="box5ChartData.title.length" style="width: 100%; height: 100%;" id="box5Chart"></div> <div v-if="box5ChartData.title.length" style="width: 100%; height: 100%;" ref="box5Ref"></div>
</div> </div>
<TipTab style="margin-top: 6px;" /> <TipTab style="margin-top: 16px;" />
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -111,7 +111,7 @@ ...@@ -111,7 +111,7 @@
<el-empty v-if="!box6Data.title.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" /> <el-empty v-if="!box6Data.title.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" />
<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 style="margin-top: 6px;" /> <TipTab />
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -139,7 +139,7 @@ ...@@ -139,7 +139,7 @@
<el-empty v-if="!box7Data.data.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" /> <el-empty v-if="!box7Data.data.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" />
<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 style="margin-top: 6px;" /> <TipTab style="margin-top: 10px;" />
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -158,9 +158,9 @@ ...@@ -158,9 +158,9 @@
<div class="box-echart-main"> <div class="box-echart-main">
<div class="box-echart-content"> <div class="box-echart-content">
<el-empty v-if="!box8Data.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" /> <el-empty v-if="!box8Data.length" description="暂无数据" style="padding: 100px 0 0;" :image-size="100" />
<div v-if="box8Data.length" style="width: 100%; height: 100%;" id="box8Chart"></div> <div v-if="box8Data.length" style="width: 100%; height: 100%;" ref="box8Ref"></div>
</div> </div>
<TipTab style="margin-top: 6px;" /> <TipTab />
</div> </div>
</OverviewNormalBox> </OverviewNormalBox>
</div> </div>
...@@ -180,7 +180,6 @@ ...@@ -180,7 +180,6 @@
</template> </template>
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</div> </div>
</div> </div>
<div class="home-main-footer-main"> <div class="home-main-footer-main">
...@@ -279,8 +278,8 @@ import CarouselItem232 from '@/views/marketAccessRestrictions/marketAccessHome/c ...@@ -279,8 +278,8 @@ import CarouselItem232 from '@/views/marketAccessRestrictions/marketAccessHome/c
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import router from "@/router"; import router from "@/router";
import getMultiLineChart from "./utils/multiLineChart"; import createLineChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/baseLineChart";
import getPieChart from "./utils/piechart"; import createPieChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/basePiechart.js";
import getRadarChart from "./utils/radarChart"; import getRadarChart from "./utils/radarChart";
import getBarChart from "./utils/barChart1"; import getBarChart from "./utils/barChart1";
...@@ -540,7 +539,7 @@ function transformAllData(originalData) { ...@@ -540,7 +539,7 @@ function transformAllData(originalData) {
// 4. 构建最终结果 // 4. 构建最终结果
return { return {
title: allYears, title: allYears,
data: categoryData list: categoryData
}; };
} }
...@@ -596,18 +595,19 @@ function transformAllData1(originalData) { ...@@ -596,18 +595,19 @@ function transformAllData1(originalData) {
// 4. 构建最终结果 // 4. 构建最终结果
return { return {
title: allDates, title: allDates,
data: categoryData list: categoryData
}; };
} }
const box5ChartData = ref({ const box5ChartData = ref({
title: [], title: [],
data: [ list: [
{ name: "337调查", value: [] }, { name: "337调查", value: [] },
{ name: "301调查", value: [] }, { name: "301调查", value: [] },
{ name: "232调查", value: [] } { name: "232调查", value: [] }
] ]
}); });
const box5Ref = ref(null)
const box5Active = ref(1); const box5Active = ref(1);
const hadleGetStatNum = async (event) => { const hadleGetStatNum = async (event) => {
if (event) box5Active.value = event; if (event) box5Active.value = event;
...@@ -623,8 +623,7 @@ const hadleGetStatNum = async (event) => { ...@@ -623,8 +623,7 @@ const hadleGetStatNum = async (event) => {
} }
} }
} catch (error) {} } catch (error) {}
let box5Chart = getMultiLineChart(box5ChartData.value); nextTick(() => { createLineChart(box5Ref, box5ChartData.value) })
nextTick(() => { setChart(box5Chart, "box5Chart") })
}; };
// 制裁领域分布 // 制裁领域分布
...@@ -767,6 +766,7 @@ const box8SurveyList = ref([ ...@@ -767,6 +766,7 @@ const box8SurveyList = ref([
// 调查结果分布 // 调查结果分布
const box8SelectedSurvey = ref("337"); const box8SelectedSurvey = ref("337");
const box8Data = ref([]); const box8Data = ref([]);
const box8Ref = ref(null);
const handleGetBox8Data = async () => { const handleGetBox8Data = async () => {
try { try {
const res = await getSearchResult({sortCode: box8SelectedSurvey.value}); const res = await getSearchResult({sortCode: box8SelectedSurvey.value});
...@@ -779,8 +779,7 @@ const handleGetBox8Data = async () => { ...@@ -779,8 +779,7 @@ const handleGetBox8Data = async () => {
} catch (error) { } catch (error) {
box8Data.value = [] box8Data.value = []
} }
const box8Chart = getPieChart(box8Data.value); nextTick(() => { createPieChart(box8Ref, box8Data.value, {labelType:1}) })
nextTick(() => { setChart(box8Chart, "box8Chart") })
}; };
// 资源库 // 资源库
...@@ -967,7 +966,7 @@ onMounted(async () => { ...@@ -967,7 +966,7 @@ onMounted(async () => {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 8px 22px 20px; padding: 12px 30px 20px;
.box-echart-content { .box-echart-content {
width: 100%; width: 100%;
height: 20px; height: 20px;
......
import * as echarts from 'echarts' import * as echarts from 'echarts'
import { MUTICHARTCOLORS } from '@/common/constant'
const getMultiLineChart = (data) => { // 十六进制颜色转 rgba 的工具函数
function hexToRgba(hex, alpha) {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
const getSerie = (data, index) => {
return { return {
name: data.name,
type: 'line',
smooth: true,
symbol: 'emptyCircle',
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: hexToRgba(MUTICHARTCOLORS[index], 0.7)
}, {
offset: 1,
color: hexToRgba(MUTICHARTCOLORS[index], 0)
}])
},
emphasis: { focus: 'series' },
data: data.value
}
}
const createLineChart = (chartDom, data, option={}) => {
if (!chartDom.value) return;
// 先销毁之前的实例
const existingChart = echarts.getInstanceByDom(chartDom.value);
if (existingChart) existingChart.dispose();
// 获取容器宽度/高度
const containerWidth = chartDom.value.clientWidth;
const containerHeight = chartDom.value.clientHeight;
const myChart = echarts.init(chartDom.value);
myChart.setOption({
color: MUTICHARTCOLORS,
tooltip: { tooltip: {
trigger: 'item', trigger: 'item',
axisPointer: { axisPointer: {
type: 'cross', type: 'cross',
label: { label: { backgroundColor: '#6a7985' }
backgroundColor: '#6a7985'
}
} }
}, },
grid: { grid: {
width: '95%', top: 40,
height: '83%', bottom: 0,
top: '15%', right: 26,
left: '1%', left: 12,
containLabel: true containLabel: true
}, },
legend: { legend: {
show: true, show: data?.list?.length>1,
top: 10, top: 10,
icon: 'circle', icon: 'circle',
textStyle: { textStyle: {
...@@ -28,7 +68,6 @@ const getMultiLineChart = (data) => { ...@@ -28,7 +68,6 @@ const getMultiLineChart = (data) => {
fontSize: '14px', fontSize: '14px',
} }
}, },
color: ['#0A57A6', '#FA8C16', '#722ED1'],
xAxis: [ xAxis: [
{ {
type: 'category', type: 'category',
...@@ -78,69 +117,9 @@ const getMultiLineChart = (data) => { ...@@ -78,69 +117,9 @@ const getMultiLineChart = (data) => {
}, },
} }
], ],
series: [ series: data.list.map(getSerie)
{ })
name: data.data[0]?.name, return myChart
type: 'line',
smooth: true,
symbol: 'emptyCircle',
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(10, 87, 166, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(10, 87, 166, 0)' // 结束颜色
}])
},
emphasis: {
focus: 'series'
},
data: data.data[0]?.value
},
{
name: data.data[1]?.name,
type: 'line',
smooth: true,
symbol: 'emptyCircle',
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(255, 172, 77, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(255, 172, 77, 0)' // 结束颜色
}])
},
emphasis: {
focus: 'series'
},
data: data.data[1]?.value,
},
{
name: data.data[2]?.name,
type: 'line',
smooth: true,
symbol: 'emptyCircle',
symbolSize: 6,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(114, 46, 209, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(114, 46, 209, 0)' // 结束颜色
}])
},
emphasis: {
focus: 'series'
},
data: data.data[2]?.value,
}
]
}
} }
export default getMultiLineChart export default createLineChart
\ No newline at end of file \ No newline at end of file
const getPieChart = (data) => { import * as echarts from 'echarts'
const colorList = ['#69B1FF','#FF7875','#B37FEB','#FFC069','#1677FF','#87E8DE','#ADC6FF','#FFBB96','#BAE0FF','#FFD591',] import { MUTICHARTCOLORS } from '@/common/constant'
let option = {
color: colorList, const truncateLabel = (value, maxLen = 6) => {
if (value === null || value === undefined) return ''
const str = String(value)
const chars = Array.from(str)
if (chars.length <= maxLen) return str
return `${chars.slice(0, maxLen).join('')}...`
}
const formatLabel = (node, type) => {
if (type==1) {
const name = truncateLabel(node.name, 6)
return `{name|${name}}\n{time|${ node.percent||0}%}`
}
return `{name|${node.name}} {time|${ node.percent||0}%}\n`
}
const createPieChart = (chartDom, data=[], option={}) => {
if (!chartDom.value) return;
// 先销毁之前的实例
const existingChart = echarts.getInstanceByDom(chartDom.value);
if (existingChart) existingChart.dispose();
// 获取容器宽度
const containerWidth = chartDom.value.clientWidth;
const myChart = echarts.init(chartDom.value);
myChart.setOption({
color: MUTICHARTCOLORS,
tooltip: {
formatter: node => `${node.name}: ${node.value}项 (${node.percent || 0}%)`,
},
series: [ series: [
{ {
type: 'pie', type: 'pie',
radius: [75, 100], radius: [70, 100],
height: '100%', height: '100%',
left: 'center',
width: '100%', width: '100%',
left: 'center',
itemStyle: { itemStyle: {
borderColor: '#fff', borderColor: '#fff',
borderWidth: 1 borderWidth: 1
}, },
label: { label: {
alignTo: 'edge', alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}', formatter: (node) => formatLabel(node, option.labelType),
minMargin: 5, minMargin: 5,
edgeDistance: 10, edgeDistance: 10,
lineHeight: 25, lineHeight: 22,
rich: { rich: {
name: { name: {
color: 'rgba(59, 65, 75, 1)', color: 'rgba(59, 65, 75, 1)',
fontFamily: 'Microsoft YaHei', fontFamily: 'Microsoft YaHei',
fontSize: 16, fontSize: 16,
fontWeight: 'bold', fontWeight: 'bold',
padding: [10, 0, 10, 0]
}, },
time: { time: {
fontSize: 16, color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei', fontFamily: 'Microsoft YaHei',
color: '#rgba(95, 101, 108, 1)' fontSize: 16,
padding: [10, 0, 10, 0]
} }
} }
}, },
labelLine: { labelLine: {
length: 15, length: 15,
length2: 0, length2: 0,
maxSurfaceAngle: 80 maxSurfaceAngle: 88
}, },
labelLayout: function (params) { labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2; const isLeft = params.labelRect.x < containerWidth / 2;
const points = params.labelLinePoints; const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft // 调整引导线终点
? params.labelRect.x if (isLeft) {
: params.labelRect.x + params.labelRect.width; points[2][0] = params.labelRect.x; // 左对齐
return { } else {
labelLinePoints: points points[2][0] = params.labelRect.x + params.labelRect.width; // 右对齐
}; }
return { labelLinePoints: points };
}, },
data: data data: data
}] }
} ]
return option });
return myChart
} }
export default getPieChart; export default createPieChart;
\ No newline at end of file \ No newline at end of file
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="top"> <div class="content-top">
<div class="item"> <div class="item">
<div class="item-left-box"> <div class="item-left-box">
<div class="item-left1">{{ "总调查案件数" }}</div> <div class="item-left1">{{ "总调查案件数" }}</div>
<div class="item-left2">{{ "1980-2025" }}</div> <div class="item-left2">{{ "1980-2025" }}</div>
</div> </div>
<div class="item-right">{{ "452项" }}</div> <div class="item-right">{{ `${totalCaseNum}项` }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-left">{{ "仍在调查中的案件" }}</div> <div class="item-left">{{ "仍在调查中的案件" }}</div>
<div class="item-right">{{ "28项" }}</div> <div class="item-right">{{ `${onCaseNum}项` }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-left">{{ "涉及中企数量" }}</div> <div class="item-left">{{ "已征收关税的案件" }}</div>
<div class="item-right">{{ "326家" }}</div> <div class="item-right">{{ `${isTariffNum}项` }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-left">{{ "胜诉/和解率" }}</div> <div class="item-left">{{ "撤销案件梳理" }}</div>
<div class="item-right">{{ "38%" }}</div> <div class="item-right">{{ `${cancelNum}` }}</div>
</div> </div>
</div> </div>
<div class="center"> <div class="content-list">
<div class="box1"> <div class="content-item">
<div class="box-header"> <AnalysisBox title="232调查数量年度变化趋势">
<div class="header-left"></div> <template #header-btn>
<div class="title">232调查数量年度变化趋势</div> <div class="header-btn-box">
<div class="header-btn-box"> <ActionButton :type="activeName === '1' ? 'active' : 'normal'" name="发起调查" @click="onStatNum('1')"></ActionButton>
<!-- <div <ActionButton :type="activeName === '0' ? 'active' : 'normal'" name="结束调查" @click="onStatNum('0')"></ActionButton>
class="btn"
:class="{ btnActive: btnActiveName === '发起调查' }"
@click="handleClickBox1Btn('发起调查')"
>
{{ "发起调查" }}
</div> </div>
<div </template>
class="btn" <div class="box-main">
:class="{ btnActive: btnActiveName === '结束调查' }" <div class="box-head" ref="chart1"></div>
@click="handleClickBox1Btn('结束调查')" <TipTab style="margin-top: 16px;" />
>
{{ "结束调查" }}
</div> -->
<ActionButton :type="btnActiveName === '发起调查' ? 'active' : 'normal'" name="发起调查" @click="handleClickBox1Btn('发起调查')"></ActionButton>
<ActionButton :type="btnActiveName === '结束调查' ? 'active' : 'normal'" name="结束调查" @click="handleClickBox1Btn('结束调查')"></ActionButton>
</div> </div>
<div class="header-right"> </AnalysisBox>
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box1-main" id="chart1"></div>
</div> </div>
<div class="box2"> <div class="content-item">
<div class="box-header"> <AnalysisBox title="调查案件领域分布">
<div class="header-left"></div> <div class="box-main">
<div class="title">调查案件领域分布</div> <div class="box-head" ref="chart2"></div>
<div class="header-right"> <TipTab style="margin-top: -16px;" />
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div> </div>
</div> </AnalysisBox>
<div class="box2-main" id="chart2"></div>
</div> </div>
</div> </div>
<div class="footer"> <div class="content-list">
<div class="box3"> <div class="content-item">
<div class="box-header"> <AnalysisBox title="关税税率">
<div class="header-left"></div> <div class="box-main">
<div class="title">关税税率</div> <div class="box-head" ref="chart3"></div>
<div class="header-right"> <TipTab style="margin-top: -16px;" />
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div> </div>
</div> </AnalysisBox>
<div class="box3-main" id="chart3"></div>
</div> </div>
<div class="box4"> <div class="content-item">
<div class="box-header"> <AnalysisBox title="被调查国家分布">
<div class="header-left"></div> <div class="box-main">
<div class="title">被调查国家分布</div> <div class="box-head" ref="chart4"></div>
<div class="header-right"> <TipTab style="margin-top: -16px;" />
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div> </div>
</div> </AnalysisBox>
<div class="box4-main" id="chart4"></div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, onMounted, nextTick } from "vue"; import { ref, onMounted, nextTick } from "vue";
import * as echarts from "echarts"; import {
getStatCount,
import ChinaJson from "../../assets/json/China.json"; getStatArea,
getSearchCountry,
getStatNum,
getSearchTariff,
} from "@/api/marketAccessRestrictions";
import getMultiLineChart from "./utils/multiLineChart"; import createLineChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/baseLineChart";
import getBarChart from "./utils/barChart"; import createPieChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/basePiechart.js";
import getPieChart from "./utils/piechart";
import getMapChart from "./utils/mapChart";
// 绘制echarts图表 // 数量统计
const setChart = (option, chartId) => { const totalCaseNum = ref(0)
let chartDom = document.getElementById(chartId); const onCaseNum = ref(0)
chartDom.removeAttribute("_echarts_instance_"); const isTariffNum = ref(0)
let chart = echarts.init(chartDom); const cancelNum = ref('0%')
chart.setOption(option); const handleGetStat = async () => {
return chart; try {
}; const res = await getStatCount({sortCode: '232'})
console.log('232数量统计', res);
const btnActiveName = ref("发起调查"); if (res.code === 200 && res.data) {
const handleClickBox1Btn = name => { totalCaseNum.value = res.data.allCaseNum
btnActiveName.value = name; onCaseNum.value = res.data.underCaseNum
}; isTariffNum.value = res.data.isTariffNum
cancelNum.value = res.data.cancelNum
const chart1Data = ref({
title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
data: [
{
name: "提出法案",
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172]
} }
] } catch (error) {}
}); }
const chart2Data = ref([ const activeName = ref('1');
{ name: "半导体", value: 50 }, const chart1 = ref(null);
{ name: "电子设备", value: 46 }, const onStatNum = async (event) => {
{ name: "显示技术", value: 40 }, if (event) activeName.value = event;
{ name: "新能源", value: 32 }, try {
{ name: "通信设备", value: 31 }, const res = await getStatNum({ sortCode: 232, searchStatus:activeName.value })
{ name: "汽车", value: 31 }, console.log('232调查数量年度变化趋势', res);
{ name: "轻工业制造", value: 30 }, if (res.code === 200 && res.data) {
{ name: "其他", value: 24 } const chart1Data = {
]); title: res.data.map(item => item.searchYorM),
const chart2ColorList = ref(["#69B1FF", "#FFC069", "#87E8DE", "#597EF7", "#D6E4FF", "#FF7875", "#B37FEB", "#FFA39E"]); list: [
{
name: "232调查", value: res.data.map(item => item.searchCount)
}
]
};
nextTick(() => { createLineChart(chart1, chart1Data) });
}
} catch (error) {
const chart3Data = ref([ }
{ name: "税率25%+", value: 50 }, }
{ name: "税率11%-25%", value: 46 },
{ name: "税率1%-10%", value: 22 },
{ name: "税率0%", value: 10 },
]
); const chart2 = ref(null);
const chart3ColorList = ref(["#69B1FF", "#FFC069", "#87E8DE", "#FFA39E"]); const handleGetStatArea = async () => {
try {
const res = await getStatArea({ sortCode: "232" });
console.log('调查案件领域分布', res);
if (res.code === 200 && res.data) {
let chart2Data = res.data.map(item => ({ name: item.areaname, value: item.areacount }) );
nextTick(() => { createPieChart(chart2, chart2Data) });
}
} catch (error) {
console.error("获取调查案件领域分布失败", error);
}
};
const chart4Data = ref([ const chart3 = ref(null);
{ name: "加拿大", value: 50 }, const onSearchTariff = async () => {
{ name: "欧盟", value: 46 }, try {
{ name: "韩国", value: 40 }, const res = await getSearchTariff({ sortCode: "232" });
{ name: "日本", value: 31 }, console.log('关税税率', res);
{ name: "中国", value: 24 }, if (res.code === 200 && res.data?.length) {
const 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 },
];
nextTick(() => { createPieChart(chart3, chart3Data) });
}
}catch (error) {}
}
]); const chart4 = ref(null);
const chart4ColorList = ref(["#69B1FF", "#FFC069", "#87E8DE", "#D6E4FF", "#FFA39E"]); const handleGetSearchCountry = async () => {
try {
const res = await getSearchCountry({ sortCode: 232 });
if (res.code === 200 && res.data) {
let chart4Data = res.data.map(item => ({ name: item.COUNTRY, value: item.NUM }) );
nextTick(() => { createPieChart(chart4, chart4Data) });
}
} catch (error) {
console.error("获取受调查国家分布失败", error);
}
};
onMounted(() => { onMounted(() => {
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value); handleGetStat()
setChart(chart1, "chart1"); onStatNum()
handleGetStatArea()
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value); onSearchTariff()
setChart(chart2, "chart2");
handleGetSearchCountry()
let chart3 = getPieChart(chart3Data.value, chart3ColorList.value);
setChart(chart3, "chart3");
let chart4 = getPieChart(chart4Data.value, chart4ColorList.value);
setChart(chart4, "chart4");
}); });
</script> </script>
...@@ -207,19 +181,23 @@ onMounted(() => { ...@@ -207,19 +181,23 @@ onMounted(() => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
.top { .content-top {
display: flex; display: flex;
justify-content: space-between; gap: 16px;
.item { .item {
width: 388px; width: 20px;
flex: auto;
height: 80px; height: 80px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2); box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
position: relative; position: relative;
display: flex; display: flex;
align-items: center;
justify-content: space-between; justify-content: space-between;
&::before { &::before {
position: absolute; position: absolute;
content: ""; content: "";
...@@ -229,9 +207,9 @@ onMounted(() => { ...@@ -229,9 +207,9 @@ onMounted(() => {
left: 0; left: 0;
top: 15px; top: 15px;
} }
.item-left { .item-left {
margin-left: 30px; margin-left: 30px;
margin-top: 25px;
height: 24px; height: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -239,8 +217,8 @@ onMounted(() => { ...@@ -239,8 +217,8 @@ onMounted(() => {
font-weight: 700; font-weight: 700;
line-height: 24px; line-height: 24px;
} }
.item-right { .item-right {
margin-top: 28px;
margin-right: 35px; margin-right: 35px;
height: 24px; height: 24px;
color: var(--color-main-active); color: var(--color-main-active);
...@@ -249,188 +227,71 @@ onMounted(() => { ...@@ -249,188 +227,71 @@ onMounted(() => {
font-weight: 700; font-weight: 700;
line-height: 24px; line-height: 24px;
} }
.item-left-box { .item-left-box {
margin-left: 30px; margin-left: 30px;
font-size: 16px;
line-height: 24px;
.item-left1 { .item-left1 {
margin-top: 13px;
height: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700; font-weight: 700;
line-height: 24px;
} }
.item-left2 { .item-left2 {
height: 2px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
} }
} }
} }
} }
.box-header {
height: 56px; .content-list {
height: 410px;
display: flex; display: flex;
position: relative; gap: 16px;
.header-left {
margin-top: 18px;
width: 8px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 14px;
height: 26px;
line-height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
} .content-item {
.header-btn-box { width: 20px;
position: absolute; flex: auto;
top: 14px; height: 100%;
right: 120px; .box-main {
display: flex; width: 100%;
gap: 8px; height: 100%;
.btn { padding: 12px 30px 20px;
margin-left: 8px; display: flex;
height: 28px; flex-direction: column;
padding: 0 8px; .box-head {
box-sizing: border-box; height: 20px;
border: 1px solid rgba(230, 231, 232, 1); flex: auto;
border-radius: 4px;
background: rgba(255, 255, 255, 1);
text-align: center;
line-height: 28px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
cursor: pointer;
}
.btnActive {
border: 1px solid var(--color-main-active);
background: rgba(246, 250, 255, 1);
color: var(--color-main-active);
}
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
} }
} }
} }
} }
.center {
display: flex; .header-btn-box {
justify-content: space-between;
.box1 {
width: 792px;
height: 360px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box1-main {
height: 300px;
}
}
.box2 {
width: 792px;
height: 360px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box2-main {
height: 300px;
// width: 752px;
box-sizing: border-box;
padding: 0 20px;
}
}
}
.footer {
display: flex; display: flex;
justify-content: space-between; gap: 8px;
.box3 { margin-right: 12px;
width: 792px; .btn {
height: 360px; height: 28px;
padding: 0 8px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px; border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box3-main { text-align: center;
height: 300px; line-height: 28px;
} color: rgba(59, 65, 75, 1);
.box3-main1 { font-family: Microsoft YaHei;
height: 300px; font-size: 16px;
display: flex; font-weight: 400;
.box3-main1-left { cursor: pointer;
width: 380px;
height: 300px;
overflow-y: auto;
overflow-x: hidden;
.box3-main1-left-item {
display: flex;
height: 36px;
margin-left: 20px;
.box3-main1-left-item-left {
width: 24px;
height: 24px;
border-radius: 12px;
margin-left: 12px;
margin-top: 6px;
background: #e7f3ff;
color: #0a57a6;
text-align: center;
line-height: 24px;
}
.box3-main1-left-item-center {
height: 36px;
line-height: 36px;
width: 220px;
margin-left: 12px;
}
.box3-main1-left-item-right {
width: 80px;
box-sizing: border-box;
padding-right: 10px;
text-align: right;
}
}
}
.box3-main1-right {
width: 390px;
height: 300px;
}
}
} }
.box4 { .btnActive {
width: 792px; border: 1px solid var(--color-main-active);
height: 360px; background: rgba(246, 250, 255, 1);
border-radius: 4px; color: var(--color-main-active);
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box4-main {
height: 300px;
box-sizing: border-box;
padding: 0 20px;
}
} }
} }
} }
......
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="top"> <div class="content-list">
<div class="box1 box" v-loading="box1Loading"> <div class="content-item" v-loading="box1Loading">
<div class="box-header"> <AnalysisBox title="对华301调查年度数量趋势">
<div class="header-left"></div> <template #header-btn>
<div class="title">对华301调查年度数量趋势</div> <div class="warning-text">{{ `${inProgressCount}项调查仍在进行中` }}</div>
<div class="warning-text"> </template>
{{ `${inProgressCount}项调查仍在进行中` }} <div class="box-main">
</div> <div class="box-head" ref="box1Chart"></div>
<div class="header-right"> <TipTab style="margin-top: 16px" />
<div class="icon"> </div>
<img src="@/assets/icons/box-header-icon1.png" alt="" /> </AnalysisBox>
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box1-main" id="box1Chart"></div>
<div class="box-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{ "近年来美对华301调查呈现案件频发、聚焦专利壁垒、力图阻断产业链升级的特点。" }}
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div> </div>
<div class="box2 box" v-loading="box2Loading"> <div class="content-item" v-loading="box2Loading">
<div class="box-header"> <AnalysisBox title="301调查国家分布">
<div class="header-left"></div> <div class="box-main">
<div class="title">301调查国家分布</div> <div class="box-head" id="box2Chart"></div>
<div class="header-right"> <TipTab style="margin-top: 16px" />
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box2-main" id="box2Chart"></div>
<div class="box-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div> </div>
<div class="box-footer-center"> </AnalysisBox>
{{ "现有调查以先进制造、半导体产业为主。" }}
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div> </div>
</div> </div>
<div class="bottom"> <div class="content-list">
<div class="box3 box" v-loading="box3Loading"> <div class="content-item" v-loading="box3Loading">
<div class="box-header"> <AnalysisBox title="301调查方向及结果分布">
<div class="header-left"></div> <div class="box-main">
<div class="title">301调查 direction 及结果分布</div> <div class="box-head" id="box3Chart"></div>
<div class="header-right"> <TipTab style="margin-top: 16px;" />
<div class="icon"> </div>
<img src="@/assets/icons/box-header-icon1.png" alt="" /> </AnalysisBox>
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box3-main" id="box3Chart"></div>
<div class="box-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{ "近年来美对华301调查呈现案件频发、聚焦专利壁垒、力图阻断产业链升级的特点。" }}
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div> </div>
<div class="box4 box" v-loading="box4Loading"> <div class="content-item" v-loading="box4Loading">
<div class="box-header"> <AnalysisBox title="301调查领域分布">
<div class="header-left"></div> <template #header-btn>
<div class="title">301调查领域分布</div> <el-select v-model="selectYear" @change="handleGetStatArea()" placeholder="选择时间" style="width:120px; margin-right:12px;">
<div class="header-select-box">
<el-select v-model="selectYear" @change="handleSelectYear" placeholder="选择时间" style="width: 120px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</template>
<div class="box-main">
<div class="box-head" ref="box4Chart"></div>
<TipTab style="margin-top: -16px;" />
</div> </div>
<div class="header-right"> </AnalysisBox>
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box4-main" id="box4Chart"></div>
<div class="box-footer">
<div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{ "主要集中在存储、芯片设计及通信领域,如长江存储、长鑫存储、华为、中兴等" }}
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, onMounted, nextTick } from "vue";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import getLineChart from "./utils/lineChart";
import getBarChart from "./utils/barChart"; import getBarChart from "./utils/barChart";
import getSankeyChart from "./utils/sankey"; import getSankeyChart from "./utils/sankey";
import getPieChart from "./utils/piechart"; import {
import getbarChart from "@/views/bill/utils/barchart"; getSearchCountry,
import { getSearchCountry, getStatArea, getStatNum, getSearchDirection } from "@/api/marketAccessRestrictions"; getStatArea,
getStatNum,
const selectYear = ref("2025"); getSearchDirection
} from "@/api/marketAccessRestrictions";
const yearList = ref([ import createLineChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/baseLineChart";
{ import createPieChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/basePiechart.js";
label: "2025",
value: "2025"
},
{
label: "2024",
value: "2024"
},
{
label: "2023",
value: "2023"
}
]);
const inProgressCount = ref(0); const inProgressCount = ref(0);
const box1Loading = ref(false); const box1Loading = ref(false);
...@@ -166,9 +69,9 @@ const box4Loading = ref(false); ...@@ -166,9 +69,9 @@ const box4Loading = ref(false);
const box1ChartData = ref({ const box1ChartData = ref({
title: [], title: [],
data: [] list: []
}); });
const box1Chart = ref(null);
const handleGetStatNum = async () => { const handleGetStatNum = async () => {
box1Loading.value = true; box1Loading.value = true;
try { try {
...@@ -179,11 +82,10 @@ const handleGetStatNum = async () => { ...@@ -179,11 +82,10 @@ const handleGetStatNum = async () => {
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const sortedData = res.data.sort((a, b) => parseInt(a.searchYorM) - parseInt(b.searchYorM)); const sortedData = res.data.sort((a, b) => parseInt(a.searchYorM) - parseInt(b.searchYorM));
box1ChartData.value.title = sortedData.map(item => item.searchYorM); box1ChartData.value.title = sortedData.map(item => item.searchYorM);
box1ChartData.value.data = sortedData.map(item => item.searchCount); box1ChartData.value.list = [{ name: "301调查", value: sortedData.map(item => item.searchCount) }]
console.log(box1ChartData.value);
inProgressCount.value = res.data.reduce((acc, cur) => acc + (cur.inSearchCount || 0), 0); inProgressCount.value = res.data.reduce((acc, cur) => acc + (cur.inSearchCount || 0), 0);
nextTick(() => { createLineChart(box1Chart, box1ChartData.value) })
const box1Chart = getLineChart(box1ChartData.value.title, box1ChartData.value.data);
setChart(box1Chart, "box1Chart");
} }
} catch (error) { } catch (error) {
console.error("获取调查年度数量趋势失败", error); console.error("获取调查年度数量趋势失败", error);
...@@ -192,22 +94,14 @@ const handleGetStatNum = async () => { ...@@ -192,22 +94,14 @@ const handleGetStatNum = async () => {
} }
}; };
const box2ChartData = ref({
title: [],
data: []
});
const box3ChartData = ref({ const box3ChartData = ref({
nodes: [], nodes: [],
links: [] links: []
}); });
const handleGetSearchDirection = async () => { const handleGetSearchDirection = async () => {
box3Loading.value = true; box3Loading.value = true;
try { try {
const res = await getSearchDirection({ const res = await getSearchDirection({ sortCode: "301" });
sortCode: "301"
});
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const nodes = []; const nodes = [];
const links = []; const links = [];
...@@ -241,51 +135,44 @@ const handleGetSearchDirection = async () => { ...@@ -241,51 +135,44 @@ const handleGetSearchDirection = async () => {
} }
}; };
const box4ChartData = ref([]); // 获取最近年份列表
const currentYear = new Date().getFullYear();
// 切换年份 const getYearList = (count = 6) => {
const handleSelectYear = val => { const yearOptions = [];
selectYear.value = val; for (let i = 0; i < count; i++) {
handleGetStatArea(); const year = currentYear - i;
yearOptions.push({ label: `${year.toString()}年`, value: year.toString() });
}
return yearOptions;
}; };
const yearList = getYearList();
const selectYear = ref('2025');
const box4ChartData = ref([]);
const box4Chart = ref(null)
const handleGetStatArea = async () => { const handleGetStatArea = async () => {
box4Loading.value = true; box4Loading.value = true;
const yearMap = {
2023: 2023,
2024: 2024,
2025: 2025
};
const params = {
years: yearMap[selectYear.value] || 2025,
sortCode: 301
};
try { try {
const res = await getStatArea(params); const res = await getStatArea({years: selectYear.value, sortCode: 301});
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
box4ChartData.value = res.data box4ChartData.value = res.data.map(item => ({name: item.areaname, value: item.areacount}));
.filter(item => item.SORTNAME === "301调查") } else {
.map(item => ({ box4ChartData.value = []
name: item.AREANAME,
value: item.AREACOUNT
}));
const box4Chart = getPieChart(box4ChartData.value);
setChart(box4Chart, "box4Chart");
} }
} catch (error) { } catch (error) {
console.error("获取制裁领域分布失败", error); box4ChartData.value = []
} finally {
box4Loading.value = false;
} }
nextTick(() => { createPieChart(box4Chart, box4ChartData.value) })
box4Loading.value = false;
}; };
const box2ChartData = ref({
title: [],
data: []
});
const handleGetSearchCountry = async () => { const handleGetSearchCountry = async () => {
box2Loading.value = true; box2Loading.value = true;
try { try {
const res = await getSearchCountry({ const res = await getSearchCountry({ sortCode: 301 });
sortCode: 301,
year: new Date().getFullYear() - 1
});
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
box2ChartData.value = { box2ChartData.value = {
title: res.data.map(item => ({ title: res.data.map(item => ({
...@@ -321,164 +208,39 @@ onMounted(() => { ...@@ -321,164 +208,39 @@ onMounted(() => {
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
.box { .content-list {
width: 792px;
height: 410px; height: 410px;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
}
.box-header {
height: 46px;
display: flex; display: flex;
position: relative; gap: 16px;
.header-left {
margin-top: 18px;
width: 8px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 14px;
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
.warning-text {
position: absolute;
top: 16px;
right: 124px;
height: 24px;
color: rgba(206, 79, 81, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: center;
}
.header-select-box {
position: absolute;
top: 13px;
right: 121px;
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
}
.box-footer {
margin: 5px auto;
width: 759px;
height: 40px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 10px;
padding: 6px 12px 6px 12px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 250, 255, 1);
.box-footer-left {
width: 19px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.box-footer-center {
width: 666px;
height: 24px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
.box-footer-right {
width: 24px;
height: 24px;
img { .content-item {
width: 20px;
flex: auto;
height: 100%;
.box-main {
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 12px 30px 20px;
display: flex;
flex-direction: column;
.box-head {
height: 20px;
flex: auto;
}
} }
} }
} }
.top { .warning-text {
display: flex; margin-right: 12px;
justify-content: center; height: 24px;
gap: 16px; color: rgba(206, 79, 81, 1);
font-family: Microsoft YaHei;
.box1 { font-size: 18px;
.box1-main { font-weight: 700;
height: 304px; line-height: 24px;
// background: orange; letter-spacing: 0px;
} text-align: center;
}
.box2 {
.box2-main {
height: 304px;
// background: orange;
}
}
}
.bottom {
display: flex;
justify-content: center;
gap: 16px;
.box3 {
.box3-main {
height: 304px;
// background: orange;
}
}
.box4 {
.box4-main {
height: 304px;
// background: orange;
}
}
} }
} }
</style> </style>
...@@ -5,7 +5,7 @@ const getBarChart = (nameList, valueList) => { ...@@ -5,7 +5,7 @@ const getBarChart = (nameList, valueList) => {
tooltip: {}, tooltip: {},
title: { title: {
text: '单位:万人', text: '单位:万人',
left: 660, right: 26,
top: 10, top: 10,
textStyle: { textStyle: {
color: 'rgba(95, 101, 108, 1)', color: 'rgba(95, 101, 108, 1)',
...@@ -16,18 +16,14 @@ const getBarChart = (nameList, valueList) => { ...@@ -16,18 +16,14 @@ const getBarChart = (nameList, valueList) => {
} }
}, },
grid: { grid: {
top: '5%', top: 40,
right: '3%', bottom: 0,
bottom: '1%', right: 26,
left: '1%', left: 12,
containLabel: true containLabel: true
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
splitLine: {
show: false
},
show: false
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
......
<template> <template>
<div class="wrap"> <div class="wrap">
<div class="top"> <div class="content-top">
<div class="item"> <div class="item">
<div class="item-left-box"> <div class="item-left-box">
<div class="item-left1">{{ "总调查案件数" }}</div> <div class="item-left1">{{ "总调查案件数" }}</div>
...@@ -18,29 +18,29 @@ ...@@ -18,29 +18,29 @@
</div> </div>
<div class="item"> <div class="item">
<div class="item-left">{{ "胜诉/和解率" }}</div> <div class="item-left">{{ "胜诉/和解率" }}</div>
<div class="item-right">{{ `${windRate}/${cancelRate}` }}</div> <div class="item-right">{{ `${windRate}` }}</div>
</div> </div>
</div> </div>
<div class="center"> <div class="content-list">
<div class="box1" v-loading="box1Loading"> <div class="content-item" v-loading="box1Loading">
<AnalysisBox title="美国对华337调查年度趋势"> <AnalysisBox title="美国对华337调查年度趋势">
<div class="box1-main" id="chart1"></div> <div class="box-main">
<div class="box1-footer"> <div class="box-head" ref="chart1"></div>
<TipTab /> <TipTab style="margin-top: 16px;" />
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
<div class="box2" v-loading="box2Loading"> <div class="content-item" v-loading="box2Loading">
<AnalysisBox title="调查案件领域分布"> <AnalysisBox title="调查案件领域分布">
<div class="box2-main" id="chart2"></div> <div class="box-main">
<div class="box2-footer"> <div class="box-head" ref="chart2"></div>
<TipTab /> <TipTab style="margin-top: -16px;" />
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
</div> </div>
<div class="footer"> <div class="content-list">
<div class="box3" v-loading="box3Loading"> <div class="content-item" v-loading="box3Loading">
<AnalysisBox title="中国公司受调查情况"> <AnalysisBox title="中国公司受调查情况">
<template #header-btn> <template #header-btn>
<div class="header-btn-box"> <div class="header-btn-box">
...@@ -52,29 +52,29 @@ ...@@ -52,29 +52,29 @@
</div> </div>
</div> </div>
</template> </template>
<div v-show="btnActiveName === '调查次数'" class="box3-main" id="chart3"></div> <div class="box-main">
<div v-show="btnActiveName === '注册地分布'" class="box3-main1"> <div v-show="btnActiveName === '调查次数'" class="box-head" id="chart3"></div>
<div class="box3-main1-left"> <div v-show="btnActiveName === '注册地分布'" class="box-head2">
<div class="box3-main1-left-item" v-for="(item, index) in mapData" :key="index"> <div class="map-box-left">
<div class="box3-main1-left-item-left">{{ index + 1 }}</div> <div class="map-box-left-item" v-for="(item, index) in mapData" :key="index">
<div class="box3-main1-left-item-center">{{ item.name }}</div> <div class="map-box-left-item-left">{{ index + 1 }}</div>
<div class="box3-main1-left-item-right"> <div class="map-box-left-item-center">{{ item.name }}</div>
{{ item.value + "次" }} <div class="map-box-left-item-right">
{{ item.value + "次" }}
</div>
</div> </div>
</div> </div>
<div class="map-box-right" id="chartMap"></div>
</div> </div>
<div class="box3-main1-right" id="chartMap"></div>
</div>
<div class="box3-footer">
<TipTab /> <TipTab />
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
<div class="box4" v-loading="box4Loading"> <div class="content-item" v-loading="box4Loading">
<AnalysisBox title="调查结果分布"> <AnalysisBox title="调查结果分布">
<div class="box4-main" id="chart4"></div> <div class="box-main">
<div class="box4-footer"> <div class="box-head" ref="chart4"></div>
<TipTab /> <TipTab style="margin-top: -16px;" />
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
...@@ -85,176 +85,20 @@ ...@@ -85,176 +85,20 @@
import { ref, onMounted, nextTick } from "vue"; import { ref, onMounted, nextTick } from "vue";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import TipTab from "@/components/base/TipTab/index.vue" import TipTab from "@/components/base/TipTab/index.vue"
import AnalysisBox from "@/components/base/boxBackground/analysisBox.vue"
import { getStatCount, getStatcnOrgCount, getSearchResult, getStatArea, getStatNum } from "@/api/marketAccessRestrictions"; import { getStatCount, getStatcnOrgCount, getSearchResult, getStatArea, getStatNum } from "@/api/marketAccessRestrictions";
import getMultiLineChart from "./utils/multiLineChart"; import createLineChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/baseLineChart";
import createPieChart from "@/views/marketAccessRestrictions/marketAccessHome/utils/basePiechart.js";
import getBarChart from "./utils/barChart"; import getBarChart from "./utils/barChart";
import getPieChart from "./utils/piechart";
import getMapChart from "./utils/mapChart"; import getMapChart from "./utils/mapChart";
import CompanyImg from "./symbol.png"
import getGraphChart from "./utils/graphChart";
import getGraph from "./utils/graph";
const box1Loading = ref(false); const box1Loading = ref(false);
const box2Loading = ref(false); const box2Loading = ref(false);
const box3Loading = ref(false); const box3Loading = ref(false);
const box4Loading = ref(false); const box4Loading = ref(false);
const btnActiveName = ref("调查次数"); const btnActiveName = ref("调查次数");
const nodes = ref([
{
id: 0,
name: "泰丰先行",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`,
},
{
id: 1,
name: "国轩高科",
// category: 0,
symbolSize: 30,
value: 9,
symbol: `image://${CompanyImg}`,
},
{
id: 2,
name: "智方纳米",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`,
},
{
id: 3,
name: "香百科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`,
},
{
id: 4,
name: "格林滨",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`,
},
{
id: 5,
name: "江西紫宸",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`,
},
{
id: 6,
name: "紫江企业",
// category: 4,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`,
},
{
id: 7,
name: "大而美法案",
// category: 4,
symbolSize: 50,
value: 5,
symbol: `image://${CompanyImg}`,
},
{
id: 8,
name: "比亚迪",
// category: 0,
symbolSize: 30,
value: 10,
symbol: `image://${CompanyImg}`,
},
{
id: 9,
name: "铜陵有色",
// category: 3,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`,
},
{
id: 10,
name: "长盛精密",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`,
},
{
id: 11,
name: "天合光能",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`,
},
{
id: 12,
name: "昆仑化学",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`,
},
{
id: 13,
name: "嘉源科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`,
},
{
id: 14,
name: "华阳集团",
// category: 4,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`,
},
{
id: 15,
name: "海辰智能",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`,
},
]);
const links = ref([
{ source: 1, target: 7, label: { show: true, formatter: '合作' } },
{ source: 2, target: 7, label: { show: true, formatter: '持股' } },
{ source: 3, target: 7, label: { show: true, formatter: '合作' } },
{ source: 4, target: 7, lineStyle: { type: 'dashed', color: '#d32f2f' }, label: { show: true, formatter: '从属' } },
{ source: 5, target: 7, label: { show: true, formatter: '合作' } },
{ source: 6, target: 7, label: { show: true, formatter: '持股' } },
{ source: 0, target: 7, label: { show: true, formatter: '持股' } },
{ source: 8, target: 7, label: { show: true, formatter: '合作' } },
{ source: 9, target: 7, lineStyle: { type: 'dashed', color: '#d32f2f' }, label: { show: true, formatter: '从属' } },
{ source: 10, target: 7, lineStyle: { type: 'dashed', color: '#d32f2f' }, label: { show: true, formatter: '合作' } },
{ source: 11, target: 7, label: { show: true, formatter: '合作' } },
{ source: 12, target: 7, label: { show: true, formatter: '合作' } },
{ source: 13, target: 7, label: { show: true, formatter: '合作' } },
{ source: 14, target: 7, label: { show: true, formatter: '合作' } },
{ source: 15, target: 7, label: { show: true, formatter: '合作', color: 'red', borderColor: 'red' } },
]);
const provinceCoords = { const provinceCoords = {
"北京": [116.46, 39.92], "北京": [116.46, 39.92],
"上海": [121.48, 31.22], "上海": [121.48, 31.22],
...@@ -296,27 +140,19 @@ const provinceCoords = { ...@@ -296,27 +140,19 @@ const provinceCoords = {
const totalCaseNum = ref(0) const totalCaseNum = ref(0)
const onCaseNum = ref(0) const onCaseNum = ref(0)
const relateCnNum = ref(0) const relateCnNum = ref(0)
const cancelRate = ref('0%')
const windRate = ref('0%') const windRate = ref('0%')
const handleGetStat = async () => { const handleGetStat = async () => {
const params = {
sortCode: '337'
}
try { try {
const res = await getStatCount(params) const res = await getStatCount({sortCode: '337'})
console.log('337数量统计', res); console.log('337数量统计', res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
totalCaseNum.value = res.data.allCaseNum totalCaseNum.value = res.data.allCaseNum
onCaseNum.value = res.data.underCaseNum onCaseNum.value = res.data.underCaseNum
relateCnNum.value = res.data.involvinChinese relateCnNum.value = res.data.involvinChinese
cancelRate.value = res.data.cancelNum
windRate.value = res.data.winRate windRate.value = res.data.winRate
} }
} catch (error) { } catch (error) {
console.error('337数量统计error', error); console.error('337数量统计error', error);
} }
} }
...@@ -377,6 +213,7 @@ const chart1Data = ref({ ...@@ -377,6 +213,7 @@ const chart1Data = ref({
data: [] data: []
}); });
const chart1 = ref(null);
const handleGetStatNum = async () => { const handleGetStatNum = async () => {
box1Loading.value = true; box1Loading.value = true;
try { try {
...@@ -387,16 +224,10 @@ const handleGetStatNum = async () => { ...@@ -387,16 +224,10 @@ const handleGetStatNum = async () => {
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const sortedData = res.data.sort((a, b) => parseInt(a.searchYorM) - parseInt(b.searchYorM)); const sortedData = res.data.sort((a, b) => parseInt(a.searchYorM) - parseInt(b.searchYorM));
chart1Data.value.title = sortedData.map(item => item.searchYorM); chart1Data.value.title = sortedData.map(item => item.searchYorM);
chart1Data.value.data = [ chart1Data.value.list = [
{ { name: "调查数量", value: sortedData.map(item => item.searchCount) }
name: "调查数量",
value: sortedData.map(item => item.searchCount)
}
]; ];
nextTick(() => { nextTick(() => { createLineChart(chart1, chart1Data.value) });
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value);
setChart(chart1, "chart1");
});
} }
} catch (error) { } catch (error) {
console.error("获取年度趋势数据失败", error); console.error("获取年度趋势数据失败", error);
...@@ -406,26 +237,18 @@ const handleGetStatNum = async () => { ...@@ -406,26 +237,18 @@ const handleGetStatNum = async () => {
}; };
const chart2Data = ref([]); const chart2Data = ref([]);
const chart2 = ref(null);
const handleGetStatArea = async () => { const handleGetStatArea = async () => {
box2Loading.value = true; box2Loading.value = true;
try { try {
const res = await getStatArea({ const res = await getStatArea({ sortCode: "337" });
sortCode: "337" console.log('调查案件领域分布', res);
});
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
console.log('调查案件领域分布', res); chart2Data.value = res.data.filter(item => item.sortcode === "337" || item.sortname === "337调查").map(item => ({
name: item.areaname,
chart2Data.value = res.data value: item.areacount
.filter(item => item.sortcode === "337" || item.sortname === "337调查") }));
.map(item => ({ nextTick(() => { createPieChart(chart2, chart2Data.value) });
name: item.areaname,
value: item.areacount
}));
nextTick(() => {
let chart2 = getPieChart(chart2Data.value);
setChart(chart2, "chart2");
});
} }
} catch (error) { } catch (error) {
console.error("获取调查案件领域分布失败", error); console.error("获取调查案件领域分布失败", error);
...@@ -442,7 +265,7 @@ const chart3Data = ref({ ...@@ -442,7 +265,7 @@ const chart3Data = ref({
const mapData = ref([]); const mapData = ref([]);
const chart4Data = ref([]); const chart4Data = ref([]);
const chart4 = ref(null)
const handleGetSearchResult = async () => { const handleGetSearchResult = async () => {
box4Loading.value = true; box4Loading.value = true;
try { try {
...@@ -454,10 +277,7 @@ const handleGetSearchResult = async () => { ...@@ -454,10 +277,7 @@ const handleGetSearchResult = async () => {
name: item.RESULTNAME, name: item.RESULTNAME,
value: item.RESULTNUM value: item.RESULTNUM
})); }));
nextTick(() => { nextTick(() => { createPieChart(chart4, chart4Data.value) });
let chart4 = getPieChart(chart4Data.value);
setChart(chart4, "chart4");
});
} }
} catch (error) { } catch (error) {
console.error("获取调查结果分布失败", error); console.error("获取调查结果分布失败", error);
...@@ -467,11 +287,6 @@ const handleGetSearchResult = async () => { ...@@ -467,11 +287,6 @@ const handleGetSearchResult = async () => {
}; };
onMounted(() => { onMounted(() => {
let graph = getGraphChart(nodes.value, links.value)
setChart(graph, 'graphChart')
handleGetStatNum(); handleGetStatNum();
handleGetStatArea(); handleGetStatArea();
handleGetStatcnOrgCount(btnActiveName.value === "调查次数" ? "01" : "02"); handleGetStatcnOrgCount(btnActiveName.value === "调查次数" ? "01" : "02");
...@@ -488,18 +303,20 @@ onMounted(() => { ...@@ -488,18 +303,20 @@ onMounted(() => {
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
.top { .content-top {
display: flex; display: flex;
justify-content: space-between; gap: 16px;
.item { .item {
width: 388px; width: 20px;
flex: auto;
height: 80px; height: 80px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2); box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
position: relative; position: relative;
display: flex; display: flex;
align-items: center;
justify-content: space-between; justify-content: space-between;
&::before { &::before {
...@@ -514,7 +331,6 @@ onMounted(() => { ...@@ -514,7 +331,6 @@ onMounted(() => {
.item-left { .item-left {
margin-left: 30px; margin-left: 30px;
margin-top: 25px;
height: 24px; height: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -524,7 +340,6 @@ onMounted(() => { ...@@ -524,7 +340,6 @@ onMounted(() => {
} }
.item-right { .item-right {
margin-top: 28px;
margin-right: 35px; margin-right: 35px;
height: 24px; height: 24px;
color: var(--color-main-active); color: var(--color-main-active);
...@@ -536,218 +351,116 @@ onMounted(() => { ...@@ -536,218 +351,116 @@ onMounted(() => {
.item-left-box { .item-left-box {
margin-left: 30px; margin-left: 30px;
font-size: 16px;
line-height: 24px;
.item-left1 { .item-left1 {
margin-top: 13px;
height: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700; font-weight: 700;
line-height: 24px;
} }
.item-left2 { .item-left2 {
height: 2px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
} }
} }
} }
} }
.box-header { .content-list {
height: 56px; height: 410px;
display: flex; display: flex;
position: relative; gap: 16px;
.header-left { .content-item {
margin-top: 18px; width: 20px;
width: 8px; flex: auto;
height: 20px; height: 100%;
border-radius: 0 4px 4px 0; .box-main {
background: var(--color-main-active); width: 100%;
} height: 100%;
padding: 12px 30px 20px;
.title { display: flex;
margin-left: 14px; flex-direction: column;
margin-top: 14px; .box-head {
height: 26px; height: 20px;
line-height: 26px; flex: auto;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
} }
} }
} }
} }
.center { .header-btn-box {
display: flex; display: flex;
justify-content: space-between; .btn {
margin-left: 8px;
.box1 { height: 28px;
width: 792px; padding: 0 8px;
height: 360px; border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
.box1-main { background: rgba(255, 255, 255, 1);
height: 263px; text-align: center;
} line-height: 28px;
color: rgba(59, 65, 75, 1);
.box1-footer { font-family: Microsoft YaHei;
height: 40px; font-size: 16px;
} font-weight: 400;
cursor: pointer;
} }
.box2 { .btnActive {
width: 792px; border: 1px solid var(--color-main-active);
height: 360px; background: rgba(246, 250, 255, 1);
color: var(--color-main-active);
.box2-main {
width: 792px;
height: 263px;
box-sizing: border-box;
padding: 0 24px;
}
.box2-footer {
height: 40px;
}
} }
} }
.footer { .box-head2 {
height: 100%;
width: 100%;
padding-top: 10px;
display: flex; display: flex;
justify-content: space-between;
.box3 { .map-box-left {
width: 792px; width: 20px;
height: 360px; flex: auto;
height: 100%;
.map-box-left-item {
.header-btn-box {
display: flex; display: flex;
align-items: center;
height: 36px;
margin-left: 20px;
.btn { .map-box-left-item-left {
margin-left: 8px; width: 24px;
height: 28px; height: 24px;
padding: 0 8px; border-radius: 12px;
box-sizing: border-box; background: #e7f3ff;
border: 1px solid rgba(230, 231, 232, 1); margin-right: 12px;
border-radius: 4px; color: #0a57a6;
background: rgba(255, 255, 255, 1);
text-align: center; text-align: center;
line-height: 28px; line-height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
cursor: pointer;
}
.btnActive {
border: 1px solid var(--color-main-active);
background: rgba(246, 250, 255, 1);
color: var(--color-main-active);
}
}
.box3-main {
height: 263px;
}
.box3-main1 {
height: 263px;
display: flex;
.box3-main1-left {
padding-top: 24px;
width: 380px;
height: 263px;
// overflow-y: auto;
overflow-x: hidden;
.box3-main1-left-item {
display: flex;
height: 36px;
margin-left: 20px;
.box3-main1-left-item-left {
width: 24px;
height: 24px;
border-radius: 12px;
margin-left: 12px;
margin-top: 6px;
background: #e7f3ff;
color: #0a57a6;
text-align: center;
line-height: 24px;
}
.box3-main1-left-item-center {
height: 36px;
line-height: 36px;
width: 220px;
margin-left: 12px;
}
.box3-main1-left-item-right {
width: 80px;
box-sizing: border-box;
padding-right: 10px;
text-align: right;
}
}
} }
.box3-main1-right { .map-box-left-item-center {
width: 390px; height: 36px;
height: 263px; line-height: 36px;
box-sizing: border-box; width: 20px;
padding-top: 24px; flex: auto;
padding-right: 24px;
} }
.box3-footer { .map-box-left-item-right {
height: 40px; min-width: 80px;
padding-right: 10px;
text-align: right;
} }
} }
} }
.box4 { .map-box-right {
width: 792px; width: 450px;
height: 360px; height: 100%;
.box4-main {
height: 263px;
box-sizing: border-box;
padding: 0 24px;
}
.box4-footer {
height: 40px;
}
} }
} }
} }
......
...@@ -43,7 +43,7 @@ const getBarChart = (nameList, valueList) => { ...@@ -43,7 +43,7 @@ const getBarChart = (nameList, valueList) => {
data: valueList, data: valueList,
label: { label: {
show: true, show: true,
position: [480, 0], position: [434, 0],
formatter: function (params) { formatter: function (params) {
return params.value + ' 次' return params.value + ' 次'
}, },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论