提交 444ad580 authored 作者: huhuiqing's avatar huhuiqing

Merge branch 'master' of http://8.140.26.4:10003/caijian/risk-monitor into dev_hhq

......@@ -166,7 +166,7 @@ body {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: relative;
box-sizing: border-box;
height: 64px;
height: 96px;
}
.main-container {
......@@ -181,7 +181,7 @@ body {
align-items: center;
gap: 12px;
position: absolute;
left: 13px;
left: 160px;
.brand-icon {
width: 48px;
height: 48px;
......@@ -204,7 +204,7 @@ body {
height: 37px;
color: rgba(10, 18, 30, 1);
font-family: Microsoft YaHei;
font-size: 28px;
font-size: 32px;
font-weight: 700;
line-height: 37px;
}
......@@ -341,14 +341,14 @@ body {
.el-header {
padding: 0;
height: 64px;
height: 96px;
position: relative;
z-index: 1;
}
.el-main {
padding: 0;
height: calc(100vh - 64px);
height: calc(100vh - 96px);
overflow: hidden;
overflow-y: auto;
background-color: rgba(246, 251, 255, 1);
......
......@@ -33,7 +33,7 @@ export function getBillPerson(params) {
export function getBillEvent(params) {
return request({
method: 'GET',
url: `/api/billInfoBean/event/${params.id}`,
url: `/api/billInfoBean/actionContent/${params.id}`,
params,
})
}
......
import request from "@/api/request.js";
// 涉华法案领域分布
/**
* @param {year}
*/
export function getBillIndustry(params) {
return request({
method: 'GET',
url: `/api/BillOverview/billIndustry/${params.year}`,
params,
})
}
\ No newline at end of file
......@@ -6,4 +6,13 @@ export function getChat(params) {
url: `/aichat/chat/chat/completions`,
data: params,
})
}
// 清单问答
export function getChecklistChat(params) {
return request({
method: 'POST',
url: `/checklistChat/langgraph/checklist/chat`,
data: params,
})
}
\ No newline at end of file
......@@ -31,7 +31,7 @@ export { getToken, setToken, removeToken }
// 创建axios实例
const service = axios.create({
// baseURL: BASE_API, //所有的后端接口请求地址前缀部分(没有后端请求不用写)
timeout: 60000*5 // 请求超时时间,这里15秒
timeout: 300 * 1000 // 请求超时时间,这里5分钟
//withCredentials: true,// 异步请求携带cookie,true为携带,false为不携带
//请求头里面设置通用传参类型
/*headers: {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -133,7 +133,8 @@ const headerTitleClasses = computed(() => [
.header-icon {
width: 20px;
height: 20px;
margin-right: 14px;
margin-left: 5px;
margin-right: 19px;
}
.blue-title-block {
......@@ -152,6 +153,7 @@ const headerTitleClasses = computed(() => [
color: $base-color;
line-height: 48px;
padding: 0 12px;
font-size: 20px;
}
.header-title-primary {
......
......@@ -4,7 +4,7 @@ import InnovationSubject from "@/views/innovationSubject/index.vue";
const innovationSubjectRoutes = [
//创新主体
{
path: "/InnovationSubject",
path: "/innovationSubject",
name: "InnovationSubject",
component: InnovationSubject,
meta: {
......
......@@ -7,10 +7,10 @@ const overViewRoutes = [
// 中美博弈概览页面路由
{
path: "/",
redirect: "/overView"
redirect: "/overview"
},
{
path: "/overView",
path: "/overview",
name: "overView",
component: overView,
meta: {
......@@ -19,7 +19,7 @@ const overViewRoutes = [
},
// GJ概览页面路由
{
path: "/gjOverView",
path: "/gjOverview",
name: "gjOverView",
component: gjOverView,
meta: {
......
// 门户
import Portal from "@/views/portals/portal/index.vue";
import Portal1 from "@/views/portals/portal1/index.vue";
import Portal2 from "@/views/portals/portal2/index.vue";
const portalRoutes = [
// 门户
{
path: "/portal",
name: "portal",
component: Portal,
path: "/portal1",
name: "portal1",
component: Portal1,
meta: {
title: "门户"
}
},
{
path: "/portal2",
name: "portal2",
component: Portal2,
meta: {
title: "门户"
}
......
//科技人物观点
import TechnologyFigures from "@/views/technologyFigures/index.vue";
const technologyFiguresRoutes = [
//创新主体
{
path: "/technologyFigures",
name: "TechnologyFigures",
component: TechnologyFigures,
meta: {
title: "主要创新主体"
}
}
]
export default technologyFiguresRoutes
\ No newline at end of file
/* 全局滚动条样式 */
* {
scrollbar-width: thin;
scrollbar-color: #c1c1c1 #f1f1f1;
}
/* Webkit 浏览器 */
::-webkit-scrollbar {
width: 10px;
height: 10px;
width: 4px;
height: 8px;
}
::-webkit-scrollbar-track {
......@@ -16,17 +12,17 @@
}
::-webkit-scrollbar-thumb {
background: #6c757d;
border-radius: 6px;
border: 2px solid #f8f9fa;
background: #c5c7c9;
border-radius: 2px;
/* border: 1px solid #f8f9fa; */
}
::-webkit-scrollbar-thumb:hover {
background: #495057;
background: #505357;
}
::-webkit-scrollbar-thumb:active {
background: #343a40;
background: #505357;
}
::-webkit-scrollbar-corner {
......@@ -40,16 +36,16 @@
/* Element UI 组件滚动条优化 */
.el-table__body-wrapper::-webkit-scrollbar {
width: 8px;
width: 4px;
height: 8px;
}
.el-table__body-wrapper::-webkit-scrollbar-thumb {
background: #909399;
border-radius: 4px;
background: #505357;
border-radius: 2px;
}
.el-select-dropdown .el-scrollbar__wrap {
scrollbar-width: thin;
scrollbar-color: #c1c1c1 #f1f1f1;
}
\ No newline at end of file
}
\ No newline at end of file
......@@ -110,7 +110,7 @@
</div>
<div class="title">{{ "热门法案" }}</div>
</div>
<div class="box1-header-right">
<div class="box1-header-right" @click="handleClickToDetail">
{{ "查看详情 >" }}
</div>
</div>
......@@ -257,7 +257,6 @@
<img src="./assets/images/box4-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
......@@ -520,6 +519,9 @@
import { onMounted, ref, computed, onUnmounted, nextTick } from "vue";
import * as echarts from "echarts";
import router from "@/router/index";
import setChart from "@/utils/setChart";
import { getBillIndustry } from "@/api/bill/billHome";
import { getHotBills, getBillRiskSignal, getBillsByType, getHylyList } from "@/api/home";
import DivideHeader from "@/components/DivideHeader.vue";
......@@ -624,6 +626,7 @@ const curBill = ref({
// 查看详情
const handleClickToDetail = () => {
// window.sessionStorage.setItem("billId", curBill.value.billId);
window.sessionStorage.setItem("billId", '119_HR_1');
// router.push("/billLayout");
const route = router.resolve("/billLayout");
window.open(route.href, "_blank");
......@@ -838,26 +841,6 @@ const box8YearList = ref([
}
]);
const box9selectetedTime = ref("2025");
const box9YearList = ref([
{
label: "2025",
value: "2025"
},
{
label: "2024",
value: "2024"
},
{
label: "2023",
value: "2023"
},
{
label: "2022",
value: "2022"
}
]);
const releaseTime = ref("近一年发布"); // 发布时间
const releaseTimeList = ref([
......@@ -897,27 +880,27 @@ const categoryList = ref([
// "航空航天",
]);
const curCategoryList = ref([])
const curCategoryIndex = ref(0)
const SHOW_COUNT = 10
const curCategoryList = ref([]);
const curCategoryIndex = ref(0);
const SHOW_COUNT = 10;
function updateShowList(startIndex) {
// 确保索引在有效范围内
startIndex = Math.max(0, Math.min(startIndex, categoryList.value.length - SHOW_COUNT));
// 截取要显示的元素
curCategoryList.value = categoryList.value.slice(startIndex, startIndex + SHOW_COUNT);
// 如果接近末尾不够10个,从末尾往前取10个
if (curCategoryList.value.length < SHOW_COUNT) {
curCategoryList.value = categoryList.value.slice(-SHOW_COUNT);
curCategoryIndex = categoryList.value.length - SHOW_COUNT;
} else {
curCategoryIndex = startIndex;
}
renderShowList();
updateButtons();
// 确保索引在有效范围内
startIndex = Math.max(0, Math.min(startIndex, categoryList.value.length - SHOW_COUNT));
// 截取要显示的元素
curCategoryList.value = categoryList.value.slice(startIndex, startIndex + SHOW_COUNT);
// 如果接近末尾不够10个,从末尾往前取10个
if (curCategoryList.value.length < SHOW_COUNT) {
curCategoryList.value = categoryList.value.slice(-SHOW_COUNT);
curCategoryIndex = categoryList.value.length - SHOW_COUNT;
} else {
curCategoryIndex = startIndex;
}
renderShowList();
updateButtons();
}
const activeCate = ref("全部分类");
......@@ -947,15 +930,6 @@ const handleClickCate = cate => {
handleGetBillsByType();
};
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
};
const chart1Data = ref({
title: [
"2024-09",
......@@ -1103,36 +1077,81 @@ const wordCloudData = ref([
{ name: "加强供应链风险管理", value: 73 }
]);
// 涉华领域分布
const box9ChartColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
const box9ChartData = ref([
// {
// name: "半导体",
// value: 50
// },
// {
// name: "电子设备",
// value: 46
// },
// {
// name: "显示技术",
// value: 40
// },
// {
// name: "新能源",
// value: 32
// },
// {
// name: "通信设备",
// value: 31
// },
// {
// name: "汽车",
// value: 30
// },
// {
// name: "其他",
// value: 24
// }
]);
const box9selectetedTime = ref("2025");
const box9YearList = ref([
{
name: "半导体",
value: 50
},
{
name: "电子设备",
value: 46
},
{
name: "显示技术",
value: 40
},
{
name: "新能源",
value: 32
label: "2025",
value: "2025"
},
{
name: "通信设备",
value: 31
label: "2024",
value: "2024"
},
{
name: "汽车",
value: 30
label: "2023",
value: "2023"
},
{
name: "其他",
value: 24
label: "2022",
value: "2022"
}
]);
const getBox9Data = async () => {
const params = {
year: box9selectetedTime.value
};
try {
const res = await getBillIndustry(params);
console.log("box9-涉华法案领域分布", res.data);
if (res.code === 200 && res.data) {
box9ChartData.value = res.data;
}
} catch (error) {}
};
const handleBox9Data = async () => {
await getBox9Data();
const box9Chart = getPieChart(
box9ChartData.value.map(item => {
return {
name: item.industryName,
value: item.countBill
};
})
);
setChart(box9Chart, "box9Chart");
};
const box7Data = ref([
[
......@@ -1252,8 +1271,6 @@ const box8Data = ref([
}
]);
const box9ChartColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
const handleToPosi = id => {
// 0 618 1240 2350
switch (id) {
......@@ -1286,11 +1303,10 @@ onMounted(async () => {
const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]);
setChart(box7Chart, "box7Chart");
const box9Chart = getPieChart(box9ChartData.value, box9ChartColorList.value);
setChart(box9Chart, "box9Chart");
await handleGetHotBills();
curBill.value = hotBillList.value[0];
handleBox9Data();
});
onUnmounted(() => {});
......
const getPieChart = (data,colorList) => {
let option = {
color: colorList,
// color: colorList,
series: [
{
type: 'pie',
......
......@@ -26,7 +26,7 @@
:key="index"
@click="handleClickBox1Btn(item, index)"
>
{{ item.hylymc }}
{{ item.name }}
</div>
</div>
</div>
......@@ -343,8 +343,8 @@ const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("行业领域字典列表", res);
industryList.value = res.data;
curHylyId.value = res.data[0].hylyid;
industryList.value = res.data.slice(0,6)
curHylyId.value = res.data[0].id;
} catch (error) {}
};
......@@ -353,7 +353,8 @@ const curHylyId = ref("");
// 根据行业领域id获取公司列表
const handleGetCompanyListById = async () => {
const params = {
id: curHylyId.value
// id: curHylyId.value
id: '0100'
};
try {
const res = await getCompanyList(params);
......@@ -785,7 +786,7 @@ onMounted(async () => {
.left-center-btn {
margin-right: 4px;
height: 28px;
width: 60px;
width: 70px;
text-align: center;
padding: 0 5px;
box-sizing: border-box;
......
<template>
<div class="container">
<div class="svg-timeline">
<svg :width="svgWidth" :height="svgHeight">
<!-- <line
<div class="container">
<div class="svg-timeline">
<svg :width="svgWidth" :height="svgHeight">
<!-- <line
:x1="lines[0].x1 - 100"
:y1="lines[0].y1"
:x2="lines[0].x1"
......@@ -11,7 +11,7 @@
stroke-width="2"
marker-end="url(#arrow)"
/> -->
<!-- <line
<!-- <line
v-for="(line, idx) in lines"
:key="'line' + idx"
:x1="line.x1"
......@@ -22,7 +22,7 @@
stroke-width="2"
marker-end="url(#arrow)"
/> -->
<!-- <path
<!-- <path
v-for="(arc, idx) in arcPaths"
:key="'arc' + idx"
:d="arc.d"
......@@ -30,23 +30,17 @@
stroke="red"
stroke-width="2"
/> -->
<line
:x1="lines[0].x1 - 100"
:y1="lines[0].y1"
:x2="lines[0].x1"
:y2="lines[0].y1"
stroke="#e8f2ff"
stroke-width="2"
marker-end="url(#arrow)"
/>
<path
:d="arcPaths"
fill="none"
stroke="#e8f2ff"
stroke-width="2"
marker-end="url(#arrow)"
/>
<!-- <defs>
<line
:x1="lines[0].x1 - 100"
:y1="lines[0].y1"
:x2="lines[0].x1"
:y2="lines[0].y1"
stroke="#e8f2ff"
stroke-width="2"
marker-end="url(#arrow)"
/>
<path :d="arcPaths" fill="none" stroke="#e8f2ff" stroke-width="2" marker-end="url(#arrow)" />
<!-- <defs>
<marker
id="arrow"
markerWidth="6"
......@@ -59,221 +53,216 @@
<path d="M0,0 L6,3 L0,6" fill="#333" />
</marker>
</defs> -->
<!-- 节点 -->
<circle
v-for="(node, idx) in nodes.slice(0, nodes.length)"
:key="'circle' + idx"
:cx="node.x"
:cy="node.y"
r="4"
fill="#fff"
stroke="#1677ff"
stroke-width="3"
/>
<line
v-for="(node, idx) in nodes.slice(0, nodes.length)"
:key="'line' + idx"
:x1="node.x"
:y1="node.y + 2"
:x2="node.x"
:y2="node.dyms?node.y + 80:node.y + 50"
stroke="#1677ff"
stroke-width="2"
/>
<text
v-for="(node, idx) in nodes"
:key="'dysj' + idx"
:x="node.x + 10"
:y="node.y + 30"
text-anchor="start"
fill="#1677ff"
font-size="14"
font-weight="600"
>
{{ node.dysj }}
</text>
<text
v-for="(node, idx) in nodes"
:key="'dyzt' + idx"
:x="node.x + 10"
:y="node.y + 50"
text-anchor="start"
fill="#3b414b"
font-size="14"
font-weight="bold"
>
{{ node.dyzt }}
</text>
<text
v-for="(node, idx) in nodes"
:key="'dyzt' + idx"
:x="node.x + 10"
:y="node.y + 70"
text-anchor="start"
fill="#84888e"
font-size="14"
>
{{ node.dyms?node.dyms:'' }}
</text>
</svg>
</div>
</div>
<!-- 节点 -->
<circle
v-for="(node, idx) in nodes.slice(0, nodes.length)"
:key="'circle' + idx"
:cx="node.x"
:cy="node.y"
r="4"
fill="#fff"
stroke="#1677ff"
stroke-width="3"
/>
<line
v-for="(node, idx) in nodes.slice(0, nodes.length)"
:key="'line' + idx"
:x1="node.x"
:y1="node.y + 2"
:x2="node.x"
:y2="node.dyms ? node.y + 80 : node.y + 50"
stroke="#1677ff"
stroke-width="2"
/>
<text
v-for="(node, idx) in nodes"
:key="'actionDate' + idx"
:x="node.x + 10"
:y="node.y + 30"
text-anchor="start"
fill="#1677ff"
font-size="14"
font-weight="600"
>
{{ node.actionDate }}
</text>
<text
v-for="(node, idx) in nodes"
:key="'actionTitle' + idx"
:x="node.x + 10"
:y="node.y + 50"
text-anchor="start"
fill="#3b414b"
font-size="14"
textLength="170"
lengthAdjust="spacing"
font-weight="bold"
>
{{ node.actionTitle.slice(0,24) }}
</text>
<text
v-for="(node, idx) in nodes"
:key="'actionTitle' + idx"
:x="node.x + 10"
:y="node.y + 70"
text-anchor="start"
fill="#84888e"
font-size="14"
>
{{ node.dyms ? node.dyms : "" }}
</text>
</svg>
</div>
</div>
</template>
<script>
export default {
props: ['dataList'],
data() {
return {
// dataList: [
// { dysj: "2025-07-08 14:20", dyzt: "起飞", dyms: '16票赞成 : 21票反对​ ' },
// { dysj: "2025-07-08 14:22", dyzt: "转弯" },
// { dysj: "2025-07-08 14:25", dyzt: "发现问题",dyms: '16票赞成 : 21票反对​ ' },
// { dysj: "2025-07-08 14:27", dyzt: "飞行",dyms: '16票赞成 : 21票反对​ ' },
// { dysj: "2025-07-08 14:29", dyzt: "飞行" },
// { dysj: "2025-07-08 14:31", dyzt: "飞行",dyms: '16票赞成 : 21票反对​ ' },
// { dysj: "2025-07-08 14:33", dyzt: "转弯" },
// { dysj: "2025-07-08 14:35", dyzt: "飞行" },
// { dysj: "2025-07-08 14:37", dyzt: "降落" },
// { dysj: "2025-07-08 14:39", dyzt: "降落" },
// { dysj: "2025-07-08 14:41", dyzt: "返航" },
// { dysj: "2025-07-08 14:42", dyzt: "返航1" },
// ],
maxPerRow: 5,
nodeGapX: 200,
nodeGapY: 100,
};
},
computed: {
nodes() {
// 计算每个节点的坐标(蛇形)
return this.dataList.map((item, idx) => {
const row = Math.floor(idx / this.maxPerRow);
const col = idx % this.maxPerRow;
let x, y;
const leftMargin = 10; // 你可以自定义这个值
props: ["dataList"],
data() {
return {
// dataList: [
// { actionDate: "2025-07-08 14:20", actionTitle: "起飞", dyms: '16票赞成 : 21票反对​ ' },
// { actionDate: "2025-07-08 14:22", actionTitle: "转弯" },
// { actionDate: "2025-07-08 14:25", actionTitle: "发现问题",dyms: '16票赞成 : 21票反对​ ' },
// { actionDate: "2025-07-08 14:27", actionTitle: "飞行",dyms: '16票赞成 : 21票反对​ ' },
// { actionDate: "2025-07-08 14:33", actionTitle: "转弯" },
// { actionDate: "2025-07-08 14:35", actionTitle: "飞行" },
// ],
maxPerRow: 5,
nodeGapX: 200,
nodeGapY: 100
};
},
computed: {
nodes() {
// 计算每个节点的坐标(蛇形)
return this.dataList.map((item, idx) => {
const row = Math.floor(idx / this.maxPerRow);
const col = idx % this.maxPerRow;
let x, y;
const leftMargin = 10; // 你可以自定义这个值
if (row % 2 === 0) {
x = leftMargin + col * this.nodeGapX + 50;
} else {
x = leftMargin + (this.maxPerRow - 1 - col) * this.nodeGapX + 50;
}
// 节点纵坐标起始值
y = 60 + row * this.nodeGapY;
return { ...item, x, y, row };
});
},
lines() {
const arr = [];
const gap = 0; // 间隔长度
for (let i = 0; i < this.nodes.length - 1; i++) {
const x1 = this.nodes[i].x;
const y1 = this.nodes[i].y;
const x2 = this.nodes[i + 1].x;
const y2 = this.nodes[i + 1].y;
const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);
// 计算起点和终点都缩进 gap
const ratioStart = gap / len;
const ratioEnd = (len - gap) / len;
const sx = x1 + dx * ratioStart;
const sy = y1 + dy * ratioStart;
const tx = x1 + dx * ratioEnd;
const ty = y1 + dy * ratioEnd;
arr.push({
x1: sx,
y1: sy,
x2: tx,
y2: ty,
});
}
return arr;
},
arcPaths() {
if (this.nodes.length < 2) return '';
let path = `M ${this.nodes[0].x} ${this.nodes[0].y}`;
for (let i = 1; i < this.nodes.length; i++) {
const prev = this.nodes[i - 1];
const curr = this.nodes[i];
console.log('prev',prev);
// 判断是否是行尾转折点
const isTurnPoint = i % 5 === 0;
if (isTurnPoint) {
// 计算半圆路径
const radius = 10 / 2;
if (prev.row % 2 === 0) {
// 偶数行向右凸半圆
path += `
if (row % 2 === 0) {
x = leftMargin + col * this.nodeGapX + 50;
} else {
x = leftMargin + (this.maxPerRow - 1 - col) * this.nodeGapX + 50;
}
// 节点纵坐标起始值
y = 60 + row * this.nodeGapY;
return { ...item, x, y, row };
});
},
lines() {
const arr = [];
const gap = 0; // 间隔长度
for (let i = 0; i < this.nodes.length - 1; i++) {
const x1 = this.nodes[i].x;
const y1 = this.nodes[i].y;
const x2 = this.nodes[i + 1].x;
const y2 = this.nodes[i + 1].y;
const dx = x2 - x1;
const dy = y2 - y1;
const len = Math.sqrt(dx * dx + dy * dy);
// 计算起点和终点都缩进 gap
const ratioStart = gap / len;
const ratioEnd = (len - gap) / len;
const sx = x1 + dx * ratioStart;
const sy = y1 + dy * ratioStart;
const tx = x1 + dx * ratioEnd;
const ty = y1 + dy * ratioEnd;
arr.push({
x1: sx,
y1: sy,
x2: tx,
y2: ty
});
}
return arr;
},
arcPaths() {
if (this.nodes.length < 2) return "";
let path = `M ${this.nodes[0].x} ${this.nodes[0].y}`;
for (let i = 1; i < this.nodes.length; i++) {
const prev = this.nodes[i - 1];
const curr = this.nodes[i];
console.log("prev", prev);
// 判断是否是行尾转折点
const isTurnPoint = i % 5 === 0;
if (isTurnPoint) {
// 计算半圆路径
const radius = 10 / 2;
if (prev.row % 2 === 0) {
// 偶数行向右凸半圆
path += `
L ${prev.x + radius} ${prev.y}
A ${radius} ${radius} 0 0 1 ${curr.x - radius} ${curr.y}
L ${curr.x} ${curr.y}`;
} else {
// 奇数行向左凸半圆
path += `
} else {
// 奇数行向左凸半圆
path += `
L ${prev.x - radius} ${prev.y}
A ${radius} ${radius} 0 0 0 ${curr.x + radius} ${curr.y}
L ${curr.x} ${curr.y}`;
}
} else {
// 同行节点间用直线连接
path += ` L ${curr.x} ${curr.y}`;
}
}
return path;
},
svgWidth() {
return this.maxPerRow * this.nodeGapX + 100;
},
svgHeight() {
// SVG高度
return (
Math.ceil(this.dataList.length / this.maxPerRow) * this.nodeGapY + 40
);
},
},
}
} else {
// 同行节点间用直线连接
path += ` L ${curr.x} ${curr.y}`;
}
}
return path;
},
svgWidth() {
return this.maxPerRow * this.nodeGapX + 100;
},
svgHeight() {
// SVG高度
return Math.ceil(this.dataList.length / this.maxPerRow) * this.nodeGapY + 40;
}
}
};
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.svg-timeline {
width: 1000px;
// background-size: 100% 100%;
// position: relative;
// .title {
// position: absolute;
// top: 0;
// left: 32px;
// width: 100%;
// height: 100%;
// font-family: YouSheBiaoTiHei;
// font-size: 16px;
// color: #ffffff;
// line-height: 24px;
// background: linear-gradient(90deg, #ffffff 0%, #79c2ff 100%);
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
// display: flex;
// align-items: center;
// height: 40px;
// img {
// width: 12px;
// height: 24px;
// }
// }
width: 1000px;
// background-size: 100% 100%;
// position: relative;
// .title {
// position: absolute;
// top: 0;
// left: 32px;
// width: 100%;
// height: 100%;
// font-family: YouSheBiaoTiHei;
// font-size: 16px;
// color: #ffffff;
// line-height: 24px;
// background: linear-gradient(90deg, #ffffff 0%, #79c2ff 100%);
// -webkit-background-clip: text;
// -webkit-text-fill-color: transparent;
// display: flex;
// align-items: center;
// height: 40px;
// img {
// width: 12px;
// height: 24px;
// }
// }
}
</style>
......@@ -21,12 +21,12 @@
<div class="box1-right">
<div class="box1-right-item">
<div class="item-left">提案人:</div>
<div class="item-right">乔迪·C·阿灵顿​(共和党-得克萨斯州第19选区)</div>
<div class="item-right">{{basicInfo.tarName}}</div>
</div>
<div class="box1-right-item">
<div class="item-left">提出时间:</div>
<div class="item-right">2025年5月20日</div>
<div class="item-right">{{basicInfo.introductionDate}}</div>
</div>
<div class="box1-right-item">
<div class="item-left">相关领域:</div>
......@@ -38,47 +38,35 @@
</div>
<div class="box1-right-item">
<div class="item-left">法案类别:</div>
<div class="item-right">公法(编号:Pub. L. No. 119-21)</div>
<div class="item-right">{{ basicInfo.typeName }}</div>
</div>
<div class="box1-right-item">
<div class="item-left">提案人</div>
<div class="item-right2">
<div class="right2-item">H. Rept. 119-106, Book 1</div>
<div class="right2-item">H. Rept. 119-106, Book 2​(两份独立报告)</div>
<div class="item-left">委员会报告</div>
<div class="item-right2" v-if="basicInfo.reportList">
<div class="right2-item" v-for="item,index in basicInfo.reportList" :key="index">{{ item }}</div>
</div>
</div>
<div class="box1-right-item">
<div class="item-left">表决记录:</div>
<div class="item-right3">全程共进行 ​47次唱名表决</div>
<div class="item-right3">{{`全程共进行${basicInfo.votetotal}次唱名表决`}}</div>
</div>
<div class="box1-right-item">
<div class="item-left">最近状态:</div>
<div class="item-right3">2025年7月4日​ 由总统签署生效</div>
<div class="item-right3">{{ basicInfo.status }}</div>
</div>
<div class="box1-right-item">
<div class="item-left">立案流程:</div>
<div class="item-right4">
<!-- <el-steps
style="max-width: 500px"
:active="6"
finish-status="success"
>
<el-step title="提出" />
<el-step title="众议院通过" />
<el-step title="参议院通过" />
<el-step title="分歧协调" />
<el-step title="提交总统" />
<el-step title="法案通过" />
</el-steps> -->
<div class="step" v-for="(item, index) in stepList" :key="index">
<div class="step" v-for="(item, index) in basicInfo.stageList" :key="index">
<div class="step-box" v-if="!item.active">
{{ item.title }}
{{ item }}
<div class="right-arrow">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
<div class="step-box-active" v-else>
{{ item.title }}
{{ item }}
<div class="right-arrow">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
......@@ -120,8 +108,8 @@
<div class="box2-center-item-box" v-if="box2BtnActive == 1">
<div class="box2-center-item" v-for="(item, index) in progressList" :key="index">
<div class="tip" :class="{ tipActive: item.fxdj }"></div>
<div class="date">{{ item.sjsj }}</div>
<div class="title">{{ item.sjnr }}</div>
<div class="date">{{ item.actionDate }}</div>
<div class="title">{{ item.actionContentCn }}</div>
<div class="info">
<div class="info-box danger-box4" v-if="item.fxdj === '特别重大风险'">
{{ item.fxdj }}
......@@ -545,6 +533,9 @@ const handleClickMore2 = () => {
};
// 获取基本信息
const basicInfo = ref({})
const handleGetBasicInfo = async () => {
const params = {
id: window.sessionStorage.getItem("billId")
......@@ -552,6 +543,7 @@ const handleGetBasicInfo = async () => {
try {
const res = await getBillInfo(params);
console.log("基本信息", res);
basicInfo.value = res.data
} catch (error) {
console.error(error);
}
......@@ -588,15 +580,15 @@ const handleGetBillDyqk = async () => {
const res = await getBillDyqk(params);
console.log("前期进展", res);
timelineData.value = res.data;
faList.value = res.data.map(item => {
return {
label: item.dyms,
value: item.dyms,
id: item.id
};
});
selectValue.value = faList.value[0];
handleGetBillPerson(faList.value[0].id);
// faList.value = res.data.map(item => {
// return {
// label: item.actionTitle,
// value: item.actionTitle,
// id: item.id
// };
// });
// selectValue.value = faList.value[0];
// handleGetBillPerson(faList.value[0].id);
} catch (error) {
console.error(error);
}
......
......@@ -85,9 +85,9 @@
<div class="text">{{ `正在思考中,请稍候` }}</div>
</div>
<div class="loading-indicator">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span v-show="loadingDotIndex < 3" class="dot"></span>
<span v-show="loadingDotIndex > 0" class="dot"></span>
<span v-show="loadingDotIndex === 2" class="dot"></span>
</div>
</div>
</div>
......@@ -140,7 +140,7 @@ import { ref, onMounted, onUnmounted, nextTick } from "vue";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import MarkdownIt from "markdown-it";
import { ElMessage } from "element-plus";
import { getChat } from "@/api/chat";
import { getChat, getChecklistChat } from "@/api/chat";
import router from "@/router/index";
import json5 from "json5";
......@@ -152,24 +152,8 @@ const areaList = ref([
value: "法案"
},
{
label: "政令",
value: "政令"
},
{
label: "智库",
value: "智库"
},
{
label: "出口管制",
value: "出口管制"
},
{
label: "投融资限制",
value: "投融资限制"
},
{
label: "市场准入限制",
value: "市场准入限制"
label: "清单",
value: "清单"
}
]);
......@@ -186,6 +170,8 @@ const userInput = ref("");
const isLoading = ref(false);
const abortController = ref(null);
const loadingDotIndex = ref(0);
// 消息数据
const messages = ref([
// {
......@@ -369,6 +355,13 @@ const connectSSE = async question => {
addMessage("ai", "");
isLoading.value = true;
const loadingInterval = setInterval(() => {
if (loadingDotIndex.value < 2) {
loadingDotIndex.value++;
} else {
loadingDotIndex.value = 0;
}
}, 500);
// 创建 AbortController 用于取消请求
abortController.value = new AbortController();
......@@ -394,6 +387,7 @@ const connectSSE = async question => {
openWhenHidden: true,
async onopen(res) {
isLoading.value = false;
clearInterval(loadingInterval);
console.log("流式回答开始", res);
},
async onmessage(res) {
......@@ -465,20 +459,256 @@ const connectSSE = async question => {
});
};
const chat = async () => {
function formatDateTime(isoString) {
const date = new Date(isoString);
// 获取各个时间部分
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
const day = String(date.getDate()).padStart(2, "0");
const hours = String(date.getHours()).padStart(2, "0");
const minutes = String(date.getMinutes()).padStart(2, "0");
const seconds = String(date.getSeconds()).padStart(2, "0");
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
const chat = async question => {
// 添加用户消息
addMessage("user", question);
const params = {
query: "如何检索?",
knowledge_base_name: "kb_test251112",
top_k: 6,
score_threshold: 0.5,
metadata: { year: 2024 }
model: "neko-checklist-agent",
// messages: [
// {
// role: "user",
// content: "2024年12月5日当期实体清单的主要制裁对象、制裁原因是?"
// }
// ]
messages: messages.value.map(item => {
return {
role: item.type === "ai" ? "assistant" : "user",
content: item.content
};
})
};
// 添加空的 AI 消息用于流式更新
addMessage("ai", "");
isLoading.value = true;
const loadingInterval = setInterval(() => {
if (loadingDotIndex.value < 2) {
loadingDotIndex.value++;
} else {
loadingDotIndex.value = 0;
}
}, 500);
// // 创建 AbortController 用于取消请求
// abortController.value = new AbortController();
// const TIMEOUT_MS = 180 * 1000;
// fetchEventSource("/checklistChat/langgraph/checklist/chat-stream", {
// method: "POST",
// headers: {
// "Content-Type": "application/json"
// },
// body: JSON.stringify(params),
// signal: abortController.value.signal,
// // 设置 3 分钟超时
// // fetch: async (input, init) => {
// // const abortController = new AbortController();
// // const timeoutId = setTimeout(() => {
// // console.log('请求超时(3分钟)');
// // abortController.value.abort();
// // }, TIMEOUT_MS);
// // try {
// // const response = await fetch(input, {
// // ...init,
// // signal: abortController.value.signal,
// // });
// // return response;
// // } finally {
// // clearTimeout(timeoutId);
// // }
// // },
// openWhenHidden: true,
// async onopen(res) {
// isLoading.value = false;
// clearInterval(loadingInterval);
// if(res.detail.error) {
// ElMessage.error(res.detail.error.message)
// }
// console.log("流式回答开始", res);
// },
// async onmessage(res) {
// console.log("res", res);
// if (res.data === "[DONE]") {
// ElMessage.success("生成完成!");
// }
// let msgData = JSON.parse(res.data);
// if (msgData.logs) {
// console.log("docs", msgData.logs);
// const lastMessage = messages.value[messages.value.length - 1];
// if (lastMessage && lastMessage.type === "ai") {
// let newDocs = msgData.logs.map(item => {
// return item.detail + " " + formatDateTime(item.ts);
// });
// lastMessage.source = newDocs;
// scrollToBottom();
// }
// }
// if (msgData.choices && msgData.choices[0].delta.content) {
// isCurAnswerMessage.value = true;
// let content = msgData.choices[0].delta.content;
// if (content === "[DONE]") {
// ElMessage.success("生成完成!");
// } else {
// aiMessage.value += content;
// updateLastAIMessage(aiMessage.value);
// }
// }
// // if (res.event === "end_of_workflow") {
// // ElMessage.success("问答完成!");
// // abortController.value.abort();
// // abortController.value = new AbortController();
// // return;
// // }
// // if (res.event === "start_of_agent" && msgData.agent_name === "answer") {
// // isCurAnswerMessage.value = true;
// // aiMessage.value = "";
// // }
// // if (res.event === "message") {
// // let content = msgData.delta.content;
// // console.log("msgData", msgData);
// // console.log("content", content);
// // if (content !== "[DONE]") {
// // aiMessage.value += content;
// // updateLastAIMessage(aiMessage.value);
// // } else {
// // aiMessage.value = "";
// // abortController.value.abort();
// // abortController.value = new AbortController();
// // }
// // }
// },
// onerror(error) {
// ElMessage({
// message: "问答报错!",
// type: "warning"
// });
// abortController.value.abort();
// abortController.value = new AbortController();
// throw new Error(error);
// }
// }).catch(error => {
// ElMessage({
// message: "问答报错!",
// type: "warning"
// });
// abortController.value.abort();
// abortController.value = new AbortController();
// throw new Error(error);
// });
// try {
// const res = await getChecklistChat(params);
// if (res.detail.error) {
// console.log(res.detail.error.message);
// ElMessage.error(res.detail.error.message);
// }
// if (res.logs) {
// isLoading.value = false;
// const lastMessage = messages.value[messages.value.length - 1];
// if (lastMessage && lastMessage.type === "ai") {
// let newDocs = res.logs.map(item => {
// return item.detail + " " + formatDateTime(item.ts);
// });
// lastMessage.source = newDocs;
// scrollToBottom();
// }
// }
// if (res.choices && res.choices[0].delta.content) {
// isLoading.value = false;
// isCurAnswerMessage.value = true;
// let content = res.choices[0].delta.content;
// if (content === "[DONE]") {
// ElMessage.success("生成完成!");
// } else {
// aiMessage.value += content;
// updateLastAIMessage(aiMessage.value);
// }
// }
// } catch (error) {
// console.log("error", error);
// if (error.detail && error.detail.error) {
// console.log(res.detail.error.message);
// ElMessage.error(res.detail.error.message);
// }
// }
try {
const res = await getChat(params);
console.log("chat", res);
const response = await fetch("/checklistChat/langgraph/checklist/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(params)
});
// console.log("状态码:", response.status); // 200
// console.log("ok:", response.ok); // true
// console.log("headers:", [...response.headers.entries()]);
// 先以文本形式读取,看看实际内容
const rawText = await response.text();
// console.log("原始响应文本:", rawText);
// 尝试解析 JSON
const data = JSON.parse(rawText); // 可能在这里抛出错误
console.log("解析后的数据:", data);
clearInterval(loadingInterval);
isLoading.value = false;
console.log("data.logs:", data.logs);
console.log("data.choices:", data.choices);
if (data.logs) {
const lastMessage = messages.value[messages.value.length - 1];
if (lastMessage && lastMessage.type === "ai") {
let newDocs = data.logs.map(item => {
return item.detail + " " + formatDateTime(item.ts);
});
lastMessage.source = newDocs;
scrollToBottom();
}
}
if (data.choices && data.choices[0].message.content) {
isCurAnswerMessage.value = true;
let content = data.choices[0].message.content;
if (content === "[DONE]") {
ElMessage.success("生成完成!");
} else {
aiMessage.value += content;
updateLastAIMessage(aiMessage.value);
}
}
if (data.detail.error) {
console.log(data.detail.error.message);
// ElMessage.error(data.detail.error.message);
isCurAnswerMessage.value = true;
let content = "我们换个新话题吧!";
aiMessage.value += content;
updateLastAIMessage(aiMessage.value);
}
} catch (error) {
console.error(error);
console.error("catch 中的错误:", error);
}
};
......@@ -496,8 +726,12 @@ const sendMessage = async () => {
}
userInput.value = "";
await connectSSE(question);
// chat();
aiMessage.value = ""
if (curArea.value === "法案") {
await connectSSE(question);
} else {
chat(question);
}
};
const newChatTitle = ref(""); // 新对话
......
......@@ -21,7 +21,6 @@
<div class="right-title">
<img src="./assets/icon02.png" alt="">
<div class="tit">社交媒体</div>
<div class="more">更多 +</div>
</div>
<div class="right-main">
<div class="trump">
......
......@@ -6,7 +6,7 @@
<div class="left-top">
<img src="./assets/icon01.png" alt="" />
<div class="left-top-title">合作限制动态</div>
<span>查看详情 ></span>
<div class="more" @click="handleClickToDetail">查看详情 ></div>
</div>
<div class="left-center">
<img src="./assets/usImg.png" alt="" />
......@@ -167,12 +167,14 @@ const handleToMoreRiskSignal = () => {
top: 15px;
left: 23px;
}
span {
.more {
position: absolute;
height: 48px;
line-height: 48px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
position: absolute;
top: 19px;
top: 0;
right: 40px;
color: rgb(5, 95, 194);
cursor: pointer;
......
......@@ -45,14 +45,17 @@ const initChart = () => {
{
type: "wordCloud",
shape: props.shape,
width: '100%',
height: '100%',
// 其他形状你可以使用形状路径
// shape: 'circle', // 示例
// 或者自定义路径
gridSize: 20, // 网格大小,影响词间距。
sizeRange: [15, 25], // 定义词云中文字大小的范围
gridSize: 30, // 网格大小,影响词间距。
sizeRange: [15, 40], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 0,
drawOutOfBound: false, // 是否超出画布
shrinkToFit: true, // 是否自动缩小以适应容器
// 字体
textStyle: {
// normal: {
......
......@@ -117,7 +117,7 @@
</div>
<div class="title">{{ "最新科技政令" }}</div>
</div>
<div class="box1-header-right">
<div class="box1-header-right" @click="handleClickToDetail">
{{ "查看详情 >" }}
</div>
</div>
......@@ -239,7 +239,6 @@
<img src="./assets/images/box4-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
......
......@@ -47,8 +47,9 @@ defineProps({
<style scoped>
.message-bubble {
display: flex;
max-width: 600px;
margin: 20px 0;
max-width: 720px;
margin-top: 5px;
margin-bottom: 16px;
}
.avatar-container {
......@@ -71,7 +72,7 @@ defineProps({
.bubble {
background-color: rgba(246, 250, 255, 1);
border-radius: 12px;
padding: 12px 16px;
padding: 10px 16px;
position: relative;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
......@@ -80,24 +81,37 @@ defineProps({
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
margin-bottom: 5px;
}
.name {
font-weight: bold;
font-size: 14px;
color: #333;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
.meta {
font-size: 12px;
color: #999;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: right;
}
.bubble-content {
font-size: 14px;
line-height: 1.5;
color: #333;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
.triangle {
......
......@@ -41,7 +41,9 @@ defineProps({
}
.title-text {
font-size: 20px;
color: rgba(10, 18, 30, 1);
font-size: 32px;
font-family: Microsoft YaHei;
font-weight: bold;
margin-left: 20px;
white-space: nowrap;
......
......@@ -220,12 +220,6 @@
</el-col>
<el-col :span="12">
<custom-container title="社交媒体" :titleIcon="dialogIcon" height="450px">
<template #header-right>
<el-button type="primary" link>
{{ "更多 +" }}
</el-button>
</template>
<template #default>
<div class="dialog-list">
<!-- <MessageBubble
......@@ -570,12 +564,6 @@ import newsImg from "@/assets/images/news-img.png";
import { getHotBills, getBillsByType, getHylyList } from "@/api/home";
import headerIcon1 from "./assets/icons/header-icon1.png";
import headerIcon2 from "./assets/icons/header-icon2.png";
import headerIcon3 from "./assets/icons/header-icon3.png";
import headerIcon4 from "./assets/icons/header-icon4.png";
import headerIcon5 from "./assets/icons/header-icon5.png";
import getMultiLineChart from "./utils/multiLineChart";
import bill1 from "./assets/images/bill1.png";
......
......@@ -397,116 +397,6 @@ export function getMapOption() {
color: 'rgba(255, 77, 79, 1)'
}
}
}, {
name: '个人会员数量',
type: 'map',
geoIndex: 0,
tooltip: {
show: false
},
data: [{
name: '北京',
value: 2256
}, {
name: '天津',
value: 744
}, {
name: '上海',
value: 578
}, {
name: '重庆',
value: 806
}, {
name: '河北',
value: 432
}, {
name: '河南',
value: 590
}, {
name: '云南',
value: 132
}, {
name: '辽宁',
value: 487
}, {
name: '黑龙江',
value: 336
}, {
name: '湖南',
value: 295
}, {
name: '安徽',
value: 398
}, {
name: '山东',
value: 1055
}, {
name: '新疆',
value: 201
}, {
name: '江苏',
value: 795
}, {
name: '浙江',
value: 655
}, {
name: '江西',
value: 311
}, {
name: '湖北',
value: 993
}, {
name: '广西',
value: 261
}, {
name: '甘肃',
value: 349
}, {
name: '山西',
value: 273
}, {
name: '内蒙古',
value: 343
}, {
name: '陕西',
value: 319
}, {
name: '吉林',
value: 325
}, {
name: '福建',
value: 317
}, {
name: '贵州',
value: 275
}, {
name: '广东',
value: 1000
}, {
name: '青海',
value: 97
}, {
name: '西藏',
value: 18
}, {
name: '四川',
value: 601
}, {
name: '宁夏',
value: 126
}, {
name: '海南',
value: 186
}, {
name: '台湾',
value: 0
}, {
name: '香港',
value: 11
}, {
name: '澳门',
value: 0
}]
}]
};
return option
......
......@@ -60,7 +60,7 @@
<el-col :span="16">
<custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px">
<template #header-right>
<el-button type="primary" link>
<el-button type="primary" link @click="handleToDetail">
{{ "查看详情 >" }}
</el-button>
</template>
......@@ -171,12 +171,6 @@
</el-col>
<el-col :span="12">
<custom-container title="社交媒体" :titleIcon="dialogIcon" height="450px">
<template #header-right>
<el-button type="primary" link>
{{ "更多 +" }}
</el-button>
</template>
<template #default>
<div class="dialog-list">
<!-- <MessageBubble
......
......@@ -70,19 +70,19 @@
</div>
</div>
<div class="home-main-header-btn-box" v-show="!isShow">
<div class="btn" @click="handleToPosi('position1')">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn" @click="handleToPosi('position2')">
<div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">{{ "资讯要闻" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn" @click="handleToPosi('position3')">
<div class="btn" @click="scrollToTop('position3')">
<div class="btn-text">{{ "数据总览" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn" @click="handleToPosi('position4')">
<div class="btn" @click="scrollToTop('position4')">
<div class="btn-text">{{ "资源库" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
......@@ -204,7 +204,6 @@
<img src="./assets/images/box4-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
......@@ -377,7 +376,8 @@
<div class="item-text2">{{ item.area }}</div>
<div class="taglist">
<div class="tag1" style="width: 82px;"
v-for="val in item.tag"
v-for="val,idx in item.tag"
:key="idx"
:class="{tag2: val === '新能源',
tag3: val === '集成电路',
tag4: val === '生物科技',
......@@ -410,6 +410,7 @@ import { onMounted, ref, computed } from "vue";
import * as echarts from "echarts";
import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow";
import getBarChart from "./utils/barChart";
import getPieChart from "./utils/piechart";
......
......@@ -116,7 +116,7 @@
</div>
<div class="title">{{ "调查进展" }}</div>
</div>
<div class="box1-header-right">
<div class="box1-header-right" @click="handleClickToDetail('337')">
{{ "查看详情 >" }}
</div>
</div>
......@@ -253,7 +253,6 @@
<img src="./assets/images/header-message.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
......
......@@ -271,7 +271,7 @@ const totalDistribution = ref([
},
{
titlle: "投融资限制",
value: 80,
value: 66,
text: "119",
unit: "次",
change: "较上月+1",
......@@ -314,6 +314,15 @@ const totalDistribution = ref([
path: "/scientificFunding",
color: ["#FDE19A", "#FEECBD", "#FFFBE6", "#D68E16"]
},
{
titlle: "创新主体",
value: 89,
text: "89",
unit: "次",
change: "较上月+8",
path: "/innovationSubject",
color: ["#C9AAF0", "#DFCAF6", "#FAF1FF", "#531DAC"]
}
]);
const startIndex = ref(0);
......@@ -497,11 +506,11 @@ const handleClickItem = item => {
};
const swiper = ref(null);
const isOnSwiper = ref(true)
const isOnSwiper = ref(true);
const handleChangeSwiper = (val) => {
isOnSwiper.value = val
}
const handleChangeSwiper = val => {
isOnSwiper.value = val;
};
onMounted(() => {
swiper.value = setInterval(() => {
......
......@@ -193,7 +193,7 @@ export default {
.card {
position: absolute;
height: 180px;
width: 15vw;
width:320px;
padding: 8px 12px;
text-align: left;
cursor: pointer;
......
......@@ -2,7 +2,22 @@
<template>
<div class="content-main">
<!-- 面包屑 -->
<div class="content-title"><span>国家科技安全</span>> <span>中美博弈概览 </span></div>
<div class="content-title">
<span>国家科技安全</span>> <span>中美博弈概览 </span>
<div class="header-search-box">
<div class="header-search-left">
<div class="input-box">
<el-input v-model="searchText" style="width: 324px" />
</div>
<div class="icon">
<img src="./assets/images/search-icon.png" alt="" />
</div>
</div>
<div class="header-search-right" @click="handleToSearch">
<div class="header-img-box"><img src="./assets/images/search-btn.png" alt="" /></div>
</div>
</div>
</div>
<!-- 中美博弈最新动态内容-->
<div class="content-box">
<div class="title-text">中美博弈最新动态</div>
......@@ -14,7 +29,7 @@
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/overview-card-header-icon.png" />
<div class="item-header-text">机构动态</div>
<div class="item-header-more">更多 +</div>
<!-- <div class="item-header-more">更多 +</div> -->
</div>
<div class="item-header-divider"></div>
<div class="item-content">
......@@ -37,17 +52,27 @@
}}
</div>
</div>
<img class="item-card-content-title-image" :src="organizationNews[organizationNewsShow].image"
alt="" />
<img
class="item-card-content-title-image"
:src="organizationNews[organizationNewsShow].image"
alt=""
/>
</div>
<div class="item-header-divider"></div>
<div class="item-card-content-text">
{{ organizationNews[organizationNewsShow].content }}
</div>
<div style="display: flex;margin-top: 30px;">
<div class="item-card-content-tag" v-for="(tag, index) in organizationNews[organizationNewsShow].tag"
<div style="display: flex; margin-top: 30px">
<div
class="item-card-content-tag"
v-for="(tag, index) in organizationNews[organizationNewsShow].tag"
:key="index"
:style="{ color: tag.textColor, background: tag.color, border: `1px solid ${tag.textColor}` }">
:style="{
color: tag.textColor,
background: tag.color,
border: `1px solid ${tag.textColor}`
}"
>
{{ tag.text }}
</div>
</div>
......@@ -80,18 +105,22 @@
<div class="item left">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/waring-card-header-icon.png" />
<div class="item-header-text" style="background-color: #ce4f51">风险信号 <div class="num">{{ warningList.length
}}</div>
<div class="item-header-text" style="background-color: #ce4f51">
风险信号
<div class="num">{{ warningList.length }}</div>
</div>
</div>
<div class="item-header-divider"></div>
<div style="padding: 30px 23px; height: 400px">
<div class="waring-item" v-for="(item, index) in warningList" :key="index">
<div style="display: flex; height: 47px">
<div class="waring-status" :style="{
color: item.status === 0 ? '#CE4F51' : item.status === 1 ? '#FA8C16' : '#52C41A',
backgroundColor: item.status === 0 ? '#FFF1F0' : item.status === 1 ? '#FFF7E6' : '#F6FFED'
}">
<div
class="waring-status"
:style="{
color: item.status === 0 ? '#CE4F51' : item.status === 1 ? '#FA8C16' : '#52C41A',
backgroundColor: item.status === 0 ? '#FFF1F0' : item.status === 1 ? '#FFF7E6' : '#F6FFED'
}"
>
{{ item.status === 0 ? "特别重大" : item.status === 1 ? "重大风险" : "一般风险" }}
</div>
<div class="waring-text">
......@@ -113,8 +142,10 @@
<div class="item right">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/news-card-header-icon.png" />
<div class="item-header-text" style="background: rgba(255, 255, 255, 0.65); color: #055fc2">新闻资讯</div>
<div class="item-header-more" style="color: #055fc2; cursor: pointer;" @click="handleToMoreNews">更多 +</div>
<div class="item-header-text-1" style="color: #055fc2">新闻资讯</div>
<div class="item-header-more" style="color: #055fc2; cursor: pointer" @click="handleToMoreNews">
更多 +
</div>
</div>
<div class="item-header-divider"></div>
<div class="news-box">
......@@ -137,8 +168,7 @@
<div class="item right">
<div class="item-header">
<img class="item-header-icon" src="@/assets/images/icon/people-card-header-icon.png" />
<div class="item-header-text" style="background: rgba(255, 255, 255, 0.65); color: #055fc2">人物动态</div>
<div class="item-header-more" style="color: #055fc2">更多 +</div>
<div class="item-header-text-1" style="color: #055fc2">人物动态</div>
</div>
<div class="item-header-divider"></div>
<div class="character-box">
......@@ -174,7 +204,14 @@ import Thematicanalysis from "./component/Thematicanalysis.vue";
import ResourceSupport from "./component/ResourceSupport.vue";
import strengthComparison from "./component/strengthComparison.vue";
import router from "@/router";
import { color } from "echarts";
const searchText = ref("");
// 跳转到综合检索页面
const handleToSearch = () => {
const route = router.resolve("/comprehensiveSearch");
window.open(route.href, "_blank");
};
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
......@@ -188,7 +225,6 @@ const handleToMoreNews = () => {
window.open(route.href, "_blank");
};
const organizationNews = ref([
{
title: "美国白宫发布关于进一步延长TikTok执法宽限期的行政令",
......@@ -221,13 +257,13 @@ const organizationNews = ref([
{
color: "#F5222D",
textColor: "#FFF1F0",
borderColor: 'rgba(255, 163, 158, 1)',
borderColor: "rgba(255, 163, 158, 1)",
text: "人工智能"
},
{
color: "#E6F4FF",
textColor: "#1677FF",
borderColor: 'rgba(145, 202, 255, 1)',
borderColor: "rgba(145, 202, 255, 1)",
text: "通信网络"
}
]
......@@ -388,7 +424,7 @@ function changeOrganizationNews(type) {
: (organizationNewsShow.value = organizationNewsShow.value + 1);
}
}
onMounted(() => { });
onMounted(() => {});
</script>
<style lang="scss" scoped>
......@@ -413,6 +449,52 @@ onMounted(() => { });
background: url("../../assets/images/bg//header-bg.png");
box-sizing: border-box;
padding-left: 160px;
position: relative;
.header-search-box {
position: absolute;
top: 14px;
right: 160px;
display: flex;
gap: 12px;
justify-content: flex-end;
.header-search-left {
width: 360px;
height: 36px;
line-height: 36px;
border-radius: 4px;
background: rgba(255, 255, 255, 0.3);
display: flex;
.input-box {
width: 324px;
}
.icon {
width: 36px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
}
.header-search-right {
width: 36px;
height: 36px;
line-height: 36px;
// box-sizing: border-box;
border-radius: 4px;
background: rgba(255, 255, 255, 0.3);
cursor: pointer;
.header-img-box {
width: 19px;
height: 24px;
margin: 6px auto;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.content-box {
......@@ -470,6 +552,7 @@ onMounted(() => { });
height: 48px;
width: 100%;
display: flex;
position: relative;
.item-header-icon {
width: 20px;
......@@ -508,6 +591,15 @@ onMounted(() => { });
font-size: 14px;
}
}
.item-header-text-1 {
// width: 150px;
height: 48px;
line-height: 48px;
text-align: left;
font-weight: 700;
font-size: 20px;
font-family: Microsoft YaHei;
}
.item-header-num {
width: 30px;
......@@ -535,9 +627,10 @@ onMounted(() => { });
font-size: 16px;
line-height: 48px;
text-align: center;
margin-left: calc(100% - 200px);
width: 50px;
margin-left: calc(100% - 250px);
position: absolute;
top: 0;
right: 27px;
}
}
......@@ -905,4 +998,30 @@ onMounted(() => { });
}
}
}
:deep(.el-input__wrapper) {
box-shadow: none;
background: none;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
:deep(.el-input__wrapper.is-focus) {
box-shadow: none !important;
}
:deep(.el-input__inner::placeholder) {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
:deep(.el-input__inner) {
color: #fff;
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 400;
line-height: 34px;
}
</style>
......@@ -15,6 +15,7 @@
:style="{
backgroundColor: titleBackgroundColor,
color: titleColor,
fontSize: titleFontSize,
paddingLeft: titleTextAlign === 'left' ? '0px' : '20px'
}"
>
......@@ -31,7 +32,7 @@
</slot>
</div>
</div>
<div class="body">
<div class="body" :style="bodyStyle">
<slot name="default"> </slot>
</div>
</div>
......@@ -44,7 +45,7 @@ const emit = defineEmits(["moreClick"]);
defineProps({
titleBackgroundColor: {
type: String,
default: "red"
default: "transparent"
},
titleColor: {
type: String,
......@@ -69,6 +70,16 @@ defineProps({
headerHeight: {
type: String,
default: "48px"
},
titleFontSize: {
type: String,
default: "20px"
},
bodyStyle: {
type: Object,
default: function () {
return {};
}
}
});
function moreClick() {
......
......@@ -10,6 +10,26 @@
<template #icon>
<div class="icon icon1"></div>
</template>
<template #right>
<div class="panel1Header">
<div class="item" v-for="(item, index) in levelMapList.slice(1, levelMapList.length)" :key="index">
<div class="itemIcon" :style="{ backgroundColor: item.color[0], borderColor: item.color[1] }"></div>
<div class="itemName">
{{ item.name }}
</div>
</div>
</div>
</template>
<div class="panel1Body">
<Echarts :option="mapOption" height="100%" @chart-ready="echarsReady"></Echarts>
<div class="countryWrap">
<div class="item" v-for="(item, index) in mapData" :key="index">
<img :src="item.flag" alt="" class="itemIcon" />
<div class="itemName">{{ item.name }}</div>
<div class="itemNumber">{{ item.children.length }}个</div>
</div>
</div>
</div>
</CardCustom>
<CardCustom
@more-click="moreClick"
......@@ -20,13 +40,15 @@
<template #icon>
<div class="icon icon1"></div>
</template>
<div class="item" v-for="(item, index) in securityExpressList" :key="index">
<span class="itemLevel" :class="levelMap[item.level].class">
{{ levelMap[item.level].text }}
</span>
<div class="itemText">{{ item.title }}</div>
<span class="itemTime">{{ item.time }}</span>
<span class="itemFlag" :style="{ backgroundImage: 'url(' + item.flag + ')' }"></span>
<div class="panel2">
<div class="item" v-for="(item, index) in securityExpressList" :key="index">
<span class="itemLevel" :class="levelMap[item.level].class">
{{ levelMap[item.level].text }}
</span>
<div class="itemText">{{ item.title }}</div>
<span class="itemTime">{{ item.time }}</span>
<span class="itemFlag" :style="{ backgroundImage: 'url(' + item.flag + ')' }"></span>
</div>
</div>
</CardCustom>
</el-row>
......@@ -150,16 +172,561 @@
<script setup>
import CardCustom from "../components/CardCustom.vue";
import PieProgress from "../components/PieProgress.vue";
import Echarts from "@/components/Chart/index.vue";
import { getMapOption } from "../utils/charts";
import flag1 from "../assets/img/flag1.png";
import flag2 from "../assets/img/flag2.png";
import flag3 from "../assets/img/flag3.png";
import mapFlag1 from "../assets/img/mapFlag1.png";
import mapFlag2 from "../assets/img/mapFlag2.png";
import mapFlag3 from "../assets/img/mapFlag3.png";
import mapFlag4 from "../assets/img/mapFlag4.png";
import mapFlag5 from "../assets/img/mapFlag5.png";
import mapFlag6 from "../assets/img/mapFlag6.png";
import { ref } from "vue";
const levelMap = {
L1: { text: "特别重大", class: "level1" },
L2: { text: "重大风险", class: "level2" },
L3: { text: "一般风险", class: "level3" }
};
const echarsReady = mycharts => {
mycharts.on("click", function (params) {
// 1. 判断点击的是否是geo组件
if (params.componentType === "geo") {
console.log("点击了地图区域:", params.name); // 可获取地区名称[citation:1]
// 2. 获取鼠标点击的像素坐标
// 注意:高版本ECharts中,event可能挂载在不同位置,建议用 params.event 获取[citation:5]
const pixelPoint = [params.event.offsetX, params.event.offsetY];
// 3. 关键:将像素坐标转换为地理坐标 (经度, 纬度)
// 第一个参数 'geo' 指定坐标系,第二个参数是像素坐标数组[citation:9]
const geoCoords = mycharts.convertFromPixel("geo", pixelPoint);
console.log("对应的经纬度坐标:", geoCoords); // 输出格式如 [116.40, 39.90]
}
});
};
let mapData = [
{
name: "加拿大",
flag: mapFlag1,
children: [
{
value: 12,
level: 1,
name: "加拿大1",
text: "",
position: [-114.92625574436123, 60.97139707757613]
},
{
value: 12,
level: 1,
name: "加拿大2",
text: "",
position: [-122.66033268519817, 64.94019971826877]
},
{
value: 12,
level: 1,
name: "加拿大3",
text: "",
position: [-95.38753505172055, 65.24549222909128]
}
]
},
{
name: "英国",
flag: mapFlag2,
children: [
{
value: 12,
level: 1,
name: "英国1",
text: "",
position: [-1.5492917852477053, 52.764489718498275]
},
{
value: 12,
level: 1,
name: "英国2",
text: "",
position: [-2.698117404891553, 54.74388521180356]
},
{
value: 12,
level: 1,
name: "英国3",
text: "",
position: [-0.6799102352469557, 53.90555300287426]
},
{
value: 12,
level: 1,
name: "英国4",
text: "",
position: [0.46891538439689207, 52.83435073590905]
},
{
value: 12,
level: 1,
name: "英国5",
text: "",
position: [-3.722745660249581, 53.13708181135574]
},
{
value: 12,
level: 1,
name: "英国6",
text: "",
position: [-4.095337753107044, 51.99601852697975]
}
]
},
{
name: "欧盟",
flag: mapFlag3,
children: [
{
value: 12,
level: 1,
name: "欧盟1",
text: "",
position: [11.724105556570102, 48.58464196103773]
},
{
value: 12,
level: 1,
name: "欧盟2",
text: "",
position: [-0.7100210266255225, 44.00223755214452]
},
{
value: 12,
level: 1,
name: "欧盟3",
text: "",
position: [-0.7100210266255225, 45.12774038941654]
},
{
value: 12,
level: 1,
name: "欧盟4",
text: "",
position: [-0.8172117730323798, 47.459139123765716]
},
{
value: 12,
level: 5,
name: "欧盟5",
text: "",
position: [0.14750494462934682, 49.147393379673744]
},
{
value: 12,
level: 5,
name: "欧盟6",
text: "",
position: [2.3985106191733827, 50.3532892767509]
},
{
value: 12,
level: 5,
name: "欧盟7",
text: "",
position: [4.542325547310561, 49.870930917920035]
},
{
value: 12,
level: 5,
name: "欧盟8",
text: "",
position: [6.793331221854594, 48.906214200258304]
},
{
value: 12,
level: 1,
name: "欧盟9",
text: "",
position: [9.901862867653499, 45.36891956883197]
},
{
value: 13,
level: 3,
name: "欧盟10",
text: "",
position: [8.937146149991769, 46.97678076493485]
},
{
value: 13,
level: 3,
name: "欧盟11",
text: "",
position: [10.545007346094657, 49.468965618894316]
},
{
value: 13,
level: 3,
name: "欧盟12",
text: "",
position: [14.296683470334713, 49.468965618894316]
},
{
value: 13,
level: 3,
name: "欧盟13",
text: "",
position: [12.79601302063869, 47.217959944350284]
},
{
value: 13,
level: 3,
name: "欧盟14",
text: "",
position: [10.437816599687793, 48.58464196103773]
},
{
value: 13,
level: 3,
name: "欧盟15",
text: "",
position: [10.652198092501514, 51.719971293438356]
},
{
value: 13,
level: 3,
name: "欧盟16",
text: "",
position: [15.047018695182722, 49.79053785811488]
},
{
value: 13,
level: 3,
name: "欧盟17",
text: "",
position: [10.759388838908372, 53.40822554934638]
},
{
value: 13,
level: 3,
name: "欧盟18",
text: "",
position: [14.832637202369007, 48.42385584142743]
}
]
},
{
name: "韩国",
flag: mapFlag4,
children: [
{
value: 40,
level: 1,
name: "韩国1",
text: "",
position: [127.6671802588885, 35.6152933447435]
},
{
value: 40,
level: 1,
name: "韩国2",
text: "",
position: [127.6671802588885, 37.49854900651488]
},
{
value: 40,
level: 1,
name: "韩国3",
text: "",
position: [128.92268403340273, 37.14543856993275]
},
{
value: 40,
level: 3,
name: "韩国4",
text: "",
position: [128.92268403340273, 36.43921769676848]
},
{
value: 40,
level: 1,
name: "韩国5",
text: "",
position: [128.13799417433134, 35.49758986588279]
},
{
value: 40,
level: 3,
name: "韩国6",
text: "",
position: [127.10764322693156, 35.25464166802588]
}
]
},
{
name: "日本",
flag: mapFlag5,
children: [
{
value: 40,
level: 1,
name: "日本1",
text: "",
position: [142.8374359085882, 43.947802361746696]
},
{
value: 40,
level: 1,
name: "日本2",
text: "",
position: [141.18555679600132, 42.96971604508341]
},
{
value: 40,
level: 2,
name: "日本3",
text: "",
position: [141.09861579007568, 41.14395492064528]
},
{
value: 40,
level: 2,
name: "日本4",
text: "",
position: [141.09861579007568, 39.709428322872455]
},
{
value: 40,
level: 1,
name: "日本5",
text: "",
position: [140.05532371896817, 38.7965477606534]
},
{
value: 40,
level: 5,
name: "日本6",
text: "",
position: [139.96838271304256, 37.36202116288057]
},
{
value: 40,
level: 1,
name: "日本7",
text: "",
position: [138.0556805826788, 36.44914060066151]
},
{
value: 40,
level: 5,
name: "日本8",
text: "",
position: [136.49074247601754, 35.01461400288869]
}
]
},
{
name: "美国",
flag: mapFlag6,
children: [
{
value: 40,
level: 1,
name: "美国1",
text: "",
position: [-120.95330892639737, 46.048538366525065]
},
{
value: 40,
level: 5,
name: "美国2",
text: "",
position: [-117.06095626240344, 45.00594390295526]
},
{
value: 40,
level: 1,
name: "美国3",
text: "",
position: [-119.56318297497097, 42.08667940495981]
},
{
value: 40,
level: 1,
name: "美国4",
text: "",
position: [-119.56318297497097, 39.375933799678315]
},
{
value: 40,
level: 3,
name: "美国5",
text: "",
position: [-118.72910740411513, 37.49926376525268]
},
{
value: 40,
level: 3,
name: "美国6",
text: "",
position: [-115.67083031097702, 35.414074838113066]
},
{
value: 40,
level: 3,
name: "美国7",
text: "",
position: [-109.55427612470085, 35.20555594539911]
},
{
value: 40,
level: 3,
name: "美国8",
text: "",
position: [-104.2717975092805, 34.162961481829306]
},
{
value: 40,
level: 3,
name: "美国9",
text: "",
position: [-101.21352041614242, 32.49481034011762]
},
{
value: 40,
level: 3,
name: "美国10",
text: "",
position: [-98.71129370357488, 29.99258362755009]
},
{
value: 40,
level: 3,
name: "美国11",
text: "",
position: [-96.48709218129264, 31.24369698383387]
},
{
value: 40,
level: 5,
name: "美国12",
text: "",
position: [-92.31671432701341, 32.91184812554555]
},
{
value: 40,
level: 3,
name: "美国13",
text: "",
position: [-95.93104180072207, 38.124820443394576]
},
{
value: 40,
level: 5,
name: "美国14",
text: "",
position: [-100.93549522585714, 37.70778265796665]
},
{
value: 40,
level: 3,
name: "美国15",
text: "",
position: [-105.38389827042164, 45.00594390295528]
},
{
value: 40,
level: 1,
name: "美国16",
text: "",
position: [-92.87276470758401, 43.963349439385496]
},
{
value: 40,
level: 3,
name: "美国17",
text: "",
position: [-89.53646242416063, 41.04408494139004]
},
{
value: 40,
level: 1,
name: "美国18",
text: "",
position: [-81.75175709617281, 37.49926376525271]
},
{
value: 40,
level: 1,
name: "美国19",
text: "",
position: [-83.4199082378845, 35.622593730827056]
},
{
value: 40,
level: 1,
name: "美国20",
text: "",
position: [-88.70238685330483, 33.32888591097349]
},
{
value: 40,
level: 2,
name: "美国21",
text: "",
position: [-75.63520290989662, 42.29519829767381]
},
{
value: 40,
level: 2,
name: "美国22",
text: "",
position: [-74.80112733904078, 43.546311653957574]
},
{
value: 40,
level: 2,
name: "美国23",
text: "",
position: [-72.85495100704381, 44.17186833209945]
},
{
value: 40,
level: 2,
name: "美国24",
text: "",
position: [-69.79667391390572, 45.214462795669256]
}
]
}
];
const levelMapList = [
{},
{
name: "特别重大风险",
color: ["rgba(255, 77, 79, 1)", "rgba(255, 163, 158, 1)"]
},
{
name: "重大风险",
color: ["rgba(255, 169, 64, 1)", "rgba(255, 213, 145, 1)"]
},
{
name: "较大风险",
color: ["rgba(250, 219, 20, 1)", "rgba(255, 251, 143, 1)"]
},
{
name: "一般风险",
color: ["rgba(64, 150, 255, 1)", "rgba(145, 202, 255, 1)"]
},
{
name: "几乎无风险",
color: ["rgba(54, 207, 201, 1)", "rgba(135, 232, 222, 1)"]
}
];
const mapOption = getMapOption(mapData, levelMapList);
const securityExpressList = ref([
{
title: "美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实",
......@@ -478,34 +1045,103 @@ function moreClick(n) {
.icon4 {
background-image: url("../assets/img/icon4.png");
}
.item {
.panel1Header {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 7px;
}
.itemLevel {
width: 40px;
height: 40px;
border-radius: 20px;
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 14px;
padding: 6px 4px;
text-align: center;
margin-right: 5px;
gap: 20px;
padding-right: 27px;
.item {
display: flex;
align-items: center;
gap: 12px;
.itemIcon {
width: 12px;
height: 12px;
border-radius: 6px;
border-width: 2px;
border-style: solid;
}
.itemName {
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
}
}
.itemTime {
color: rgba(132, 136, 142, 1);
.panel1Body {
position: relative;
height: 100%;
.countryWrap {
position: absolute;
bottom: 8px;
left: 0;
right: 0;
width: 782px;
margin: 0 auto;
display: flex;
gap: 10px;
overflow-x: auto;
.item {
display: flex;
align-items: center;
height: 42px;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 21px;
background: rgba(255, 255, 255, 0.8);
color: rgba(5, 95, 194, 1);
font-size: 16px;
font-weight: 700;
line-height: 24px;
padding-left: 12px;
padding-right: 12px;
flex-shrink: 0;
.itemIcon {
width: 24px;
height: 24px;
margin-right: 10px;
}
.itemName {
}
.itemNumber {
}
}
}
}
.itemFlag {
width: 20px;
height: 20px;
background-size: cover;
background-repeat: no-repeat;
margin-left: 10px;
.panel2 {
height: 100%;
display: flex;
flex-direction: column;
.item {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 7px;
.itemLevel {
width: 40px;
height: 40px;
border-radius: 20px;
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 14px;
padding: 6px 4px;
text-align: center;
margin-right: 5px;
}
.itemTime {
color: rgba(132, 136, 142, 1);
}
.itemFlag {
width: 20px;
height: 20px;
background-size: cover;
background-repeat: no-repeat;
margin-left: 10px;
}
}
}
.itemTrends {
display: flex;
flex-direction: row;
......
<template>
<div class="wrap">
<el-row>
<CardCustom
@more-click="moreClick"
title="热门数据"
title-color="rgba(5, 95, 194, 1)"
title-text-align="left"
title-font-size="16px"
:style="{ width: '520px', height: '460px' }"
:body-style="{ padding: 0 }"
>
<template #icon>
<div class="icon icon5"></div>
</template>
<template #right>
<div></div>
</template>
<div class="panel1Body">
<div class="item" v-for="(item, index) in panel1Data" :key="index">
<div class="number" :class="getClass(index + 1)">{{ index + 1 }}</div>
<div class="title">{{ item.title }}</div>
<div class="type">{{ item.type }}</div>
</div>
</div>
</CardCustom>
<CardCustom
@more-click="moreClick"
title="数据分布"
title-color="rgba(5, 95, 194, 1)"
title-text-align="left"
title-font-size="16px"
:style="{ width: '1064px', height: '460px', marginLeft: '14px' }"
>
<template #icon>
<div class="icon icon3"></div>
</template>
<div class="panel2">
<Echarts :option="mapOption" height="100%" @chart-ready="echarsReady"></Echarts>
</div>
</CardCustom>
</el-row>
<el-card class="gap">
<el-row>
<div class="panel3"></div>
</el-row>
</el-card>
<el-row class="gap">
<CardCustom
@more-click="moreClick"
title="科技动态"
:style="{ width: '792px', height: '360px' }"
title-background-color="rgba(10, 87, 166, 1)"
line-color="rgba(10, 87, 166, 1)"
>
<template #icon>
<div class="icon icon2"></div>
</template>
<div class="itemTrends" v-for="(item, index) in trendsList" :key="index">
<span class="itemTrendsIcon"> </span>
<div class="itemTrendsText">{{ item.title }}</div>
<span class="itemTrendsTime">{{ item.time }}</span>
</div>
</CardCustom>
<CardCustom
@more-click="moreClick"
title="科技政策"
:style="{ width: '792px', height: '360px', marginLeft: '16px' }"
title-background-color="rgba(10, 87, 166, 1)"
line-color="rgba(10, 87, 166, 1)"
>
<template #icon>
<div class="icon icon3"></div>
</template>
<div class="itemTrends" v-for="(item, index) in policyList" :key="index">
<span class="itemTrendsIcon"> </span>
<div class="itemTrendsText">{{ item.title }}</div>
<span class="itemTrendsTime">{{ item.time }}</span>
</div>
</CardCustom>
</el-row>
<div class="gap">
<el-row class="cardContainer">
<div class="itemCard">
<span class="itemCardIcon itemCardIcon1"></span>
<div class="itemCardTitle">业务协同</div>
</div>
<div class="itemCard">
<span class="itemCardIcon itemCardIcon2"></span>
<div class="itemCardTitle">专题研判</div>
</div>
<div class="itemCard">
<span class="itemCardIcon itemCardIcon3"></span>
<div class="itemCardTitle">数据直报</div>
</div>
<div class="itemCard">
<span class="itemCardIcon itemCardIcon4"></span>
<div class="itemCardTitle">专家库</div>
</div>
</el-row>
</div>
<el-row class="gap">
<CardCustom
@more-click="moreClick"
title="最新报告"
:style="{ width: '1600px', height: '360px' }"
title-background-color="rgba(10, 87, 166, 1)"
line-color="rgba(10, 87, 166, 1)"
>
<template #icon>
<div class="icon icon4"></div>
</template>
<template #right>
<div class="moreWrap">
<el-button text @click="moreClick" :style="{ marginLeft: '515px' }">
<span class="moreText">更多</span>
<el-icon :size="14"> <Plus /> </el-icon>
</el-button>
<el-button text @click="moreClick">
<span class="moreText">换一批</span>
<span class="shuaxinIcon"></span>
</el-button>
</div>
</template>
<el-row>
<div :style="{ width: '750px' }">
<div class="itemTrends" v-for="(item, index) in policyList" :key="index">
<span class="itemTrendsIcon"> </span>
<div class="itemTrendsText">{{ item.title }}</div>
<span class="itemTrendsTime">{{ item.time }}</span>
</div>
</div>
<div class="CardCustomRight">
<div class="itemCard1" v-for="item in 3">
<div class="itemCard1Img">
<div class="itemCard1Footer">国内外技术创新合作模式探索与实践</div>
</div>
</div>
</div>
</el-row>
</CardCustom>
</el-row>
<el-row class="gap spaceBetween">
<el-card v-for="(item, index) in catdList" class="itemCard2" :key="index">
<div class="itemCard2Line" :style="{ backgroundColor: item.bgColor }"></div>
<div class="itemCard2Container">
<div class="itemCard2BigTextWrap" :style="{ color: item.bgColor }">
{{ item.title }}
</div>
<div class="itemCard2TextWrap" v-for="(itemText, inde) in item.list" :key="index">
<div class="temCard2Title">{{ itemText.title }}</div>
<div class="temCard2Text">{{ itemText.text }}</div>
</div>
</div>
</el-card>
</el-row>
</div>
</template>
<script setup>
import CardCustom from "../components/CardCustom.vue";
import PieProgress from "../components/PieProgress.vue";
import Echarts from "@/components/Chart/index.vue";
import { getMapOption } from "../utils/charts";
import flag1 from "../assets/img/flag1.png";
import flag2 from "../assets/img/flag2.png";
import flag3 from "../assets/img/flag3.png";
import mapFlag1 from "../assets/img/mapFlag1.png";
import mapFlag2 from "../assets/img/mapFlag2.png";
import mapFlag3 from "../assets/img/mapFlag3.png";
import mapFlag4 from "../assets/img/mapFlag4.png";
import mapFlag5 from "../assets/img/mapFlag5.png";
import mapFlag6 from "../assets/img/mapFlag6.png";
import { ref } from "vue";
const panel2Data = [
{
title: "H.R.1-119th-大而美法案",
type: "科技法案"
},
{
title: "欧盟单方面宣布对中国电动汽车加征反补贴...",
type: "媒体报道"
},
{
title: "禁止在中国建设半导体产能",
type: "总统政令"
},
{
title: "2025年实体清单",
type: "实体清单"
},
{
title: "2025年度中美贸易统计公报",
type: "统计公报"
},
{
title: "生物科技法案",
type: "科技法案"
},
{
title: "阻止中俄法案",
type: "科技法案"
},
{
title: "美国密歇根大学终止与上海交通大学的长期...",
type: "媒体报道"
},
{
title: "禁止卫星出口至中国",
type: "智库报告"
},
{
title: "禁购华为设备",
type: "社交媒体贴文"
}
];
const getClass = number => {
if (number === 1) {
return "one";
} else if (number === 2) {
return "two";
} else if (number === 3) {
return "three";
} else {
return "";
}
};
const panel3Data = [
{
id: 1,
name: "科研学术",
number: "1135"
},
{
id: 2,
name: "政策法规",
number: "2431"
},
{
id: 3,
name: "人才教育",
number: "4652"
},
{
id: 4,
name: "科研项目",
number: "1325"
},
{
id: 5,
name: "贸易投资",
number: "9846"
},
{
id: 6,
name: "企业产业",
number: "955"
},
{
id: 7,
name: "媒体智库",
number: "1135"
},
{
id: 8,
name: "安全治理",
number: "1091"
}
];
const panel3ActiveId = ref(panel3Data[0].id);
const panel3SetActiveId = id => {
panel3ActiveId.value = id;
};
const securityExpressList = ref([
{
title: "美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实美国新增出口管制,52家中国科技实",
level: "L1",
time: "一天前",
flag: flag1
},
{
title: "美国加强对华AI芯片出口限制,考虑制...",
level: "L1",
time: "一天前",
flag: flag1
},
{
title: "日本出台《半导体材料出口管制令》...",
level: "L1",
time: "一天前",
flag: flag2
},
{
title: "日本对GAAFET技术、EUV光刻设备等...",
level: "L1",
time: "一天前",
flag: flag2
},
{
title: "欧盟签署协议限制高端AI芯片对华出口",
level: "L2",
time: "一天前",
flag: flag3
},
{
title: "欧盟第18轮制裁中首次将3家中资企业...",
level: "L2",
time: "一天前",
flag: flag3
},
{
title: "美国发布《保障信息和通信技术与服务...",
level: "L2",
time: "一天前",
flag: flag1
},
{
title: "日本将42家中国实体列入出口管制“...",
level: "L3",
time: "一天前",
flag: flag2
},
{
title: "美国政府放慢向英伟达和超威等芯片...",
level: "L3",
time: "一天前",
flag: flag1
},
{
title: "七国集团成员国就人工智能发表了以...",
level: "L3",
time: "一天前",
flag: flag3
}
]);
const trendsList = ref([
{
title: "韩研制用于存内计算的小型低功耗神经形态模块",
time: "08-16"
},
{
title: "中国科学院大学等在有机太阳能电池领域取得重要突破",
time: "08-16"
},
{
title: "德国于利希研究中心成功制造并实验验证全球首个二维半金属材料",
time: "08-16"
},
{
title: "浙江大学开发“女娲”AI模型,精准预测基因组调控序列",
time: "08-16"
},
{
title: "我国基于碳量子点材料制备出高效低成本有机太阳能电池",
time: "08-16"
},
{
title: "谷歌Gemini 2.5系列模型更新,实现高速推理与极致性价比",
time: "08-16"
},
{
title: "上海理工大学联合杜克大学在AI赋能仿生视觉技术领域实现突破",
time: "08-16"
}
]);
const policyList = ref([
{
title: "美国发布《2025财年国防授权法案》,拨款替换华为、中兴设备;禁止国防...",
time: "08-16"
},
{
title: "美国发布对华投资限制新规,限制美资在半导体、AI、量子技术等领域的对...",
time: "08-16"
},
{
title: "欧盟发布《网络弹性法案》(CRA),要求数字产品全生命周期安全合规,...",
time: "08-16"
},
{
title: "欧盟发布对外投资审查建议,要求成员国审查在半导体、AI、量子技术等领...",
time: "08-16"
},
{
title: "日本出台《半导体出口管制修正》加强对十余种半导体相关物项的出口管制...",
time: "08-16"
},
{
title: "日本拟出台“许可制”,限制外国留学生(特别提及中国)学习半导体、机...",
time: "08-16"
},
{
title: "日本通过并实施《经济安全保障推进法案》相关措施",
time: "08-16"
}
]);
const List = ref([
{
title: "当月/总数",
titleSub: "较上月+4",
progress: 90,
slope: "add",
total: 8,
current: 7
},
{
title: "人工智能",
titleSub: "较上月+4",
progress: 50,
slope: "add",
total: 26,
current: 3
},
{
title: "生物技术",
titleSub: "较上月+4",
progress: 60,
slope: "add",
total: 13,
current: 3
},
{
title: "航空航天",
titleSub: "较上月+4",
progress: 40,
slope: "add",
total: 15,
current: 3
},
{
title: "新一代信息技术",
titleSub: "较上月+4",
progress: 50,
slope: "add",
total: 12,
current: 3
},
{
title: "量子科技",
titleSub: "较上月+4",
progress: 20,
slope: "add",
total: 8,
current: 3
},
{
title: "新能源",
titleSub: "较上月+4",
progress: 90,
slope: "add",
total: 18,
current: 3
},
{
title: "集成电路",
titleSub: "较上月+4",
progress: 20,
slope: "add",
total: 16,
current: 3
},
{
title: "海洋",
titleSub: "较上月+4",
progress: 50,
slope: "add",
total: 8,
current: 3
},
{
title: "先进制造",
titleSub: "较上月+4",
progress: 50,
slope: "add",
total: 15,
current: 3
},
{
title: "新材料",
titleSub: "较上月+4",
progress: 50,
slope: "add",
total: 8,
current: 3
}
]);
const catdList = ref([
{
title: "数据资源管理",
bgColor: "rgba(206, 79, 81, 1)",
list: [
{
title: "数据资源目录",
text: "平台各类数据资源汇总导航"
},
{
title: "数据统计分析",
text: "查看资源发布量、各部门资源注册情况"
},
{
title: "信息空间",
text: "对数据资源的全生命周期进行管理"
}
]
},
{
title: "信息发布与管理",
bgColor: "rgba(19, 168, 168, 1)",
list: [
{
title: "信息编辑",
text: "信息的内容导入、格式编辑"
},
{
title: "信息审核",
text: "发布前内容自动审核、词库屏蔽"
},
{
title: "信息发布",
text: "提供点到点以及点到面的消息发送"
}
]
},
{
title: "应用支撑平台",
bgColor: "rgba(250, 140, 22, 1)",
list: [
{
title: "应用功能目录",
text: "快速访问和使用系统功能"
},
{
title: "应用工具目录",
text: "各项应用工具的使用方法和应用场景"
},
{
title: "应用功能与工具管理",
text: "实现功能及工具快捷访问配置入口"
}
]
},
{
title: "后台服务管理",
bgColor: "rgba(10, 87, 166, 1)",
list: [
{
title: "界面配置管理",
text: "支持界面布局、样式定制化修改"
},
{
title: "数据接口管理",
text: "实现数据接口的访问调用、权限控制等"
},
{
title: "系统配置管理",
text: "支持各分系统配置的定制与调整"
}
]
}
]);
const echarsReady = mycharts => {
mycharts.on("click", function (params) {
// 1. 判断点击的是否是geo组件
if (params.componentType === "geo") {
console.log("点击了地图区域:", params.name); // 可获取地区名称[citation:1]
// 2. 获取鼠标点击的像素坐标
// 注意:高版本ECharts中,event可能挂载在不同位置,建议用 params.event 获取[citation:5]
const pixelPoint = [params.event.offsetX, params.event.offsetY];
// 3. 关键:将像素坐标转换为地理坐标 (经度, 纬度)
// 第一个参数 'geo' 指定坐标系,第二个参数是像素坐标数组[citation:9]
const geoCoords = mycharts.convertFromPixel("geo", pixelPoint);
console.log("对应的经纬度坐标:", geoCoords); // 输出格式如 [116.40, 39.90]
}
});
};
let mapData = [
{
name: "加拿大",
flag: mapFlag1,
children: [
{
value: 12,
level: 1,
name: "加拿大1",
text: "",
position: [-114.92625574436123, 60.97139707757613]
},
{
value: 12,
level: 1,
name: "加拿大2",
text: "",
position: [-122.66033268519817, 64.94019971826877]
},
{
value: 12,
level: 1,
name: "加拿大3",
text: "",
position: [-95.38753505172055, 65.24549222909128]
}
]
},
{
name: "英国",
flag: mapFlag2,
children: [
{
value: 12,
level: 1,
name: "英国1",
text: "",
position: [-1.5492917852477053, 52.764489718498275]
},
{
value: 12,
level: 1,
name: "英国2",
text: "",
position: [-2.698117404891553, 54.74388521180356]
},
{
value: 12,
level: 1,
name: "英国3",
text: "",
position: [-0.6799102352469557, 53.90555300287426]
},
{
value: 12,
level: 1,
name: "英国4",
text: "",
position: [0.46891538439689207, 52.83435073590905]
},
{
value: 12,
level: 1,
name: "英国5",
text: "",
position: [-3.722745660249581, 53.13708181135574]
},
{
value: 12,
level: 1,
name: "英国6",
text: "",
position: [-4.095337753107044, 51.99601852697975]
}
]
},
{
name: "欧盟",
flag: mapFlag3,
children: [
{
value: 12,
level: 1,
name: "欧盟1",
text: "",
position: [11.724105556570102, 48.58464196103773]
},
{
value: 12,
level: 1,
name: "欧盟2",
text: "",
position: [-0.7100210266255225, 44.00223755214452]
},
{
value: 12,
level: 1,
name: "欧盟3",
text: "",
position: [-0.7100210266255225, 45.12774038941654]
},
{
value: 12,
level: 1,
name: "欧盟4",
text: "",
position: [-0.8172117730323798, 47.459139123765716]
},
{
value: 12,
level: 5,
name: "欧盟5",
text: "",
position: [0.14750494462934682, 49.147393379673744]
},
{
value: 12,
level: 5,
name: "欧盟6",
text: "",
position: [2.3985106191733827, 50.3532892767509]
},
{
value: 12,
level: 5,
name: "欧盟7",
text: "",
position: [4.542325547310561, 49.870930917920035]
},
{
value: 12,
level: 5,
name: "欧盟8",
text: "",
position: [6.793331221854594, 48.906214200258304]
},
{
value: 12,
level: 1,
name: "欧盟9",
text: "",
position: [9.901862867653499, 45.36891956883197]
},
{
value: 13,
level: 3,
name: "欧盟10",
text: "",
position: [8.937146149991769, 46.97678076493485]
},
{
value: 13,
level: 3,
name: "欧盟11",
text: "",
position: [10.545007346094657, 49.468965618894316]
},
{
value: 13,
level: 3,
name: "欧盟12",
text: "",
position: [14.296683470334713, 49.468965618894316]
},
{
value: 13,
level: 3,
name: "欧盟13",
text: "",
position: [12.79601302063869, 47.217959944350284]
},
{
value: 13,
level: 3,
name: "欧盟14",
text: "",
position: [10.437816599687793, 48.58464196103773]
},
{
value: 13,
level: 3,
name: "欧盟15",
text: "",
position: [10.652198092501514, 51.719971293438356]
},
{
value: 13,
level: 3,
name: "欧盟16",
text: "",
position: [15.047018695182722, 49.79053785811488]
},
{
value: 13,
level: 3,
name: "欧盟17",
text: "",
position: [10.759388838908372, 53.40822554934638]
},
{
value: 13,
level: 3,
name: "欧盟18",
text: "",
position: [14.832637202369007, 48.42385584142743]
}
]
},
{
name: "韩国",
flag: mapFlag4,
children: [
{
value: 40,
level: 1,
name: "韩国1",
text: "",
position: [127.6671802588885, 35.6152933447435]
},
{
value: 40,
level: 1,
name: "韩国2",
text: "",
position: [127.6671802588885, 37.49854900651488]
},
{
value: 40,
level: 1,
name: "韩国3",
text: "",
position: [128.92268403340273, 37.14543856993275]
},
{
value: 40,
level: 3,
name: "韩国4",
text: "",
position: [128.92268403340273, 36.43921769676848]
},
{
value: 40,
level: 1,
name: "韩国5",
text: "",
position: [128.13799417433134, 35.49758986588279]
},
{
value: 40,
level: 3,
name: "韩国6",
text: "",
position: [127.10764322693156, 35.25464166802588]
}
]
},
{
name: "日本",
flag: mapFlag5,
children: [
{
value: 40,
level: 1,
name: "日本1",
text: "",
position: [142.8374359085882, 43.947802361746696]
},
{
value: 40,
level: 1,
name: "日本2",
text: "",
position: [141.18555679600132, 42.96971604508341]
},
{
value: 40,
level: 2,
name: "日本3",
text: "",
position: [141.09861579007568, 41.14395492064528]
},
{
value: 40,
level: 2,
name: "日本4",
text: "",
position: [141.09861579007568, 39.709428322872455]
},
{
value: 40,
level: 1,
name: "日本5",
text: "",
position: [140.05532371896817, 38.7965477606534]
},
{
value: 40,
level: 5,
name: "日本6",
text: "",
position: [139.96838271304256, 37.36202116288057]
},
{
value: 40,
level: 1,
name: "日本7",
text: "",
position: [138.0556805826788, 36.44914060066151]
},
{
value: 40,
level: 5,
name: "日本8",
text: "",
position: [136.49074247601754, 35.01461400288869]
}
]
},
{
name: "美国",
flag: mapFlag6,
children: [
{
value: 40,
level: 1,
name: "美国1",
text: "",
position: [-120.95330892639737, 46.048538366525065]
},
{
value: 40,
level: 5,
name: "美国2",
text: "",
position: [-117.06095626240344, 45.00594390295526]
},
{
value: 40,
level: 1,
name: "美国3",
text: "",
position: [-119.56318297497097, 42.08667940495981]
},
{
value: 40,
level: 1,
name: "美国4",
text: "",
position: [-119.56318297497097, 39.375933799678315]
},
{
value: 40,
level: 3,
name: "美国5",
text: "",
position: [-118.72910740411513, 37.49926376525268]
},
{
value: 40,
level: 3,
name: "美国6",
text: "",
position: [-115.67083031097702, 35.414074838113066]
},
{
value: 40,
level: 3,
name: "美国7",
text: "",
position: [-109.55427612470085, 35.20555594539911]
},
{
value: 40,
level: 3,
name: "美国8",
text: "",
position: [-104.2717975092805, 34.162961481829306]
},
{
value: 40,
level: 3,
name: "美国9",
text: "",
position: [-101.21352041614242, 32.49481034011762]
},
{
value: 40,
level: 3,
name: "美国10",
text: "",
position: [-98.71129370357488, 29.99258362755009]
},
{
value: 40,
level: 3,
name: "美国11",
text: "",
position: [-96.48709218129264, 31.24369698383387]
},
{
value: 40,
level: 5,
name: "美国12",
text: "",
position: [-92.31671432701341, 32.91184812554555]
},
{
value: 40,
level: 3,
name: "美国13",
text: "",
position: [-95.93104180072207, 38.124820443394576]
},
{
value: 40,
level: 5,
name: "美国14",
text: "",
position: [-100.93549522585714, 37.70778265796665]
},
{
value: 40,
level: 3,
name: "美国15",
text: "",
position: [-105.38389827042164, 45.00594390295528]
},
{
value: 40,
level: 1,
name: "美国16",
text: "",
position: [-92.87276470758401, 43.963349439385496]
},
{
value: 40,
level: 3,
name: "美国17",
text: "",
position: [-89.53646242416063, 41.04408494139004]
},
{
value: 40,
level: 1,
name: "美国18",
text: "",
position: [-81.75175709617281, 37.49926376525271]
},
{
value: 40,
level: 1,
name: "美国19",
text: "",
position: [-83.4199082378845, 35.622593730827056]
},
{
value: 40,
level: 1,
name: "美国20",
text: "",
position: [-88.70238685330483, 33.32888591097349]
},
{
value: 40,
level: 2,
name: "美国21",
text: "",
position: [-75.63520290989662, 42.29519829767381]
},
{
value: 40,
level: 2,
name: "美国22",
text: "",
position: [-74.80112733904078, 43.546311653957574]
},
{
value: 40,
level: 2,
name: "美国23",
text: "",
position: [-72.85495100704381, 44.17186833209945]
},
{
value: 40,
level: 2,
name: "美国24",
text: "",
position: [-69.79667391390572, 45.214462795669256]
}
]
}
];
const levelMapList = [
{},
{
name: "特别重大风险",
color: ["rgba(255, 77, 79, 1)", "rgba(255, 163, 158, 1)"]
},
{
name: "重大风险",
color: ["rgba(255, 169, 64, 1)", "rgba(255, 213, 145, 1)"]
},
{
name: "较大风险",
color: ["rgba(250, 219, 20, 1)", "rgba(255, 251, 143, 1)"]
},
{
name: "一般风险",
color: ["rgba(64, 150, 255, 1)", "rgba(145, 202, 255, 1)"]
},
{
name: "几乎无风险",
color: ["rgba(54, 207, 201, 1)", "rgba(135, 232, 222, 1)"]
}
];
const mapOption = getMapOption(mapData, levelMapList);
function moreClick(n) {
alert(n);
}
</script>
<style lang="scss" scoped>
.wrap {
width: 1600px;
margin: 30px auto;
}
.gap {
margin-top: 24px;
}
.icon {
width: 24px;
height: 22px;
background-size: contain;
background-repeat: no-repeat;
}
.icon5 {
background-image: url("../assets/img/icon5.png");
}
.icon6 {
background-image: url("../assets/img/icon6.png");
}
.icon3 {
background-image: url("../assets/img/icon3.png");
}
.icon4 {
background-image: url("../assets/img/icon4.png");
}
.panel1Header {
display: flex;
align-items: center;
gap: 20px;
padding-right: 27px;
.item {
display: flex;
align-items: center;
gap: 12px;
.itemIcon {
width: 12px;
height: 12px;
border-radius: 6px;
border-width: 2px;
border-style: solid;
}
.itemName {
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
}
}
.panel1Body {
position: relative;
height: 100%;
display: flex;
flex-direction: column;
padding: 22px 30px 20px 25px;
gap: 12px;
.item {
display: flex;
align-items: center;
.number {
width: 24px;
height: 24px;
color: transparent;
font-size: 18px;
font-weight: 900;
display: flex;
justify-content: center;
align-items: center;
margin-right: 20px;
}
.title {
flex: 1;
color: rgba(59, 65, 75, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: noWrap;
margin-right: 16px;
}
.type {
margin-left: auto;
color: rgba(132, 136, 142, 1);
font-size: 14px;
font-weight: 400;
}
.one {
color: rgba(206, 79, 81, 1);
}
.two {
color: rgba(255, 169, 64, 1);
}
.three {
color: rgba(255, 197, 61, 1);
}
}
}
.panel2 {
height: 100%;
display: flex;
flex-direction: column;
.item {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 7px;
.itemLevel {
width: 40px;
height: 40px;
border-radius: 20px;
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 14px;
padding: 6px 4px;
text-align: center;
margin-right: 5px;
}
.itemTime {
color: rgba(132, 136, 142, 1);
}
.itemFlag {
width: 20px;
height: 20px;
background-size: cover;
background-repeat: no-repeat;
margin-left: 10px;
}
}
}
.itemTrends {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 20px;
}
.itemTrendsIcon {
width: 4px;
height: 4px;
background-color: rgba(206, 79, 81, 1);
border-radius: 50%;
margin-right: 14px;
margin-left: 20px;
}
.itemTrendsText {
flex: 1;
}
.itemTrendsTime {
margin-right: 6px;
}
.level1 {
background: rgb(255, 241, 240);
color: rgb(245, 34, 45);
}
.level2 {
color: rgb(250, 140, 22);
background: rgb(255, 247, 230);
}
.level3 {
color: rgb(82, 196, 26);
background: rgb(246, 255, 237);
}
.itemText {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.cardContainer {
justify-content: space-between;
}
.itemCardWrap {
width: 400px;
display: flex;
flex-direction: row;
justify-content: center;
}
.itemCard {
width: 388px;
height: 80px;
border-radius: 4px;
background-image: url("../assets/img/cardBg.png");
background-size: cover;
display: flex;
justify-content: center;
align-items: center;
.itemCardIcon {
width: 30px;
height: 30px;
background-size: contain;
margin-right: 7px;
}
.itemCardIcon1 {
background-image: url("../assets/img/cardIcon1.png");
}
.itemCardIcon2 {
background-image: url("../assets/img/cardIcon2.png");
}
.itemCardIcon3 {
background-image: url("../assets/img/cardIcon3.png");
}
.itemCardIcon4 {
background-image: url("../assets/img/cardIcon4.png");
}
.itemCardTitle {
font-size: 24px;
font-weight: 700;
color: #ffffff;
}
}
.moreWrap {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
height: 100%;
padding-left: 10px;
padding-right: 10px;
flex: 1;
.moreText {
margin-right: 3px;
}
.shuaxinIcon {
width: 16px;
height: 16px;
background-image: url("../assets/img/shuaxin.png");
background-size: contain;
}
}
.CardCustomRight {
flex: 1;
padding-left: 50px;
padding-right: 50px;
margin-left: 30px;
display: flex;
justify-content: space-between;
}
.itemCard1 {
.itemCard1Img {
position: relative;
width: 204px;
height: 266px;
background-image: url("../assets/img/book.png");
background-size: contain;
.itemCard1Footer {
position: absolute;
left: 0;
bottom: 0;
width: 204px;
height: 64px;
padding: 10px;
background-color: #000;
color: #fff;
}
}
}
.spaceBetween {
justify-content: space-between;
}
.itemCard2 {
width: 388px;
height: 360px;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
:deep(.el-card__body) {
padding-top: 0;
}
.itemCard2Line {
/* 矩形 214 */
width: 320px;
height: 4px;
background-color: rgba(206, 79, 81, 1);
position: absolute;
top: 0;
left: 34px;
}
.itemCard2Container {
width: 320px;
height: 360px;
.itemCard2BigTextWrap {
color: rgba(206, 79, 81, 1);
font-size: 24px;
font-weight: 700;
height: 83px;
display: flex;
flex-direction: column;
justify-content: center;
border-bottom: 1px solid #ddd;
}
.itemCard2TextWrap {
height: 83px;
display: flex;
flex-direction: column;
justify-content: center;
border-bottom: 1px solid #ddd;
}
.temCard2Title {
color: rgba(59, 65, 75, 1);
font-size: 20px;
font-weight: 700;
}
.temCard2Text {
color: rgba(95, 101, 108, 1);
font-size: 16px;
font-weight: 400;
}
}
}
</style>
import * as echarts from "echarts";
const getPieChart = (number, current, total) => {
import worldJson from '@/assets/json/world.json'
import _ from "lodash";
export function getPieChart(number, current, total) {
const option = {
// 图表标题可置于中心,模拟居中文字的一部分
title: {
......@@ -67,12 +69,136 @@ const getPieChart = (number, current, total) => {
};
return option
}
const setChart = (option, chartDom) => {
export function setChart(option, chartDom) {
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
};
export {
getPieChart,
setChart
export function getMapOption(data,levelMap) {
echarts.registerMap('world', worldJson);
function convertData(data) {
let res = [];
_.each(data, (item1) => {
_.each(item1.children, (item) => {
res.push({
name: item1.name,
value: item.position.concat(item.level),
itemStyle: {
color: levelMap[item.level].color[0],
borderColor: levelMap[item.level].color[1]
}
});
})
})
return res;
}
let option = {
tooltip: {
show: false
},
// visualMap: {
// type: 'piecewise', // 可选:'continuous' (连续型) 或 'piecewise' (分段型)[citation:2]
// dimension: 2, // 指定使用数据的第3个维度(即上面数据中的等级值)进行映射
// min: 1, // 映射范围最小值
// max: 5, // 映射范围最大值
// // 定义分段区间和颜色
// show: false,
// pieces: [
// {
// min: 1,
// max: 1,
// label: '特别重大风险',
// color: 'rgba(255, 77, 79, 1)'
// }, // 绿色
// {
// min: 2,
// max: 2,
// label: '重大风险',
// color: 'rgba(255, 169, 64, 1)'
// },
// {
// min: 3,
// max: 3,
// label: '较大风险',
// color: 'rgba(250, 219, 20, 1)'
// },
// {
// min: 4,
// max: 4,
// label: '一般风险',
// color: 'rgba(64, 150, 255, 1)'
// },
// {
// min: 5,
// max: 5,
// label: '几乎无风险',
// color: 'rgba(54, 207, 201, 1)'
// },
// ],
// orient: 'horizontal',
// left: 'center',
// top: 0
// },
geo: {
map: 'world',
roam: true,
// 地图尺寸为容器宽高较小值的80%
zoom: 1.5,
center: [31.614149450443932, 20.978078159827206],
// scaleLimit:{
// max:'1.2',
// min:'0.7'
// },
label: {
normal: {
show: false,
textStyle: {
color: 'rgba(0,0,0,0.6)'
}
}
},
itemStyle: {
areaColor: 'rgba(231, 243, 255, 1)', // 设置所有区域的默认填充色[citation:8]
borderColor: 'rgb(5, 95, 194)', // 设置边界线颜色[citation:8]
borderWidth: 1 // 设置边界线宽度[citation:8]
},
},
// backgroundColor: 'rgba(0,51,102, 1)',
series: [{
type: 'scatter',
coordinateSystem: 'geo',
data: convertData(data),
symbolSize: 10,
symbolRotate: 0,
symbolOffset: ['50%', '-100%'],
tooltip: {
show: true
},
label: {
normal: {
formatter: '{a}',
position: 'top',
show: false,
textStyle: {
color: '#000000',
fontSize: 16
}
},
emphasis: {
show: false
}
},
itemStyle: {
normal: {
borderWidth: 4,
borderColor: 'rgba(255, 163, 158, 1)',
color: 'rgba(255, 77, 79, 1)'
}
}
}]
};
return option
}
\ No newline at end of file
......@@ -21,7 +21,6 @@
<div class="right-title">
<img src="./assets/icon02.png" alt="">
<div class="tit">社交媒体</div>
<div class="more">更多 +</div>
</div>
<div class="right-main">
<div class="trump">
......
......@@ -6,7 +6,7 @@
<div class="left-top">
<img src="./assets/icon01.png" alt="" />
<div class="left-top-title">规则限制动态</div>
<span>查看详情 ></span>
<div class="more" @click="handleClickToDetail">查看详情 ></div>
</div>
<div class="left-center">
<img src="./assets/usImg.png" alt="" />
......@@ -166,12 +166,14 @@ const handleToMoreRiskSignal = () => {
top: 15px;
left: 23px;
}
span {
.more {
height: 48px;
line-height: 48px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
position: absolute;
top: 19px;
top: 0;
right: 40px;
color: rgb(5, 95, 194);
cursor: pointer;
......
......@@ -21,7 +21,6 @@
<div class="right-title">
<img src="./assets/icon02.png" alt="">
<div class="tit">社交媒体</div>
<div class="more">更多 +</div>
</div>
<div class="right-main">
<div class="trump">
......
<template>
<div class="home-wrapper">
<div class="home-main">
<div class="home-main-header">
<div class="home-main-header-top">
<div class="header-item">国家科技安全</div>
<div class="header-item">></div>
<div class="header-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="header-item">></div>
<div class="header-item">市场准入限制</div>
</div>
<div class="home-main-header-center">
<el-input v-model="input" style="width: 838px; height: 100%" placeholder="搜索科技人物及观点" />
<div class="search">
<div class="search-icon">
<img src="./assets/images/search-icon.png" alt="" />
</div>
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">843</div>
<div class="item-footer">政府官员</div>
</div>
<div class="home-main-header-footer-item">
<div class="item-top">131</div>
<div class="item-footer">科技企业领袖</div>
</div>
<div class="home-main-header-footer-item">
<div class="item-top">633</div>
<div class="item-footer">顶级科学家</div>
</div>
<div class="home-main-header-footer-item">
<div class="item-top">312</div>
<div class="item-footer">国会议员</div>
</div>
</div>
<div class="home-main-header-btn-box">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">{{ "资讯要闻" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn" @click="scrollToTop('position3')">
<div class="btn-text">{{ "统计概览" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn" @click="scrollToTop('position4')">
<div class="btn-text">{{ "资源库" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
</div>
</div>
<div class="home-main-center">
<DivideHeader id="position1" class="divide-header" :titleText="'最新动态'"></DivideHeader>
<div class="center-top">
<div class="box1">
<div class="box1-left">
<img src="./assets/images/box1-left.png" alt="" />
</div>
<div class="box1-right">
<img src="./assets/images/box1-right.png" alt="" />
</div>
<div class="box1-header">
<div class="box1-header-left">
<div class="icon">
<img src="./assets/images/box1-header-icon.png" alt="" />
</div>
<div class="title">{{ "人物新闻动态" }}</div>
</div>
<div class="box1-header-right" @click="handleClickToDetail('337')">
{{ "查看详情 >" }}
</div>
</div>
<div class="box1-main"></div>
</div>
<div class="box2">
<div class="box2-header">
<div class="icon">
<img src="./assets/images/box2-header-icon.png" alt="" />
</div>
<div class="title">
<div class="text">{{ "风险信号" }}</div>
<div class="num">{{ warningList.length }}</div>
</div>
</div>
<div class="box2-main">
<div class="box2-main-item" v-for="(item, index) in warningList" :key="index">
<div
class="item-left"
:class="{
itemLeftStatus1: item.status === '一般风险',
itemLeftStatus2: item.status === '重大风险'
}"
>
{{ item.status }}
</div>
<div class="item-right">
<div class="text">
{{ item.title }}
</div>
<div class="time">{{ item.time }}</div>
</div>
</div>
</div>
<div class="box2-footer" @click="handleToMoreRiskSignal">
<div class="icon">
<img src="./assets/images/box2-footer-icon.png" alt="" />
</div>
<div class="text">{{ "查看更多" }}</div>
</div>
</div>
</div>
<DivideHeader id="position2" class="divide-header" :titleText="'言论动态'"></DivideHeader>
<div class="center-center">
<div class="box3">
<div class="box3-header">
<div class="box3-header-left">
<div class="box3-header-icon">
<img src="./assets/images/header-news.png" alt="" />
</div>
<div class="box3-header-title">{{ "人物动向" }}</div>
</div>
</div>
<div class="box3-main"></div>
</div>
<div class="box4">
<div class="box4-header">
<div class="header-icon">
<img src="./assets/images/header-message.png" alt="" />
</div>
<div class="header-title">{{ "重要人物言论及立场" }}</div>
</div>
<div class="box4-main"></div>
</div>
</div>
<DivideHeader id="position3" class="divide-header" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer">
<div class="box5">
<div class="box5-header">
<div class="box5-header-left">
<div class="box5-header-icon">
<img src="./assets/images/box3-header-icon.png" alt="" />
</div>
<div class="box5-header-title">{{ "科技人物观点词云" }}</div>
</div>
</div>
<div class="box5-main" id="box5Chart"></div>
</div>
<div class="box6">
<div class="box6-header">
<div class="header-icon">
<img src="./assets/images/box6-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "科技人物观点涉及领域变化趋势" }}</div>
</div>
<div class="box6-main" id="box6Chart"></div>
</div>
</div>
<div class="center-footer1">
<div class="box7">
<div class="box7-header">
<div class="box7-header-left">
<div class="box7-header-icon">
<img src="./assets/images/box3-header-icon.png" alt="" />
</div>
<div class="box7-header-title">{{ "科技人物类型" }}</div>
</div>
</div>
<div class="box7-main" id="box7Chart"></div>
</div>
<div class="box8">
<div class="box8-header">
<div class="box8-header-left">
<div class="box8-header-icon">
<img src="./assets/images/box6-header-icon.png" alt="" />
</div>
<div class="box8-header-title">{{ "主要人物涉华观点统计" }}</div>
</div>
</div>
<div class="box8-main"></div>
</div>
</div>
</div>
<div class="home-main-footer">
<DivideHeader id="position4" class="divide-header" :titleText="'资源库'"></DivideHeader>
<div class="home-main-footer-header">
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: activeCate === cate }"
v-for="(cate, index) in categoryList"
:key="index"
@click="handleClickCate(cate)"
>
{{ cate }}
</div>
</div>
</div>
<div class="home-main-footer-main"></div>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import scrollToTop from "@/utils/scrollToTop";
import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue";
import setChart from "@/utils/setChart";
import getMultiLineChart from "./utils/multiLineChart";
import getPieChart from "./utils/piechart";
import getRadarChart from "./utils/radarChart";
import getMapChart from "./utils/mapChart";
import getBarChart from "./utils/barChart";
// 返回首页
const handleBackHome = () => {
router.push({
path: "/overview"
});
};
const handleClickToDetail = id => {
const route = router.resolve({
path: "/marketAccessLayout",
query: {
id: id
}
});
window.open(route.href, "_blank");
};
// 风险信号
const warningList = ref([
{
title: "关于对中华人民共和国合成阿片类药物供应链...",
time: "一天前",
status: "特别重大"
},
{
title: "关于调整汽车及汽车零部件进口的公告",
time: "一天前",
status: "特别重大"
},
{
title: "关于调整钢铁进口的公告",
time: "一天前",
status: "重大风险"
},
{
title: "关于使用互惠关税规范进口以纠正导致大规模...",
time: "一天前",
status: "重大风险"
},
{
title: "关于修订对中华人民共和国低价值进口商品适...",
time: "一天前",
status: "一般风险"
}
]);
const categoryList = ref(["全部人物", "国会议员", "行政主官", "科技领袖", "顶尖科学家"]);
const activeCate = ref("全部人物");
const activeHylyId = ref("");
const handleClickCate = cate => {
console.log(cate);
activeCate.value = cate.hylymc;
activeHylyId.value = cate.hylyid;
handleGetBillsByType();
};
const chart1Data = ref({
title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
data: [
{
name: "337调查",
value: [73, 32, 42, 48, 38, 49, 63, 75, 70, 86, 95, 87]
},
{
name: "301调查",
value: [8, 3, 2, 8, 9, 10, 12, 18, 16, 18, 20, 22]
},
{
name: "232调查",
value: [1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3]
}
]
});
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
window.open(route.href, "_blank");
};
const box7Chart1Data = ref([
{
name: "337调查",
data: [
{ name: "北京", value: 10, coord: [115.46, 39.92] },
{ name: "上海", value: 9, coord: [120.48, 31.22] },
{ name: "广东", value: 15, coord: [114.23, 23.16] },
{ name: "江苏", value: 30, coord: [117.78, 32.04] },
{ name: "浙江", value: 20, coord: [121.19, 30.26] },
{ name: "四川", value: 4, coord: [105.06, 30.67] },
{ name: "陕西", value: 1, coord: [106.95, 34.27] },
{ name: "辽宁", value: 3, coord: [122.38, 41.8] }
]
},
{
name: "301调查",
data: [
{ name: "北京", value: 10, coord: [112.48, 38.95] },
{ name: "上海", value: 9, coord: [121.5, 33.25] },
{ name: "广东", value: 15, coord: [118.25, 21.18] },
{ name: "江苏", value: 30, coord: [115.8, 34.06] },
{ name: "浙江", value: 20, coord: [124.21, 31.28] },
{ name: "四川", value: 4, coord: [114.08, 32.69] },
{ name: "陕西", value: 1, coord: [109.97, 30.29] },
{ name: "辽宁", value: 3, coord: [113.4, 40.82] }
]
},
{
name: "232调查",
data: [
{ name: "北京", value: 10, coord: [116.44, 39.9] },
{ name: "上海", value: 9, coord: [121.46, 31.2] },
{ name: "广东", value: 15, coord: [113.21, 23.14] },
{ name: "江苏", value: 30, coord: [118.76, 32.02] },
{ name: "浙江", value: 20, coord: [120.19, 30.24] },
{ name: "四川", value: 4, coord: [104.04, 30.67] },
{ name: "陕西", value: 1, coord: [108.95, 34.25] },
{ name: "辽宁", value: 3, coord: [123.36, 41.8] }
]
}
]);
const box7Chart2Data = ref([
{
name: "广东省",
value: 42
},
{
name: "上海市",
value: 35
},
{
name: "浙江省",
value: 28
},
{
name: "江苏省",
value: 19
},
{
name: "北京市",
value: 15
},
{
name: "四川省",
value: 12
},
{
name: "山东省",
value: 11
},
{
name: "福建省",
value: 8
}
]);
onMounted(async () => {
let chart1 = getMultiLineChart(
chart1Data.value.title,
chart1Data.value.data[0].value,
chart1Data.value.data[1].value,
chart1Data.value.data[2].value
);
setChart(chart1, "chart1");
let chart2 = getRadarChart();
setChart(chart2, "chart2");
let box7Chart1 = getMapChart(box7Chart1Data.value);
setChart(box7Chart1, "box7Chart1");
let box7Chart2 = getBarChart(box7Chart2Data.value);
setChart(box7Chart2, "box7Chart2");
});
</script>
<style lang="scss" scoped>
:deep(.el-input__wrapper) {
box-shadow: none;
}
.home-wrapper {
.home-main {
width: 1920px;
margin: 0 auto;
background: url("./assets/images/background.png");
background-size: 100% 100%;
.home-main-header {
display: flex;
flex-direction: column;
align-items: center;
.home-main-header-top {
box-sizing: border-box;
width: 100%;
height: 64px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 64px;
background: url("./assets/images/header-bg.png");
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
color: #fff;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.home-main-header-center {
margin-top: 48px;
width: 960px;
height: 48px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
padding: 1px;
position: relative;
border: 1px solid transparent;
&:hover {
border: 1px solid var(--color-main-active);
}
.search {
position: absolute;
right: -1px;
top: 0px;
width: 120px;
height: 46px;
border-radius: 10px;
background: var(--color-main-active);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
.search-icon {
width: 18px;
height: 18px;
img {
width: 100%;
height: 100%;
}
}
.search-text {
margin-left: 8px;
height: 22px;
color: #fff;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 22px;
}
}
}
.home-main-header-footer {
margin-top: 38px;
width: 688px;
height: 64px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
.home-main-header-footer-item {
padding: 0 10px;
text-align: center;
.item-top {
height: 22px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 36px;
font-weight: 700;
line-height: 22px;
}
.item-footer {
margin-top: 10px;
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
}
}
}
.home-main-header-btn-box {
width: 688px;
margin: 0 auto;
margin-top: 39px;
display: flex;
justify-content: space-between;
.btn {
display: flex;
width: 140px;
height: 36px;
border: 1px solid #aed6ff;
box-sizing: border-box;
border-radius: 18px;
justify-content: center;
background: #e7f3ff;
position: relative;
cursor: pointer;
&:hover {
background: #cae3fc;
}
.btn-text {
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 34px;
margin-left: 5px;
}
.btn-icon {
height: 20px;
line-height: 20px;
position: absolute;
top: 6px;
right: 8px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
}
}
}
}
.home-main-center {
margin-top: 34px;
.center-top {
height: 450px;
display: flex;
justify-content: center;
gap: 20px;
.box1 {
width: 1064px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: #fff;
box-sizing: border-box;
position: relative;
.box1-left {
position: absolute;
left: 0;
top: 220px;
width: 24px;
height: 48px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.box1-right {
position: absolute;
right: 0;
top: 220px;
width: 24px;
height: 48px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.box1-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
justify-content: space-between;
padding-left: 31px;
padding-right: 41px;
.box1-header-left {
display: flex;
.icon {
width: 18px;
height: 18px;
margin-top: 19px;
img {
width: 100%;
height: 100%;
}
}
.title {
width: 152px;
height: 53px;
margin-left: 18px;
color: #fff;
background: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 53px;
text-align: center;
}
}
.box1-header-right {
margin-top: 19px;
height: 16px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 16px;
cursor: pointer;
}
}
.box1-main {
width: 1064px;
height: 354px;
margin-top: 22px;
margin-left: 31px;
}
}
.box2 {
width: 521px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.box2-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.icon {
width: 24px;
height: 22px;
margin-left: 33px;
margin-top: 13px;
img {
width: 100%;
height: 100%;
}
}
.title {
display: flex;
width: 148px;
height: 48px;
background: rgba(206, 79, 81, 1);
margin-left: 25px;
.text {
margin-left: 15px;
margin-top: 13px;
height: 22px;
color: #fff;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
.num {
width: 24px;
height: 20px;
line-height: 20px;
text-align: center;
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 12px;
margin-left: 15px;
margin-top: 14px;
border-radius: 100px;
background: rgba(255, 255, 255, 0.3);
}
}
.more {
margin-top: 16px;
margin-left: 200px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 16px;
cursor: pointer;
}
}
.box2-main {
margin-top: 2px;
height: 330px;
overflow-y: auto;
.box2-main-item {
margin-left: 23px;
height: 47px;
width: 464px;
display: flex;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.itemLeftStatus1 {
color: rgba(82, 196, 26, 1) !important;
background: rgba(246, 255, 237, 1) !important;
}
.itemLeftStatus2 {
color: rgba(250, 140, 22, 1) !important;
background: rgba(255, 247, 230, 1) !important;
}
.item-left {
margin-top: 4px;
margin-left: 2px;
width: 40px;
height: 40px;
border-radius: 20px;
background: rgba(255, 241, 240);
color: rgba(245, 34, 45, 1);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
line-height: 14px;
box-sizing: border-box;
padding: 6px 4px;
text-align: center;
}
.item-right {
margin-left: 13px;
width: 408px;
height: 47px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.text {
width: 348px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 47px;
}
.time {
margin-left: 10px;
line-height: 47px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
}
}
}
}
.box2-footer {
position: absolute;
left: 30px;
bottom: 20px;
width: 460px;
height: 42px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
border-radius: 6px;
background: var(--color-main-active);
gap: 8px;
cursor: pointer;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 22px;
}
}
}
}
.center-center {
width: 1600px;
margin: 0 auto;
margin-top: 21px;
.box3 {
width: 1600px;
height: 640px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box3-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
position: relative;
.box3-header-left {
display: flex;
.box3-header-icon {
margin-top: 16px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box3-header-title {
margin-top: 16px;
margin-left: 19px;
height: 22px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
.more {
width: 49px;
height: 24px;
position: absolute;
top: 14px;
right: 27px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
}
}
}
.box3-main {
height: 402px;
overflow-y: auto;
overflow-x: hidden;
padding-top: 6px;
}
}
.box4 {
margin-top: 16px;
width: 1600px;
height: 460px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box4-header {
width: 792px;
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
box-sizing: border-box;
padding-left: 22px;
position: relative;
.header-icon {
margin-top: 15px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.header-title {
margin-top: 16px;
margin-left: 18px;
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
.more {
width: 49px;
height: 24px;
position: absolute;
top: 14px;
right: 27px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
}
}
.box4-main {
height: 402px;
overflow-y: auto;
box-sizing: border-box;
padding-top: 8px;
}
}
}
.center-footer {
margin-top: 21px;
height: 460px;
display: flex;
justify-content: center;
gap: 15px;
.box5 {
width: 1064px;
height: 460px;
box-sizing: border-box;
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);
.box5-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
position: relative;
.box5-header-left {
display: flex;
.box5-header-icon {
margin-top: 15px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box5-header-title {
margin-top: 12px;
margin-left: 19px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
}
.box-header-right {
position: absolute;
height: 24px;
top: 12px;
right: 17px;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 8px;
.icon {
width: 14px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
}
.box5-main {
height: 397px;
}
}
.box6 {
width: 521px;
height: 460px;
box-sizing: border-box;
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);
.box6-header {
width: 521px;
height: 53px;
box-sizing: border-box;
padding: 0 20px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
position: relative;
.header-icon {
margin-top: 18px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.header-title {
margin-top: 16px;
margin-left: 15px;
height: 22px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
.box-header-right {
position: absolute;
height: 24px;
top: 12px;
right: 17px;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 8px;
.icon {
width: 14px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
}
.box6-main {
height: 360px;
}
}
}
.center-footer1 {
margin-top: 16px;
display: flex;
justify-content: center;
gap: 15px;
.box7 {
width: 1064px;
height: 460px;
box-sizing: border-box;
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);
.box7-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
position: relative;
.box7-header-left {
display: flex;
.box7-header-icon {
margin-top: 15px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box7-header-title {
margin-top: 12px;
margin-left: 19px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
}
.box-header-right {
position: absolute;
height: 24px;
top: 12px;
right: 17px;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 8px;
.icon {
width: 14px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
}
.box7-main {
height: 412px;
}
}
.box8 {
width: 521px;
height: 460px;
box-sizing: border-box;
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);
.box8-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
position: relative;
.box8-header-left {
display: flex;
.box8-header-icon {
margin-top: 15px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box8-header-title {
margin-top: 12px;
margin-left: 19px;
height: 26px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
}
.box-header-right {
position: absolute;
height: 24px;
top: 12px;
right: 17px;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 8px;
.icon {
width: 14px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
}
.box8-main {
width: 469px;
height: 360px;
}
}
}
}
.home-main-footer {
height: 1149px;
overflow: hidden;
.home-main-footer-header {
width: 1600px;
height: 42px;
margin: 36px auto;
// background: orange;
display: flex;
justify-content: space-between;
.btn-box {
width: 1000px;
display: flex;
.btn {
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 42px;
padding: 0 24px;
border-radius: 21px;
background: rgba(20, 89, 187, 0);
margin-right: 20px;
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
}
}
.btnActive {
padding: 0 24px;
border-radius: 21px;
background: rgba(20, 89, 187, 1);
color: #fff;
&:hover {
color: #fff;
background: rgba(20, 89, 187, 1);
}
}
}
.select-box {
height: 42px;
box-sizing: border-box;
padding: 5px 0;
}
}
.home-main-footer-main {
width: 1600px;
margin-bottom: 20px;
height: 985px;
// box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
// background: rgba(255, 255, 255, 1);
margin: 0 auto;
box-sizing: border-box;
// padding: 20px;
display: flex;
.left {
width: 300px;
height: 560px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.left-box1 {
margin-top: 17px;
height: 260px;
.left-box1-header {
display: flex;
.icon {
width: 8px;
height: 16px;
margin-top: 4px;
border-radius: 2px 2px 0 0;
background: rgba(10, 87, 166, 1);
}
.title {
height: 2px;
margin-left: 17px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
}
}
.left-box1-main {
margin-top: 10px;
.time-label {
height: 35px;
margin-left: 25px;
}
}
}
.left-box2 {
margin-top: 17px;
height: 260px;
.left-box2-header {
display: flex;
.icon {
width: 8px;
height: 16px;
margin-top: 4px;
border-radius: 2px 2px 0 0;
background: rgba(10, 87, 166, 1);
}
.title {
height: 2px;
margin-left: 17px;
color: rgba(10, 87, 166, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
}
}
.left-box2-main {
margin-top: 10px;
.area-label {
height: 35px;
margin-left: 25px;
}
}
}
}
.right {
margin-left: 16px;
width: 1284px;
height: 899px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.right-header {
height: 54px;
background: rgba(59, 65, 75, 1);
display: flex;
.header-item1 {
width: 500px;
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 54px;
padding-left: 80px;
box-sizing: border-box;
}
.header-item2 {
width: 196px;
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 54px;
padding-left: 20px;
box-sizing: border-box;
}
.header-item3 {
width: 196px;
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 54px;
padding-left: 20px;
box-sizing: border-box;
}
.header-item4 {
width: 196px;
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 54px;
padding-left: 20px;
box-sizing: border-box;
}
.header-item5 {
width: 196px;
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 54px;
padding-left: 20px;
box-sizing: border-box;
}
}
.right-main {
height: 780px;
// background: orange;
.item {
display: flex;
padding: 16px 0;
// height: 56px;
&:nth-child(2n) {
background: rgba(247, 248, 249, 1);
}
.item-box1 {
width: 500px;
display: flex;
.name {
height: 22px;
padding: 0 8px;
box-sizing: border-box;
border-radius: 4px;
margin-left: 32px;
margin-top: 10px;
// display: flex;
// align-items: center;
}
.name1 {
color: rgba(250, 140, 22, 1);
border: 1px solid rgba(255, 213, 145, 1);
background: rgba(255, 247, 230, 1);
}
.name2 {
color: rgba(10, 87, 166, 1);
border: 1px solid rgba(145, 202, 255, 1);
background: rgba(230, 244, 255, 1);
}
.name3 {
color: rgba(114, 46, 209, 1);
border: 1px solid rgba(211, 173, 247, 1);
background: rgba(249, 240, 255, 1);
}
.title {
margin-left: 12px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
display: flex;
align-items: center;
}
}
.item-box2 {
width: 196px;
padding-left: 20px;
box-sizing: border-box;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.item-box3 {
width: 196px;
padding-left: 20px;
box-sizing: border-box;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.item-box4 {
width: 196px;
padding-left: 20px;
box-sizing: border-box;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.item-box5 {
width: 196px;
padding-left: 20px;
box-sizing: border-box;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
}
}
.right-footer {
display: flex;
// height: 60px;
// background: orange;
justify-content: space-between;
.footer-left {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
margin-left: 24px;
margin-top: 6px;
}
.footer-right {
margin-right: 24px;
}
}
}
}
}
}
}
.divide-header {
margin: 0 auto;
margin-top: 52px;
margin-bottom: 36px;
}
:deep(.el-input__wrapper) {
box-shadow: none;
border-radius: 10px;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
:deep(.el-input__wrapper.is-focus) {
box-shadow: none !important;
}
</style>
import { reverse } from "d3";
import * as echarts from "echarts";
const getBarChart = (originalData) => {
// 按 value 从大到小排序
const sortedData = [...originalData].sort((a, b) => b.value - a.value);
const option = {
tooltip: {},
grid: {
top: '3%',
right: '3%',
bottom: '1%',
left: '1%',
containLabel: true
},
xAxis: {
type: 'value',
splitLine: {
show: false
},
show: false
},
yAxis: {
type: 'category',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: false
},
axisLabel: {
show: true,
formatter: function (value, index) {
// index 是从 0 开始的
const rank = index + 1;
// 基础版本
// return `${rank}. ${value}`;
// 带样式的版本
return `{rank|${rank}} {name|${value}}`;
},
// 启用富文本
rich: {
rank: {
color: 'rgba(5, 95, 194, 1)', // 序号颜色
fontFamily: 'Microsoft YaHei',
fontSize: 12, // 字体大小
width: 24,
height: 24,
align: 'center',
verticalAlign: 'middle',
backgroundColor: 'rgba(231, 243, 255, 1)',
borderRadius: 12,
padding: [0, 0]
},
name: {
color: '#333', // 名称颜色
fontSize: 12
}
}
},
data: sortedData.map(item => item.name),
inverse: true, // Y轴反向,使第一个在顶部
},
series: [{
type: 'bar',
data: sortedData.map(item => item.value),
label: {
show: true,
position: [300, 0],
formatter: function (params) {
return params.value + ' 次'
}
},
barWidth: 8,
itemStyle: {
color: function (params) {
if (params.dataIndex === 0) {
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: 'rgba(206, 79, 81, 0)'
},
{
offset: 1,
color: 'rgba(206, 79, 81, 1)'
}
]);
} else if (params.dataIndex < 3) {
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: 'rgba(255, 172, 77, 0)'
},
{
offset: 1,
color: 'rgba(255, 172, 77, 1)'
}
]);
} else {
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: 'rgba(5, 95, 194, 0)'
},
{
offset: 1,
color: 'rgba(5, 95, 194, 1)'
}
]);
}
},
barBorderRadius: 4,
}
}]
}
return option
}
export default getBarChart
\ No newline at end of file
import * as echarts from 'echarts'
import chinaJson from '@/assets/json/China.json'
const getMapChart = (mapData) => {
echarts.registerMap('china', chinaJson);
const option = {
legend: {
show: true,
top: 15
},
tooltip: {
trigger: 'item',
formatter: (params) => {
if (params.componentType === 'series') {
if (params.seriesType === 'scatter') {
return `${params.data.name}<br/>数值: ${params.data.value[2]}`;
} else {
return `${params.name}<br/>数值: ${params.value[2] || 0}`;
}
}
return params.name;
}
},
geo: {
map: 'china',
roam: true,
zoom: 1,
label: {
emphasis: {
show: true,
color: '#fff'
}
},
itemStyle: {
areaColor: '#F9FAFC',
borderColor: '#E7F1FF',
borderWidth: 1
},
emphasis: {
itemStyle: {
areaColor: '#ffd700'
},
label: {
show: true,
color: '#fff',
fontSize: 12
}
}
},
series: [
// 地图系列 - 用于省份高亮
{
name: '',
type: 'map',
map: 'china',
geoIndex: 0,
data: mapData.map(item => ({
name: item.name,
value: item.value,
itemStyle: {
// color: getColorByValue(item.value, colorRanges),
areaColor: '#E7F1FF'
}
})),
emphasis: {
itemStyle: {
areaColor: '#ffd700',
borderColor: '#333',
borderWidth: 2
},
label: {
show: true,
fontSize: 14,
fontWeight: 'bold',
color: '#333'
}
}
},
// 散点系列 - 用于显示圆点数字标记
{
name: mapData[0].name,
type: 'scatter',
coordinateSystem: 'geo',
symbol: 'circle',
symbolSize: 10,
itemStyle: {
color: 'rgba(5, 95, 194, 1)',
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
data: mapData[0].data.map(item => ({
name: item.name,
value: [item.coord[0], item.coord[1], item.value],
itemStyle: {
color: 'rgba(5, 95, 194, 1)'
}
})),
// data: mapData[0].data,
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
},
itemStyle: {
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.8)'
}
}
},
{
name: mapData[1].name,
type: 'scatter',
coordinateSystem: 'geo',
symbol: 'circle',
symbolSize: 10,
itemStyle: {
color: 'rgba(250, 140, 22, 1)',
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
data: mapData[1].data.map(item => ({
name: item.name,
value: [item.coord[0], item.coord[1], item.value],
itemStyle: {
color: 'rgba(250, 140, 22, 1)'
}
})),
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
},
itemStyle: {
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.8)'
}
}
},
{
name: mapData[2].name,
type: 'scatter',
coordinateSystem: 'geo',
symbol: 'circle',
symbolSize: 10,
itemStyle: {
color: 'rgba(114, 46, 209, 1)',
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
},
data: mapData[2].data.map(item => ({
name: item.name,
value: [item.coord[0], item.coord[1], item.value],
itemStyle: {
color: 'rgba(114, 46, 209, 1)'
}
})),
emphasis: {
label: {
show: true,
fontSize: 14,
fontWeight: 'bold'
},
itemStyle: {
shadowBlur: 20,
shadowColor: 'rgba(0, 0, 0, 0.8)'
}
}
}
]
};
return option
}
export default getMapChart
\ No newline at end of file
import * as echarts from 'echarts'
const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
return {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
grid: {
top: '15%',
right: '5%',
bottom: '5%',
left: '5%',
containLabel: true
},
legend: {
show: true,
top: 10,
left:'5%'
},
color: ['#0A57A6', '#FA8C16','#722ED1'],
xAxis: [
{
type: 'category',
boundaryGap: false,
data: dataX
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '337调查',
type: 'line',
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: dataY1
},
{
name: '301调查',
type: 'line',
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: dataY2
},
{
name: '232调查',
type: 'line',
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: dataY3
}
]
}
}
export default getMultiLineChart
\ No newline at end of file
const getPieChart = (data,colorList) => {
let option = {
color: colorList,
series: [
{
type: 'pie',
radius: [70, 100],
height: '100%',
left: 'center',
width: '100%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
}
}
},
labelLine: {
length: 15,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints;
// Update the end point.
points[2][0] = isLeft
? params.labelRect.x
: params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points
};
},
data: data
}]
}
return option
}
export default getPieChart;
\ No newline at end of file
const getRadarChart = () => {
const indicators = [
{ name: "集成电路", max: 10 },
{ name: "能源领域", max: 10 },
{ name: "量子科技", max: 10 },
{ name: "通信网络", max: 10 },
{ name: "人工智能", max: 10 },
{ name: "生物科技", max: 10 }
];
const data337 = [9, 6, 6, 6, 9, 7];
const data301 = [5, 3, 7, 8, 7, 9];
const data232 = [4, 10, 3, 4, 2, 5];
const option = {
color: ["rgba(5, 95, 194, 1)", "rgba(250, 140, 22, 1)", "rgba(146, 84, 222, 1)"],
legend: {
top: 8,
left: 30,
icon: "circle",
itemWidth: 12,
itemHeight: 12,
itemGap: 24,
textStyle: {
color: "rgb(95, 101, 108)",
fontSize: 16,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 24
},
data: ["337调查", "301调查", "232调查"]
},
radar: {
shape: "polygon",
splitNumber: 5,
indicator: indicators,
center: ["50%", "56%"],
radius: "58%",
startAngle: 90,
clockwise: false,
axisName: {
color: "rgba(59, 65, 75, 1)",
fontSize: 16,
fontFamily: "Microsoft YaHei",
fontWeight: 700,
lineHeight: 24,
padding: [0, 5]
},
splitLine: {
lineStyle: {
color: "#d0d0d0",
width: 1
}
},
axisLine: {
lineStyle: {
color: "#d0d0d0",
width: 1
}
},
splitArea: {
show: true,
areaStyle: {
color: ["#fff", "rgb(247, 248, 249)", "#fff", "rgb(247, 248, 249)", "#fff"]
}
}
},
series: [
{
name: "337调查",
type: "radar",
data: [{ value: data337 }],
lineStyle: {
width: 2,
color: "rgba(5, 95, 194,1)"
},
symbol: "none",
areaStyle: {
color: "rgba(5, 95, 194,0.15)"
}
},
{
name: "301调查",
type: "radar",
data: [{ value: data301 }],
lineStyle: {
width: 2,
color: "rgba(250, 140, 22, 1)"
},
symbol: "none",
areaStyle: {
color: "rgba(250, 140, 22, 0.15)"
}
},
{
name: "232调查",
type: "radar",
data: [{ value: data232 }],
lineStyle: {
width: 2,
color: "rgba(146, 84, 222, 1)"
},
symbol: "none",
areaStyle: {
color: "rgba(146, 84, 222, 0.15)"
}
},
]
};
return option
}
export default getRadarChart
\ No newline at end of file
......@@ -156,8 +156,7 @@
<div class="header-icon">
<img src="@/views/bill/billHome/assets/images/box4-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "智库人物动态" }}</div>
<div class="more">{{ "更多 +" }}</div>
<div class="header-title">{{ "社交媒体" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
......@@ -605,14 +604,13 @@ onMounted(() => {
}
}
.box3-header-title {
margin-top: 16px;
margin-left: 19px;
height: 22px;
height: 48px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 48px;
}
.more {
width: 49px;
......@@ -721,14 +719,13 @@ onMounted(() => {
}
}
.header-title {
margin-top: 16px;
height: 48px;
margin-left: 18px;
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
line-height: 48px;
}
.more {
width: 49px;
......
......@@ -56,6 +56,11 @@ export default defineConfig({
target: 'http://192.168.184.24:7861/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/aichat/, '')
},
'/checklistChat': {
target: 'http://8.140.26.4:10021/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/checklistChat/, '')
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论