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

update

上级 4f47da48
...@@ -10,4 +10,58 @@ export function getBillIndustry(params) { ...@@ -10,4 +10,58 @@ export function getBillIndustry(params) {
url: `/api/BillOverview/billIndustry/${params.year}`, url: `/api/BillOverview/billIndustry/${params.year}`,
params, 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() { ...@@ -16,5 +16,32 @@ export function getThinkTankRiskSignal() {
method: 'GET', method: 'GET',
url: `/api/thinkTankOverview/riskSignal`, 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 @@ ...@@ -307,7 +307,7 @@
<div class="header-right-text">{{ "数据来源:美国国会官方网站" }}</div> <div class="header-right-text">{{ "数据来源:美国国会官方网站" }}</div>
</div> </div>
</div> </div>
<div class="box5-main" id="chart1"></div> <div class="box5-main" id="box5Chart"></div>
</div> </div>
<div class="box6"> <div class="box6">
<div class="box6-header"> <div class="box6-header">
...@@ -435,10 +435,10 @@ ...@@ -435,10 +435,10 @@
<div class="btn-box"> <div class="btn-box">
<div <div
class="btn" class="btn"
:class="{ btnActive: activeCate === cate.name }" :class="{ btnActive: activeTabName === cate.name }"
v-for="(cate, index) in curCategoryList" v-for="(cate, index) in tabList"
:key="index" :key="index"
@click="handleClickCate(cate)" @click="handleClickTab(cate)"
> >
{{ cate.name }} {{ cate.name }}
</div> </div>
...@@ -452,78 +452,132 @@ ...@@ -452,78 +452,132 @@
:value="item.value" :value="item.value"
/> />
</el-select> </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> </div>
<div class="home-main-footer-main"> <div class="home-main-footer-main">
<div class="main-item" v-for="(bill, index) in curBillList" :key="index" @click="handleClickToDetail"> <div class="left">
<div <div class="select-box">
class="status-box" <div class="select-box-header">
:class="{ <div class="icon"></div>
statusBox1: bill.status === '特别重大风险', <div class="title">{{ "科技领域" }}</div>
statusBox2: bill.status === '重大风险', </div>
statusBox3: bill.status === '一般风险' <div class="select-main">
}" <div class="checkbox-group">
> <el-checkbox
<div v-for="area in areaList"
class="status-icon" :key="area.id"
:class="{ v-model="activeAreaList"
statusIcon1: bill.status === '特别重大风险', :label="area.id"
statusIcon2: bill.status === '重大风险', class="filter-checkbox"
statusIcon3: bill.status === '一般风险' >
}" {{ area.name }}
></div> </el-checkbox>
<div </div>
class="status-text"
:class="{
status1: bill.status === '特别重大风险',
status2: bill.status === '重大风险',
status3: bill.status === '一般风险'
}"
>
{{ bill.status }}
</div> </div>
</div> </div>
<div class="main-item-box1"> <div class="select-box">
<img :src="bill.img" alt="" /> <div class="select-box-header">
</div> <div class="icon"></div>
<div class="main-item-box2"> <div class="title">{{ "党派" }}</div>
{{ bill.billName }} </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>
<div class="main-item-box3">{{ bill.introductionDate }}</div> <div class="select-box">
<div class="main-item-box4"> <div class="select-box-header">
<span>{{ bill.yuan }}</span <div class="icon"></div>
><span>{{ bill.dangpai }}</span> <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>
<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>
</div> <div class="right">
<div class="home-main-footer-footer"> <div class="right-header">
<div class="footer-left"> <div class="right-header-box">
{{ `共${billList.length}项调查` }} <el-select v-model="footerSelect1" placeholder="选择委员会" style="width: 240px">
</div> <el-option
<div class="footer-right"> v-for="item in footerSelectList1"
<el-pagination :key="item.value"
@current-change="handleCurrentChange" :label="item.label"
:pageSize="12" :value="item.value"
:current-page="currentPage" />
background </el-select>
layout="prev, pager, next" </div>
:total="billList.length" <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> </div>
</div> </div>
...@@ -533,13 +587,18 @@ ...@@ -533,13 +587,18 @@
<script setup> <script setup>
import { onMounted, ref, computed, onUnmounted, nextTick } from "vue"; import { onMounted, ref, computed, onUnmounted, nextTick } from "vue";
import * as echarts from "echarts";
import router from "@/router/index"; import router from "@/router/index";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import { getBillIndustry } from "@/api/bill/billHome"; import {
getBillIndustry,
import { getHotBills, getBillRiskSignal, getBillsByType, getHylyList } from "@/api/home"; getHotBills,
getBillRiskSignal,
getBillsByType,
getHylyList,
getBillOverviewKeyTK,
getBillCount
} from "@/api/bill/billHome";
import DivideHeader from "@/components/DivideHeader.vue"; import DivideHeader from "@/components/DivideHeader.vue";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
...@@ -900,25 +959,6 @@ const curCategoryList = ref([]); ...@@ -900,25 +959,6 @@ const curCategoryList = ref([]);
const curCategoryIndex = ref(0); const curCategoryIndex = ref(0);
const SHOW_COUNT = 10; 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 activeCate = ref("全部分类");
const activeHylyId = ref(""); const activeHylyId = ref("");
...@@ -946,33 +986,6 @@ const handleClickCate = cate => { ...@@ -946,33 +986,6 @@ const handleClickCate = cate => {
handleGetBillsByType(); 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([ const newsList = ref([
{ {
...@@ -1070,6 +1083,53 @@ const handleGetBillsByType = async () => { ...@@ -1070,6 +1083,53 @@ const handleGetBillsByType = async () => {
} catch (error) {} } 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([ const wordCloudData = ref([
{ name: "限制中国获取能源技术", value: 100 }, { name: "限制中国获取能源技术", value: 100 },
{ name: "未实现赤字控制目标", value: 66 }, { name: "未实现赤字控制目标", value: 66 },
...@@ -1092,6 +1152,27 @@ const wordCloudData = ref([ ...@@ -1092,6 +1152,27 @@ const wordCloudData = ref([
{ name: "减少燃料对外依赖", value: 81 }, { name: "减少燃料对外依赖", value: 81 },
{ name: "加强供应链风险管理", value: 73 } { 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"]); const box9ChartColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
...@@ -1304,17 +1385,85 @@ const handleToPosi = id => { ...@@ -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 () => { onMounted(async () => {
handleGetHylyList(); handleGetHylyList();
handleGetBillRiskSignal(); handleGetBillRiskSignal();
// handleGetBillsByType(); // 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); handleBox5(); //涉华法案统计
setChart(wordCloudChart, "wordCloudChart"); handleBox6(); // 关键条款
const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]); const box7Chart = getDoublePieChart(box7Data.value[0], box7Data.value[1]);
setChart(box7Chart, "box7Chart"); setChart(box7Chart, "box7Chart");
...@@ -1915,7 +2064,7 @@ onUnmounted(() => {}); ...@@ -1915,7 +2064,7 @@ onUnmounted(() => {});
.box2 { .box2 {
width: 520px; width: 520px;
height: 450px; height: 450px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
position: relative; position: relative;
...@@ -2081,7 +2230,7 @@ onUnmounted(() => {}); ...@@ -2081,7 +2230,7 @@ onUnmounted(() => {});
.box3 { .box3 {
width: 792px; width: 792px;
height: 450px; height: 450px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2); box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box3-header { .box3-header {
...@@ -2200,7 +2349,7 @@ onUnmounted(() => {}); ...@@ -2200,7 +2349,7 @@ onUnmounted(() => {});
margin-left: 20px; margin-left: 20px;
width: 792px; width: 792px;
height: 450px; height: 450px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2); box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box4-header { .box4-header {
...@@ -2312,7 +2461,7 @@ onUnmounted(() => {}); ...@@ -2312,7 +2461,7 @@ onUnmounted(() => {});
.box5 { .box5 {
width: 1059px; width: 1059px;
height: 450px; height: 450px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box5-header { .box5-header {
...@@ -2376,7 +2525,7 @@ onUnmounted(() => {}); ...@@ -2376,7 +2525,7 @@ onUnmounted(() => {});
margin-left: 20px; margin-left: 20px;
width: 521px; width: 521px;
height: 450px; height: 450px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box6-header { .box6-header {
...@@ -2742,7 +2891,7 @@ onUnmounted(() => {}); ...@@ -2742,7 +2891,7 @@ onUnmounted(() => {});
} }
.home-main-footer { .home-main-footer {
width: 100%; width: 100%;
height: 1160px; height: 1740px;
background: rgba(248, 249, 250, 1); background: rgba(248, 249, 250, 1);
margin-bottom: 20px; margin-bottom: 20px;
overflow: hidden; overflow: hidden;
...@@ -2764,38 +2913,31 @@ onUnmounted(() => {}); ...@@ -2764,38 +2913,31 @@ onUnmounted(() => {});
justify-content: space-between; justify-content: space-between;
.btn-box { .btn-box {
display: flex; display: flex;
gap: 4px; gap: 24px;
width: 1300px; width: 1000px;
// justify-content: space-between;
.btn { .btn {
min-width: 100px;
height: 42px; height: 42px;
overflow: hidden; line-height: 42px;
color: rgba(95, 101, 108, 1); padding: 0 20px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 20px;
font-weight: 400; font-weight: 400;
line-height: 42px;
text-align: center;
border-radius: 21px; border-radius: 21px;
background: rgba(20, 89, 187, 0); // background: rgba(20, 89, 187, 0);
padding: 0 15px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: rgba(20, 89, 187, 0.1); background: rgba(20, 89, 187, 0.1);
} }
} }
.btnActive { .btnActive {
border-radius: 21px; background: var(--color-main-active);
background: rgba(20, 89, 187, 1);
color: #fff; color: #fff;
font-weight: 700; font-weight: 700;
&:hover { &:hover {
color: #fff; color: #fff;
background: rgba(20, 89, 187, 1); background: var(--color-main-active);
} }
} }
} }
...@@ -2807,141 +2949,79 @@ onUnmounted(() => {}); ...@@ -2807,141 +2949,79 @@ onUnmounted(() => {});
} }
.home-main-footer-main { .home-main-footer-main {
width: 1600px; width: 1600px;
height: 1401px;
margin: 0 auto; margin: 0 auto;
// background: orange;
display: flex; display: flex;
flex-wrap: wrap; .left {
padding: 5px 0px; width: 300px;
padding-left: 5px; height: 784px;
overflow: hidden; box-sizing: border-box;
height: 700px; border: 1px solid rgba(234, 236, 238, 1);
.main-item {
width: 240px;
height: 320px;
border-radius: 10px; border-radius: 10px;
background: linear-gradient(0deg, rgba(255, 255, 255, 1) 44%, rgba(255, 255, 255, 0) 100%); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); background: rgba(255, 255, 255, 1);
background: #fff; .select-box {
margin-bottom: 24px; margin-top: 21px;
margin-right: 25px; .select-box-header {
position: relative; display: flex;
cursor: pointer; gap: 17px;
.status-box { .icon {
position: absolute; margin-top: 4px;
top: 15px; width: 8px;
right: 16px; height: 16px;
height: 28px; background: var(--color-main-active);
padding: 0 8px; border-radius: 0 4px 4px 0;
border-radius: 20px; }
display: flex; .title {
justify-content: center; height: 24px;
align-items: center; color: var(--color-main-active);
gap: 8px; font-family: Microsoft YaHei;
.status-icon { font-size: 16px;
width: 4px; font-weight: 700;
height: 4px; line-height: 24px;
border-radius: 2px; letter-spacing: 1px;
} text-align: left;
.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);
} }
.status3 { .select-main {
color: rgba(33, 129, 57, 1); margin-left: 25px;
} }
} .select-main1 {
.statusBox1 { width: 100px;
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%;
} }
} }
.main-item-box2 { }
width: 188px; .right {
height: 50px; margin-left: 20px;
width: 1280px;
.right-header {
height: 48px;
display: flex; display: flex;
align-items: flex-end; gap: 18px;
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;
} }
.main-item-box3 { .right-main {
text-align: center; height: 1264px;
height: 30px; .right-main-box {
color: rgba(132, 136, 142, 1); width: 1280px;
font-family: Microsoft YaHei; height: 300px;
font-size: 16px; border-radius: 10px;
font-weight: 400; box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
line-height: 30px; background: rgba(255, 255, 255, 1);
} margin-bottom: 16px;
.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;
} }
.main-item-box5 { .right-footer {
height: 85px;
display: flex; display: flex;
width: 188px; justify-content: space-between;
height: 24px; box-sizing: border-box;
margin: 0 auto; padding-top: 12px;
overflow: hidden; .footer-left {
justify-content: center; color: rgba(59, 65, 75, 1);
gap: 8px;
.tag {
height: 24px;
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 14px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 32px;
padding: 0 8px;
} }
} }
} }
......
...@@ -22,10 +22,10 @@ const getWordCloudChart = (data) => { ...@@ -22,10 +22,10 @@ const getWordCloudChart = (data) => {
// shape: 'pentagon' // 五边形 // shape: 'pentagon' // 五边形
// shape: 'star' // 星形 // shape: 'star' // 星形
// shape: 'cardioid' // 心形 // shape: 'cardioid' // 心形
gridSize: 5, // 网格大小,影响词间距。 gridSize: 15, // 网格大小,影响词间距。
sizeRange: [10, 30], // 定义词云中文字大小的范围 sizeRange: [10, 30], // 定义词云中文字大小的范围
rotationRange: [0, 0], rotationRange: [0, 0],
rotationStep: 10, rotationStep: 15,
drawOutOfBound: false, // 是否超出画布 drawOutOfBound: false, // 是否超出画布
// 字体 // 字体
textStyle: { textStyle: {
......
...@@ -582,8 +582,6 @@ import entityIcon from "./assets/images/icon-entity.png"; ...@@ -582,8 +582,6 @@ import entityIcon from "./assets/images/icon-entity.png";
import newsImg from "@/assets/images/news-img.png"; import newsImg from "@/assets/images/news-img.png";
import { getHotBills, getBillsByType, getHylyList } from "@/api/home";
import getMultiLineChart from "./utils/multiLineChart"; import getMultiLineChart from "./utils/multiLineChart";
import bill1 from "./assets/images/bill1.png"; import bill1 from "./assets/images/bill1.png";
......
...@@ -550,7 +550,6 @@ import entityIcon from "./assets/images/icon-entity.png"; ...@@ -550,7 +550,6 @@ import entityIcon from "./assets/images/icon-entity.png";
import newsImg from "@/assets/images/news-img.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 headerIcon1 from "./assets/icons/header-icon1.png";
import headerIcon2 from "./assets/icons/header-icon2.png"; import headerIcon2 from "./assets/icons/header-icon2.png";
......
...@@ -480,14 +480,13 @@ onMounted(() => {}); ...@@ -480,14 +480,13 @@ onMounted(() => {});
width: 36px; width: 36px;
height: 36px; height: 36px;
line-height: 36px; line-height: 36px;
// box-sizing: border-box;
border-radius: 4px; border-radius: 4px;
background: rgba(255, 255, 255, 0.3); background: rgba(255, 255, 255, 0.3);
cursor: pointer; cursor: pointer;
.header-img-box { .header-img-box {
width: 19px; width: 19px;
height: 24px; height: 24px;
margin: 6px auto; margin: 4px auto;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
......
...@@ -129,11 +129,12 @@ ...@@ -129,11 +129,12 @@
<div <div
class="item-left" class="item-left"
:class="{ :class="{
itemLeftStatus1: item.status === '一般风险', itemLeftStatus1: item.status === '一般风险 ' || item.status === '暂无数值',
itemLeftStatus2: item.status === '重大风险' itemLeftStatus2: item.status === '重大风险',
itemLeftStatus3: item.status === '特别重大'
}" }"
> >
{{ item.status }} {{ item.status || "一般风险" }}
</div> </div>
<div class="item-right"> <div class="item-right">
<div class="text"> <div class="text">
...@@ -414,7 +415,13 @@ import router from "@/router"; ...@@ -414,7 +415,13 @@ import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue"; import DivideHeader from "@/components/DivideHeader.vue";
import setChart from "@/utils/setChart"; 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 getMultiLineChart from "./utils/multiLineChart";
import getPieChart from "./utils/piechart"; import getPieChart from "./utils/piechart";
...@@ -722,23 +729,7 @@ const handleClickCate = cate => { ...@@ -722,23 +729,7 @@ const handleClickCate = cate => {
handleGetBillsByType(); 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 handleToMoreRiskSignal = () => {
...@@ -821,6 +812,24 @@ const curFooterList = ref([ ...@@ -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 box5selectetedYear = ref("近十年");
const box5YearList = ref([ const box5YearList = ref([
{ {
...@@ -1020,30 +1029,164 @@ const handleGetThinkTankList = async () => { ...@@ -1020,30 +1029,164 @@ const handleGetThinkTankList = async () => {
// 获取智库风险信号 // 获取智库风险信号
const handleGetThinkTankRiskSignal = async () => { const handleGetThinkTankRiskSignal = async () => {
try { try {
const res = await getThinkTankRiskSignal() const res = await getThinkTankRiskSignal();
console.log('智库风险信号',res); 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) { } catch (error) {
console.error("获取智库风险信号error", error); console.error("获取智库风险信号error", error);
} }
} };
onMounted(async () => { // 政策建议趋势分布
handleGetThinkTankList(); const handleGetThinkTankPolicyIndustryChange = async () => {
handleGetThinkTankRiskSignal() 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( let box5Chart = getMultiLineChart(
chart1Data.value.title, box5Data.value.title,
chart1Data.value.data[0].value, box5Data.value.data[0].value,
chart1Data.value.data[1].value, box5Data.value.data[1].value,
chart1Data.value.data[2].value box5Data.value.data[2].value
); );
setChart(box5Chart, "box5Chart"); 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); const box6Chart = getPieChart(box6Data.value);
setChart(box6Chart, "box6Chart"); 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); const box7Chart = getSankeyChart(box7Data.value.nodes, box7Data.value.links);
setChart(box7Chart, "box7Chart"); setChart(box7Chart, "box7Chart");
};
onMounted(async () => {
handleGetThinkTankList();
handleGetThinkTankRiskSignal();
handleBox5()
handleBox6()
handleBox7();
}); });
</script> </script>
...@@ -1521,22 +1664,13 @@ onMounted(async () => { ...@@ -1521,22 +1664,13 @@ onMounted(async () => {
&:hover { &:hover {
background: var(--color-bg-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 { .item-left {
margin-top: 4px; margin-top: 4px;
margin-left: 2px; margin-left: 2px;
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 20px; border-radius: 20px;
background: rgba(255, 241, 240);
color: rgba(245, 34, 45, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 12px; font-size: 12px;
font-weight: 400; font-weight: 400;
...@@ -1545,6 +1679,18 @@ onMounted(async () => { ...@@ -1545,6 +1679,18 @@ onMounted(async () => {
padding: 6px 4px; padding: 6px 4px;
text-align: center; 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 { .item-right {
margin-left: 13px; margin-left: 13px;
width: 408px; width: 408px;
...@@ -1552,12 +1698,15 @@ onMounted(async () => { ...@@ -1552,12 +1698,15 @@ onMounted(async () => {
border-bottom: 1px solid rgba(240, 242, 244, 1); border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex; display: flex;
.text { .text {
width: 348px; width: 315px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 47px; line-height: 47px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.time { .time {
margin-left: 10px; margin-left: 10px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论