提交 3729dff3 authored 作者: 付康's avatar 付康

合并分支 'zz-dev' 到 'master'

feat:智库概览页,智库详情报告分析 查看合并请求 !174
......@@ -83,6 +83,15 @@ export function getThinkTankReport(params) {
})
}
// 智库概览:政策建议(资源库-政策建议)
export function getThinkTankOverviewPolicy(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/policy`,
params
})
}
/********* 智库信息 */
//智库百科:获取全局信息
export function getThinkTankSummary(params) {
......@@ -119,6 +128,13 @@ export function getThinkPolicyIndustry(params) {
url: `/api/thinkTankInfo/policyIndustry/${params.id}/${params.year}`,
})
}
//提出政策建议涉及部门分布
export function getPolicyAdviceDeptDistribution(params){
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyDepartment/${params.id}/${params.year}`,
})
}
//获取相关政策领域分布
export function getThinkPolicyIndustryTotal(params) {
......@@ -201,6 +217,15 @@ export const getThinkTankReportSummary = (params) => {
}
);
}
//智库报告:获取相关报告
export const getThinkTankReportRelated = (params) => {
return request(
{
method: 'GET',
url: `/api/thinkTankReport/related/${params}`,
}
);
}
//获取报告原文
export const getThinkTankReportcontentUrl = (params) => {
......
......@@ -80,6 +80,7 @@ const handleToNewsAnalysis = (item, index) => {
flex-direction: column;
gap: 0 !important;
overflow: hidden;
border: 1px solid rgba(234, 236, 238, 1) !important;
.news-header {
height: 48px !important;
......@@ -149,6 +150,7 @@ const handleToNewsAnalysis = (item, index) => {
&:hover {
background: var(--color-bg-hover);
.right-top .title {
text-decoration: underline;
color: rgb(5, 95, 194) !important;
......
......@@ -50,7 +50,7 @@
</template>
<script setup>
import NewsList from "@/components/NewsList.vue";
import NewsList from "@/components/base/newsList/index.vue";
import { ref, onMounted } from "vue";
import router from '@/router'
import { getCoopRestrictionNews, getCoopRestrictionSocial } from '@/api/coopRestriction/coopRestriction'
......
......@@ -311,7 +311,7 @@
<script setup>
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import RiskSignal from "@/components/base/riskSignal/index.vue";
import NewsList from "@/components/base/newsList/index.vue";
import { onMounted, ref, computed } from "vue";
import * as echarts from "echarts";
......
......@@ -61,7 +61,7 @@
</template>
<script setup>
import NewsList from "@/components/NewsList.vue";
import NewsList from "@/components/base/newsList/index.vue";
import { ref, onBeforeMount } from "vue";
import router from "@/router"
......
......@@ -3,13 +3,8 @@
<div class="main-content" ref="homeMainRef">
<div class="home-top-bg"></div>
<!-- 搜索栏部分 -->
<SearchContainer
v-if="homeMainRef"
:countInfo="statCountInfo"
placeholder="搜索规则限制"
:containerRef="homeMainRef"
areaName=""
/>
<SearchContainer v-if="homeMainRef" :countInfo="statCountInfo" placeholder="搜索规则限制" :containerRef="homeMainRef"
areaName="" />
<!-- 最新动态 -->
<div class="newdata" id="position1">
<com-title title="最新动态" />
......
......@@ -215,9 +215,11 @@ onMounted(async () => {
margin: 0;
padding: 0;
}
.coop-page {
width: 100%;
height: 100%;
// .breadcrumb {
// width: 100%;
// height: 64px;
......@@ -245,6 +247,7 @@ onMounted(async () => {
width: 960px;
height: 168px;
margin: 0 auto 68px auto;
.search-center {
width: 688px;
height: 48px;
......@@ -284,6 +287,7 @@ onMounted(async () => {
}
}
}
.search-main {
display: flex;
padding-right: 3px;
......@@ -295,9 +299,11 @@ onMounted(async () => {
background-color: rgba(255, 255, 255, 0.65);
border-radius: 10px;
border: 1px solid #fff;
&:hover {
border: 1px solid var(--color-main-active);
}
.search-input {
border: none;
outline: none;
......@@ -315,6 +321,7 @@ onMounted(async () => {
color: #a8abb2;
}
}
.search-btn {
cursor: pointer;
display: flex;
......@@ -330,6 +337,7 @@ onMounted(async () => {
font-family: "Microsoft YaHei";
line-height: 22px;
color: #fff;
img {
width: 18px;
height: 18px;
......@@ -337,6 +345,7 @@ onMounted(async () => {
}
}
}
.search-bottom {
width: 688px;
height: 48px;
......@@ -344,6 +353,7 @@ onMounted(async () => {
margin-top: 36px;
display: flex;
justify-content: space-between;
// gap: 16px;
.btn {
display: flex;
......@@ -357,9 +367,11 @@ onMounted(async () => {
background: #e7f3ff;
cursor: pointer;
position: relative;
&:hover {
background: #cae3fc;
}
.btn-text {
width: 80px;
color: var(--color-main-active);
......@@ -370,12 +382,14 @@ onMounted(async () => {
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
top: 16px;
right: 19px;
width: 6px;
height: 12px;
img {
width: 100%;
height: 100%;
......@@ -384,40 +398,48 @@ onMounted(async () => {
}
}
}
.newdata {
width: 1600px;
height: 538px;
margin: 36px auto 64px auto;
.newdata-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.ask {
width: 1600px;
height: 528px;
margin: 0 auto 64px auto;
.ask-main {
width: 1600px;
height: 450px;
margin-top: 36px;
}
}
.datasub {
width: 1600px;
height: 538px;
margin: 0 auto 88px auto;
.datasub-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.reslib {
width: 1600px;
height: 1633px;
margin: 0 auto 0px auto;
.reslib-main {
width: 1600px;
height: 1565px;
......@@ -486,6 +508,7 @@ onMounted(async () => {
.search-icon {
width: 18px;
height: 18px;
img {
width: 100%;
height: 100%;
......@@ -522,9 +545,11 @@ onMounted(async () => {
background: #e7f3ff;
cursor: pointer;
position: relative;
&:hover {
background: #cae3fc;
}
.btn-text {
width: 80px;
color: var(--color-main-active);
......@@ -535,12 +560,14 @@ onMounted(async () => {
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
top: 16px;
right: 19px;
width: 6px;
height: 12px;
img {
width: 100%;
height: 100%;
......
......@@ -53,7 +53,7 @@
</template>
<script setup>
import NewsList from "@/components/NewsList.vue";
import NewsList from "@/components/base/newsList/index.vue";
import { ref, onMounted } from "vue";
import {
......
......@@ -19,7 +19,10 @@
</div>
</div>
<div class="header-top-right">
<div class="image-name-box">
<div class="image"> <img :src=thinkInfo.thinkTankLogoUrl alt="" /></div>
<div class="name">{{ thinkInfo.thinkTankName }}</div>
</div>
<div class="time">{{ thinkInfo.times }}</div>
</div>
</div>
......@@ -47,6 +50,12 @@
</div>
<div class="text">{{ "查看官网" }}</div>
</div> -->
<div class="btn">
<div class="icon">
<img src="./images/btn-icon2.png" alt="" />
</div>
<div class="text" @click="goToOfficialWebsite()">{{ "查看官网" }}</div>
</div>
<div class="btn">
<div class="icon">
<img src="./images/btn-icon2.png" alt="" />
......@@ -69,7 +78,7 @@
</div>
</div>
<div class="main">
<ReportAnalysis v-if="tabActiveName === '报告分析'"></ReportAnalysis>
<ReportAnalysis v-if="tabActiveName === '报告分析'" :thinkInfo="thinkInfo" :reportList="reportList"></ReportAnalysis>
<PolicyTracking v-else></PolicyTracking>
</div>
</div>
......@@ -80,12 +89,13 @@ import { ref, onMounted } from "vue";
import ReportAnalysis from "./reportAnalysis/index.vue";
import PolicyTracking from "./policyTracking/index.vue";
import { getThinkTankReportSummary } from "@/api/thinkTank/overview";
import { getThinkTankReportSummary, getThinkTankReportRelated } from "@/api/thinkTank/overview";
import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const reportUrl = ref("");
const thinkInfo = ref({});
const reportList = ref({})
// 获取报告全局信息
const handleGetThinkTankReportSummary = async () => {
......@@ -101,7 +111,20 @@ const handleGetThinkTankReportSummary = async () => {
console.error("获取报告全局信息error", error);
}
};
// 获取相关报告信息
const handleGetThinkTankReport = async () => {
try {
const res = await getThinkTankReportRelated(router.currentRoute._value.params.id);
console.log("报告全局信息", res);
if (res.code === 200 && res.data) {
reportList.value = res.data;
}
} catch (error) {
console.error("获取相关报告error", error);
}
};
const toReport = () => {
console.log(reportUrl.value, "reportUrl.valuereportUrl.value");
const route = router.resolve({
......@@ -129,7 +152,17 @@ const handleAnalysisClick = () => {
};
onMounted(async () => {
handleGetThinkTankReportSummary();
handleGetThinkTankReport();
});
const goToOfficialWebsite = () => {
const url = thinkInfo.value?.reportUrl;
if (!url) {
return;
}
// 简单校验一下,防止空字符串
window.open(url, "_blank");
};
</script>
<style lang="scss" scoped>
......@@ -199,6 +232,20 @@ onMounted(async () => {
}
.header-top-right {
display: flex;
flex-direction: column;
text-align: right;
align-items: flex-end;
.image-name-box {
width: 118px;
height: 24px;
gap: 6px;
text-align: right;
display: flex;
justify-content: flex-end;
.name {
height: 24px;
color: rgba(95, 101, 108, 1);
......@@ -208,6 +255,23 @@ onMounted(async () => {
line-height: 24px;
letter-spacing: 0px;
text-align: right;
}
.image {
width: 16px;
height: 16px;
margin-top: 5px;
img {
width: 100%;
height: 100%;
}
}
}
.time {
......
import * as echarts from 'echarts'
import { size, split } from 'lodash'
const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
return {
......@@ -19,23 +20,55 @@ const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
containLabel: true
},
legend: {
icon:'circle',
show: true,
top: 10,
left:'10%',
textStyle: {
fontSize: 16
}
fontSize: 16,
fontFamily: 'Source Han Sans CN',
fontWeight: 400,
lineHeight: 24,
letterSpacing: 0,
align: 'left',
color:'rgb(95, 101, 108)'
},
itemWidth:12,
itemHeight:12,
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: dataX
data: dataX,
axisLine: {
lineStyle: {
color: 'rgb(231, 243, 255)',
},
},
axisLabel: {
color: 'rgb(132, 136, 142)',
fontFamily: 'Microsoft YaHei',
fontWeight: 400,
fontSize:12,
},
}
],
yAxis: [
{
type: 'value'
type: 'value',
splitLine:{
show:true,
lineStyle:{
color:"rgb(231, 243, 255)",
type:'dashed'
}
}
}
],
series: [
......
......@@ -13,21 +13,31 @@ const getPieChart = (data) => {
},
label: {
alignTo: 'edge',
formatter: '{name|{b}} {time|{c} 条 {d}%}\n',
formatter: params => {
const name = params.name || "";
const value = params.value ?? "";
const percent = params.percent != null ? Math.round(params.percent) : 0;
return `{name|${name}}\n{time|${value}${percent}%}`;
},
minMargin: 10,
edgeDistance: 20,
lineHeight: 20,
rich: {
name: {
fontSize: 16,
color: 'rgba(59, 65, 75, 1)',
fontFamily: 'Microsoft YaHei',
fontWeight: 700
fontFamily: 'Source Han Sans CN',
fontWeight: 700,
lineHeight:24,
},
time: {
fontSize: 16,
fontSize: 14,
color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei',
fontFamily: 'Source Han Sans CN',
}
}
},
......
......@@ -18,7 +18,7 @@
</div>
</div>
<div class="header-top-right">
<button class="blue-btn">
<button class="blue-btn" @click="handleOpenThinkTankSite">
<img class="btn-img" src="./images/image1.png" alt="" />
<span class="text">{{ '查看智库官网' }}</span>
</button>
......@@ -88,6 +88,16 @@ const handleGetThinkTankSummary = async () => {
}
};
// 查看智库官网
const handleOpenThinkTankSite = () => {
const url = thinkTank.value?.url;
if (!url) {
return;
}
// 简单校验一下,防止空字符串
window.open(url, "_blank");
};
onMounted(async () => {
handleGetThinkTankSummary();
});
......
......@@ -18,7 +18,7 @@
<div class="select-research-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "研究类型" }}</div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
......@@ -271,16 +271,19 @@ const handleToReportDetail = item => {
};
</script>
<style lang="scss" scoped>
/* 统一智库动态国会听证会内所有 el-checkbox 文本为 16px */
:deep(.el-checkbox__label) {
font-size: 16px;
}
.main-content {
display: flex;
gap: 16px;
.left {
width: 360px;
height: 874px;
padding-bottom: 36px;
height: 100%;
padding-bottom: 24px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
......@@ -290,8 +293,8 @@ const handleToReportDetail = item => {
.select-research-box {
width: 360px;
height: 284px;
margin-top: 19px;
height: 100%;
margin-top: 16px;
.select-box-header {
display: flex;
......@@ -309,10 +312,10 @@ const handleToReportDetail = item => {
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -325,7 +328,7 @@ const handleToReportDetail = item => {
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
......@@ -343,9 +346,9 @@ const handleToReportDetail = item => {
}
.select-time-box {
margin-top: 44px;
margin-top: 16px;
width: 360px;
height: 156px;
height: 100%;
.select-box-header {
margin-bottom: 12px;
......@@ -363,10 +366,10 @@ const handleToReportDetail = item => {
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -379,7 +382,7 @@ const handleToReportDetail = item => {
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
......@@ -405,8 +408,8 @@ const handleToReportDetail = item => {
}
.select-hearing-box {
margin-top: 36px;
width: 360px;
margin-top: 16px;
width: 100%;
.select-box-header {
display: flex;
......@@ -425,9 +428,9 @@ const handleToReportDetail = item => {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -601,8 +604,4 @@ const handleToReportDetail = item => {
margin-right: 0 !important;
}
:deep(.el-checkbox__inner) {
border-radius: 4px !important;
}
</style>
\ No newline at end of file
......@@ -18,7 +18,7 @@
<div class="select-research-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "研究类型" }}</div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
......@@ -183,14 +183,19 @@ const handleToReportDetail = item => {
};
</script>
<style lang="scss" scoped>
/* 统一智库动态调查报告内所有 el-checkbox 文本为 16px */
:deep(.el-checkbox__label) {
font-size: 16px;
}
.main-content {
display: flex;
gap: 16px;
.left {
width: 360px;
height: 541px;
padding-bottom: 36px;
height: 100%;
padding-bottom: 24px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
......@@ -200,8 +205,8 @@ const handleToReportDetail = item => {
.select-research-box {
width: 360px;
height: 284px;
margin-top: 19px;
height: 100%;
margin-top: 16px;
.select-box-header {
display: flex;
......@@ -219,10 +224,10 @@ const handleToReportDetail = item => {
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -234,7 +239,7 @@ const handleToReportDetail = item => {
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
......@@ -260,9 +265,9 @@ const handleToReportDetail = item => {
}
.select-time-box {
margin-top: 44px;
margin-top: 16px;
width: 360px;
height: 156px;
height: 100%;
.select-box-header {
display: flex;
......@@ -280,10 +285,10 @@ const handleToReportDetail = item => {
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -295,7 +300,7 @@ const handleToReportDetail = item => {
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
......@@ -431,26 +436,4 @@ const handleToReportDetail = item => {
margin-right: 0 !important;
}
/* PolicyTracking 分页按钮样式:1px 描边 + 白底 + 6px 圆角 */
:deep(.right-footer .el-pagination.is-background .btn-prev),
:deep(.right-footer .el-pagination.is-background .btn-next),
:deep(.right-footer .el-pagination.is-background .el-pager li) {
border: 1px solid rgba(0, 0, 0, 0.15) !important;
background-color: rgba(255, 255, 255, 1) !important;
border-radius: 6px !important;
box-sizing: border-box;
}
// 选中状态的页码样式(描边+文字颜色改为指定蓝色)
:deep(.right-footer .el-pagination.is-background .el-pager li.is-active) {
border-color: rgba(22, 119, 255, 1) !important; // 选中后描边颜色
color: rgba(22, 119, 255, 1) !important; // 选中后页码文字颜色
background-color: rgba(255, 255, 255, 1) !important; // 保持白色背景
font-weight: 400;
}
:deep(.el-checkbox__inner) {
border-radius: 4px !important;
}
</style>
\ No newline at end of file
......@@ -18,7 +18,7 @@
<div class="select-research-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "研究类型" }}</div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
......@@ -183,14 +183,19 @@ const handleToReportDetail = item => {
};
</script>
<style lang="scss" scoped>
/* 统一智库动态智库报告内所有 el-checkbox 文本为 16px */
:deep(.el-checkbox__label) {
font-size: 16px;
}
.main-content {
display: flex;
gap: 16px;
.left {
width: 360px;
height: 541px;
padding-bottom: 36px;
height: 100%;
padding-bottom: 24px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
......@@ -200,8 +205,8 @@ const handleToReportDetail = item => {
.select-research-box {
width: 360px;
height: 284px;
margin-top: 19px;
height: 100%;
margin-top: 16px;
.select-box-header {
display: flex;
......@@ -219,10 +224,10 @@ const handleToReportDetail = item => {
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -234,7 +239,7 @@ const handleToReportDetail = item => {
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
......@@ -260,9 +265,9 @@ const handleToReportDetail = item => {
}
.select-time-box {
margin-top: 44px;
margin-top: 16px;
width: 360px;
height: 156px;
height: 100%;
.select-box-header {
display: flex;
......@@ -280,10 +285,10 @@ const handleToReportDetail = item => {
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 26px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
......@@ -295,7 +300,7 @@ const handleToReportDetail = item => {
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
......@@ -431,26 +436,4 @@ const handleToReportDetail = item => {
margin-right: 0 !important;
}
/* PolicyTracking 分页按钮样式:1px 描边 + 白底 + 6px 圆角 */
:deep(.right-footer .el-pagination.is-background .btn-prev),
:deep(.right-footer .el-pagination.is-background .btn-next),
:deep(.right-footer .el-pagination.is-background .el-pager li) {
border: 1px solid rgba(0, 0, 0, 0.15) !important;
background-color: rgba(255, 255, 255, 1) !important;
border-radius: 6px !important;
box-sizing: border-box;
}
// 选中状态的页码样式(描边+文字颜色改为指定蓝色)
:deep(.right-footer .el-pagination.is-background .el-pager li.is-active) {
border-color: rgba(22, 119, 255, 1) !important; // 选中后描边颜色
color: rgba(22, 119, 255, 1) !important; // 选中后页码文字颜色
background-color: rgba(255, 255, 255, 1) !important; // 保持白色背景
font-weight: 400;
}
:deep(.el-checkbox__inner) {
border-radius: 4px !important;
}
</style>
\ No newline at end of file
......@@ -72,25 +72,22 @@
<div v-if="isThinkTankReport">
<ThinkTankReport :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:key="`智库报告-${tabResetKey}`" :selected-filters="selectedFilters" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage"
@update:selected-filters="handleSelectedFiltersUpdate"
:current-page="currentPage" @update:selected-filters="handleSelectedFiltersUpdate"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
<div v-if="isCongressHearing">
<CongressHearing :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:key="`国会听证会-${tabResetKey}`" :research-hearing-list="researchHearingList"
:selected-filters="selectedFilters" :selected-year="selectedYear" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage" :hearing-data="hearingData"
@update:selected-filters="handleSelectedFiltersUpdate"
:key="`国会听证会-${tabResetKey}`" :research-hearing-list="researchHearingList" :selected-filters="selectedFilters"
:selected-year="selectedYear" :cur-footer-list="curFooterList" :total="total" :current-page="currentPage"
:hearing-data="hearingData" @update:selected-filters="handleSelectedFiltersUpdate"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
<div>
<SurveyForm v-if="isSurveyForm" :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:key="`调查项目-${tabResetKey}`" :selected-filters="selectedFilters" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage"
@update:selected-filters="handleSelectedFiltersUpdate"
:current-page="currentPage" @update:selected-filters="handleSelectedFiltersUpdate"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
......@@ -633,8 +630,9 @@ onMounted(async () => {
<style lang="scss" scoped>
.main-header {
height: 64px;
width: 1600px;
margin-bottom: 16px;
display: flex;
align-items: center;
background: rgb(255, 255, 255);
......@@ -889,62 +887,4 @@ onMounted(async () => {
}
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
</style>
\ No newline at end of file
......@@ -113,6 +113,10 @@
</div>
<div class="box1-main-right" id="box1Chart"></div>
</div>
<div class="source">
<div class="info"><img src="./images/image-exclamation.png"></div>
<div class="text"> 数据来源:美国国会官网,数据时间:2015.1至2025.12</div>
</div>
</AnalysisBox>
</div>
<div class="box">
......@@ -211,7 +215,13 @@
</div> -->
<AnalysisBox title="核心研究人员">
<div class="box3-main">
<div class="box3-main-left" id="box3Chart"></div>
<div class="box3-main-left">
<div id="box3Chart"></div>
<div class="source">
<div class="info"><img src="./images/image-exclamation.png"></div>
<div class="text"> 数据来源:美国国会官网,数据时间:2015.1至2025.12</div>
</div>
</div>
<div class="box3-main-right">
<div class="box3-right-item" v-for="(item, index) in box3RightData" :key="index">
<div class="icon" @click="handleClickPerson(item)">
......@@ -250,6 +260,7 @@ import {
import { useRouter } from "vue-router";
import DefaultIcon1 from '@/assets/icons/default-icon1.png'
import { getPersonSummaryInfo } from "@/api/common/index";
const router = useRouter();
import InfoImg from "./images/img.png";
......@@ -392,13 +403,11 @@ const handleGetThinkTankFundsSource = async () => {
console.log("获取经费来源", res);
if (res.code === 200 && res.data) {
let data = []
res.data.map(item => {
data.push({
const topList = Array.isArray(res.data) ? res.data.slice(0, 7) : []
const data = topList.map(item => ({
name: item.institution,
value: item.amount,
})
})
}))
box1ChartData.value = data
const box1Chart = getPieChart(box1ChartData.value);
......@@ -664,18 +673,64 @@ const handleGetThinkPerson = async () => {
};
// 点击人物头像,跳转到人物主页
const handleClickPerson = (item) => {
console.log('item', item);
window.sessionStorage.setItem("curTabName", item.name)
const handleClickPerson = async item => {
console.log("person", item);
const personTypeList = JSON.parse(window.sessionStorage.getItem("personTypeList"));
console.log("personTypeList", personTypeList);
let type = 0;
let personTypeName = "";
const params = {
personId: item.personId
};
try {
const res = await getPersonSummaryInfo(params);
console.log("人物全局信息", res);
if (res.code === 200 && res.data) {
const arr = personTypeList.filter(t => {
const typeIdNum = Number(t.typeId);
const personTypeNum = Number(res.data.personType);
return !Number.isNaN(typeIdNum) && !Number.isNaN(personTypeNum) && typeIdNum === personTypeNum;
});
console.log("arr", arr);
if (arr && arr.length > 0) {
personTypeName = arr[0].typeName;
console.log("personTypeName", personTypeName);
if (personTypeName === "科技企业领袖") {
type = 1;
} else if (personTypeName === "国会议员") {
type = 2;
} else if (personTypeName === "智库研究人员") {
type = 3;
} else {
personTypeName = "";
ElMessage.warning("找不到当前人员的类型值!");
return;
}
window.sessionStorage.setItem("curTabName", item.name);
const route = router.resolve({
path: "/characterPage",
query: {
type: 3 // 1 2 3
type: type, // type=1为科技企业领袖,2为国会议员,3为智库研究人员
personId: item.personId
}
});
window.open(route.href, "_blank");
} else {
personTypeName = "";
ElMessage.warning("找不到当前人员的类型值!");
return;
}
} else {
ElMessage.warning("找不到当前人员的类型值!");
return;
}
} catch (error) { }
};
onMounted(() => {
handleGetThinkTankInfoBasic()
handleGetThinkTankInfoBranch()
......@@ -1005,6 +1060,42 @@ onMounted(() => {
}
}
.source {
margin: 0 auto;
margin-top: 10px;
/* 上下0,左右自动居中 */
width: 370px;
height: 22px;
display: flex;
.info {
width: 16px;
height: 16px;
margin-top: 3px;
img {
width: 100%;
height: 100%;
}
}
.text {
font-family: "Source Han Sans CN";
font-weight: 400;
font-size: 14px;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
color: rgb(132, 136, 142);
margin-left: 8px;
}
}
.box2-main {
height: 320px;
display: flex;
......@@ -1144,6 +1235,48 @@ onMounted(() => {
width: 536px;
height: 326px;
margin-left: 9px;
box-sizing: border-box;
#box3Chart {
width: 536px;
height: 290px;
}
.source {
margin: 0 auto;
margin-top: 10px;
/* 上下0,左右自动居中 */
width: 370px;
height: 22px;
display: flex;
.info {
width: 16px;
height: 16px;
margin-top: 3px;
img {
width: 100%;
height: 100%;
}
}
.text {
font-family: "Source Han Sans CN";
font-weight: 400;
font-size: 14px;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
color: rgb(132, 136, 142);
margin-left: 8px;
}
}
}
......@@ -1222,6 +1355,8 @@ onMounted(() => {
}
}
}
}
}
}
......
<template>
<div class="home-main-footer-main">
<div class="left">
<div class="select-box">
<div class="header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox v-model="checkAllModel" class="all-checkbox" @change="emit('check-all-change', $event)">
全部领域
</el-checkbox>
<el-checkbox v-for="research in areaList" :key="research.id" v-model="selectedAreaListModel"
:label="research.id" @change="emit('checked-area-change')" class="filter-checkbox">
{{ research.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="select-box">
<div class="header">
<div class="icon"></div>
<div class="title">{{ "发布时间" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox v-model="checkAllTimeModel" class="all-checkbox"
@change="emit('check-all-time-change', $event)">
全部时间
</el-checkbox>
<el-checkbox v-for="time in pubTimeList" :key="time.id" v-model="selectedPubTimeListModel" :label="time.id"
class="filter-checkbox" @change="emit('checked-area-time-change')">
{{ time.name }}
</el-checkbox>
</div>
</div>
</div>
</div>
<div class="right">
<div class="card-box">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index"
@click="emit('report-click', item)">
<div class="footer-card-top">
<img :src="item.imageUrl" alt="" />
</div>
<div class="footer-card-title">
{{ item.name }}
</div>
<div class="footer-card-footer">
<div class="time">{{ item.times }}</div>
<div class="from">{{ item.thinkTankName }}</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">{{ total }} 篇政府报告</div>
<div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="emit('page-change', $event)" :current-page="currentPage" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
checkAll: { type: Boolean, default: false },
isIndeterminate: { type: Boolean, default: false },
areaList: { type: Array, default: () => [] },
selectedAreaList: { type: Array, default: () => [] },
checkAllTime: { type: Boolean, default: false },
isIndeterminateTime: { type: Boolean, default: false },
pubTimeList: { type: Array, default: () => [] },
selectedPubTimeList: { type: Array, default: () => [] },
curFooterList: { type: Array, default: () => [] },
total: { type: Number, default: 0 },
currentPage: { type: Number, default: 1 }
});
const emit = defineEmits([
"update:checkAll",
"update:selectedAreaList",
"check-all-change",
"checked-area-change",
"update:checkAllTime",
"update:selectedPubTimeList",
"check-all-time-change",
"checked-area-time-change",
"report-click",
"page-change"
]);
const checkAllModel = computed({
get: () => props.checkAll,
set: val => emit("update:checkAll", val)
});
const selectedAreaListModel = computed({
get: () => props.selectedAreaList,
set: val => emit("update:selectedAreaList", val)
});
const checkAllTimeModel = computed({
get: () => props.checkAllTime,
set: val => emit("update:checkAllTime", val)
});
const selectedPubTimeListModel = computed({
get: () => props.selectedPubTimeList,
set: val => emit("update:selectedPubTimeList", val)
});
</script>
<style lang="scss" scoped>
.home-main-footer-main {
margin: 0 auto;
margin-top: 36px;
width: 1600px;
display: flex;
gap: 16px;
.left {
width: 360px;
height: 100%;
padding-bottom: 24px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.select-box {
margin-top: 16px;
.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: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 24px;
margin-top: 12px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.all-checkbox {
width: 160px;
height: 24px;
margin: 0;
}
.filter-checkbox {
width: 160px;
height: 24px;
margin-right: 0 !important;
}
}
}
.select-main1 {
width: 100px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
.filter-checkbox {
width: 160px;
height: 24px;
margin-right: 0 !important;
}
}
}
}
}
.right {
width: 1284px;
max-height: 1377px;
.card-box {
width: 1226px;
max-height: 1248px;
min-height: 616px;
display: flex;
flex-wrap: wrap;
gap: 16px 16px;
.footer-card {
width: 398px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.footer-card-top {
width: 364px;
height: 180px;
margin: 0 auto;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 13px;
width: 376px;
height: 48px;
/* 修改高度为两行的高度 */
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
overflow: hidden;
/* 隐藏超出部分 */
text-overflow: ellipsis;
/* 显示省略号 */
display: -webkit-box;
/* 使用弹性盒模型 */
-webkit-line-clamp: 2;
/* 限制显示两行 */
-webkit-box-orient: vertical;
/* 设置盒模型方向为垂直 */
}
.footer-card-footer {
margin: 0 auto;
margin-top: 5px;
width: 376px;
height: 22px;
display: flex;
justify-content: space-between;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
}
.right-footer {
height: 50px;
margin-top: 43px;
display: flex;
justify-content: space-between;
.info {
height: 19px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
}
}
}
.filter-checkbox {
width: 160px;
height: 24px;
margin: 0;
}
</style>
<template>
<!-- 调查项目:结构/样式与智库报告一致,但组件独立,避免互相影响 -->
<div class="home-main-footer-main">
<div class="left">
<div class="select-box">
<div class="header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox v-model="checkAllModel" class="all-checkbox" @change="emit('check-all-change', $event)">
全部领域
</el-checkbox>
<el-checkbox v-for="research in areaList" :key="research.id" v-model="selectedAreaListModel"
:label="research.id" @change="emit('checked-area-change')" class="filter-checkbox">
{{ research.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="select-box">
<div class="header">
<div class="icon"></div>
<div class="title">{{ "发布时间" }}</div>
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox v-model="checkAllTimeModel" class="all-checkbox"
@change="emit('check-all-time-change', $event)">
全部时间
</el-checkbox>
<el-checkbox v-model="selectedPubTimeListModel" v-for="time in pubTimeList" :key="time.id" :label="time.id"
class="filter-checkbox" @change="emit('checked-area-time-change')">
{{ time.name }}
</el-checkbox>
</div>
</div>
</div>
</div>
<div class="right">
<div class="card-box">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index"
@click="emit('report-click', item)">
<div class="footer-card-top">
<img :src="item.imageUrl" alt="" />
</div>
<div class="footer-card-title">
{{ item.name }}
</div>
<div class="footer-card-footer">
<div class="time">{{ item.times }}</div>
<div class="from">{{ item.thinkTankName }}</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">{{ total }} 篇智库报告</div>
<div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="emit('page-change', $event)" :current-page="currentPage" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed } from "vue";
const props = defineProps({
checkAll: { type: Boolean, default: false },
isIndeterminate: { type: Boolean, default: false },
areaList: { type: Array, default: () => [] },
selectedAreaList: { type: Array, default: () => [] },
checkAllTime: { type: Boolean, default: false },
isIndeterminateTime: { type: Boolean, default: false },
pubTimeList: { type: Array, default: () => [] },
selectedPubTimeList: { type: Array, default: () => [] },
curFooterList: { type: Array, default: () => [] },
total: { type: Number, default: 0 },
currentPage: { type: Number, default: 1 }
});
const emit = defineEmits([
"update:checkAll",
"update:selectedAreaList",
"check-all-change",
"checked-area-change",
"update:checkAllTime",
"update:selectedPubTimeList",
"check-all-time-change",
"checked-area-time-change",
"report-click",
"page-change"
]);
const checkAllModel = computed({
get: () => props.checkAll,
set: val => emit("update:checkAll", val)
});
const selectedAreaListModel = computed({
get: () => props.selectedAreaList,
set: val => emit("update:selectedAreaList", val)
});
const checkAllTimeModel = computed({
get: () => props.checkAllTime,
set: val => emit("update:checkAllTime", val)
});
const selectedPubTimeListModel = computed({
get: () => props.selectedPubTimeList,
set: val => emit("update:selectedPubTimeList", val)
});
</script>
<style lang="scss" scoped>
/* 复制 HomeMainFooterMain 的样式,保证完全不影响外观 */
.home-main-footer-main {
margin: 0 auto;
margin-top: 36px;
width: 1600px;
display: flex;
gap: 16px;
.left {
width: 360px;
height: 100%;
padding-bottom: 24px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.select-box {
margin-top: 16px;
.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: "Source Han Sans CN";
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 24px;
margin-top: 12px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 160px);
gap: 8px 4px;
}
}
.select-main1 {
width: 100px;
}
}
}
.right {
width: 1284px;
max-height: 1377px;
.card-box {
width: 1226px;
max-height: 1248px;
min-height: 616px;
display: flex;
flex-wrap: wrap;
gap: 16px 16px;
.footer-card {
width: 398px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.footer-card-top {
width: 364px;
height: 180px;
margin: 0 auto;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 13px;
width: 376px;
height: 48px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.footer-card-footer {
margin: 0 auto;
margin-top: 5px;
width: 376px;
height: 22px;
display: flex;
justify-content: space-between;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
}
.right-footer {
height: 50px;
margin-top: 43px;
display: flex;
justify-content: space-between;
.info {
height: 19px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
}
}
}
.all-checkbox {
width: 160px;
height: 24px;
margin: 0;
}
.filter-checkbox {
width: 160px;
height: 24px;
margin: 0;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论