提交 1a528d62 authored 作者: 朱政's avatar 朱政

feat:美国科研资助体系概览页样式与功能

上级 ac2f6b40
流水线 #309 已通过 于阶段
in 1 分 26 秒
......@@ -126,11 +126,25 @@ export function getAreaType() {
})
}
/**
* 资助项目列表:领域、年份用逗号拼接为一个查询参数(arealist=1,2,3&yearlist=2025,2024)
*/
function normalizeProjectListQueryParams(params) {
const next = { ...(params || {}) }
if (Array.isArray(next.arealist)) {
next.arealist = next.arealist.filter((v) => v !== undefined && v !== null && v !== "").join(",")
}
if (Array.isArray(next.yearlist)) {
next.yearlist = next.yearlist.filter((v) => v !== undefined && v !== null && v !== "").join(",")
}
return next
}
//资助体系v2.0:资助项目列表分页
export function getProjectListNew(params) {
return request({
method: 'GET',
url: `/api/fund/getProjectListNew`,
params
params: normalizeProjectListQueryParams(params)
})
}
......@@ -70,7 +70,9 @@ router.beforeEach((to, from, next) => {
if (to.meta.dynamicTitle) {
console.log('to', to);
const storageKey = to.meta.titleStorageKey || "curTabName";
document.title = window.sessionStorage.getItem(storageKey) || to.meta.title;
// 新开页签时 sessionStorage 不共享,优先用 query 带过来的 title/name
const queryTitle = (to.query && (to.query.title || to.query.name)) ? String(to.query.title || to.query.name) : "";
document.title = queryTitle || window.sessionStorage.getItem(storageKey) || to.meta.title;
} else {
document.title = to.meta.title
......
......@@ -88,7 +88,8 @@ const decreeRoutes = [
component: Institution,
meta: {
title: "行政机构主页",
dynamicTitle: true
dynamicTitle: true,
titleStorageKey: "institutionTabName"
}
},
{
......
......@@ -23,8 +23,8 @@
</div>
</div> -->
<NewsList :newsList="leftList" @more-click="handleToMoreNews" img="newsImage" title="newsTitle"
content="newsContent" from="from" />
<MessageBubble :messageList="rightList" @more-click="handleToSocialDetail" source="orgName" content="remarks"
content="newsContent" from="from" @item-click="item => gotoNewsDetail(item.newsId)" />
<MessageBubble :messageList="rightList" @person-click="handleToSocialDetail" source="orgName" content="remarks"
name="personName" imageUrl="personImage">
</MessageBubble>
<!-- <div class="right-box">
......@@ -56,6 +56,7 @@
import NewsList from "@/components/base/newsList/index.vue";
import { ref, onMounted } from "vue";
import { useGotoNewsDetail } from "@/router/modules/news";
import {
getSocialMediaInfo, getNews
} from "@/api/scientificFunding/overview";
......@@ -171,15 +172,19 @@ const handleToMoreNews = () => {
};
// 查看社交媒体详情
const handleToSocialDetail = item => {
const personId = item?.personId || item?.id;
if (!personId) return;
const route = router.resolve({
path: "/characterPage",
query: {
personId: item.id
personId
}
});
window.open(route.href, "_blank");
};
const gotoNewsDetail = useGotoNewsDetail();
onMounted(async () => {
handleNews()
handleSocialMediaInfo()
......
......@@ -21,23 +21,30 @@
<div class="left-center-main-ul">
<ul>
<li>
<img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">投资主体:</span>
<span class="ul-content">美国国家科学基金会</span>
</li>
<li>
<img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">发布日期:</span>
<span class="ul-content">{{ itemData.publicationDate }}</span>
</li>
<li>
<img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">资助经费:</span>
<span class="ul-content">{{ itemData.amount }}</span>
</li>
<li>
<img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">涉及领域:</span>
<span class="ul-pie cl1" v-for="value in itemData.toOrgNameList">{{ value }}</span>
<span class="ul-pie cl1">
<AreaTag v-for="(val, idx) in itemData.areaList" :key="idx" :tagName="val" />
</span>
</li>
<li>
<img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">资助对象:</span>
<span class="ul-content">{{ itemData.fromOrgNameList.join(',') }}</span>
</li>
......@@ -97,42 +104,7 @@ import {
import router from "@/router";
const list = ref([
{
id: 1,
title: "特别重大",
content: "NSF宣布新的“新兴技术体验式学习”计划资...",
time: "一天前"
},
{
id: 2,
title: "一般风险",
content: "美国NASA公布NIAC计划2025年度第一轮资助",
time: "一天前"
},
{
id: 3,
title: "特别重大",
content: "美国NASA公布“早期创新计划”2026年资助...",
time: "一天前"
},
{
id: 4,
title: "重大风险",
content: '美国NIH冻结多所顶尖大学资金引发广泛争议"',
time: "一天前"
},
{
id: 5,
title: "重大风险",
content: "美国NIH终止哥伦比亚大学研究项目拨款引发...",
time: "一天前"
},
{
id: 6,
title: "特别重大",
content: "美国DARPA资助可调控生物功能微系统技术开发",
time: "一天前"
}
]);
//// 获取风险信号
......@@ -286,7 +258,7 @@ onMounted(async () => {
height: 175px;
.left-center-main-title {
margin-left: 19px;
margin-left: 22px;
margin-bottom: 17px;
font-size: 20px;
font-weight: 700;
......@@ -305,6 +277,20 @@ onMounted(async () => {
width: 100%;
height: 24px;
margin-bottom: 12px;
display: flex;
.li-img {
width: 4px;
height: 4px;
margin-right: 18px;
margin-top: 10px;
img {
width: 100%;
height: 100%;
display: block;
}
}
.ul-title {
display: inline-block;
......@@ -326,19 +312,14 @@ onMounted(async () => {
}
.ul-pie {
display: inline-block;
display: flex;
gap: 8px;
box-sizing: border-box;
padding: 2px 8px;
border: 1px solid;
border-radius: 4px;
flex-direction: row;
margin-right: 8px;
}
.cl1 {
border-color: rgba(186, 224, 255, 1);
background-color: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.cl2 {
border-color: rgba(255, 163, 158, 1);
......
......@@ -14,14 +14,8 @@
<div class="main-content" ref="containerRef">
<div class="home-top-bg"></div>
<!-- 搜索栏部分 -->
<SearchContainer
style="margin-bottom: 48px; height: fit-content"
v-if="containerRef"
:countInfo="countInfo"
placeholder="搜索科研资助实体、资助记录"
:containerRef="containerRef"
areaName=""
/>
<SearchContainer style="margin-bottom: 48px; height: fit-content" v-if="containerRef" :countInfo="countInfo"
placeholder="搜索科研资助实体、资助记录" :containerRef="containerRef" areaName="" />
<!-- <div class="search"> -->
<!-- <div class="search-main">
......@@ -78,7 +72,8 @@
<!-- </div> -->
<!-- 6个数据 -->
<div class="data">
<div v-for="(item, index) in dataList" :key="item.id" class="data-item">
<div v-for="(item, index) in dataList" :key="item.orgId || item.id" class="data-item"
@click="handleClickOrg(item)">
<img v-if="item.logoUrl && /\\.(jpe?g|png)$/i.test(item.logoUrl)" :src="item.logoUrl" alt="" />
<img v-else src="./assets/images/nullcorpimg.png" alt="" />
<div class="data-text-item">
......@@ -91,28 +86,28 @@
</div>
<!-- 最新动态 -->
<div class="newdata" id="position1">
<com-title title="最新动态" />
<com-title title="最新动态" style="width: 1600px;" />
<div class="newdata-main">
<newData />
</div>
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="资讯要闻" />
<com-title title="资讯要闻" style="width: 1600px;" />
<div class="ask-main">
<askPage />
</div>
</div>
<!-- 数据总览 -->
<div class="datasub" id="position3">
<com-title title="数据总览" />
<com-title title="数据总览" style="width: 1600px;" />
<div class="datasub-main">
<dataSub />
</div>
</div>
<!-- 资源库 -->
<div class="reslib" id="position4">
<com-title title="资源库" />
<com-title title="资源库" style="width: 1600px;" />
<div class="reslib-main">
<resLib />
</div>
......@@ -170,6 +165,21 @@ const handleBackHome = () => {
path: "/overview"
});
};
// 点击机构卡片跳转机构详情
const handleClickOrg = (item) => {
const orgId = item?.orgId;
if (!orgId) return;
// Institution 路由开启了 dynamicTitle,这里提前写入标题,避免沿用上一次的“白宫”等旧值
const title = item?.orgName || "";
window.sessionStorage.setItem("institutionTabName", title);
window.sessionStorage.setItem("curTabName", title);
const route = router.resolve({
path: "/institution",
query: { id: orgId, name: title }
});
window.open(route.href, "_blank");
};
// 固定数据
const dataList = ref([
{
......@@ -576,12 +586,12 @@ onMounted(async () => {
.reslib {
width: 1600px;
height: 1633px;
margin: 0 auto 0px auto;
.reslib-main {
width: 1600px;
height: 1565px;
margin-top: 26px;
}
}
......
......@@ -399,7 +399,8 @@ const reportAuthors = computed(() => {
// 点击报告作者头像,跳转到人物主页
// 与核心研究人员逻辑一致:核心依赖 personId,本页面依赖作者的 id(作为 personId 传入)
const handleClickReportAuthor = async (author) => {
const personId = author?.id;
const personId = author?.personId;
if (!personId) return;
......
......@@ -96,6 +96,7 @@
</div>
<div class="divider" v-if="index !== hearingData.length - 1"></div>
</div>
</div>
</div>
<div class="right-footer">
......@@ -107,6 +108,7 @@
@current-change="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
</div>
</template>
......@@ -287,6 +289,12 @@ const handleToReportDetail = item => {
.main-content {
display: flex;
gap: 16px;
height: 100%;
margin-bottom: 100px;
.left {
width: 360px;
......@@ -299,6 +307,7 @@ const handleToReportDetail = item => {
background: rgba(255, 255, 255, 1);
position: relative;
.select-research-box {
width: 360px;
height: 100%;
......@@ -480,14 +489,20 @@ const handleToReportDetail = item => {
.right {
width: 1224px;
height: 1377px;
.card-box {
width: 100%;
height: 1248px;
height: 100%;
display: flex;
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
......@@ -495,12 +510,15 @@ const handleToReportDetail = item => {
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-top: 33px;
margin-left: 37px;
padding-bottom: 27px;
.card-item {
width: 100%;
......@@ -585,21 +603,25 @@ const handleToReportDetail = item => {
}
.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;
}
}
.right-footer {
margin-top: 35px;
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;
}
}
}
......
......@@ -58,6 +58,7 @@
<div class="right">
<div class="card-box">
<div class="card-content">
<div v-for="(item, index) in hearingData" :key="item.id ?? index">
<div class="card-item">
<img class="card-item-img" :src="item.coverImgUrl" alt="report image" />
......@@ -80,9 +81,10 @@
</div>
<div class="divider" v-if="index !== hearingData.length - 1"></div>
</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">
{{ hearingData.length }} 篇智库报告
......@@ -92,6 +94,7 @@
@current-change="handlePageChange" :current-page="currentPage" />
</div>
</div>
</div>
</div>
</template>
......@@ -186,6 +189,7 @@ const handlePageChange = page => {
.home-main-footer-main {
margin: 0 auto;
margin-top: 36px;
width: 1600px;
display: flex;
gap: 16px;
......@@ -270,11 +274,11 @@ const handlePageChange = page => {
.right {
width: 1224px;
height: 1377px;
.card-box {
width: 100%;
height: 1134px;
display: flex;
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
......@@ -282,30 +286,35 @@ const handlePageChange = page => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
padding-right: 36px;
height: 100%;
.card-content {
width: 1211px;
height: 1067px;
margin-top: 33px;
margin-left: 37px;
padding-bottom: 27px;
}
}
.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;
}
}
.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;
}
}
......
......@@ -369,8 +369,9 @@
<ThinkTankCongressHearingOverview v-else-if="activeCate === '国会听证会'" :key="`congress-${resourceTabResetKey}`"
:hearing-data="hearingData" :research-type-list="areaList" :research-time-list="pubTimeList"
v-model:selectedAreaList="congressSelectedAreaList" v-model:selectedPubTimeList="congressSelectedPubTimeList"
:total="congressTotal" :current-page="congressCurrentPage" @filter-change="handleCongressFilterChange"
v-model:selectedAreaList="congressSelectedAreaList"
v-model:selectedPubTimeList="congressSelectedPubTimeList" :total="congressTotal"
:current-page="congressCurrentPage" @filter-change="handleCongressFilterChange"
@page-change="handleCongressCurrentChange" @report-click="handleToHearingDetail" />
<ThinkTankPolicyAdviceOverview v-else :key="`policy-${resourceTabResetKey}`" :research-type-list="areaList"
......@@ -2194,7 +2195,7 @@ const handleSearch = () => {
// 下钻至数据资源库
const handleToDataLibrary = (item) => {
if(!item.reportNumber) {
if (!item.reportNumber) {
ElMessage.warning('当前智库没有相关报告!')
return
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论