提交 9264a145 authored 作者: 朱政's avatar 朱政

feat:资助体系概览页样式功能开发

上级 edc8537f
流水线 #324 已通过 于阶段
in 1 分 33 秒
...@@ -28,12 +28,12 @@ ...@@ -28,12 +28,12 @@
<li> <li>
<img src="./assets/icon-black.png" alt="" class="li-img" /> <img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">发布日期:</span> <span class="ul-title">发布日期:</span>
<span class="ul-content">{{ itemData.publicationDate }}</span> <span class="ul-content">{{ formatDate(itemData.publicationDate) }}</span>
</li> </li>
<li> <li>
<img src="./assets/icon-black.png" alt="" class="li-img" /> <img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">资助经费:</span> <span class="ul-title">资助经费:</span>
<span class="ul-content">{{ itemData.amount }}</span> <span class="ul-content">{{ itemData.amount }}{{ "亿美元" }}</span>
</li> </li>
<li> <li>
<img src="./assets/icon-black.png" alt="" class="li-img" /> <img src="./assets/icon-black.png" alt="" class="li-img" />
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
<li> <li>
<img src="./assets/icon-black.png" alt="" class="li-img" /> <img src="./assets/icon-black.png" alt="" class="li-img" />
<span class="ul-title">资助对象:</span> <span class="ul-title">资助对象:</span>
<span class="ul-content">{{ itemData.fromOrgNameList.join(',') }}</span> <span class="ul-content">{{ itemData.fromOrgNameList.join('') }}</span>
</li> </li>
</ul> </ul>
</div> </div>
...@@ -119,7 +119,11 @@ const handleGetRiskSignal = async () => { ...@@ -119,7 +119,11 @@ const handleGetRiskSignal = async () => {
console.error("获取风险信号error", error); console.error("获取风险信号error", error);
} }
}; };
const formatDate = (dateStr) => {
if (!dateStr) return '';
const [y, m, d] = dateStr.split('-');
return `${y}${m}${d}日`;
};
// 查看更多风险信号 // 查看更多风险信号
const handleToMoreRiskSignal = () => { const handleToMoreRiskSignal = () => {
const route = router.resolve("/viewRiskSignal"); const route = router.resolve("/viewRiskSignal");
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
</div> </div>
<div class="left-main"> <div class="left-main ">
<div class="left-main-echarts" ref="leftChartRef" v-show="radio1 === true"></div> <div class="left-main-echarts" ref="leftChartRef" v-show="radio1 === true"></div>
<div class="left-main-echarts" ref="leftChartRef1" v-show="radio1 === false"></div> <div class="left-main-echarts" ref="leftChartRef1" v-show="radio1 === false"></div>
<el-empty v-show="!hasLeft1ChartData && !isLeft1Loading" class="datasub-el-empty" description="暂无数据" <el-empty v-show="!hasLeft1ChartData && !isLeft1Loading" class="datasub-el-empty" description="暂无数据"
...@@ -166,13 +166,14 @@ const options = [ ...@@ -166,13 +166,14 @@ const options = [
label: "近五年" label: "近五年"
} }
]; ];
/** value 须与 v-model 类型一致(数字),否则 el-select 无法匹配 label,会显示成「2025」而非「2025年」 */
const options1 = [ const options1 = [
{ {
value: "2025", value: 2025,
label: "2025年" label: "2025年"
}, },
{ {
value: "2024", value: 2024,
label: "2024年" label: "2024年"
} }
]; ];
...@@ -344,7 +345,13 @@ const initLeftDonut = (rawData, show) => { ...@@ -344,7 +345,13 @@ const initLeftDonut = (rawData, show) => {
type: 'shadow' type: 'shadow'
} }
}, },
grid: {
left: 5,
right: 0,
top: 0,
bottom: 10,
containLabel: true
},
xAxis: { xAxis: {
type: 'value', type: 'value',
boundaryGap: [0, 0.01], boundaryGap: [0, 0.01],
...@@ -1061,8 +1068,9 @@ const initLeftSankey = (data) => { ...@@ -1061,8 +1068,9 @@ const initLeftSankey = (data) => {
draggable: false, draggable: false,
nodeAlign: "justify", nodeAlign: "justify",
orient: "horizontal", orient: "horizontal",
/* 整体左移约 20px,并略增右侧留白,避免右侧行业名(如新一代通信网络)被裁切 */
left: 10, left: 10,
right: 70, right: 130,
top: 0, top: 0,
bottom: 0, bottom: 0,
nodeWidth: 40, nodeWidth: 40,
......
<template> <template>
<div class="reslib-page"> <div class="reslib-page">
<div class="nav"> <div class="nav">
<div class="nav-item" :class="{ active: isAllProjectsActive }" @click="handleNavSelect(null)">
{{ "全部资助项目" }}
</div>
<div v-for="item in navList" :key="item.orgId" class="nav-item" :class="{ active: item.orgId === activeItem }" <div v-for="item in navList" :key="item.orgId" class="nav-item" :class="{ active: item.orgId === activeItem }"
@click="activeItem = item.orgId, handleGetProjectListNew()"> @click="handleNavSelect(item.orgId)">
{{ item.orgName }} {{ item.orgName }}
</div> </div>
</div> </div>
<div class="reslib-sort-box"> <div class="reslib-sort-box">
<div class="paixu-btn" @click="handleSwithSort()"> <div class="select-box">
<div class="icon1"> <el-select v-model="sortModel" class="resource-library-sort-select" placeholder="发布时间" style="width: 120px"
<img v-if="sort" src="@/assets/icons/shengxu1.png" alt="" /> :teleported="true" placement="bottom-start" :popper-options="resourceLibrarySortPopperOptions"
<img v-else src="@/assets/icons/jiangxu1.png" alt="" /> @change="handleResourceLibrarySortChange">
</div> <template #prefix>
<div class="text">{{ "发布时间" }}</div> <img v-if="sortModel !== true" src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image down.png"
<div class="icon2"> class="resource-library-sort-prefix-img" alt="" @click.stop="toggleResourceLibrarySortPrefix" />
<img v-if="sort" src="@/assets/icons/shengxu2.png" alt="" /> <img v-else src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image up.png"
<img v-else src="@/assets/icons/jiangxu2.png" alt="" /> class="resource-library-sort-prefix-img" alt="" @click.stop="toggleResourceLibrarySortPrefix" />
</div> </template>
<el-option :key="'reslib-sort-asc'" label="正序" :value="true" />
<el-option :key="'reslib-sort-desc'" label="倒序" :value="false" />
</el-select>
</div> </div>
</div> </div>
<div class="main"> <div class="main">
...@@ -70,7 +77,7 @@ ...@@ -70,7 +77,7 @@
<AreaTag v-for="(val, idx) in item.areaList" :key="idx" :tagName="val" /> <AreaTag v-for="(val, idx) in item.areaList" :key="idx" :tagName="val" />
</div> </div>
<div class="right-item-time">{{ item.publicationDate }}</div> <div class="right-item-time">{{ formatDate(item.publicationDate) }}</div>
<div class="right-item-money" <div class="right-item-money"
:style="{ color: item.amount <= 1000 ? 'rgba(232, 189, 11, 1)' : item.amount <= 10000 ? 'rgba(255, 149, 77, 1)' : 'rgba(206, 79, 81, 1)' }"> :style="{ color: item.amount <= 1000 ? 'rgba(232, 189, 11, 1)' : item.amount <= 10000 ? 'rgba(255, 149, 77, 1)' : 'rgba(206, 79, 81, 1)' }">
{{ '$' + item.amount + '万' }}</div> {{ '$' + item.amount + '万' }}</div>
...@@ -89,7 +96,7 @@ ...@@ -89,7 +96,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { import {
getProjectListNew, geFundSourceOrg, getAreaType getProjectListNew, geFundSourceOrg, getAreaType
} from "@/api/scientificFunding/overview"; } from "@/api/scientificFunding/overview";
...@@ -109,7 +116,11 @@ const normalizeAreaId = (id) => { ...@@ -109,7 +116,11 @@ const normalizeAreaId = (id) => {
const n = Number(id); const n = Number(id);
return Number.isFinite(n) ? n : id; return Number.isFinite(n) ? n : id;
}; };
const formatDate = (dateStr) => {
if (!dateStr) return '';
const [y, m, d] = dateStr.split('-');
return `${y}${m}${d}日`;
};
/** 请求用:仅保留合法整数领域 id */ /** 请求用:仅保留合法整数领域 id */
const toAreaIdListForRequest = (ids) => { const toAreaIdListForRequest = (ids) => {
const list = Array.isArray(ids) ? ids : []; const list = Array.isArray(ids) ? ids : [];
...@@ -119,7 +130,9 @@ const toAreaIdListForRequest = (ids) => { ...@@ -119,7 +130,9 @@ const toAreaIdListForRequest = (ids) => {
}; };
const navList = ref([]); const navList = ref([]);
const activeItem = ref(""); /** null 表示「全部资助项目」,不传 orgId */
const activeItem = ref(null);
const isAllProjectsActive = computed(() => activeItem.value === null);
const areaList = ref([]); const areaList = ref([]);
...@@ -130,8 +143,7 @@ const handleGeFundSourceOrg = async () => { ...@@ -130,8 +143,7 @@ const handleGeFundSourceOrg = async () => {
const res = await geFundSourceOrg(); const res = await geFundSourceOrg();
console.log("来源机构列表", res); console.log("来源机构列表", res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
navList.value = res.data navList.value = res.data;
activeItem.value = res.data[0].orgId
} }
} catch (error) { } catch (error) {
console.error("获取来源机构列表error", error); console.error("获取来源机构列表error", error);
...@@ -213,9 +225,22 @@ const buildYearlistForRequest = (selectedTimeModel) => { ...@@ -213,9 +225,22 @@ const buildYearlistForRequest = (selectedTimeModel) => {
return strippedNums.map((n) => String(n)); return strippedNums.map((n) => String(n));
}; };
const sort = ref(false); /** null:占位「发布时间」且默认倒序;true 正序;false 倒序(与智库概览资源库一致) */
const handleSwithSort = () => { const sortModel = ref(null);
sort.value = !sort.value;
const resourceLibrarySortPopperOptions = {
modifiers: [
{ name: "preventOverflow", options: { mainAxis: false, altAxis: false } },
{ name: "flip", enabled: false }
]
};
const handleResourceLibrarySortChange = () => {
handleGetProjectListNew();
};
const toggleResourceLibrarySortPrefix = () => {
sortModel.value = sortModel.value === true ? false : true;
handleGetProjectListNew(); handleGetProjectListNew();
}; };
...@@ -243,6 +268,12 @@ const handlePageChange = p => { ...@@ -243,6 +268,12 @@ const handlePageChange = p => {
currentPage.value = p; currentPage.value = p;
handleGetProjectListNew() handleGetProjectListNew()
}; };
const handleNavSelect = (orgId) => {
activeItem.value = orgId;
handleGetProjectListNew();
};
// 资助体系v2.0:资助项目列表分页 // 资助体系v2.0:资助项目列表分页
const handleGetProjectListNew = async () => { const handleGetProjectListNew = async () => {
try { try {
...@@ -257,13 +288,15 @@ const handleGetProjectListNew = async () => { ...@@ -257,13 +288,15 @@ const handleGetProjectListNew = async () => {
const yearlist = buildYearlistForRequest(selectedPubTimeListModel.value); const yearlist = buildYearlistForRequest(selectedPubTimeListModel.value);
let params = { const params = {
arealist, arealist,
currentPage: currentPage.value, currentPage: currentPage.value,
pageSize: 10, pageSize: 10,
yearlist, yearlist,
funSort: sort.value ? 'desc' : 'asc', funSort: sortModel.value === true ? 'asc' : 'desc'
orgId: activeItem.value };
if (activeItem.value != null) {
params.orgId = activeItem.value;
} }
const res = await getProjectListNew(params); const res = await getProjectListNew(params);
console.log("资助项目列表分页", res); console.log("资助项目列表分页", res);
...@@ -296,60 +329,38 @@ onMounted(async () => { ...@@ -296,60 +329,38 @@ onMounted(async () => {
position: relative; position: relative;
.reslib-sort-box { .reslib-sort-box {
width: 128px;
position: absolute; position: absolute;
top: 7px; top: 7px;
right: 0px; right: 0px;
.paixu-btn { .select-box {
display: flex; height: 42px;
width: 120px;
height: 32px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1); padding: 5px 0;
border-radius: 4px;
background: rgba(255, 255, 255, 1);
&:hover { .resource-library-sort-select {
background: var(--color-bg-hover); height: 32px;
} box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
border: 1px solid rgb(230, 231, 232);
border-radius: 4px;
background: rgb(255, 255, 255);
.resource-library-sort-prefix-img {
width: 8px;
height: 8px;
margin-right: 4px;
cursor: pointer; cursor: pointer;
.icon1 {
width: 11px;
height: 14px;
margin-top: 10px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
} }
.text { :deep(.el-select__wrapper) {
height: 19px; min-height: 30px;
color: rgba(95, 101, 108, 1); box-shadow: none;
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 { :deep(.el-select-dropdown) {
width: 10px; left: 0 !important;
height: 5px; top: 100% !important;
margin-top: 5px; transform: none !important;
margin-left: 13px;
img {
width: 100%;
height: 100%;
} }
} }
} }
...@@ -526,7 +537,7 @@ onMounted(async () => { ...@@ -526,7 +537,7 @@ onMounted(async () => {
/* 隐藏超出部分 */ /* 隐藏超出部分 */
text-overflow: ellipsis; text-overflow: ellipsis;
/* 超出部分显示省略号 */ /* 超出部分显示省略号 */
width: 1112px; width: 992px;
/* 设置一个固定的宽度或百分比 */ /* 设置一个固定的宽度或百分比 */
position: absolute; position: absolute;
top: 44px; top: 44px;
......
...@@ -71,15 +71,15 @@ ...@@ -71,15 +71,15 @@
</div> --> </div> -->
<!-- </div> --> <!-- </div> -->
<!-- 6个数据 --> <!-- 6个数据 -->
<div class="data"> <div class="data" v-if="dataList.length > 0">
<div v-for="(item, index) in dataList" :key="item.orgId || item.id" class="data-item" <div v-for="(item, index) in dataList" :key="item.orgId || item.id" class="data-item"
@click="handleClickOrg(item)"> @click="handleClickOrg(item)">
<img v-if="item.logoUrl && /\\.(jpe?g|png)$/i.test(item.logoUrl)" :src="item.logoUrl" alt="" /> <img v-if="item.logoUrl" :src="item.logoUrl" alt="" />
<img v-else src="./assets/images/nullcorpimg.png" alt="" /> <img v-else src="./assets/images/nullcorpimg.png" alt="" />
<div class="data-text-item"> <div class="data-text-item">
<div class="data-item-abb" v-if="item.orgAbbEn">{{ item.orgAbbEn }}</div>
<div class="data-item-title">{{ item.orgName }}</div> <div class="data-item-title">{{ item.orgName }}</div>
<div class="data-item-name">{{ item.orgNameEn }}</div> <div class="data-item-name">{{ item.orgNameEn }}</div>
<div v-if="item.orgAbbEn" class="data-item-abb">{{ item.orgAbbEn }}</div>
</div> </div>
<div class="data-item-num" :style="{ color: color[index] }">{{ item.num + "项" }}</div> <div class="data-item-num" :style="{ color: color[index] }">{{ item.num + "项" }}</div>
</div> </div>
...@@ -182,60 +182,7 @@ const handleClickOrg = (item) => { ...@@ -182,60 +182,7 @@ const handleClickOrg = (item) => {
}; };
// 固定数据 // 固定数据
const dataList = ref([ const dataList = ref([
{
id: 1,
title: "NSF",
name: "美国国家科学基金会",
abb: "National Science Foundation",
num: "218项",
image: img01,
color: "rgb(206, 79, 81)"
},
{
id: 2,
title: "DARPA",
name: "美国国防高级研究计划局",
abb: "Defense Advanced Research Projects Agency",
num: "95项",
image: img02,
color: "rgba(114, 46, 209, 1)"
},
{
id: 3,
title: "NIH",
name: "美国国立卫生研究院",
abb: "National Institutes of Health",
num: "90项",
image: img03,
color: "rgba(19, 168, 168, 1)"
},
{
id: 4,
title: "NASA",
name: "美国国家航空航天局",
abb: "National Aeronautics and Space...",
num: "42项",
image: img04,
color: "rgba(64, 150, 255, 1)"
},
{
id: 5,
title: "DOE",
name: "美国能源部",
abb: "Department of Energy",
num: "95项",
image: img05,
color: "rgb(33, 129, 57)"
},
{
id: 6,
title: "NIST",
name: "国家标准与技术研究院",
abb: "National Institute of Standards and ...",
num: "218项",
image: img06,
color: "rgb(5, 95, 194)"
}
]); ]);
const color = ref([ const color = ref([
"rgb(206, 79, 81)", "rgb(206, 79, 81)",
...@@ -494,11 +441,18 @@ onMounted(async () => { ...@@ -494,11 +441,18 @@ onMounted(async () => {
height: 100%; height: 100%;
margin-left: 16px; margin-left: 16px;
margin-bottom: 4px; margin-bottom: 4px;
}
img { .data-item-abb {
width: 88px;
height: 88px; font-family: "Source Han Sans CN", sans-serif;
font-weight: 700;
/* 对应 Bold 字重 */
font-size: 32px;
line-height: 48px;
letter-spacing: 0px;
text-align: left;
/* 左对齐 */
color: rgb(59, 65, 75);
} }
.data-item-title { .data-item-title {
...@@ -509,31 +463,35 @@ onMounted(async () => { ...@@ -509,31 +463,35 @@ onMounted(async () => {
/* 隐藏超出部分 */ /* 隐藏超出部分 */
text-overflow: ellipsis; text-overflow: ellipsis;
/* 超出部分显示省略号 */ /* 超出部分显示省略号 */
font-size: 24px; font-family: "Source Han Sans CN", sans-serif;
font-weight: 700; font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 42px;
color: rgb(59, 65, 75);
}
.data-item-name {
font-size: 18px; font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
letter-spacing: 0px;
text-align: justify;
color: rgb(95, 101, 108); color: rgb(95, 101, 108);
} }
.data-item-abb { .data-item-name {
position: absolute; font-family: "Source Han Sans CN", sans-serif;
top: 101px;
left: 134px;
font-size: 16px;
font-weight: 700; font-weight: 700;
font-family: "Microsoft YaHei"; font-size: 16px;
line-height: 24px; line-height: 24px;
letter-spacing: 0px;
text-align: justify;
color: rgb(95, 101, 108); color: rgb(95, 101, 108);
} }
}
img {
width: 88px;
height: 88px;
}
.data-item-num { .data-item-num {
position: absolute; position: absolute;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论