提交 e23612cd authored 作者: coderBryanFu's avatar coderBryanFu

update

上级 4f47da48
......@@ -10,4 +10,58 @@ export function getBillIndustry(params) {
url: `/api/BillOverview/billIndustry/${params.year}`,
params,
})
}
// 涉华法案统计
export function getBillCount() {
return request({
method: 'GET',
url: `/api/BillOverview/billCount`,
})
}
// 获取关键条款
export function getBillOverviewKeyTK() {
return request({
method: 'GET',
url: `/api/BillOverview/keyTk`,
})
}
// 获取热门法案列表
export function getHotBills() {
return request({
method: 'GET',
url: '/api/BillOverview/hotBills',
})
}
// 获取法案风险信号
export function getBillRiskSignal() {
return request({
method: 'GET',
url: '/api/BillOverview/riskSignal',
})
}
// 根据法案类型获取法案列表
/**
* @param {type}
*/
export function getBillsByType(params) {
return request({
method: 'GET',
url: '/api/BillOverview/bills',
params,
})
}
// 根据行业领域字典列表
export function getHylyList() {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 获取热门法案列表
export function getHotBills() {
return request({
method: 'GET',
url: '/api/BillOverview/hotBills',
})
}
// 获取法案风险信号
export function getBillRiskSignal() {
return request({
method: 'GET',
url: '/api/BillOverview/riskSignal',
})
}
// 根据法案类型获取法案列表
/**
* @param {type}
*/
export function getBillsByType(params) {
return request({
method: 'GET',
url: '/api/BillOverview/bills',
params,
})
}
// 根据行业领域字典列表
export function getHylyList() {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
\ No newline at end of file
......@@ -16,5 +16,32 @@ export function getThinkTankRiskSignal() {
method: 'GET',
url: `/api/thinkTankOverview/riskSignal`,
})
}
// 政策建议趋势分布
export function getThinkTankPolicyIndustryChange() {
return request({
method: 'GET',
url: `/api/thinkTankOverview/policyIndustryChange`,
})
}
// 政策建议领域分布
export function getThinkTankPolicyIndustry(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/policyIndustry/${params.year}`,
params
})
}
// 资金流向
export function getThinkTankDonation() {
return request({
method: 'GET',
url: `/api/thinkTankOverview/donation`,
})
}
\ No newline at end of file
......@@ -307,7 +307,7 @@
<div class="header-right-text">{{ "数据来源:美国国会官方网站" }}</div>
</div>
</div>
<div class="box5-main" id="chart1"></div>
<div class="box5-main" id="box5Chart"></div>
</div>
<div class="box6">
<div class="box6-header">
......@@ -435,10 +435,10 @@
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: activeCate === cate.name }"
v-for="(cate, index) in curCategoryList"
:class="{ btnActive: activeTabName === cate.name }"
v-for="(cate, index) in tabList"
:key="index"
@click="handleClickCate(cate)"
@click="handleClickTab(cate)"
>
{{ cate.name }}
</div>
......@@ -452,78 +452,132 @@
:value="item.value"
/>
</el-select>
<!-- <el-select
v-model="releaseTime"
placeholder="选择发布时间"
style="width: 120px"
>
<el-option
v-for="item in releaseTimeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
</div>
</div>
<div class="home-main-footer-main">
<div class="main-item" v-for="(bill, index) in curBillList" :key="index" @click="handleClickToDetail">
<div
class="status-box"
:class="{
statusBox1: bill.status === '特别重大风险',
statusBox2: bill.status === '重大风险',
statusBox3: bill.status === '一般风险'
}"
>
<div
class="status-icon"
:class="{
statusIcon1: bill.status === '特别重大风险',
statusIcon2: bill.status === '重大风险',
statusIcon3: bill.status === '一般风险'
}"
></div>
<div
class="status-text"
:class="{
status1: bill.status === '特别重大风险',
status2: bill.status === '重大风险',
status3: bill.status === '一般风险'
}"
>
{{ bill.status }}
<div class="left">
<div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="area in areaList"
:key="area.id"
v-model="activeAreaList"
:label="area.id"
class="filter-checkbox"
>
{{ area.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="main-item-box1">
<img :src="bill.img" alt="" />
</div>
<div class="main-item-box2">
{{ bill.billName }}
<div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "党派" }}</div>
</div>
<div class="select-main select-main1">
<div class="checkbox-group">
<el-checkbox
v-for="dp in dpList"
:key="dp.id"
v-model="activeDpList"
:label="dp.id"
class="filter-checkbox"
>
{{ dp.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="main-item-box3">{{ bill.introductionDate }}</div>
<div class="main-item-box4">
<span>{{ bill.yuan }}</span
><span>{{ bill.dangpai }}</span>
<div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "议院" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="yy in yyList"
:key="yy.id"
v-model="activeYyList"
:label="yy.id"
class="filter-checkbox"
>
{{ yy.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="main-item-box5">
<div class="tag" v-for="(tag, idx) in bill.tagList" :key="idx">{{ tag }}</div>
<div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "发布时间" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="time in pubTime"
:key="time.id"
v-model="activePubTime"
:label="time.id"
class="filter-checkbox"
>
{{ time.name }}
</el-checkbox>
</div>
</div>
</div>
</div>
</div>
<div class="home-main-footer-footer">
<div class="footer-left">
{{ `共${billList.length}项调查` }}
</div>
<div class="footer-right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="12"
:current-page="currentPage"
background
layout="prev, pager, next"
:total="billList.length"
/>
<div class="right">
<div class="right-header">
<div class="right-header-box">
<el-select v-model="footerSelect1" placeholder="选择委员会" style="width: 240px">
<el-option
v-for="item in footerSelectList1"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div class="right-header-box">
<el-select v-model="footerSelect2" placeholder="选择提出议员" style="width: 240px">
<el-option
v-for="item in footerSelectList2"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
</div>
<div class="right-main">
<div class="right-main-box"></div>
<div class="right-main-box"></div>
<div class="right-main-box"></div>
<div class="right-main-box"></div>
</div>
<div class="right-footer">
<div class="footer-left">
{{ `共1149项调查` }}
</div>
<div class="footer-right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="12"
:current-page="currentPage"
background
layout="prev, pager, next"
:total="1149"
/>
</div>
</div>
</div>
</div>
</div>
......@@ -533,13 +587,18 @@
<script setup>
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 {
getBillIndustry,
getHotBills,
getBillRiskSignal,
getBillsByType,
getHylyList,
getBillOverviewKeyTK,
getBillCount
} from "@/api/bill/billHome";
import DivideHeader from "@/components/DivideHeader.vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
......@@ -900,25 +959,6 @@ 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();
}
const activeCate = ref("全部分类");
const activeHylyId = ref("");
......@@ -946,33 +986,6 @@ const handleClickCate = cate => {
handleGetBillsByType();
};
const chart1Data = ref({
title: [
"2024-09",
"2024-10",
"2024-11",
"2024-12",
"2025-01",
"2025-02",
"2025-03",
"2025-04",
"2025-05",
"2025-06",
"2025-07",
"2025-08"
],
data: [
{
name: "提出法案",
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172]
},
{
name: "通过法案",
value: [6, 3, 4, 6, 11, 5, 2, 14, 16, 27, 28, 44]
}
]
});
// 新闻资讯
const newsList = ref([
{
......@@ -1070,6 +1083,53 @@ const handleGetBillsByType = async () => {
} catch (error) {}
};
// 涉华法案数量
const box5Data = ref({
title: [
"2024-09",
"2024-10",
"2024-11",
"2024-12",
"2025-01",
"2025-02",
"2025-03",
"2025-04",
"2025-05",
"2025-06",
"2025-07",
"2025-08"
],
data: [
{
name: "提出法案",
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172]
},
{
name: "通过法案",
value: [6, 3, 4, 6, 11, 5, 2, 14, 16, 27, 28, 44]
}
]
});
const handleGetBillCount = async () => {
try {
const res = await getBillCount();
console.log("涉华法案统计", res);
if (res.code === 200 && res.data) {
} else {
box5Data.value = {};
}
} catch (error) {
console.error("获取涉华法案统计error", error);
}
};
const handleBox5 = async () => {
await handleGetBillCount();
let box5Chart = getMultiLineChart(box5Data.value.title, box5Data.value.data[0].value, box5Data.value.data[1].value);
setChart(box5Chart, "box5Chart");
};
// 关键条款
const wordCloudData = ref([
{ name: "限制中国获取能源技术", value: 100 },
{ name: "未实现赤字控制目标", value: 66 },
......@@ -1092,6 +1152,27 @@ const wordCloudData = ref([
{ name: "减少燃料对外依赖", value: 81 },
{ name: "加强供应链风险管理", value: 73 }
]);
const handleGetKeyTK = async () => {
try {
const res = await getBillOverviewKeyTK();
console.log("关键条款", res);
if (res.code === 200 && res.data) {
wordCloudData.value = res.data.map(item => {
return {
name: item.clause,
value: item.count
};
});
}
} catch (error) {
console.error("获取关键条款error", error);
}
};
const handleBox6 = async () => {
await handleGetKeyTK();
const wordCloudChart = getWordCloudChart(wordCloudData.value);
setChart(wordCloudChart, "wordCloudChart");
};
// 涉华领域分布
const box9ChartColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
......@@ -1304,17 +1385,85 @@ const handleToPosi = id => {
}
};
const tabList = ref([
{
name: "国会法案",
active: true
},
{
name: "国会议员",
active: false
},
{
name: "议员合作关系",
active: false
},
{
name: "涉华委员会",
active: false
}
]);
const activeTabName = ref("国会法案");
const handleClickTab = tab => {
activeTabName.value = tab.name;
};
const areaList = [
{ id: "人工智能", name: "人工智能" },
{ id: "集成电路", name: "集成电路" },
{ id: "通信网络", name: "通信网络" },
{ id: "量子科技", name: "量子科技" }
];
const activeAreaList = ["人工智能"];
const dpList = ref([
{ id: "民主党", name: "民主党" },
{ id: "共和党", name: "共和党" }
]);
const activeDpList = ["民主党"];
const yyList = ref([
{ id: "参议院", name: "参议院" },
{ id: "众议院", name: "众议院" }
]);
const activeYyList = ["参议院"];
const pubTime = ref([
{ id: "2025年", name: "2025年" },
{ id: "2024年", name: "2024年" },
{ id: "2023年", name: "2023年" },
{ id: "2022年", name: "2022年" },
{ id: "2021年", name: "2021年" },
{ id: "更早时间", name: "更早时间" }
]);
const activePubTime = ref(["2025年"]);
const footerSelectList1 = ref([
{
label: "全部委员会",
value: "全部委员会"
}
]);
const footerSelect1 = ref("全部委员会");
const footerSelectList2 = ref([
{
label: "全部提出议员",
value: "全部提出议员"
}
]);
const footerSelect2 = ref("全部提出议员");
onMounted(async () => {
handleGetHylyList();
handleGetBillRiskSignal();
// handleGetBillsByType();
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value, chart1Data.value.data[1].value);
setChart(chart1, "chart1");
const wordCloudChart = getWordCloudChart(wordCloudData.value);
setChart(wordCloudChart, "wordCloudChart");
handleBox5(); //涉华法案统计
handleBox6(); // 关键条款
const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]);
setChart(box7Chart, "box7Chart");
......@@ -1915,7 +2064,7 @@ onUnmounted(() => {});
.box2 {
width: 520px;
height: 450px;
border-radius: 10px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
......@@ -2081,7 +2230,7 @@ onUnmounted(() => {});
.box3 {
width: 792px;
height: 450px;
border-radius: 10px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box3-header {
......@@ -2200,7 +2349,7 @@ onUnmounted(() => {});
margin-left: 20px;
width: 792px;
height: 450px;
border-radius: 10px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box4-header {
......@@ -2312,7 +2461,7 @@ onUnmounted(() => {});
.box5 {
width: 1059px;
height: 450px;
border-radius: 10px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.box5-header {
......@@ -2376,7 +2525,7 @@ onUnmounted(() => {});
margin-left: 20px;
width: 521px;
height: 450px;
border-radius: 10px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.box6-header {
......@@ -2742,7 +2891,7 @@ onUnmounted(() => {});
}
.home-main-footer {
width: 100%;
height: 1160px;
height: 1740px;
background: rgba(248, 249, 250, 1);
margin-bottom: 20px;
overflow: hidden;
......@@ -2764,38 +2913,31 @@ onUnmounted(() => {});
justify-content: space-between;
.btn-box {
display: flex;
gap: 4px;
width: 1300px;
// justify-content: space-between;
gap: 24px;
width: 1000px;
.btn {
min-width: 100px;
height: 42px;
overflow: hidden;
color: rgba(95, 101, 108, 1);
line-height: 42px;
padding: 0 20px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-size: 20px;
font-weight: 400;
line-height: 42px;
text-align: center;
border-radius: 21px;
background: rgba(20, 89, 187, 0);
padding: 0 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// background: rgba(20, 89, 187, 0);
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
}
}
.btnActive {
border-radius: 21px;
background: rgba(20, 89, 187, 1);
background: var(--color-main-active);
color: #fff;
font-weight: 700;
&:hover {
color: #fff;
background: rgba(20, 89, 187, 1);
background: var(--color-main-active);
}
}
}
......@@ -2807,141 +2949,79 @@ onUnmounted(() => {});
}
.home-main-footer-main {
width: 1600px;
height: 1401px;
margin: 0 auto;
// background: orange;
display: flex;
flex-wrap: wrap;
padding: 5px 0px;
padding-left: 5px;
overflow: hidden;
height: 700px;
.main-item {
width: 240px;
height: 320px;
.left {
width: 300px;
height: 784px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
background: linear-gradient(0deg, rgba(255, 255, 255, 1) 44%, rgba(255, 255, 255, 0) 100%);
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: #fff;
margin-bottom: 24px;
margin-right: 25px;
position: relative;
cursor: pointer;
.status-box {
position: absolute;
top: 15px;
right: 16px;
height: 28px;
padding: 0 8px;
border-radius: 20px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
.status-icon {
width: 4px;
height: 4px;
border-radius: 2px;
}
.statusIcon1 {
background: rgba(206, 79, 81, 1);
}
.statusIcon2 {
background: rgba(255, 149, 77, 1);
}
.statusIcon3 {
background: rgba(33, 129, 57, 1);
}
.status-text {
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
height: 28px;
line-height: 28px;
}
.status1 {
color: rgba(206, 79, 81, 1);
}
.status2 {
color: rgba(255, 149, 77, 1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.select-box {
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
.icon {
margin-top: 4px;
width: 8px;
height: 16px;
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 24px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.status3 {
color: rgba(33, 129, 57, 1);
.select-main {
margin-left: 25px;
}
}
.statusBox1 {
background: rgba(206, 79, 81, 0.1);
}
.statusBox2 {
background: rgba(255, 149, 77, 0.1);
}
.statusBox3 {
background: rgba(33, 129, 57, 0.1);
}
.main-item-box1 {
margin-top: 20px;
margin-left: 45px;
width: 150px;
height: 200px;
box-sizing: border-box;
img {
width: 100%;
height: 100%;
.select-main1 {
width: 100px;
}
}
.main-item-box2 {
width: 188px;
height: 50px;
}
.right {
margin-left: 20px;
width: 1280px;
.right-header {
height: 48px;
display: flex;
align-items: flex-end;
justify-content: center;
text-align: center;
margin: 0 auto;
margin-top: -45px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 25px;
gap: 18px;
}
.main-item-box3 {
text-align: center;
height: 30px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
}
.main-item-box4 {
text-align: center;
height: 30px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
gap: 15px;
display: flex;
justify-content: center;
.right-main {
height: 1264px;
.right-main-box {
width: 1280px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
margin-bottom: 16px;
}
}
.main-item-box5 {
.right-footer {
height: 85px;
display: flex;
width: 188px;
height: 24px;
margin: 0 auto;
overflow: hidden;
justify-content: center;
gap: 8px;
.tag {
height: 24px;
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: rgba(5, 95, 194, 1);
justify-content: space-between;
box-sizing: border-box;
padding-top: 12px;
.footer-left {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-size: 16px;
font-weight: 400;
line-height: 24px;
padding: 0 8px;
line-height: 32px;
}
}
}
......
......@@ -22,10 +22,10 @@ const getWordCloudChart = (data) => {
// shape: 'pentagon' // 五边形
// shape: 'star' // 星形
// shape: 'cardioid' // 心形
gridSize: 5, // 网格大小,影响词间距。
gridSize: 15, // 网格大小,影响词间距。
sizeRange: [10, 30], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 10,
rotationStep: 15,
drawOutOfBound: false, // 是否超出画布
// 字体
textStyle: {
......
......@@ -582,8 +582,6 @@ import entityIcon from "./assets/images/icon-entity.png";
import newsImg from "@/assets/images/news-img.png";
import { getHotBills, getBillsByType, getHylyList } from "@/api/home";
import getMultiLineChart from "./utils/multiLineChart";
import bill1 from "./assets/images/bill1.png";
......
......@@ -550,7 +550,6 @@ import entityIcon from "./assets/images/icon-entity.png";
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";
......
......@@ -480,14 +480,13 @@ onMounted(() => {});
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;
margin: 4px auto;
img {
width: 100%;
height: 100%;
......
......@@ -129,11 +129,12 @@
<div
class="item-left"
:class="{
itemLeftStatus1: item.status === '一般风险',
itemLeftStatus2: item.status === '重大风险'
itemLeftStatus1: item.status === '一般风险 ' || item.status === '暂无数值',
itemLeftStatus2: item.status === '重大风险',
itemLeftStatus3: item.status === '特别重大'
}"
>
{{ item.status }}
{{ item.status || "一般风险" }}
</div>
<div class="item-right">
<div class="text">
......@@ -414,7 +415,13 @@ import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue";
import setChart from "@/utils/setChart";
import { getThinkTankList, getThinkTankRiskSignal } from "@/api/thinkTank/overview";
import {
getThinkTankList,
getThinkTankRiskSignal,
getThinkTankPolicyIndustryChange,
getThinkTankPolicyIndustry,
getThinkTankDonation
} from "@/api/thinkTank/overview";
import getMultiLineChart from "./utils/multiLineChart";
import getPieChart from "./utils/piechart";
......@@ -722,23 +729,7 @@ const handleClickCate = cate => {
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 = () => {
......@@ -821,6 +812,24 @@ const curFooterList = ref([
}
]);
const box5Data = ref({
title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
data: [
{
name: "人工智能",
value: [73, 32, 42, 48, 38, 49, 63, 75, 70, 86, 95, 87]
},
{
name: "集成电路",
value: [8, 3, 2, 8, 9, 10, 12, 18, 16, 18, 20, 22]
},
{
name: "量子科技",
value: [1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3]
}
]
});
const box5selectetedYear = ref("近十年");
const box5YearList = ref([
{
......@@ -1020,30 +1029,164 @@ const handleGetThinkTankList = async () => {
// 获取智库风险信号
const handleGetThinkTankRiskSignal = async () => {
try {
const res = await getThinkTankRiskSignal()
console.log('智库风险信号',res);
const res = await getThinkTankRiskSignal();
console.log("智库风险信号", res);
if (res.code === 200) {
warningList.value = res.data.map(item => {
return {
title: item.name,
time: item.times,
id: item.reportId,
status: item.riskLevel || "暂无数值"
};
});
}
} catch (error) {
console.error("获取智库风险信号error", error);
}
}
};
onMounted(async () => {
handleGetThinkTankList();
handleGetThinkTankRiskSignal()
// 政策建议趋势分布
const handleGetThinkTankPolicyIndustryChange = async () => {
try {
const res = await getThinkTankPolicyIndustryChange();
console.log("政策建议趋势分布", res);
if(res.code === 200 && res.data) {
} else {
box5Data.value = []
}
} catch (error) {
console.error("获取政策建议趋势分布error", error);
}
};
const handleBox5 = async() => {
await handleGetThinkTankPolicyIndustryChange()
let box5Chart = getMultiLineChart(
chart1Data.value.title,
chart1Data.value.data[0].value,
chart1Data.value.data[1].value,
chart1Data.value.data[2].value
box5Data.value.title,
box5Data.value.data[0].value,
box5Data.value.data[1].value,
box5Data.value.data[2].value
);
setChart(box5Chart, "box5Chart");
}
// 政策建议趋势分布
const handleGetThinkTankPolicyIndustry = async () => {
const params = {
apply: 1,
yaer: box6selectetedYear.value
}
try {
const res = await getThinkTankPolicyIndustry(params);
console.log("政策建议领域分布", res);
if(res.code === 200 && res.data) {
} else {
box6Data.value = []
}
} catch (error) {
console.error("获取政策建议领域分布error", error);
}
};
const handleBox6 = async() => {
await handleGetThinkTankPolicyIndustry()
const box6Chart = getPieChart(box6Data.value);
setChart(box6Chart, "box6Chart");
}
function transformThinkTankData(data) {
const nodes = [];
const links = [];
const nodeSet = new Set(); // 用于去重
// 遍历每个智库
data.forEach(thinkTank => {
const thinkTankName = thinkTank.thinkTankName;
// 添加智库节点
if (!nodeSet.has(thinkTankName)) {
nodes.push({ name: thinkTankName });
nodeSet.add(thinkTankName);
}
// 遍历每个资金来源
thinkTank.thinkTankDonationSourceVOList.forEach(source => {
const { amount, institution, secondInstitution } = source;
// 处理机构节点
if (institution && !nodeSet.has(institution)) {
nodes.push({ name: institution });
nodeSet.add(institution);
}
// 处理二级机构节点
if (secondInstitution && !nodeSet.has(secondInstitution)) {
nodes.push({ name: secondInstitution });
nodeSet.add(secondInstitution);
}
// 构建链接
if (institution && secondInstitution) {
// 情况1: institution → secondInstitution → thinkTankName
links.push({
source: institution,
target: secondInstitution,
value: amount
});
links.push({
source: secondInstitution,
target: thinkTankName,
value: amount
});
} else if (institution && !secondInstitution) {
// 情况2: institution → thinkTankName
links.push({
source: institution,
target: thinkTankName,
value: amount
});
} else if (!institution && !secondInstitution) {
// 情况3: 只有智库节点
links.push({
source: thinkTankName,
value: amount
});
}
});
});
return { nodes, links };
}
// 智库资金流向
const handleGetThinkTankDonation = async () => {
try {
const res = await getThinkTankDonation();
console.log("智库资金流向", res);
if (res.code === 200 && res.data) {
box7Data.value = transformThinkTankData(res.data);
}
} catch (error) {
console.error("获取智库资金流向error", error);
}
};
const handleBox7 = async () => {
await handleGetThinkTankDonation();
const box7Chart = getSankeyChart(box7Data.value.nodes, box7Data.value.links);
setChart(box7Chart, "box7Chart");
};
onMounted(async () => {
handleGetThinkTankList();
handleGetThinkTankRiskSignal();
handleBox5()
handleBox6()
handleBox7();
});
</script>
......@@ -1521,22 +1664,13 @@ onMounted(async () => {
&: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;
......@@ -1545,6 +1679,18 @@ onMounted(async () => {
padding: 6px 4px;
text-align: center;
}
.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;
}
.itemLeftStatus3 {
color: rgba(245, 34, 45, 1);
background: rgba(255, 241, 240);
}
.item-right {
margin-left: 13px;
width: 408px;
......@@ -1552,12 +1698,15 @@ onMounted(async () => {
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.text {
width: 348px;
width: 315px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 47px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
margin-left: 10px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论