提交 b0e9b3b2 authored 作者: 朱政's avatar 朱政

feat:智库主页智库动态智库报告、调查项目、国会听诊会项目按要求完善,智库主页政策追踪部分完成

上级 0ad9f2da
<template>
<div class="search-container" v-show="!isShow">
<div class="search-main">
<input v-model="store.searchBillText" :placeholder="placeholder" @keyup.enter="handleSearch" class="search-input" />
<input v-model="store.searchBillText" :placeholder="placeholder" @keyup.enter="handleSearch"
class="search-input" />
<div class="search-btn" @click="handleSearch">
<img src="@/assets/icons/search-icon.png" alt />
搜索
......@@ -100,7 +101,7 @@ watchEffect(() => {
store.changeIsShowSearchBar(isShow.value);
});
store.setSearchData({ placeholder, areaName,containerRef:homeMainRef });
store.setSearchData({ placeholder, areaName, containerRef: homeMainRef });
// 锚点跳转
const handleToPosi = id => {
const element = document.getElementById(id);
......@@ -131,6 +132,7 @@ const handleToPosi = id => {
width: 960px;
height: 168px;
margin: 0 auto 68px auto;
.search-center {
width: 688px;
height: 48px;
......@@ -170,6 +172,7 @@ const handleToPosi = id => {
}
}
}
.search-main {
display: flex;
padding-right: 3px;
......@@ -181,9 +184,11 @@ const handleToPosi = id => {
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;
......@@ -201,6 +206,7 @@ const handleToPosi = id => {
color: #a8abb2;
}
}
.search-btn {
cursor: pointer;
display: flex;
......@@ -216,6 +222,7 @@ const handleToPosi = id => {
font-family: "Microsoft YaHei";
line-height: 22px;
color: #fff;
img {
width: 18px;
height: 18px;
......@@ -223,6 +230,7 @@ const handleToPosi = id => {
}
}
}
.search-bottom {
width: 688px;
height: 48px;
......@@ -230,6 +238,7 @@ const handleToPosi = id => {
margin-top: 36px;
display: flex;
justify-content: space-between;
// gap: 16px;
.btn {
display: flex;
......@@ -243,9 +252,11 @@ const handleToPosi = id => {
background: #e7f3ff;
cursor: pointer;
position: relative;
&:hover {
background: #cae3fc;
}
.btn-text {
width: 80px;
color: var(--color-main-active);
......@@ -256,12 +267,14 @@ const handleToPosi = id => {
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
top: 16px;
right: 19px;
width: 6px;
height: 12px;
img {
width: 100%;
height: 100%;
......
......@@ -4,7 +4,9 @@
<div class="header-icon">
<img src="./image1.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
<div class="header-title">
<slot name='title'>{{ "社交媒体" }}</slot>
</div>
<div class="more" @click="handleToMoreNews">{{ "更多 +" }}</div>
</div>
<div class="box4-main">
......@@ -149,7 +151,7 @@ const handleToMoreNews = (item) => {
}
.header-title {
width: 80px;
width: 100%;
margin-top: 11px;
margin-left: 18px;
height: 26px;
......
......@@ -29,7 +29,7 @@
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt />
</div>
</div>
</div>,
<div class="btn" @click="handleToPosi('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">
......
......@@ -6,17 +6,35 @@
<div class="icon">
<img src="./images/box-header-icon1.png" alt="" />
</div>
<div class="title">{{ "提出建议领域分布" }}</div>
<div class="title">{{ "政策建议领域分布" }}</div>
<!-- <div class="box-header-right">{{ "查看数据源 >" }}</div> -->
<div class="select-box">
<el-select v-model="box1SelectYear" placeholder="选择时间" style="width: 100px">
<el-option v-for="(item, index) in box1YearList" :key="index" :label="item.label + '年'"
:value="item.value" @click="handleGetThinkPolicyIndustry()" />
</el-select>
</div>
</div>
<div class="box-main">
<div id="box1Chart"></div>
</div>
</div>
<div class="box1 box">
<div class="box-header">
<div class="icon">
<img src="./images/box-header-icon2.png" alt="" />
</div>
<div class="title">{{ "政策建议涉及部门分布" }}</div>
<!-- <div class="box-header-right">{{ "查看数据源 >" }}</div> -->
<div class="select-box">
<el-select v-model="box1SelectYear" placeholder="选择时间" style="width: 100px">
<el-option v-for="(item, index) in box1YearList" :key="index" :label="item.label" :value="item.value"
@click="handleGetThinkPolicyIndustry()" />
<el-option v-for="(item, index) in box1YearList" :key="index" :label="item.label + '年'"
:value="item.value" @click="handleGetThinkPolicyIndustry()" />
</el-select>
</div>
<div id="box1Chart"></div>
</div>
<div class="box-main">
<div id="box2Chart"></div>
</div>
</div>
<!-- <div class="box2 box">
......@@ -53,14 +71,14 @@
</div>
<div class="title">{{ "热门研究方向变化趋势" }}</div>
<!-- <div class="box-header-right">{{ "查看数据源 >" }}</div> -->
</div>
<div class="box-main">
<div class="select-box">
<el-select v-model="box3SelectMonths" placeholder="选择时间" style="width: 100px">
<el-option v-for="item in box3MonthsList" :key="item.value" :label="item.label" :value="item.value"
<el-option v-for="item in box3MonthsList" :key="item.value" :label="item.label + '年'" :value="item.value"
@click="handleGetThinkPolicyIndustryChange()" />
</el-select>
</div>
</div>
<div class="box-main">
<div id="box3Chart"></div>
</div>
</div>
......@@ -78,43 +96,68 @@
<el-select v-model="selectedYear" placeholder="选择时间" style="width: 120px" @click="handleGetThinkPolicy()">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div class="paixu-btn" @click="handleSwithSort()">
<div class="icon1">
<img v-if="sort" src="@/assets/icons/shengxu1.png" alt="" />
<img v-else src="@/assets/icons/jiangxu1.png" alt="" />
</div>
<div class="text">{{ "发布时间" }}</div>
<div class="icon2">
<img v-if="sort" src="@/assets/icons/shengxu2.png" alt="" />
<img v-else src="@/assets/icons/jiangxu2.png" alt="" />
</div>
</div>
<!-- <el-select v-model="sort" placeholder="发布时间" style="width: 120px; margin-left: 8px">
<el-select class="select-box-sort" v-model="sort" placeholder="倒序" style="width: 120px;" :teleported="true"
:placement="'bottom-start'" :popper-options="{
modifiers: [
{
name: 'preventOverflow',
options: { mainAxis: false, altAxis: false }
},
{
name: 'flip',
enabled: false
}
]
}">
<template #prefix>
<img v-if="!sort" src="../thinkDynamics/images/image down.png" class="select-prefix-img" alt="" />
<img v-else src="../thinkDynamics/images/image up.png" class="select-prefix-img" alt="" />
</template>
<el-option @click="handleGetThinkPolicy()" :key="true" label="正序" :value="true" />
<el-option @click="handleGetThinkPolicy()" :key="false" label="倒序" :value="false" />
</el-select> -->
</el-select>
</div>
</div>
<div class="bottom-main">
<div class="left">
<div class="select-box">
<div class="select-box-header" style=" display: flex;">
<div class="select-box-science">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main" style="padding: 25px;">
<div class="select-main">
<div class="checkbox-group">
<!-- <el-checkbox v-for="(item, index) in areaList" :key="index" v-model="selectedAreaList" :label="item"
class="filter-checkbox">
{{ item }}
</el-checkbox> -->
<el-checkbox style="width: 180px" v-for="research in areaList" :key="research.id"
v-model="selectedAreaList" :label="research.id" class="filter-checkbox">
<el-checkbox class="filter-checkbox" label="全部领域"></el-checkbox>
<el-checkbox class="filter-checkbox" v-for="research in areaList" :key="research.id"
v-model="selectedAreaList" :label="research.id">
{{ research.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="select-box-publish">
<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="(item, index) in areaList" :key="index" v-model="selectedAreaList" :label="item"
class="filter-checkbox">
{{ item }}
</el-checkbox> -->
<el-checkbox class="filter-checkbox" label="全部领域"></el-checkbox>
<el-checkbox class="filter-checkbox" v-for="year in selectableYears" :key="year"
v-model="selectedAreaList" :label="year">
{{ year }}
</el-checkbox>
</div>
</div>
</div>
</div>
<div class="right">
<div class="right-main">
......@@ -244,7 +287,7 @@ const box1YearList = ref([
value: "2023"
}
]);
const selectableYears = ref(["2025年", "2024年", "2023年", "2022年", "2021年", "更早"]);
const handleGetThinkPolicyIndustry = async () => {
try {
const parmas = {
......@@ -265,6 +308,7 @@ const handleGetThinkPolicyIndustry = async () => {
box1Data.value = data;
const box1Chart = getPieChart(box1Data.value);
setChart(box1Chart, "box1Chart");
setChart(box1Chart, "box2Chart");
}
} catch (error) {
console.error("获取提出建议领域分布error", error);
......@@ -458,7 +502,7 @@ const selectedAreaList = ref([]);
const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("智库研究类型信息", res);
console.log("智库研究类型信息", res.data);
if (res.code === 200 && res.data) {
areaList.value = res.data;
}
......@@ -617,12 +661,12 @@ onMounted(() => {
.top {
height: 420px;
width: 1600px;
margin: 24px 0;
margin: 16px 0;
display: flex;
gap: 16px;
.box {
width: 790px;
width: 520px;
height: 420px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
......@@ -631,7 +675,7 @@ onMounted(() => {
background: rgba(255, 255, 255, 1);
.box-header {
width: 790px;
width: 520px;
height: 48px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
......@@ -675,87 +719,34 @@ onMounted(() => {
letter-spacing: 0px;
text-align: right;
}
}
.box-main {
height: 360px;
position: relative;
overflow: hidden;
#box1Chart {
height: 360px;
}
#box2Chart {
width: 470px;
margin: 0 auto;
margin-top: 50px;
height: 300px;
overflow: hidden;
overflow-y: auto;
.box2-item {
height: 30px;
margin-top: 20px;
display: flex;
align-items: center;
.icon {
width: 12px;
height: 12px;
border-radius: 6px;
}
.select-box {
position: absolute;
z-index: 999;
top: 12px;
right: 43px;
width: 100px;
height: 28px;
.name {
width: 120px;
margin-left: 7px;
margin-right: 23px;
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
.select-box-sort {
background: rgb(255, 255, 255);
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
border: 1px solid rgb(230, 231, 232);
border-radius: 4px;
height: 32px;
}
.num {
width: 100px;
margin-left: 10px;
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
text-align: right;
}
.per {
margin-left: 5px;
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
}
#box3Chart {
height: 360px;
:deep(.el-select-dropdown) {
left: 0 !important;
/* 强制下拉框左对齐选择框 */
top: 100% !important;
/* 强制下拉框在选择框正下方 */
transform: none !important;
/* 禁用默认的位移变换 */
}
.select-box {
position: absolute;
z-index: 999;
top: 13px;
right: 33px;
width: 100px;
height: 28px;
.paixu-btn {
display: flex;
width: 120px;
......@@ -810,6 +801,26 @@ onMounted(() => {
}
}
}
.box-main {
height: 360px;
position: relative;
overflow: hidden;
#box1Chart {
height: 360px;
}
#box2Chart {
height: 360px;
}
#box3Chart {
height: 360px;
}
}
}
}
......@@ -823,18 +834,26 @@ onMounted(() => {
.search-box {
display: flex;
width: 300px;
width: 360px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
position: relative;
.icon {
width: 16px;
height: 16px;
margin: 8px 7px;
cursor: pointer;
position: absolute;
right: 8px;
top: 8px;
display: flex;
justify-content: flex-end;
img {
width: 100%;
......@@ -907,17 +926,165 @@ onMounted(() => {
justify-content: space-between;
.left {
width: 300px;
height: 800px;
width: 360px;
height: 100%;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.select-box {
margin-top: 21px;
.select-box-science {
margin-top: 16px;
.select-box-header {
display: flex;
.title {
font-family: "Source Han Sans CN";
font-weight: 700;
font-size: 16px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-top: 12px;
}
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px 4px;
margin-left: 24px;
.filter-checkbox {
width: 160px;
margin: 0;
font-family: "Source Han Sans CN", sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
}
.paixu-btn {
display: flex;
width: 120px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
&:hover {
background: var(--color-bg-hover);
}
cursor: pointer;
.icon1 {
width: 11px;
height: 14px;
margin-top: 10px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 19px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
margin-top: 7px;
margin-left: 9px;
}
.icon2 {
width: 10px;
height: 5px;
margin-top: 5px;
margin-left: 13px;
img {
width: 100%;
height: 100%;
}
}
}
.icon {
margin-top: 4px;
width: 8px;
height: 16px;
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
color: rgba(5, 95, 194, 1);
margin-left: 17px;
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
}
.select-box-publish {
margin-top: 24px;
margin-bottom: 24px;
.select-box-header {
display: flex;
.title {
font-family: "Source Han Sans CN";
font-weight: 700;
font-size: 16px;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-top: 12px;
}
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px 4px;
margin-left: 24px;
.filter-checkbox {
width: 160px;
margin: 0;
font-family: "Source Han Sans CN", sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
}
.paixu-btn {
display: flex;
......@@ -995,7 +1162,7 @@ onMounted(() => {
}
.right {
width: 1284px;
width: 1224px;
max-height: 1670px;
margin-bottom: 20px;
box-sizing: border-box;
......@@ -1148,4 +1315,10 @@ onMounted(() => {
}
}
}
:deep(.select-prefix-img) {
width: 8px !important;
height: 8px !important;
margin-right: 4px;
}
</style>
\ No newline at end of file
......@@ -14,10 +14,19 @@
{{ thinkTank.describe }}
</div>
<div class="center-footer">
<div class="tag" v-for="(tag, index) in thinkTank.tags" :key="index">{{ tag.industryName }}</div>
<div class="tag" v-for="(tag, index) in thinkTank.tags" :key="index">
<div class="tag-industryName">
{{ tag.industryName }}
</div>
</div>
<!-- <div class="header-top-right">{{ '查看智库官网' }}</div> -->
</div>
</div>
<div class="header-top-right">
<button class="blue-btn">
<img class="btn-img" src="./images/image1.png" alt="" />
<span class="text">{{ '查看智库官网' }}</span>
</button>
</div>
</div>
<div class="header-footer">
<div class="tab" :class="{ tabActive: tabActiveName === '智库动态' }" @click="switchTab('智库动态')">
......@@ -94,19 +103,22 @@ onMounted(async () => {
height: 100%;
overflow: hidden;
overflow-y: auto;
.header {
width: 100%;
height: 188px;
box-sizing: border-box;
padding: 0 160px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
border-bottom: 1px solid rgb(234, 236, 238);
border-top: 1px solid rgb(234, 236, 238);
box-shadow: 0 0 20px 0 rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
position: sticky;
top: 0;
z-index: 99999;
overflow: hidden;
overflow: visible;
.header-top {
width: 1600px;
margin: 0 auto;
......@@ -116,6 +128,8 @@ onMounted(async () => {
.header-top-left {
width: 88px;
height: 88px;
img {
width: 100%;
height: 100%;
......@@ -130,8 +144,8 @@ onMounted(async () => {
.name {
height: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
color: rgb(59, 65, 75);
font-family: 'Source Han Sans CN';
font-size: 20px;
font-weight: 700;
line-height: 26px;
......@@ -142,11 +156,11 @@ onMounted(async () => {
.e-name {
margin-left: 11px;
height: 26px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
color: rgb(132, 136, 142);
font-family: 'Source Han Sans CN';
font-size: 14px;
font-weight: 400;
line-height: 26px;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
......@@ -156,12 +170,13 @@ onMounted(async () => {
margin-top: 4px;
width: 769px;
height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
color: rgb(132, 136, 142);
font-family: 'Source Han Sans CN';
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
}
.center-footer {
......@@ -171,18 +186,71 @@ onMounted(async () => {
.tag {
height: 26px;
line-height: 26px;
text-align: center;
padding: 0 8px;
padding: 1px 8px 1px 8px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border: 1px solid rgb(231, 243, 255);
border-radius: 4px;
background: rgba(246, 250, 255, 1);
color: rgba(5, 95, 194, 1);
background: rgb(246, 250, 255);
position: relative;
display: inline-flex;
align-items: center;
.tag-industryName {
color: rgb(5, 95, 194);
font-family: 'Source Han Sans CN';
font-size: 16px;
font-weight: 400;
line-height: 23px;
text-align: left;
letter-spacing: 0px;
}
}
}
}
.header-top-right {
margin-left: auto;
height: 36px;
box-sizing: border-box;
position: relative;
.blue-btn {
height: 100%;
box-sizing: border-box;
border: none;
outline: none;
border-radius: 6px;
background: rgba(5, 95, 194, 1);
padding: 7px 16px;
display: flex;
align-items: center;
&:focus {
outline: none;
}
.btn-img {
width: 16px;
height: 16px;
margin-left: 0px;
margin-top: 3px;
margin-bottom: 3px;
margin-right: 8px;
}
.text {
color: #fff;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
line-height: 22px;
}
}
}
......@@ -191,14 +259,14 @@ onMounted(async () => {
.header-footer {
width: 1600px;
margin: 0 auto;
margin-top: 25px;
margin-top: 28px;
height: 48px;
display: flex;
gap: 24px;
.tab {
width: 94px;
height: 48px;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
......@@ -218,21 +286,21 @@ onMounted(async () => {
.text {
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
color: rgb(59, 65, 75);
font-family: 'Source Han Sans CN';
font-size: 18px;
font-weight: 400;
line-height: 24px;
}
.textActive {
color: rgba(5, 95, 194, 1);
color: rgb(5, 95, 194);
font-weight: 700;
}
}
.tabActive {
border-bottom: 2px solid rgba(5, 95, 194, 1);
.tab.tabActive {
border-bottom: 2px solid rgb(5, 95, 194);
}
}
}
......@@ -241,167 +309,7 @@ onMounted(async () => {
margin: 0 auto;
width: 1600px;
.main-header {
height: 64px;
display: flex;
justify-content: space-between;
.search-box {
margin-top: 16px;
display: flex;
width: 300px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
.icon {
width: 16px;
height: 16px;
margin: 8px 7px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
.select-box {
margin-top: 16px;
margin-right: 5px;
}
}
.main-content {
display: flex;
gap: 16px;
.left {
width: 300px;
height: 806px;
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: 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;
}
}
.select-main {
margin-left: 25px;
}
.select-main1 {
width: 100px;
}
}
}
.right {
width: 1284px;
height: 1377px;
.card-box {
width: 1284px;
height: 1248px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.footer-card {
width: 418px;
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: 384px;
height: 206px;
margin: 0 auto;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 13px;
width: 376px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
}
.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 {
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;
}
}
}
}
}
}
......
<template>
<div class="main-content">
<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="type in reportTypeList" :key="type.id" v-model="selectedReportTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.typeName }}
</el-checkbox>
</div>
</div>
</div> -->
<div class="select-research-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 label="全部领域"></el-checkbox>
<el-checkbox v-for="type in researchTypeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="select-time-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 label="全部时间"></el-checkbox>
<el-checkbox v-for="type in researchTimeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
</div>
<!-- <div class="input-main">
<el-input placeholder="输入作者名字" v-model="author" @input="handleGetThinkDynamicsReport()" />
</div> -->
</div>
<div class="select-hearing-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 label="全部部门"></el-checkbox>
<el-checkbox v-for="type in researchHearingList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
</div>
<!-- <div class="input-main">
<el-input placeholder="输入作者名字" v-model="author" @input="handleGetThinkDynamicsReport()" />
</div> -->
</div>
</div>
<div class="right">
<div class="card-box">
<div class="card-content">
<div v-for="(item, index) in displayList" :key="item.id">
<div class="card-item">
<img class="card-item-img" src="../images/img congress.png" alt="report image" />
<div class="card-item-text">
<div class="card-item-title">
{{ item.title }}
</div>
<div class="card-item-time">
{{ item.time + ' · ' + item.content }}
<img src="../images/image open.png" alt="open icon" class="card-open-image" />
</div>
<div class="card-item-category"> {{ item.category }}</div>
</div>
</div>
<div class="divider" v-if="index !== displayList.length - 1"></div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">
{{ hearingData.length }}
</div>
<div class="page-box">
<el-pagination :page-size="10" background layout="prev, pager, next" :total="hearingData.length"
@current-change="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, toRefs, watch, computed } from "vue";
const props = defineProps({
researchTypeList: {
type: Array,
default: () => []
},
researchTimeList: {
type: Array,
default: () => []
},
researchHearingList: {
type: Array,
default: () => []
},
hearingData: {
type: Array,
default: () => []
},
selectedResearchTypeList: {
type: Array,
default: () => []
},
curFooterList: {
type: Array,
default: () => []
},
total: {
type: Number,
default: 0
},
currentPage: {
type: Number,
default: 1
}
});
const emit = defineEmits([
"update:selectedResearchTypeList",
"filter-change",
"page-change",
"report-click"
]);
// 解构 props,保持模板里变量名不变
const { researchTypeList, researchTimeList, curFooterList, total, currentPage, researchHearingList, hearingData } = toRefs(props);
const pageSize = 10;
// 只展示当前页的 12 条,否则会一页显示全部 20 条
const displayList = computed(() => {
const list = hearingData.value || [];
const start = (currentPage.value - 1) * pageSize;
return list.slice(start, start + pageSize);
});
// 用本地 ref 替代 computed,el-checkbox 会直接修改数组,需要可变的 ref
const selectedResearchTypeList = ref([...(props.selectedResearchTypeList || [])]);
// 父组件更新时同步到子组件
watch(
() => props.selectedResearchTypeList,
val => {
selectedResearchTypeList.value = val ? [...val] : [];
},
{ immediate: true, deep: true }
);
// 子组件勾选变化时通知父组件,flush: 'sync' 确保在 @change 触发前父组件已更新,否则 filter-change 时父组件拿到的还是旧值
watch(
selectedResearchTypeList,
val => {
emit("update:selectedResearchTypeList", val);
},
{ deep: true, flush: "sync" }
);
// 保持模板里的方法名不变,但改成通知父组件,直接传入当前选中值避免时序问题
const handleGetThinkDynamicsReport = () => {
emit("update:selectedResearchTypeList", [...selectedResearchTypeList.value]);
emit("filter-change", [...selectedResearchTypeList.value]);
};
const handleCurrentChange = page => {
emit("page-change", page);
};
const handleToReportDetail = item => {
emit("report-click", item);
};
</script>
<style lang="scss" scoped>
.main-content {
display: flex;
gap: 16px;
.left {
width: 360px;
height: 874px;
padding-bottom: 36px;
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-research-box {
width: 360px;
height: 284px;
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
margin-bottom: 12px;
.icon {
margin-top: 4px;
width: 8px;
height: 16px;
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 25px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
.select-main1 {
width: 100px;
}
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
border-radius: 10px;
border: 1px solid rgba(230, 231, 232, 1);
}
}
.select-time-box {
margin-top: 21px;
width: 360px;
height: 156px;
.select-box-header {
margin-bottom: 12px;
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: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 25px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
.select-main1 {
width: 100px;
}
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
border-radius: 10px;
border: 1px solid rgba(230, 231, 232, 1);
}
}
.select-hearing-box {
margin-top: 21px;
width: 360px;
.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: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 25px;
.checkbox-group {
display: grid;
}
}
.select-main1 {
width: 100px;
}
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
border-radius: 10px;
border: 1px solid rgba(230, 231, 232, 1);
}
}
}
.right {
width: 1224px;
height: 1377px;
.card-box {
width: 100%;
height: 1248px;
display: flex;
background: rgba(255, 255, 255, 1);
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);
.card-content {
width: 1211px;
height: 1067px;
margin-top: 33px;
margin-left: 37px;
.card-item {
width: 100%;
height: 77px;
display: flex;
align-items: center;
.card-item-img {
width: 56px;
height: 77px;
margin-right: 22px;
flex-shrink: 0;
}
.card-item-text {
flex: 1;
min-width: 0;
flex-direction: column;
justify-content: space-between;
display: flex;
.card-item-title {
color: rgb(59, 65, 75);
font-family: "Source Han Sans CN";
font-size: 18px;
font-weight: 700;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
margin-bottom: 2px;
display: inline-flex;
}
.card-item-time {
color: rgb(95, 101, 108);
font-family: "Source Han Sans CN";
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
margin-bottom: 7px;
text-align: left;
display: inline-flex;
.card-open-image {
width: 16px;
height: 16px;
margin-left: 9px;
margin-top: 3px;
}
}
.card-item-category {
padding: 1px 8px;
box-sizing: border-box;
border: 1px solid rgb(231, 243, 255);
border-radius: 4px;
display: inline-flex;
background-color: rgb(247, 248, 249);
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
width: fit-content;
}
}
}
.divider {
height: 1px;
background: rgb(234, 236, 238);
margin: 16px 0;
}
}
}
.right-footer {
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;
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="main-content">
<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="type in reportTypeList" :key="type.id" v-model="selectedReportTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.typeName }}
</el-checkbox>
</div>
</div>
</div> -->
<div class="select-research-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 label="全部领域" class="filter-checkbox"></el-checkbox>
<el-checkbox v-for="type in researchTypeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="select-time-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 label="全部时间"></el-checkbox>
<el-checkbox v-for="type in researchTimeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
</div>
<!-- <div class="input-main">
<el-input placeholder="输入作者名字" v-model="author" @input="handleGetThinkDynamicsReport()" />
</div> -->
</div>
</div>
<div class="right">
<div class="card-box">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index"
@click="handleToReportDetail(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="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, toRefs, watch } from "vue";
const props = defineProps({
researchTypeList: {
type: Array,
default: () => []
},
researchTimeList: {
type: Array,
default: () => []
},
selectedResearchTypeList: {
type: Array,
default: () => []
},
curFooterList: {
type: Array,
default: () => []
},
total: {
type: Number,
default: 0
},
currentPage: {
type: Number,
default: 1
}
});
const emit = defineEmits([
"update:selectedResearchTypeList",
"filter-change",
"page-change",
"report-click"
]);
// 解构 props,保持模板里变量名不变
const { researchTypeList, researchTimeList, curFooterList, total, currentPage } = toRefs(props);
// 用本地 ref 替代 computed,el-checkbox 会直接修改数组,需要可变的 ref
const selectedResearchTypeList = ref([...(props.selectedResearchTypeList || [])]);
// 父组件更新时同步到子组件
watch(
() => props.selectedResearchTypeList,
val => {
selectedResearchTypeList.value = val ? [...val] : [];
},
{ immediate: true, deep: true }
);
// 子组件勾选变化时通知父组件,flush: 'sync' 确保在 @change 触发前父组件已更新,否则 filter-change 时父组件拿到的还是旧值
watch(
selectedResearchTypeList,
val => {
emit("update:selectedResearchTypeList", val);
},
{ deep: true, flush: "sync" }
);
// 保持模板里的方法名不变,但改成通知父组件,直接传入当前选中值避免时序问题
const handleGetThinkDynamicsReport = () => {
emit("update:selectedResearchTypeList", [...selectedResearchTypeList.value]);
emit("filter-change", [...selectedResearchTypeList.value]);
};
const handleCurrentChange = page => {
emit("page-change", page);
};
const handleToReportDetail = item => {
emit("report-click", item);
};
</script>
<style lang="scss" scoped>
.main-content {
display: flex;
gap: 16px;
.left {
width: 360px;
height: 541px;
padding-bottom: 36px;
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-research-box {
width: 360px;
height: 284px;
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
margin-bottom: 12px;
.icon {
margin-top: 4px;
width: 8px;
height: 16px;
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 25px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px 4px;
.filter-checkbox {
width: 160px;
height: 24px;
}
}
}
.select-main1 {
width: 100px;
}
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
border-radius: 10px;
border: 1px solid rgba(230, 231, 232, 1);
}
}
.select-time-box {
margin-top: 21px;
width: 360px;
height: 156px;
.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: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 25px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
}
.select-main1 {
width: 100px;
}
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
border-radius: 10px;
border: 1px solid rgba(230, 231, 232, 1);
}
}
}
.right {
width: 1284px;
height: 1377px;
.card-box {
width: 1226px;
height: 1248px;
display: flex;
flex-wrap: wrap;
gap: 13px;
.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);
transition: transform 0.3s ease, box-shadow 0.3s ease;
position: relative;
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
cursor: pointer;
.footer-card-top {
width: 364px;
height: 180px;
margin: 0 auto;
margin-top: 15px;
position: relative;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 12px;
width: 360px;
color: rgb(59, 65, 75);
font-family: "Source Han Sans CN";
font-size: 18px;
font-weight: 700;
line-height: 24px;
// 多行省略 + 自动换行(兼容写法)
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box; // webkit 私有:开启弹性盒模型
display: box; // 标准写法(兜底)
-webkit-line-clamp: 2; // webkit 私有:限制行数
line-clamp: 2; // 标准属性:解决兼容性提示
-webkit-box-orient: vertical; // webkit 私有:垂直排列
box-orient: vertical; // 标准写法(兜底)
// 基础换行属性(确保文字能换行)
word-wrap: break-word;
word-break: break-all;
white-space: normal;
}
.footer-card-footer {
position: absolute;
left: 50%;
bottom: 15px;
transform: translateX(-50%);
margin: 0;
width: 360px;
height: 22px;
display: flex;
justify-content: space-between;
color: rgb(95, 101, 108);
font-family: "Source Han Sans CN";
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
}
.right-footer {
margin-top: 35px;
display: flex;
justify-content: space-between;
.info {
height: 19px;
color: rgb(132, 136, 142);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
}
}
}
:deep(.el-checkbox) {
margin-right: 0 !important;
}
</style>
\ No newline at end of file
......@@ -3,90 +3,86 @@
<div class="main-header">
<div class="search-box">
<el-input placeholder="搜索智库报告" v-model="searchReport" style="width: 270px" />
<el-input placeholder="搜索智库动态" v-model="searchReport" style="width: 270px" />
<div class="icon">
<img src="./images/search-icon.png" alt="" @click="handleGetThinkDynamicsReport()" />
</div>
</div>
<div class="report-btn-group">
<div class="report-btn" v-for="type in choseTypeList" :key="type.id"
:class="{ active: activeTypeId === type.id }" @click="handleChooseType(type)">
<div class="text"> {{ type.name }}</div>
</div>
</div>
<div>
<div class="select-box">
<el-select v-model="selectedYear" placeholder="选择时间" style="width: 120px">
<div class="select-box-time">
<el-select v-model="selectedYear" placeholder="近一年以来" style="width: 120px" :teleported="true"
:placement="'bottom-start'" :popper-options="{
modifiers: [
{
name: 'preventOverflow', // 禁用自动翻转逻辑
options: {
mainAxis: false, // 禁用垂直方向的自动调整
altAxis: false, // 禁用水平方向的自动调整
}
},
{
name: 'flip', // 完全禁用翻转功能
enabled: false
}
]
}">
<el-option @click="handleGetThinkDynamicsReport()" v-for="item in yearList" :key="item.value"
:label="item.label" :value="item.value" />
</el-select>
<el-select v-model="sort" placeholder="发布时间" style="width: 120px; margin-left: 8px;">
</div>
<div class="select-box-sort">
<el-select v-model="sort" placeholder="倒序" style="width: 120px" :teleported="true"
:placement="'bottom-start'" :popper-options="{
modifiers: [
{
name: 'preventOverflow', // 禁用自动翻转逻辑
options: {
mainAxis: false, // 禁用垂直方向的自动调整
altAxis: false, // 禁用水平方向的自动调整
}
},
{
name: 'flip', // 完全禁用翻转功能
enabled: false
}
]
}">
<template #prefix>
<img src="./images/image down.png" class="select-prefix-img" alt="" @click.stop="toggleSortAndFetch()"
:key="true" label="正序" :value="true" v-if="!sort" />
<img src="./images/image up.png" class="select-prefix-img" alt="" @click.stop="toggleSortAndFetch()"
:key="true" label="正序" :value="true" v-if="sort" />
</template>
<el-option @click="handleGetThinkDynamicsReport()" :key="true" label="正序" :value="true" />
<el-option @click="handleGetThinkDynamicsReport()" :key="false" label="倒序" :value="false" />
</el-select>
</div>
</div>
</div>
<div class="main-content">
<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="type in reportTypeList" :key="type.id" v-model="selectedReportTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.typeName }}
</el-checkbox>
</div>
</div>
</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="type in researchTypeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
</div>
</div>
<div class="select-box">
<div class="select-box-header">
<div class="icon"></div>
<div class="title">{{ "作者" }}</div>
</div>
<div class="input-main">
<el-input placeholder="输入作者名字" v-model="author" @input="handleGetThinkDynamicsReport()" />
</div>
</div>
</div>
<div class="right">
<div class="card-box">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index"
@click="handleToReportDetail(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="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
<div v-if="pageChange">
<ThinkTankReport :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:selected-research-type-list="selectedResearchTypeList" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage" @update:selected-research-type-list="val => (selectedResearchTypeList.value = val)"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
<div v-if="!pageChange">
<CongressHearing :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:research-hearing-list="researchHearingList" :selected-research-type-list="selectedResearchTypeList"
:cur-footer-list="curFooterList" :total="total" :current-page="currentPage" :hearing-data="hearingData"
@update:selected-research-type-list="val => (selectedResearchTypeList.value = val)"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
</div>
</template>
......@@ -112,8 +108,10 @@ import {
getThinkDynamicsReport
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
import ThinkTankReport from "./ThinkTankReport/index.vue";
import CongressHearing from "./CongressHearing/index.vue";
const router = useRouter();
const pageChange = ref(true)
const searchReport = ref('')
const handleToReportDetail = (item) => {
......@@ -126,7 +124,130 @@ const handleToReportDetail = (item) => {
});
window.open(route.href, "_blank");
}
const hearingData = ref([
// 军事类(10条)
{
title: "2025财年美国国防部国防授权法案听证会:军事预算与战略部署",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年7月8日"
},
{
title: "美国国会众议院听证会:美军网络安全与军事信息系统防护",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年6月15日"
},
{
title: "俄乌冲突背景下美国对乌军事援助听证会:援助规模与后续规划",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年5月22日"
},
{
title: "美国海军舰艇建造与维护听证会:舰队规模目标与工业基础支撑",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年4月10日"
},
{
title: "美军太空军事能力建设听证会:太空军发展与反卫星武器管控",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年3月5日"
},
{
title: "美国国防工业基础听证会:军工供应链韧性与本土制造能力",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年2月18日"
},
{
title: "美军人工智能军事应用听证会:伦理规范与作战效能评估",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年1月30日"
},
{
title: "美国陆军未来作战系统听证会:下一代战车与单兵装备研发",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年7月2日"
},
{
title: "北约军事合作听证会:美国对北约防务开支承诺与兵力部署",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年6月8日"
},
{
title: "美军核力量现代化听证会:洲际导弹更新与核不扩散政策",
content: "参与美中经济与安全审查委员会听证会",
category: "军事",
time: "2025年5月1日"
},
// 先进制造类(10条)
{
title: "美国国会听证会:先进制造业供应链重塑与本土产业回流",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年7月15日"
},
{
title: "先进制造中的人工智能应用听证会:智能制造与产业升级",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年6月20日"
},
{
title: "美国先进制造业研发法案听证会:资金分配与技术突破方向",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年4月25日"
},
{
title: "新能源装备先进制造听证会:动力电池与氢能装备产业化",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年3月12日"
},
{
title: "美国半导体先进制造听证会:芯片制造本土化与技术封锁",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年2月8日"
},
{
title: "先进制造劳动力培训听证会:技能匹配与产业人才供给",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年1月15日"
},
{
title: "航空航天先进制造听证会:民用飞机轻量化材料与智能制造",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年7月20日"
},
{
title: "先进制造中的可持续发展听证会:绿色制造与碳中和目标",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年6月1日"
},
{
title: "美国国防先进制造听证会:军工制造数字化与快速响应能力",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年5月18日"
},
{
title: "先进制造标准制定听证会:美国主导的全球制造标准体系构建",
content: "参与美中经济与安全审查委员会听证会",
category: "先进制造",
time: "2025年4月8日"
}
])
const reportTypeList = ref([
{
id: '研究报告',
......@@ -165,6 +286,88 @@ const researchTypeList = ref([
name: '期刊文章',
},
])
const choseTypeList = ref([
{
id: '智库报告',
name: '智库报告',
},
{
id: '调查项目',
name: '调查项目',
},
{
id: '国会听证会',
name: '国会听证会',
},
])
const activeTypeId = ref(choseTypeList.value[0]?.id || null)
const handleChooseType = (type) => {
activeTypeId.value = type.id
if (type.id === '国会听证会') {
pageChange.value = false
} else {
pageChange.value = true
}
}
const researchTimeList = ref([
{
id: '2025年',
name: '2025年',
},
{
id: '2024年',
name: '2024年',
},
{
id: '2023年',
name: '2023年',
},
{
id: '2022年',
name: '2022年',
},
{
id: '2021年',
name: '2021年',
},
{
id: '更早以前',
name: '更早以前',
}
])
const researchHearingList = ref([
{
id: '美中经济与安全审查委员会',
name: '美中经济与安全审查委员会',
},
{
id: '国会-行政部门中国委员会',
name: '国会-行政部门中国委员会',
},
{
id: '美中战略竞争特设委员会',
name: '美中战略竞争特设委员会',
},
{
id: '众议院小企业委员会',
name: '众议院小企业委员会',
},
{
id: '众议院国土安全委员会',
name: '众议院国土安全委员会',
},
{
id: '参议院能源与自然资源委员会',
name: '参议院能源与自然资源委员会',
},
{
id: '新材料',
name: '新材料',
}
])
const selectedResearchTypeList = ref([])
const author = ref('') // 作者
......@@ -260,7 +463,7 @@ const yearList = ref([
]);
const selectedYear = ref(1);
const sort = ref(true)
const sort = ref(false);
//获取当前时间x年前的日期
function getDateYearsAgo(years) {
// 获取当前日期
......@@ -301,7 +504,10 @@ const handleGetHylyList = async () => {
}
};
const toggleSortAndFetch = async () => {
sort.value = !sort.value
await handleGetThinkDynamicsReport()
}
const currentPage = ref(1);
// 处理页码改变事件
const handleCurrentChange = page => {
......@@ -318,22 +524,23 @@ function arrayToString(arr) {
}, "");
}
// 获取智库动态报告
const handleGetThinkDynamicsReport = async () => {
// 获取智库动态报告,payload 为子组件筛选变更时传入的当前选中值,避免时序导致拿到旧值
const handleGetThinkDynamicsReport = async (payload) => {
const selectedIds = Array.isArray(payload) ? payload : selectedResearchTypeList.value;
if (Array.isArray(payload)) {
selectedResearchTypeList.value = payload;
}
try {
const parmas = {
id: router.currentRoute._value.params.id,
startDate: getDateYearsAgo(selectedYear.value),
startDate: getDateYearsAgo(selectedYear.value ?? 1),
parmas: {
searchText: searchReport.value,
authorName: author.name,
sortFun: sort.value,
authorName: author.value ? author.value : null,
sortFun: sort.value ?? true,
currentPage: currentPage.value - 1,
pageSize: 12,
// reportTypeIds: arrayToString(selectedReportTypeList.value) === '' ? null : arrayToString(selectedResearchTypeList.value),
researchTypeIds: arrayToString(selectedResearchTypeList.value) === '' ? null : arrayToString(selectedResearchTypeList.value)
researchTypeIds: arrayToString(selectedIds) === '' ? null : arrayToString(selectedIds)
}
}
......@@ -365,22 +572,86 @@ onMounted(async () => {
height: 64px;
width: 1600px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgb(255, 255, 255);
// 让右侧下拉框整体靠右
>div:last-child {
margin-left: auto;
display: flex;
align-items: center;
}
.report-btn-group {
width: 384px;
height: 32px;
/* 定位参数:top:268px、left:536px(需基于定位父容器) */
/* 布局分布:集中分布(水平+垂直居中) */
display: flex;
margin-top: 16px;
margin-left: 16px;
/* 图层模式:穿透(事件+视觉穿透) */
background: rgb(255, 255, 255); // 与整体背景一致的纯白色
/* 基础兼容:避免尺寸偏移 */
box-sizing: border-box;
gap: 12px;
.report-btn {
width: 120px; // 宽度:120px
height: 32px; // 高度:32px
border-radius: 21px; // 圆角半径:21px
border: 1px solid rgb(230, 231, 232); // 描边:1px实线,颜色为rgb(230, 231, 232)
background: rgb(255, 255, 255); // 背景色:白色
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
// 布局分布:集中分布(水平+垂直居中)
display: flex;
align-items: center;
justify-content: center;
// 文字样式(匹配你项目的字体风格)
color: rgba(59, 65, 75, 1); // 适配你项目的文字主色
font-family: 'Source Han Sans CN';
font-size: 16px;
font-weight: 400;
line-height: 1; // 消除行高对垂直居中的影响
// 图层模式:穿透(即允许点击事件穿透,如需的话)
box-sizing: border-box; // 确保描边/内边距不影响尺寸
&.active {
background: rgb(5, 95, 194); // 蓝色背景
color: #fff; // 文字变白
box-shadow: none; // 需要的话可以关掉灰描边
}
}
}
.search-box {
margin-top: 16px;
display: flex;
width: 300px;
width: 360px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border: 1px solid rgb(230, 231, 232);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
background: rgb(255, 255, 255);
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
.icon {
width: 16px;
height: 16px;
margin: 8px 7px;
margin-top: 8px;
margin-bottom: 8px;
margin-left: 50px;
cursor: pointer;
img {
......@@ -392,7 +663,31 @@ onMounted(async () => {
.select-box {
margin-top: 16px;
margin-right: 5px;
display: flex;
.select-box-time,
.select-box-sort {
background: rgb(255, 255, 255);
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
border: 1px solid rgb(230, 231, 232);
border-radius: 4px;
height: 32px;
}
.select-prefix-img {
width: 8px;
height: 8px;
margin-right: 4px;
}
:deep(.el-select-dropdown) {
left: 0 !important;
/* 强制下拉框左对齐选择框 */
top: 100% !important;
/* 强制下拉框在选择框正下方 */
transform: none !important;
/* 禁用默认的位移变换 */
}
}
}
......@@ -401,8 +696,8 @@ onMounted(async () => {
gap: 16px;
.left {
width: 300px;
height: 100%;
width: 360px;
height: 541px;
padding-bottom: 36px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
......@@ -411,49 +706,7 @@ onMounted(async () => {
background: rgba(255, 255, 255, 1);
position: relative;
.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: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 1px;
text-align: left;
}
}
.select-main {
margin-left: 25px;
}
.select-main1 {
width: 100px;
}
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
border-radius: 10px;
border: 1px solid rgba(230, 231, 232, 1);
}
}
}
.right {
......@@ -461,14 +714,14 @@ onMounted(async () => {
height: 1377px;
.card-box {
width: 1284px;
width: 1226px;
height: 1248px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.footer-card {
width: 418px;
width: 398px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
......@@ -483,7 +736,7 @@ onMounted(async () => {
cursor: pointer;
.footer-card-top {
width: 384px;
width: 364px;
height: 206px;
margin: 0 auto;
margin-top: 15px;
......@@ -546,6 +799,7 @@ onMounted(async () => {
.filter-checkbox {
width: 180px;
}
......
......@@ -13,7 +13,7 @@
</div> -->
<div class="home-main-header-center">
<SearchContainer style="margin-bottom: 0; margin-top: 48px; height: fit-content" v-if="containerRef"
<SearchContainer style="margin-bottom: 0; margin-top: 51px; height: fit-content" v-if="containerRef"
placeholder="搜索智库报告" :containerRef="containerRef" areaName="智库" />
<!-- <el-input v-model="searchThinktankText" @keyup.enter="handleSearch"
style="width: 838px; height: 100%" placeholder="搜索智库报告" />
......@@ -229,7 +229,9 @@
<NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews"
img="newsImage" title="newsTitle" content="newsContent" from="from" />
<MessageBubble :messageList="messageList" imageUrl="personImage" @more-click="handleToSocialDetail"
@person-click="handleClickPerson" name="personName" content="remarks" source="orgName" />
@person-click="handleClickPerson" name="personName" content="remarks" source="orgName">
<template #title>智库任务动态</template>
</MessageBubble>
<!-- <div class="box4">
<div class="box4-header">
<div class="header-icon">
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论