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

update

...@@ -76,4 +76,23 @@ export function getCoopRestrictionDomain(params) { ...@@ -76,4 +76,23 @@ export function getCoopRestrictionDomain(params) {
url: `/api/cooperationlimitinfo/getLimitArea`, url: `/api/cooperationlimitinfo/getLimitArea`,
params params
}) })
}
// 合作限制-获取合作限制列表接口
/**
* @param {area} 涉及领域
* @param {currentPage} 当前页码
* @param {pageSize} 每页数量
* @param {sortOrder} 排序顺序
* @param {source} 合作来源
* @param {sortField} 排序字段
* @param {type} 合作限制类型
* @header token
*/
export function getCoopRestrictionList(params) {
return request({
method: 'GET',
url: `/api/cooperationlimitinfo/statList`,
params
})
} }
\ No newline at end of file
// 智库概览信息 // 智库概览信息
import request from "@/api/request.js"; import request from "@/api/request.js";
// 获取新闻资讯
/**
* @param {moduleId}
*/
export function getNews(moduleId = "0105") {
return request({
method: 'GET',
url: `/api/commonFeature/news/${moduleId}`,
})
}
/**
* 社交媒体
*/
export function getSocialMediaInfo(moduleId = "0105") {
return request({
method: "GET",
url: `/api/commonFeature/remarks/${moduleId}`
})
}
// 获取法案风险信号
/**
* @param {moduleId}
*/
export function getBillRiskSignal(moduleId = "0105") {
return request({
method: 'GET',
url: `/api/commonFeature/riskSignal/${moduleId}`,
})
}
//创新主体主页:统计不同创新主体类型对应的主体数量 //创新主体主页:统计不同创新主体类型对应的主体数量
export function getCountSubjectType() { export function getCountSubjectType() {
return request({ return request({
...@@ -40,4 +75,105 @@ export function getOverallRanking(params) { ...@@ -40,4 +75,105 @@ export function getOverallRanking(params) {
url: `/api/innovateSubject/overallRanking`, url: `/api/innovateSubject/overallRanking`,
params params
}) })
} }
\ No newline at end of file
//创新主体主页:领域布局
export function getResearchField(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/researchField`,
params
})
}
//创新主体主页:主体类型分类领域布局
export function getResearchFieldSubjectType(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/researchFieldSubjectType`,
params
})
}
/***********详情页 */
//创新主体详情:基本信息
export function getInfo(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/info/${params.id}`,
params
})
}
//最新动态
export function getDynamics(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/dynamics/${params.orgId}`,
params
})
}
//创新主体详情:历史事件轴
export function getEventList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/eventList/${params.id}`,
params
})
}
//创新主体详情:重点人物
export function getPersonList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/personList/${params.id}`,
params
})
}
//创新主体科研实力:专利数量统计
export function getPatentList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/patentList/${params.id}`,
params
})
}
// 创新主体科研实力:论文数量统计
export function getPaperList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/paperList/${params.id}`,
params
})
}
//创新主体科研实力:经费增长情况
export function getFundGrowth(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/fundGrowth/${params.id}`,
params
})
}
//创新主体科研实力:经费来源
export function getFundFromList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/fundFromList/${params.id}`,
params
})
}
//创新主体科研实力:经费分配
export function getFundToList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/fundToList/${params.id}`,
params
})
}
...@@ -3,7 +3,7 @@ import InnovationSubject from "@/views/innovationSubject/index.vue"; ...@@ -3,7 +3,7 @@ import InnovationSubject from "@/views/innovationSubject/index.vue";
import InnovationInstitution from "@/views/innovationSubject/innovativeInstitutions/index.vue"; import InnovationInstitution from "@/views/innovationSubject/innovativeInstitutions/index.vue";
const innovationSubjectRoutes = [ const innovationSubjectRoutes = [
//创新主体 //创新主体
{ {
path: "/innovationSubject", path: "/innovationSubject",
name: "InnovationSubject", name: "InnovationSubject",
...@@ -13,7 +13,7 @@ const innovationSubjectRoutes = [ ...@@ -13,7 +13,7 @@ const innovationSubjectRoutes = [
} }
}, },
{ {
path: "/InnovativeInstitutions", path: "/InnovativeInstitutions/:id",
name: "InnovativeInstitutions", name: "InnovativeInstitutions",
component: InnovationInstitution, component: InnovationInstitution,
meta: { meta: {
......
...@@ -39,13 +39,8 @@ ...@@ -39,13 +39,8 @@
{{ `共有${total}条${box1BtnActive === 1 ? "涉华" : "全部"}背景` }} {{ `共有${total}条${box1BtnActive === 1 ? "涉华" : "全部"}背景` }}
</div> </div>
<div class="page-box"> <div class="page-box">
<el-pagination <el-pagination background layout="prev, pager, next" :total="total" v-model:current-page="currentPage"
background @current-change="handleGetBillBackground" />
layout="prev, pager, next"
:total="total"
v-model:current-page="currentPage"
@current-change="handleGetBillBackground"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -119,21 +114,13 @@ ...@@ -119,21 +114,13 @@
</div> --> </div> -->
<div class="right-box1-main"> <div class="right-box1-main">
<div class="right-box1-main-top"> <div class="right-box1-main-top">
<el-icon <el-icon style="margin-top: 20px; cursor: pointer" size="20"
style="margin-top: 20px; cursor: pointer" :color="currentIndex > 0 ? '#5f656c' : '#ccc'" @click="handlePrev">
size="20" <CaretLeft />
:color="currentIndex > 0 ? '#5f656c' : '#ccc'" </el-icon>
@click="handlePrev"
><CaretLeft
/></el-icon>
<div class="user-list-container"> <div class="user-list-container">
<div class="user-list-wrapper" :style="{ transform: `translateX(-${currentIndex * 110}px)` }"> <div class="user-list-wrapper" :style="{ transform: `translateX(-${currentIndex * 110}px)` }">
<div <div class="user-box" v-for="(item, index) in personList" :key="index" @click="handleClickUser(item)">
class="user-box"
v-for="(item, index) in personList"
:key="index"
@click="handleClickUser(item)"
>
<div class="img-box"> <div class="img-box">
<img :src="item.image" alt="" /> <img :src="item.image" alt="" />
<div class="icon1"> <div class="icon1">
...@@ -149,21 +136,14 @@ ...@@ -149,21 +136,14 @@
</div> </div>
</div> </div>
</div> </div>
<el-icon <el-icon style="margin-top: 20px; cursor: pointer" size="20"
style="margin-top: 20px; cursor: pointer" :color="currentIndex < personList.length - 4 ? '#5f656c' : '#ccc'" @click="handleNext">
size="20" <CaretRight />
:color="currentIndex < personList.length - 4 ? '#5f656c' : '#ccc'" </el-icon>
@click="handleNext"
><CaretRight
/></el-icon>
</div> </div>
<div class="right-box1-main-bottom"> <div class="right-box1-main-bottom">
<WordCloudMap <WordCloudMap :data="wordCloudData" :selectedName="selectedIndustryName" shape="circle"
:data="wordCloudData" @wordClick="handleWordClick" />
:selectedName="selectedIndustryName"
shape="circle"
@wordClick="handleWordClick"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -320,7 +300,7 @@ const handleGetBillBackground = async () => { ...@@ -320,7 +300,7 @@ const handleGetBillBackground = async () => {
console.log("立法背景", res); console.log("立法背景", res);
backgroundList.value = res.data.content; backgroundList.value = res.data.content;
total.value = res.data.totalElements; // 假设API返回totalElements total.value = res.data.totalElements; // 假设API返回totalElements
} catch (error) {} } catch (error) { }
}; };
// 获取相关事件 // 获取相关事件
...@@ -345,7 +325,7 @@ const handleGetRelatedEvent = async () => { ...@@ -345,7 +325,7 @@ const handleGetRelatedEvent = async () => {
item.image = event5; item.image = event5;
} }
}); });
} catch (error) {} } catch (error) { }
}; };
// 议员相关性分析 // 议员相关性分析
...@@ -386,7 +366,7 @@ const handleGetBillPersonAnalyze = async isOppose => { ...@@ -386,7 +366,7 @@ const handleGetBillPersonAnalyze = async isOppose => {
wordCloudData.value = []; wordCloudData.value = [];
aboutUserList.value = []; aboutUserList.value = [];
} }
} catch (error) {} } catch (error) { }
}; };
...@@ -408,7 +388,7 @@ const handleGetBillPersonAnalyzeDy = async () => { ...@@ -408,7 +388,7 @@ const handleGetBillPersonAnalyzeDy = async () => {
icon: userIcon, icon: userIcon,
icon1: m.party === "共和党" ? userIcon2 : userIcon1 icon1: m.party === "共和党" ? userIcon2 : userIcon1
})); }));
} catch (error) {} } catch (error) { }
}; };
onMounted(() => { onMounted(() => {
...@@ -424,10 +404,12 @@ onMounted(() => { ...@@ -424,10 +404,12 @@ onMounted(() => {
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
.box-header { .box-header {
height: 56px; height: 56px;
display: flex; display: flex;
position: relative; position: relative;
.header-left { .header-left {
margin-top: 18px; margin-top: 18px;
width: 8px; width: 8px;
...@@ -435,6 +417,7 @@ onMounted(() => { ...@@ -435,6 +417,7 @@ onMounted(() => {
border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0;
background: var(--color-main-active); background: var(--color-main-active);
} }
.title { .title {
margin-left: 14px; margin-left: 14px;
margin-top: 14px; margin-top: 14px;
...@@ -445,15 +428,18 @@ onMounted(() => { ...@@ -445,15 +428,18 @@ onMounted(() => {
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
} }
.header-btn-box { .header-btn-box {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 84px; right: 84px;
display: flex; display: flex;
.btn { .btn {
margin-left: 8px; margin-left: 8px;
} }
} }
.header-right { .header-right {
position: absolute; position: absolute;
top: 14px; top: 14px;
...@@ -461,9 +447,11 @@ onMounted(() => { ...@@ -461,9 +447,11 @@ onMounted(() => {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 4px; gap: 4px;
.icon { .icon {
width: 28px; width: 28px;
height: 28px; height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -471,14 +459,17 @@ onMounted(() => { ...@@ -471,14 +459,17 @@ onMounted(() => {
} }
} }
} }
.background-wrap-left { .background-wrap-left {
width: 1150px; width: 1150px;
margin-top: 16px; margin-top: 16px;
.background-wrap-left-box1 { .background-wrap-left-box1 {
width: 1150px; width: 1150px;
height: 415px; height: 415px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 4px;
.box1-main { .box1-main {
.box1-main-center { .box1-main-center {
margin: 0 22px; margin: 0 22px;
...@@ -488,6 +479,7 @@ onMounted(() => { ...@@ -488,6 +479,7 @@ onMounted(() => {
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
align-content: flex-start; align-content: flex-start;
.box1-main-item { .box1-main-item {
width: 544px; width: 544px;
height: 48px; height: 48px;
...@@ -497,6 +489,7 @@ onMounted(() => { ...@@ -497,6 +489,7 @@ onMounted(() => {
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
display: flex; display: flex;
margin-top: 8px; margin-top: 8px;
.id { .id {
width: 24px; width: 24px;
height: 24px; height: 24px;
...@@ -509,6 +502,7 @@ onMounted(() => { ...@@ -509,6 +502,7 @@ onMounted(() => {
font-weight: 400; font-weight: 400;
margin: 12px 16px 12px 18px; margin: 12px 16px 12px 18px;
} }
.title { .title {
width: 440px; width: 440px;
height: 48px; height: 48px;
...@@ -520,6 +514,7 @@ onMounted(() => { ...@@ -520,6 +514,7 @@ onMounted(() => {
text-align: left; text-align: left;
overflow: hidden; overflow: hidden;
} }
.share { .share {
margin-left: 13px; margin-left: 13px;
margin-top: 16px; margin-top: 16px;
...@@ -527,6 +522,7 @@ onMounted(() => { ...@@ -527,6 +522,7 @@ onMounted(() => {
height: 16px; height: 16px;
padding: 2px; padding: 2px;
cursor: pointer; cursor: pointer;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -534,11 +530,13 @@ onMounted(() => { ...@@ -534,11 +530,13 @@ onMounted(() => {
} }
} }
} }
.box1-main-footer { .box1-main-footer {
margin: 30px 22px 0 22px; margin: 30px 22px 0 22px;
height: 22px; height: 22px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.info { .info {
height: 22px; height: 22px;
line-height: 22px; line-height: 22px;
...@@ -551,18 +549,21 @@ onMounted(() => { ...@@ -551,18 +549,21 @@ onMounted(() => {
} }
} }
} }
.background-wrap-left-box2 { .background-wrap-left-box2 {
margin-top: 15px; margin-top: 15px;
width: 1150px; width: 1150px;
height: 415px; height: 415px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 4px;
.box2-main { .box2-main {
// margin-top: 9px; // margin-top: 9px;
width: 1110px; width: 1110px;
margin-left: 23px; margin-left: 23px;
height: 349px; height: 349px;
overflow-y: auto; overflow-y: auto;
.box2-main-item { .box2-main-item {
width: 1103px; width: 1103px;
height: 60px; height: 60px;
...@@ -570,21 +571,26 @@ onMounted(() => { ...@@ -570,21 +571,26 @@ onMounted(() => {
box-sizing: border-box; box-sizing: border-box;
padding: 6px 8px; padding: 6px 8px;
display: flex; display: flex;
&:hover { &:hover {
background: rgba(225, 225, 225, 0.3); background: rgba(225, 225, 225, 0.3);
} }
.left { .left {
width: 64px; width: 64px;
height: 48px; height: 48px;
border-radius: 2px; border-radius: 2px;
img { img {
width: 64px; width: 64px;
height: 48px; height: 48px;
} }
} }
.center { .center {
margin-left: 14px; margin-left: 14px;
width: 900px; width: 900px;
.title { .title {
height: 22px; height: 22px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
...@@ -598,6 +604,7 @@ onMounted(() => { ...@@ -598,6 +604,7 @@ onMounted(() => {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.content { .content {
margin-top: 2px; margin-top: 2px;
height: 22px; height: 22px;
...@@ -613,6 +620,7 @@ onMounted(() => { ...@@ -613,6 +620,7 @@ onMounted(() => {
white-space: nowrap; white-space: nowrap;
} }
} }
.right { .right {
margin-left: 25px; margin-left: 25px;
line-height: 60px; line-height: 60px;
...@@ -626,14 +634,17 @@ onMounted(() => { ...@@ -626,14 +634,17 @@ onMounted(() => {
} }
} }
} }
.box2-footer { .box2-footer {
margin-top: 7px; margin-top: 7px;
display: flex; display: flex;
justify-content: center; justify-content: center;
.btn-more { .btn-more {
width: 108px; width: 108px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -642,6 +653,7 @@ onMounted(() => { ...@@ -642,6 +653,7 @@ onMounted(() => {
} }
} }
} }
.background-wrap-right { .background-wrap-right {
margin-right: 18px; margin-right: 18px;
margin-left: 16px; margin-left: 16px;
...@@ -650,22 +662,27 @@ onMounted(() => { ...@@ -650,22 +662,27 @@ onMounted(() => {
height: 845px; height: 845px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 4px;
.background-wrap-right-main { .background-wrap-right-main {
.right-box1 { .right-box1 {
height: 365px; height: 365px;
.right-box1-header { .right-box1-header {
height: 22px; height: 22px;
margin-left: 22px; margin-left: 22px;
display: flex; display: flex;
.icon { .icon {
margin: 1px 12px 3px 0; margin: 1px 12px 3px 0;
width: 16px; width: 16px;
height: 16px; height: 16px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.title { .title {
height: 22px; height: 22px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -677,37 +694,45 @@ onMounted(() => { ...@@ -677,37 +694,45 @@ onMounted(() => {
text-align: left; text-align: left;
} }
} }
.right-box1-main { .right-box1-main {
width: 502px; width: 502px;
margin-top: 17px; margin-top: 17px;
.right-box1-main-top { .right-box1-main-top {
margin-left: 16px; margin-left: 16px;
width: 544px; width: 544px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.user-list-container { .user-list-container {
width: 440px; // 4个 user-box 的宽度 (110 * 4) width: 440px; // 4个 user-box 的宽度 (110 * 4)
overflow: hidden; overflow: hidden;
.user-list-wrapper { .user-list-wrapper {
display: flex; display: flex;
transition: transform 0.3s ease; transition: transform 0.3s ease;
} }
} }
.user-box { .user-box {
width: 110px; width: 110px;
flex-shrink: 0; flex-shrink: 0;
height: 80px; height: 80px;
.img-box { .img-box {
width: 48px; width: 48px;
height: 48px; height: 48px;
position: relative; position: relative;
margin: 0 auto; margin: 0 auto;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 50%; // 圆形头像 border-radius: 50%; // 圆形头像
object-fit: cover; object-fit: cover;
} }
.icon1 { .icon1 {
position: absolute; position: absolute;
left: 5px; left: 5px;
...@@ -717,11 +742,13 @@ onMounted(() => { ...@@ -717,11 +742,13 @@ onMounted(() => {
border-radius: 10px; border-radius: 10px;
padding: 2px; padding: 2px;
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.icon2 { .icon2 {
position: absolute; position: absolute;
right: 5px; right: 5px;
...@@ -731,12 +758,14 @@ onMounted(() => { ...@@ -731,12 +758,14 @@ onMounted(() => {
border-radius: 10px; border-radius: 10px;
padding: 2px; padding: 2px;
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
} }
.name { .name {
margin-top: 10px; margin-top: 10px;
height: 14px; height: 14px;
...@@ -756,6 +785,7 @@ onMounted(() => { ...@@ -756,6 +785,7 @@ onMounted(() => {
} }
} }
} }
.right-box1-main-bottom { .right-box1-main-bottom {
margin: 17px 16px 0 16px; margin: 17px 16px 0 16px;
border-top: 1px solid rgba(243, 243, 244, 1); border-top: 1px solid rgba(243, 243, 244, 1);
...@@ -781,8 +811,10 @@ onMounted(() => { ...@@ -781,8 +811,10 @@ onMounted(() => {
// } // }
} }
} }
.right-box1-footer { .right-box1-footer {
display: flex; display: flex;
.left { .left {
width: 70px; width: 70px;
height: 18px; height: 18px;
...@@ -794,6 +826,7 @@ onMounted(() => { ...@@ -794,6 +826,7 @@ onMounted(() => {
margin-left: 26px; margin-left: 26px;
margin-top: 23px; margin-top: 23px;
} }
.right { .right {
flex: 1; flex: 1;
display: flex; display: flex;
...@@ -801,6 +834,7 @@ onMounted(() => { ...@@ -801,6 +834,7 @@ onMounted(() => {
margin-right: 20px; margin-right: 20px;
margin-top: 20px; margin-top: 20px;
justify-content: space-between; justify-content: space-between;
.right-tag { .right-tag {
padding: 1px 8px 1px 8px; padding: 1px 8px 1px 8px;
// box-sizing: border-box; // box-sizing: border-box;
...@@ -812,21 +846,25 @@ onMounted(() => { ...@@ -812,21 +846,25 @@ onMounted(() => {
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
} }
.tag1 { .tag1 {
border: 1px solid rgba(186, 224, 255, 1); border: 1px solid rgba(186, 224, 255, 1);
background: rgba(230, 244, 255, 1); background: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1); color: rgba(22, 119, 255, 1);
} }
.tag2 { .tag2 {
border: 1px solid rgba(217, 247, 190, 1); border: 1px solid rgba(217, 247, 190, 1);
background: rgba(246, 255, 237, 1); background: rgba(246, 255, 237, 1);
color: rgba(82, 196, 26, 1); color: rgba(82, 196, 26, 1);
} }
.tag3 { .tag3 {
border: 1px solid rgba(255, 204, 199, 1); border: 1px solid rgba(255, 204, 199, 1);
background: rgba(255, 241, 240, 1); background: rgba(255, 241, 240, 1);
color: rgba(255, 77, 79, 1); color: rgba(255, 77, 79, 1);
} }
.tag4 { .tag4 {
border: 1px solid rgba(255, 241, 184, 1); border: 1px solid rgba(255, 241, 184, 1);
background: rgba(255, 251, 230, 1); background: rgba(255, 251, 230, 1);
...@@ -835,22 +873,27 @@ onMounted(() => { ...@@ -835,22 +873,27 @@ onMounted(() => {
} }
} }
} }
.right-box2 { .right-box2 {
height: 423px; height: 423px;
.right-box2-header { .right-box2-header {
height: 22px; height: 22px;
margin-left: 22px; margin-left: 22px;
padding-top: 10px; padding-top: 10px;
display: flex; display: flex;
.icon { .icon {
margin: 1px 12px 3px 0; margin: 1px 12px 3px 0;
width: 16px; width: 16px;
height: 16px; height: 16px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.title { .title {
height: 22px; height: 22px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -860,6 +903,7 @@ onMounted(() => { ...@@ -860,6 +903,7 @@ onMounted(() => {
line-height: 22px; line-height: 22px;
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
.title-active { .title-active {
color: var(--color-main-active); color: var(--color-main-active);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -868,6 +912,7 @@ onMounted(() => { ...@@ -868,6 +912,7 @@ onMounted(() => {
} }
} }
} }
.right-box2-center { .right-box2-center {
height: 345px; height: 345px;
overflow: auto; overflow: auto;
...@@ -875,6 +920,7 @@ onMounted(() => { ...@@ -875,6 +920,7 @@ onMounted(() => {
margin-top: 19px; margin-top: 19px;
margin-left: 16px; margin-left: 16px;
width: 544px; width: 544px;
.user-box { .user-box {
cursor: pointer; cursor: pointer;
width: 538px; width: 538px;
...@@ -883,22 +929,27 @@ onMounted(() => { ...@@ -883,22 +929,27 @@ onMounted(() => {
border-bottom: 1px solid rgba(241, 243, 246, 1); border-bottom: 1px solid rgba(241, 243, 246, 1);
margin-bottom: 0; margin-bottom: 0;
display: flex; display: flex;
&:last-child { &:last-child {
border-bottom: none; border-bottom: none;
} }
.user-left { .user-left {
margin-left: 14px; margin-left: 14px;
margin-top: 12px; margin-top: 12px;
.img-box { .img-box {
width: 56px; width: 56px;
height: 56px; height: 56px;
position: relative; position: relative;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 50%; border-radius: 50%;
object-fit: cover; object-fit: cover;
} }
.icon1 { .icon1 {
position: absolute; position: absolute;
left: -2px; left: -2px;
...@@ -912,12 +963,14 @@ onMounted(() => { ...@@ -912,12 +963,14 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
img { img {
width: 14px; width: 14px;
height: 14px; height: 14px;
border-radius: 0; border-radius: 0;
} }
} }
.icon2 { .icon2 {
position: absolute; position: absolute;
right: -2px; right: -2px;
...@@ -931,6 +984,7 @@ onMounted(() => { ...@@ -931,6 +984,7 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
img { img {
width: 14px; width: 14px;
height: 14px; height: 14px;
...@@ -939,12 +993,15 @@ onMounted(() => { ...@@ -939,12 +993,15 @@ onMounted(() => {
} }
} }
} }
.user-right { .user-right {
margin-left: 16px; margin-left: 16px;
flex: 1; flex: 1;
:deep(.text-ellipsis) { :deep(.text-ellipsis) {
white-space: normal; white-space: normal;
} }
.name { .name {
margin-top: 10px; margin-top: 10px;
height: 24px; height: 24px;
...@@ -954,6 +1011,7 @@ onMounted(() => { ...@@ -954,6 +1011,7 @@ onMounted(() => {
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
} }
.content { .content {
margin-top: 4px; margin-top: 4px;
color: #666; color: #666;
...@@ -972,6 +1030,7 @@ onMounted(() => { ...@@ -972,6 +1030,7 @@ onMounted(() => {
} }
} }
} }
// .right-box2-footer { // .right-box2-footer {
// margin-top: 7px; // margin-top: 7px;
// display: flex; // display: flex;
...@@ -994,15 +1053,18 @@ onMounted(() => { ...@@ -994,15 +1053,18 @@ onMounted(() => {
:deep(.el-steps--simple) { :deep(.el-steps--simple) {
padding: 6px 10px; padding: 6px 10px;
} }
:deep(.el-timeline-item) { :deep(.el-timeline-item) {
padding-bottom: 5px !important; padding-bottom: 5px !important;
} }
:deep(.el-timeline-item__timestamp) { :deep(.el-timeline-item__timestamp) {
color: rgba(95, 101, 108, 1) !important; color: rgba(95, 101, 108, 1) !important;
font-family: Microsoft YaHei !important; font-family: Microsoft YaHei !important;
font-size: 14px !important; font-size: 14px !important;
font-weight: 600 !important; font-weight: 600 !important;
} }
.timeline-content { .timeline-content {
color: rgba(132, 136, 142, 1); color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
......
...@@ -1524,24 +1524,26 @@ watch(box8selectetedTime, () => { ...@@ -1524,24 +1524,26 @@ watch(box8selectetedTime, () => {
}); });
const handleToPosi = id => { const handleToPosi = id => {
let top = 0; const element = document.getElementById(id);
switch (id) { if (element && containerRef.value) {
case "position2": // 1. 如果是从完整搜索框跳转,先强制切换状态稳定布局
top = isShow.value ? 634 : 980; if (!isShow.value) {
break; isShow.value = true;
case "position3": }
top = isShow.value ? 1204 : 1550;
break; // 2. 使用 nextTick 等待 DOM 布局(如高度切换)完成后再进行坐标计算
case "position4": nextTick(() => {
top = isShow.value ? 2334 : 2680; const containerRect = containerRef.value.getBoundingClientRect();
break; const elementRect = element.getBoundingClientRect();
default: // 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离
top = 0; const top = elementRect.top - containerRect.top + containerRef.value.scrollTop;
containerRef.value.scrollTo({
top: top,
behavior: "smooth"
});
});
} }
containerRef.value.scrollTo({
top: top,
behavior: "smooth"
});
}; };
const tabList = ref([ const tabList = ref([
...@@ -1838,6 +1840,7 @@ onUnmounted(() => {}); ...@@ -1838,6 +1840,7 @@ onUnmounted(() => {});
overflow-y: auto; overflow-y: auto;
} }
.home-box { .home-box {
position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: url("./assets/images/background.png"); background: url("./assets/images/background.png");
......
...@@ -116,62 +116,6 @@ const handleClickLeftSiderBtn = (item) => { ...@@ -116,62 +116,6 @@ const handleClickLeftSiderBtn = (item) => {
} }
}) })
} }
const progressList = ref([
{
tip: true,
date: "7月5日",
title:
"特朗普于美国独立日签署法案,​公法编号Pub. L. No. 119-21。白宫举行庆典,B-2轰炸机飞越上空,象征“美国新时代”开启。",
degree: "特别重大风险",
rank: 4,
},
{
tip: true,
date: "7月4日",
title:
"众议院最终表决218票赞成 vs 214票反对,修订版法案以4票优势通过,2名共和党议员倒戈,民主党全员反对。",
degree: "重大风险",
rank: 3,
},
{
tip: true,
date: "7月3日",
title:
"民主党领袖杰弗里斯发表 ​8小时45分钟​ 演讲(众议院现代史最长),抗议法案“劫贫济富”,但仍未阻止表决。",
degree: "较大风险",
rank: 2,
},
{
tip: true,
date: "7月2日",
title:
"众议院以 ​219:213​ 通过程序规则,为最终表决铺路。此前4名共和党议员反对程序规则,议长约翰逊紧急游说挽回1票。",
degree: "低风险",
rank: 1,
},
{
tip: false,
date: "7月1日",
title:
"参议院最终表决投票51:50​,副总统万斯(JD Vance)投出关键票打破平局。3名共和党参议员倒戈(蒂利斯、保罗、柯林斯)。",
degree: "",
},
]);
const wordCloudData = [
{ name: "财政保守主义", value: 100 },
{ name: "移民与边境安全", value: 5 },
{ name: "削减市民福利", value: 77 },
{ name: "债务驱动型经济", value: 35 },
{ name: "传统能源", value: 96 },
{ name: "与马斯克公开冲突", value: 57 },
{ name: "共和党财政鹰派", value: 72 },
{ name: "财政问责法案", value: 18 },
{ name: "强硬边境政策", value: 34 },
{ name: "扩大军费", value: 16 },
{ name: "债务与赤字警告", value: 72 },
{ name: "批评美国债务膨胀", value: 58 },
];
onMounted(() => {}); onMounted(() => {});
</script> </script>
......
...@@ -335,6 +335,14 @@ onMounted(() => { ...@@ -335,6 +335,14 @@ onMounted(() => {
margin-bottom: 12px; margin-bottom: 12px;
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
&::before {
content: "·";
font-size: 24px;
line-height: 20px;
font-weight: bold;
margin-right: 16px;
color: rgb(59, 65, 75);
}
.ul-title { .ul-title {
flex-shrink: 0; flex-shrink: 0;
width: 120px; width: 120px;
...@@ -413,6 +421,16 @@ onMounted(() => { ...@@ -413,6 +421,16 @@ onMounted(() => {
line-height: 24px; line-height: 24px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
margin-bottom: 10px; margin-bottom: 10px;
display: flex;
align-items: center;
&::before {
content: "·";
font-size: 24px;
line-height: 20px;
font-weight: bold;
margin-right: 12px;
color: rgb(59, 65, 75);
}
} }
} }
.left-bottom-content { .left-bottom-content {
......
<template> <template>
<div class="reslib-page"> <div class="reslib-page" ref="reslibContainer">
<div class="nav"> <div class="nav">
<div <div
v-for="item in navList" v-for="item in navList"
:key="item" :key="item.id"
class="nav-item" class="nav-item"
:class="{ active: item === activeItem }" :class="{ active: item.id === activeItem }"
@click="activeItem = item" @click="activeItem = item.id"
> >
{{ item }} {{ item.name }}
</div> </div>
</div> </div>
<el-select v-model="value" placeholder="Select" class="select"> <el-select v-model="value" placeholder="排序方式" class="select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" /> <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select> </el-select>
<div class="main"> <div class="main">
...@@ -21,13 +21,21 @@ ...@@ -21,13 +21,21 @@
<div class="left-title">数据来源</div> <div class="left-title">数据来源</div>
<div class="left-content"> <div class="left-content">
<div v-for="item in dataList" :key="item.id" class="left-item"> <div v-for="item in dataList" :key="item.id" class="left-item">
<input type="checkbox" checked />{{ item.name }} <input
type="checkbox"
:value="String(item.id)"
v-model="selectedSources"
/>{{ item.name }}
</div> </div>
</div> </div>
<div class="left-title cl1">涉及领域</div> <div class="left-title cl1">涉及领域</div>
<div class="left-content"> <div class="left-content">
<div v-for="(item, i) in dataList2" :key="item.id" class="left-item"> <div v-for="item in dataList2" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }} <input
type="checkbox"
:value="String(item.id)"
v-model="selectedDomains"
/>{{ item.name }}
</div> </div>
</div> </div>
</div> </div>
...@@ -47,15 +55,14 @@ ...@@ -47,15 +55,14 @@
<div class="domain"> <div class="domain">
<div v-for="(domain, i) in item.domain" :key="i" class="domain-item">{{ domain }}</div> <div v-for="(domain, i) in item.domain" :key="i" class="domain-item">{{ domain }}</div>
</div> </div>
<div class="type" :class="{ type1: item.type === '行政令', type2: item.type === '法案' }"> <div class="type" :class="getTypeClass(item.type)">
{{ item.type }} {{ item.type }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="line"></div> <div class="page">
<div class="page"> <div class="count">{{ total }}项调查</div>
<div class="count">共1205项调查</div>
<el-pagination <el-pagination
v-model:current-page="currentPage" v-model:current-page="currentPage"
:page-size="pageSize" :page-size="pageSize"
...@@ -72,202 +79,245 @@ ...@@ -72,202 +79,245 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onMounted, watch } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { getCoopRestrictionList } from "@/api/coopRestriction/coopRestriction";
import defaultImg from "../../assets/images/default-icon2.png";
// 合作限制-获取合作限制列表接口
const getMainDataList = async () => {
const params = {
currentPage: currentPage.value - 1, // 后端通常从0开始计页
pageSize: pageSize.value,
sortField: "date"
};
if (!selectedDomains.value.includes("0")) {
params.area = selectedDomains.value.join(",");
}
if (!selectedSources.value.includes("0")) {
params.source = selectedSources.value.join(",");
}
if (activeItem.value !== "0") {
params.type = activeItem.value;
}
if (value.value) {
params.sortOrder = value.value;
}
try {
const res = await getCoopRestrictionList(params);
if (res && res.code === 200) {
mainDataList.value = (res.data.content || []).map(item => ({
id: item.limitId,
title: item.limitName,
content: item.limitIntroduction,
date: item.limitDate,
domain: item.limitArea || [],
type: item.limitMeans,
// 使用默认图片
img: defaultImg
}));
total.value = res.data.totalElements || 0;
} else {
mainDataList.value = [];
total.value = 0;
}
} catch (error) {
console.error("获取合作限制列表失败:", error);
mainDataList.value = [];
total.value = 0;
}
};
import whitehouse from "./assets/白宫.png";
import guohui from "./assets/国会.png";
import guotuanquanbu from "./assets/国土安全部.png";
import guowuyuan from "./assets/国务院.png";
import weishengyanjiuyuan from "./assets/卫生研究院.png";
import zhongyiyuan from "./assets/众议院.png";
import fda from "./assets/FDA.png";
const router = useRouter(); const router = useRouter();
const handleClick = item => { const handleClick = item => {
router.push({ const routeData = router.resolve({
path: "/cooperationRestrictions/detail", path: "/cooperationRestrictions/detail",
query: { query: {
id: item.id id: item.id
} }
}); });
window.open(routeData.href, "_blank");
}; };
const navList = ref(["全部限制", "学术交流限制", "科研合作限制", "人才流动限制", "数据共享限制"]); const navList = ref([
const activeItem = ref("全部限制"); { id: "0", name: "全部限制" },
{ id: "01", name: "学术交流限制" },
{ id: "02", name: "科研合作限制" },
{ id: "03", name: "人才流动限制" },
{ id: "04", name: "数据共享限制" }
]);
const activeItem = ref("0");
const value = ref("发布时间"); const value = ref("");
const options = [ const options = [
{ {
value: "发布时间", value: "asc",
label: "发布时间" label: "正序"
}, },
{ {
value: "发布日期", value: "desc",
label: "发布日期" label: "倒序"
} }
]; ];
const dataList = ref([ const dataList = ref([
{ {
id: 1, id: "0",
name: "全部来源" name: "全部来源"
}, },
{ {
id: 2, id: "02",
name: "法案" name: "法案"
}, },
{ {
id: 3, id: "01",
name: "政令" name: "政令"
}, },
{ {
id: 4, id: "03",
name: "政府公告" name: "政府公告"
} }
]); ]);
const selectedSources = ref(["0"]);
const dataList2 = ref([ const dataList2 = ref([
{ {
id: 1, id: 0,
name: "全部领域" name: "全部领域"
}, },
{ {
id: 2, id: 1,
name: "人工智能" name: "人工智能"
}, },
{
id: 2,
name: "生物科技"
},
{ {
id: 3, id: 3,
name: "集成电路" name: "新一代信息技术"
}, },
{ {
id: 4, id: 4,
name: "通信网络" name: "量子科技"
}, },
{ {
id: 5, id: 5,
name: "量子科技" name: "新能源"
}, },
{ {
id: 6, id: 6,
name: "能源" name: "集成电路"
}, },
{ {
id: 7, id: 7,
name: "生物科技" name: "海洋"
}, },
{ {
id: 8, id: 8,
name: "航空航天" name: "先进制造"
}, },
{ {
id: 9, id: 9,
name: "海洋" name: "新材料"
}
]);
const mainDataList = ref([
{
id: 1,
title: "美国国土安全部:取消哈佛大学SEVP认证,禁止其招收国际新生",
content:
"国土安全部长诺姆以安全审查为由,正式终止哈佛大学“学生与交流访问学者项目”(SEVP)认证,导致该校丧失2025~2026学年招收国际新生的资格。",
date: "2025年10月15日",
domain: ["人才流动限制"],
type: "行政令",
img: guotuanquanbu
},
{
id: 2,
title: "美国白宫:通过应对哈佛大学的风险来增强国家安全",
content:
"学生交换签证计划(SEVP)根本依赖于学术机构的诚信、透明度以及对相关监管框架的完全遵守。 这是出于关键的国家安全原因。 联邦调查局(FBI)长期警告称,外国对手和竞争对手利用美国高等教育的便捷通道,窃取技术信息和产品,利用昂贵的研发项目来实现自身野心,并出于政治或其他原因传...",
date: "2025年9月30日",
domain: ["人才流动限制"],
type: "行政令",
img: whitehouse
},
{
id: 3,
title: "美国白宫:限制外国公民入境,以保护美国免受外国恐怖分子及其他国家安全和公共安全威胁",
content: "美国商务部宣称将“至少每年”更新一次管制规则,以堵塞已发现的政策“漏洞”。",
date: "2025年9月15日",
domain: ["人才流动限制"],
type: "行政令",
img: whitehouse
},
{
id: 4,
title: "美国白宫:提升生物研究的安全性与保障",
content: "停止联邦资助外国实体在关注国家(如中国)进行的危险功能增益研究。",
date: "2025年9月15日",
domain: ["人才流动限制", "生物科技"],
type: "行政令",
img: whitehouse
}, },
{ {
id: 5, id: 10,
title: "美国国会:《2026财年拨款法案》审议通过重启“中国行动计划”", name: "航空航天"
content: "美国众议院拨款委员会在审议《2026财年拨款法案》时,加入条款要求司法部重启已被拜登政府叫停的“中国行动计划”。",
date: "2025年9月1日",
domain: ["人才流动限制"],
type: "法案",
img: guohui
}, },
{ {
id: 6, id: 11,
title: "美国FDA:紧急叫停涉及将美国公民活体细胞送往中国等“敌对国家”实验室的临床试验", name: "深海"
content: "涉及将人类生物样本(如活体细胞)转移至中国进行基因工程等研究的临床试验项目,相关研究被叫停。",
date: "2025年8月26日",
domain: ["数据共享限制", "生物科技"],
type: "行政令",
img: fda
}, },
{ {
id: 7, id: 12,
title: "美国众议院“美中战略竞争特设委员会”:要求杜克大学终止昆山杜克大学合作项目", name: "极地"
content: "指控其“通过先进摄像系统研究协助中国导弹制导技术发展”,并质疑美国学生被用于中国宣传。",
date: "2025年8月22日",
domain: ["科研合作限制"],
type: "行政令",
img: zhongyiyuan
}, },
{ {
id: 8, id: 13,
title: "美国国务院:大规模撤销部分中国学生签证,重点审查STEM领域", name: "太空"
content:
"美国国务卿鲁比奥宣布将开始大规模撤销部分中国学生的签证,重点针对STEM(科学、技术、工程和数学)领域的学习者以及所谓“与中国政府有联系”的人员,并全面提升对中国大陆和香港地区申请者的签证审查标准",
date: "2025年8月15日",
domain: ["人才流动限制"],
type: "行政令",
img: guowuyuan
}, },
{ {
id: 9, id: 14,
title: "美国FDA:针对两家中国第三方检测机构的数据完整性问题采取行动", name: "核"
content:
"FDA因发现数据伪造或无效问题,向两家中国第三方检测公司(天津中联科技检测有限公司和苏州大学卫生与环境技术研究所)正式发出“一般信函”。",
date: "2025年10月15日",
domain: ["数据共享限制", "生物科技"],
type: "行政令",
img: fda
},
{
id: 10,
title: "美国国家卫生研究院:限制中国等国的研究人员访问其受控访问数据存储库",
content: "美国商务部宣称将“至少每年”更新一次管制规则,以堵塞已发现的政策“漏洞”。",
date: "2025年9月15日",
domain: ["数据共享限制", "生物科技"],
type: "行政令",
img: weishengyanjiuyuan
} }
]); ]);
const selectedDomains = ref(["0"]);
const mainDataList = ref([]);
const total = ref(0);
const pageSize = ref(10);
const currentPage = ref(1);
const reslibContainer = ref(null);
const getTypeClass = (type) => {
const map = {
'行政令': 'type1',
'法案': 'type2',
'政府公告': 'type3',
'政令': 'type4'
};
return map[type] || 'type-default';
};
const total = ref(1205);
const pageSize = ref(121);
const currentPage = ref(5);
const handlePageChange = p => { const handlePageChange = p => {
currentPage.value = p; currentPage.value = p;
// 翻页后平滑滚动到资源库顶部
if (reslibContainer.value) {
reslibContainer.value.scrollIntoView({ behavior: "smooth" });
}
}; };
onMounted(() => {
getMainDataList();
});
watch(
[activeItem, selectedSources, selectedDomains, value],
(newVal, oldVal) => {
const [newActive, newSources, newDomains] = newVal;
const [, oldSources, oldDomains] = oldVal;
if (newSources.includes("0") && newSources.length > 1) {
if (oldSources.includes("0")) {
selectedSources.value = newSources.filter(i => i !== "0");
return;
} else {
selectedSources.value = ["0"];
return;
}
} else if (newSources.length === 0) {
selectedSources.value = ["0"];
return;
}
if (newDomains.includes("0") && newDomains.length > 1) {
if (oldDomains.includes("0")) {
selectedDomains.value = newDomains.filter(i => i !== "0");
return;
} else {
selectedDomains.value = ["0"];
return;
}
} else if (newDomains.length === 0) {
selectedDomains.value = ["0"];
return;
}
if (currentPage.value === 1) {
getMainDataList();
} else {
currentPage.value = 1;
}
},
{ deep: true }
);
watch(currentPage, () => {
getMainDataList();
});
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
...@@ -277,8 +327,10 @@ const handlePageChange = p => { ...@@ -277,8 +327,10 @@ const handlePageChange = p => {
} }
.reslib-page { .reslib-page {
width: 1600px; width: 1600px;
height: 1565px; min-height: 1565px;
height: auto;
position: relative; position: relative;
padding-bottom: 50px;
.nav { .nav {
width: 808px; width: 808px;
height: 42px; height: 42px;
...@@ -310,11 +362,12 @@ const handlePageChange = p => { ...@@ -310,11 +362,12 @@ const handlePageChange = p => {
} }
.main { .main {
width: 1600px; width: 1600px;
height: 1489px; height: auto;
min-height: 1489px;
display: flex; display: flex;
.left { .left {
width: 300px; width: 300px;
height: 584px; height: 760px;
margin-right: 16px; margin-right: 16px;
border-radius: 10px; border-radius: 10px;
background-color: #fff; background-color: #fff;
...@@ -350,12 +403,12 @@ const handlePageChange = p => { ...@@ -350,12 +403,12 @@ const handlePageChange = p => {
margin-top: 13px; margin-top: 13px;
} }
.left-content { .left-content {
width: 109px; // width: 109px;
height: 132px; // height: 132px;
margin-left: 25px; margin-left: 25px;
margin-top: 13px; margin-top: 13px;
.left-item { .left-item {
width: 89px; // width: 89px;
height: 30px; height: 30px;
margin-bottom: 4px; margin-bottom: 4px;
font-size: 16px; font-size: 16px;
...@@ -397,7 +450,8 @@ const handlePageChange = p => { ...@@ -397,7 +450,8 @@ const handlePageChange = p => {
} }
.right { .right {
width: 1284px; width: 1284px;
height: 1489px; height: auto;
min-height: 1489px;
border-radius: 10px; border-radius: 10px;
background-color: #fff; background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
...@@ -427,46 +481,58 @@ const handlePageChange = p => { ...@@ -427,46 +481,58 @@ const handlePageChange = p => {
} }
.right-main { .right-main {
width: 1284px; width: 1284px;
height: 1441px; height: auto;
padding: 22px 43px 15px 20px; min-height: 1441px;
padding: 22px 43px 80px 20px;
position: relative; position: relative;
.main-content { .main-content {
width: 1221px; width: 1221px;
height: 1345px; height: auto;
min-height: 1345px;
.main-item { .main-item {
width: 1221px; width: 1221px;
height: auto;
min-height: 116px; min-height: 116px;
max-height: 140px; margin-bottom: 24px;
margin-bottom: 16px;
position: relative; position: relative;
.date { display: flex;
&::after {
content: "";
position: absolute; position: absolute;
top: 4px; top: 37px;
left: 10px; bottom: -37px;
left: 91px;
width: 2px;
background-color: rgb(230, 231, 232);
z-index: 1;
}
&:last-child::after {
display: none;
}
.date {
flex-shrink: 0;
width: 62px; width: 62px;
height: 68px;
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
color: rgb(5, 95, 194); color: rgb(5, 95, 194);
text-align: right; text-align: right;
margin-top: 13px;
} }
.img { .img {
flex-shrink: 0;
width: 24px; width: 24px;
height: 24px; height: 24px;
position: absolute; margin: 13px 21px 0 18px;
top: 13px; position: relative;
left: 90px;
z-index: 100; z-index: 100;
} }
.box { .box {
width: 1086px; flex: 1;
min-height: 91px; min-height: 91px;
max-height: 114px; position: relative;
position: absolute; padding-top: 10px;
top: 10px;
left: 135px;
.title { .title {
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
...@@ -493,7 +559,7 @@ const handlePageChange = p => { ...@@ -493,7 +559,7 @@ const handlePageChange = p => {
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
position: absolute; position: absolute;
top: 0px; top: 10px;
right: 0px; right: 0px;
} }
.type1 { .type1 {
...@@ -504,6 +570,18 @@ const handlePageChange = p => { ...@@ -504,6 +570,18 @@ const handlePageChange = p => {
background-color: rgba(206, 79, 81, 0.1); background-color: rgba(206, 79, 81, 0.1);
color: rgb(206, 79, 81); color: rgb(206, 79, 81);
} }
.type3 {
background-color: rgba(5, 95, 194, 0.1);
color: rgb(5, 95, 194);
}
.type4 {
background-color: rgba(103, 194, 58, 0.1);
color: rgb(103, 194, 58);
}
.type-default {
background-color: rgba(144, 147, 153, 0.1);
color: rgb(144, 147, 153);
}
.domain { .domain {
margin-bottom: 15px; margin-bottom: 15px;
display: flex; display: flex;
...@@ -522,14 +600,6 @@ const handlePageChange = p => { ...@@ -522,14 +600,6 @@ const handlePageChange = p => {
} }
} }
} }
.line {
height: 1150px;
border: 2px solid rgb(235, 238, 242);
position: absolute;
top: 75px;
left: 120px;
z-index: 1;
}
.page { .page {
width: 1221px; width: 1221px;
height: 40px; height: 40px;
......
<template> <template>
<div class="coop-page"> <div class="coop-page">
<!-- 吸顶简易搜索框 -->
<div class="search-header" v-show="isShow">
<div class="home-main-header-center">
<input v-model="input" class="search-input" placeholder="搜索合作限制" />
<div class="search-btn-small" @click="handleSearch">
<div class="search-icon">
<img src="./assets/icons/search-icon.png" alt="" />
</div>
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-btn-box">
<div class="btn" @click="handleToPosi('position1')">
<div class="btn-text">最新动态</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
<div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
<div class="btn" @click="handleToPosi('position3')">
<div class="btn-text">数据总览</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
<div class="btn" @click="handleToPosi('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
</div>
</div>
<!-- 面包屑 --> <!-- 面包屑 -->
<div class="breadcrumb"> <div class="breadcrumb" v-show="!isShow">
<div class="breadcrumb-box"> <div class="breadcrumb-box">
<div class="breadcrumb-item">国家科技安全</div> <div class="breadcrumb-item">国家科技安全</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div> <div class="breadcrumb-item">&nbsp;>&nbsp;</div>
...@@ -11,9 +50,9 @@ ...@@ -11,9 +50,9 @@
</div> </div>
</div> </div>
<!-- 主页面 --> <!-- 主页面 -->
<div class="main-content"> <div class="main-content" ref="homeMainRef" :class="{ 'scroll-main': isShow }">
<!-- 搜索栏部分 --> <!-- 搜索栏部分 -->
<div class="search"> <div class="search" v-show="!isShow">
<div class="search-main"> <div class="search-main">
<input v-model="input" placeholder="搜索合作限制" class="search-input" /> <input v-model="input" placeholder="搜索合作限制" class="search-input" />
<div class="search-btn"> <div class="search-btn">
...@@ -36,25 +75,25 @@ ...@@ -36,25 +75,25 @@
</div> </div>
</div> --> </div> -->
<div class="search-bottom"> <div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')"> <div class="btn" @click="handleToPosi('position1')">
<div class="btn-text">最新动态</div> <div class="btn-text">最新动态</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div> </div>
</div> </div>
<div class="btn" @click="scrollToTop('position2')"> <div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div> <div class="btn-text">咨询要闻</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div> </div>
</div> </div>
<div class="btn" @click="scrollToTop('position3')"> <div class="btn" @click="handleToPosi('position3')">
<div class="btn-text">数据总览</div> <div class="btn-text">数据总览</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div> </div>
</div> </div>
<div class="btn" @click="scrollToTop('position4')"> <div class="btn" @click="handleToPosi('position4')">
<div class="btn-text">资源库</div> <div class="btn-text">资源库</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
...@@ -95,21 +134,52 @@ ...@@ -95,21 +134,52 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, onMounted, nextTick } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import comTitle from "./common/comTitle.vue"; import comTitle from "./common/comTitle.vue";
import newData from "./components/dataNew/index.vue"; import newData from "./components/dataNew/index.vue";
import askPage from "./components/askPage/index.vue"; import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue"; import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue"; import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
// 搜索框 // 搜索框
const input = ref(""); const input = ref("");
const homeMainRef = ref(null);
const { isShow } = useContainerScroll(homeMainRef);
const router = useRouter(); const router = useRouter();
// 搜索功能
const handleSearch = () => {
console.log("搜索内容:", input.value);
};
// 锚点跳转
const handleToPosi = id => {
const element = document.getElementById(id);
if (element && homeMainRef.value) {
// 如果当前还未显示吸顶搜索栏,先强制切换状态以稳定布局
if (!isShow.value) {
isShow.value = true;
}
// 使用 nextTick 确保 DOM 状态更新(高度变化生效)后再计算
nextTick(() => {
const containerRect = homeMainRef.value.getBoundingClientRect();
const elementRect = element.getBoundingClientRect();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const top = elementRect.top - containerRect.top + homeMainRef.value.scrollTop;
homeMainRef.value.scrollTo({
top: top,
behavior: "smooth"
});
});
}
};
// 返回首页 // 返回首页
const handleBackHome = () => { const handleBackHome = () => {
router.push({ router.push({
...@@ -152,6 +222,7 @@ const handleBackHome = () => { ...@@ -152,6 +222,7 @@ const handleBackHome = () => {
} }
} }
.main-content { .main-content {
position: relative;
overflow: auto; overflow: auto;
width: 100%; width: 100%;
height: calc(100% - 64px); height: calc(100% - 64px);
...@@ -188,7 +259,11 @@ const handleBackHome = () => { ...@@ -188,7 +259,11 @@ const handleBackHome = () => {
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 24px;
color: rgb(132, 136, 142); color: rgba(59, 65, 75, 1);
&::placeholder {
color: #a8abb2;
}
} }
.search-btn { .search-btn {
margin-right: -3px; margin-right: -3px;
...@@ -335,5 +410,132 @@ const handleBackHome = () => { ...@@ -335,5 +410,132 @@ const handleBackHome = () => {
} }
} }
} }
.search-header {
width: 100%;
height: 144px;
background: #fff;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
overflow: hidden;
.home-main-header-center {
margin-top: 20px;
margin-left: 200px;
width: 800px;
height: 48px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
padding: 1px;
position: relative;
border: 1px solid transparent;
display: flex;
align-items: center;
&:hover {
border: 1px solid var(--color-main-active);
}
.search-input {
border: none;
outline: none;
width: 800px;
height: 46px;
background-color: transparent;
font-size: 16px;
padding: 12px 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
}
.search-btn-small {
position: absolute;
right: -1px;
top: 0px;
width: 120px;
height: 46px;
border-radius: 10px;
background: var(--color-main-active);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
.search-icon {
width: 18px;
height: 18px;
img {
width: 100%;
height: 100%;
}
}
.search-text {
margin-left: 8px;
height: 22px;
color: #fff;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 22px;
}
}
}
.home-main-header-btn-box {
margin-top: 20px;
margin-left: 200px;
display: flex;
gap: 16px;
.btn {
display: flex;
align-items: center;
gap: 9px;
width: 160px;
height: 48px;
border: 1px solid #aed6ff;
box-sizing: border-box;
border-radius: 24px;
background: #e7f3ff;
cursor: pointer;
position: relative;
&:hover {
background: #cae3fc;
}
.btn-text {
width: 80px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 48px;
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
top: 16px;
right: 19px;
width: 6px;
height: 12px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.scroll-main {
height: calc(100% - 144px) !important;
}
} }
</style> </style>
...@@ -627,8 +627,7 @@ ...@@ -627,8 +627,7 @@
</template> </template>
<script setup> <script setup>
import { onMounted, ref, computed, reactive, shallowRef, watch } from "vue"; import { onMounted, ref, computed, reactive, shallowRef, watch, nextTick } from "vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
const homeMainRef = ref(null); const homeMainRef = ref(null);
const { isShow } = useContainerScroll(homeMainRef); const { isShow } = useContainerScroll(homeMainRef);
...@@ -686,12 +685,22 @@ import { ...@@ -686,12 +685,22 @@ import {
const handleToPosi = id => { const handleToPosi = id => {
const element = document.getElementById(id); const element = document.getElementById(id);
if (element && homeMainRef.value) { if (element && homeMainRef.value) {
const containerRect = homeMainRef.value.getBoundingClientRect(); // 1. 如果是从完整搜索框跳转,先强制切换状态稳定布局
const elementRect = element.getBoundingClientRect(); if (!isShow.value) {
const top = elementRect.top - containerRect.top + homeMainRef.value.scrollTop; isShow.value = true;
homeMainRef.value.scrollTo({ }
top: top,
behavior: "smooth" // 2. 使用 nextTick 等待 DOM 布局(如高度切换)完成后再进行坐标计算
nextTick(() => {
const containerRect = homeMainRef.value.getBoundingClientRect();
const elementRect = element.getBoundingClientRect();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const top = elementRect.top - containerRect.top + homeMainRef.value.scrollTop;
homeMainRef.value.scrollTo({
top: top,
behavior: "smooth"
});
}); });
} }
}; };
...@@ -2159,6 +2168,7 @@ const handleMediaClick = item => { ...@@ -2159,6 +2168,7 @@ const handleMediaClick = item => {
overflow-y: hidden; overflow-y: hidden;
.home-main { .home-main {
position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
......
...@@ -103,36 +103,37 @@ ...@@ -103,36 +103,37 @@
</div> </div>
</div> </div>
<div class="right-title"> <div class="right-title">
<div class="filter-row">
<!-- <div class="filter-left">
<el-select v-model="filterEntity" placeholder="受制裁实体" style="width: 184px">
<el-option label="受制裁实体" value="1" />
</el-select>
</div> -->
<div class="filter-right">
<el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select v-model="filterField" placeholder="全部领域" style="width: 150px; margin: 0 12px 0 16px">
<el-option label="全部领域" value="" />
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-input v-model="searchKeyword" placeholder="搜索实体" style="width: 150px" :suffix-icon="Search" />
</div>
</div>
<div class="stats-row"> <div class="stats-row">
<!-- <div class="tabs"> <div class="tabs">
<div class="tab-btn" :class="{ active: activeTab === 'add' }" @click="activeTab = 'add'">新增实体</div> <div class="tab-btn" :class="{ active: activeTab === 'add' }" @click="activeTab = 'add'">新增实体</div>
<div class="tab-btn" :class="{ active: activeTab === 'remove' }" @click="activeTab = 'remove'">移除实体</div> <div class="tab-btn" :class="{ active: activeTab === 'remove' }" @click="activeTab = 'remove'">移除实体</div>
</div> --> </div>
<div class="stats-info"> <div class="stats-info">
<div class="stat-item"> <div class="stat-item">
<span class="dot red"></span> <span class="dot red"></span>
<span class="text">新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{ <span class="text">新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{
addRuleCount }}</span>家)</span> addRuleCount }}</span>家)</span>
</div> </div>
<!-- <div class="stat-item"> <div class="stat-item">
<span class="dot green"></span> <span class="dot green"></span>
<span class="text">移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span class="num green">{{ removeRuleCount }}</span>家)</span> <span class="text">移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span class="num green">{{ removeRuleCount }}</span>家)</span>
</div> --> </div>
</div>
</div>
<div class="filter-row">
<div class="filter-left">
<!-- <el-select v-model="filterEntity" placeholder="受制裁实体" style="width: 184px">
<el-option label="受制裁实体" value="1" />
</el-select> -->
</div>
<div class="filter-right">
<el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select v-model="filterField" placeholder="全部领域" style="width: 150px; margin: 0 12px 0 16px">
<el-option label="全部领域" value="" />
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-input v-model="searchKeyword" placeholder="搜索实体" style="width: 150px" :suffix-icon="Search" />
</div> </div>
</div> </div>
</div> </div>
...@@ -185,6 +186,7 @@ ...@@ -185,6 +186,7 @@
<script setup> <script setup>
import { ref, defineProps, computed, onMounted, watch } from "vue"; import { ref, defineProps, computed, onMounted, watch } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import { DArrowRight, Search } from "@element-plus/icons-vue"; import { DArrowRight, Search } from "@element-plus/icons-vue";
import { debounce } from "lodash"; import { debounce } from "lodash";
import title from "../../assets/title.png" import title from "../../assets/title.png"
...@@ -195,14 +197,10 @@ import RuleSubsidiaryDialog from "../../../v2.0EntityList/components/sanctionsOv ...@@ -195,14 +197,10 @@ import RuleSubsidiaryDialog from "../../../v2.0EntityList/components/sanctionsOv
// 跳转公司详情页 // 跳转公司详情页
const handleCompClick = item => { const handleCompClick = item => {
// console.log("item", item); if (!item.entityId) {
// const route = router.resolve({ ElMessage.warning("暂无数据");
// path: "/companyPages", return;
// query: { }
// id: item.entityId
// }
// });
// window.open(route.href, "_blank");
const curRoute = router.resolve({ name: "companyPages", params: { id: item.entityId } }); const curRoute = router.resolve({ name: "companyPages", params: { id: item.entityId } });
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
...@@ -817,10 +815,9 @@ onMounted(() => { ...@@ -817,10 +815,9 @@ onMounted(() => {
.filter-row { .filter-row {
display: flex; display: flex;
// 隐藏使用right,解除使用space-between
justify-content: right; justify-content: right;
align-items: center; align-items: center;
margin-bottom: 20px; // margin-bottom: 20px;
:deep(.el-input__inner) { :deep(.el-input__inner) {
font-size: 16px; font-size: 16px;
...@@ -850,8 +847,8 @@ onMounted(() => { ...@@ -850,8 +847,8 @@ onMounted(() => {
.stats-row { .stats-row {
display: flex; display: flex;
// 隐藏使用right,解除使用space-between margin-bottom: 20px;
justify-content: right; justify-content: space-between;
align-items: center; align-items: center;
.tabs { .tabs {
......
...@@ -158,16 +158,16 @@ ...@@ -158,16 +158,16 @@
<div class="box2-main"> <div class="box2-main">
<div class="box2-main-item" v-for="(item, index) in warningList" :key="index"> <div class="box2-main-item" v-for="(item, index) in warningList" :key="index">
<div class="item-left" :class="{ <div class="item-left" :class="{
itemLeftStatus1: item.status === '一般风险', itemLeftStatus1: item.signalLevel === '一般风险',
itemLeftStatus2: item.status === '重大风险' itemLeftStatus2: item.signalLevel === '重大风险'
}"> }">
{{ item.status }} {{ item.signalLevel }}
</div> </div>
<div class="item-right"> <div class="item-right">
<div class="text"> <div class="text">
{{ item.title }} {{ item.signalTitle }}
</div> </div>
<div class="time">{{ item.time }}</div> <div class="time">{{ item.signalTime }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -194,14 +194,14 @@ ...@@ -194,14 +194,14 @@
<div class="box3-main"> <div class="box3-main">
<div class="box3-item" v-for="(news, index) in newsList" :key="index"> <div class="box3-item" v-for="(news, index) in newsList" :key="index">
<div class="left"> <div class="left">
<img :src="news.img" alt="" /> <img :src="news.newsImage" alt="" />
</div> </div>
<div class="right"> <div class="right">
<div class="right-top"> <div class="right-top">
<div class="title">{{ news.title }}</div> <div class="title">{{ news.newsTitle }}</div>
<div class="time">{{ news.from }}</div> <div class="time">{{ news.newsDate + '.' + news.newsOrg }}</div>
</div> </div>
<div class="right-footer">{{ news.content }}</div> <div class="right-footer">{{ news.newsContent }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -216,14 +216,14 @@ ...@@ -216,14 +216,14 @@
<div class="box4-main"> <div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index"> <div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left"> <div class="left">
<img :src="item.img" alt="" /> <img :src="item.personImage" alt="" />
</div> </div>
<div class="right"> <div class="right">
<div class="right-top"> <div class="right-top">
<div class="name">{{ item.name }}</div> <div class="name">{{ item.personName }}</div>
<div class="time">{{ item.time }}</div> <div class="time">{{ item.time + '.' + item.orgName }}</div>
</div> </div>
<div class="content">{{ item.content }}</div> <div class="content">{{ item.remarks }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -240,7 +240,7 @@ ...@@ -240,7 +240,7 @@
</div> </div>
</div> </div>
<div class="select-box"> <div class="select-box">
<el-select v-model="releaseTime" placeholder="2022" style="width: 120px" <el-select v-model="releaseTime" pl aceholder="2022" style="width: 120px"
@change="handleGetOverallRanking"> @change="handleGetOverallRanking">
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" <el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label"
:value="item.value" /> :value="item.value" />
...@@ -308,7 +308,8 @@ ...@@ -308,7 +308,8 @@
</div> </div>
</div> </div>
<div class="select-box"> <div class="select-box">
<el-select v-model="releaseTime" placeholder="2022" style="width: 120px"> <el-select v-model="releaseTime" placeholder="2022" style="width: 120px"
@change="handleGetResearchField(), handleGetResearchFieldSubjectType()">
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" <el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label"
:value="item.value" /> :value="item.value" />
</el-select> </el-select>
...@@ -324,7 +325,7 @@ ...@@ -324,7 +325,7 @@
</div> </div>
<div class="center-footer-layout-content"> <div class="center-footer-layout-content">
<div class="center-footer-layout-content-item"> <div class="center-footer-layout-content-item">
<EChart :option="pieOption" autoresize :style="{ height: '370px', width: '750px' }" /> <EChart :option="pieOption(barOptionData)" autoresize :style="{ height: '370px', width: '750px' }" />
<div class="center-footer-elx-footer"> <div class="center-footer-elx-footer">
<img src="./assets/images/ai.png" alt="" /> <img src="./assets/images/ai.png" alt="" />
<div class="center-footer-elx-footer-text"> <div class="center-footer-elx-footer-text">
...@@ -335,7 +336,8 @@ ...@@ -335,7 +336,8 @@
</div> </div>
<div style="width: 1px;height: 432px;background: rgba(234, 236, 238, 1);"></div> <div style="width: 1px;height: 432px;background: rgba(234, 236, 238, 1);"></div>
<div class="center-footer-layout-content-item"> <div class="center-footer-layout-content-item">
<EChart :option="raderOption" autoresize :style="{ height: '370px', width: '750px' }" /> <EChart :option="raderOption(raderOptionData)" autoresize
:style="{ height: '370px', width: '750px' }" />
<div class="center-footer-elx-footer"> <div class="center-footer-elx-footer">
<img src="./assets/images/ai.png" alt="" /> <img src="./assets/images/ai.png" alt="" />
<div class="center-footer-elx-footer-text"> <div class="center-footer-elx-footer-text">
...@@ -365,7 +367,8 @@ ...@@ -365,7 +367,8 @@
</div> </div>
<div class="home-main-footer-main"> <div class="home-main-footer-main">
<div style=" width: 1600px;"> <div style=" width: 1600px;">
<div class="footer-main-item" v-for="item in universityList" :key="item.name" @click="handleClickToDetail"> <div class="footer-main-item" v-for="item in universityList" :key="item.name"
@click="handleClickToDetail(item.orgId)">
<img :src="item.logoUrl" style="height: 32px; width: 32px;" /> <img :src="item.logoUrl" style="height: 32px; width: 32px;" />
<div class="item-text">{{ item.orgName }}</div> <div class="item-text">{{ item.orgName }}</div>
<div class="item-text2">{{ item.address }}</div> <div class="item-text2">{{ item.address }}</div>
...@@ -409,11 +412,16 @@ import getCalendarHeatChart from "./utils/cleandarHeat"; ...@@ -409,11 +412,16 @@ import getCalendarHeatChart from "./utils/cleandarHeat";
import EChart from "@/components/Chart/index.vue"; import EChart from "@/components/Chart/index.vue";
import { pieOption, raderOption } from "./utils/charts"; import { pieOption, raderOption } from "./utils/charts";
import { import {
getNews,
getSocialMediaInfo,
getBillRiskSignal,
getCountGeography, getCountGeography,
getCountSubjectType, getCountSubjectType,
getSubjectTypeList, getSubjectTypeList,
findListBySubjectTypeId, findListBySubjectTypeId,
getOverallRanking getOverallRanking,
getResearchField,
getResearchFieldSubjectType
} from "@/api/innovationSubject/overview.js"; } from "@/api/innovationSubject/overview.js";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
...@@ -555,9 +563,11 @@ const handleGetCountGeography = async () => { ...@@ -555,9 +563,11 @@ const handleGetCountGeography = async () => {
} }
}; };
// 点击查看详情 // 点击查看详情
const handleClickToDetail = () => { const handleClickToDetail = (university) => {
const route = router.resolve("/InnovativeInstitutions"); const curRoute = router.resolve({ name: "InnovativeInstitutions", params: { id: university } });
window.open(route.href, "_blank"); window.open(curRoute.href, "_blank");
// const route = router.resolve("/InnovativeInstitutions");
// window.open(route.href, "_blank");
}; };
// 查看更多风险信号 // 查看更多风险信号
...@@ -610,7 +620,17 @@ const warningList = ref([ ...@@ -610,7 +620,17 @@ const warningList = ref([
status: "重大风险" status: "重大风险"
} }
]); ]);
const handleGetBillRiskSignal = async () => {
try {
const res = await getBillRiskSignal();
console.log("风险信号", res);
if (res.code === 200 && res.data) {
warningList.value = res.data
}
} catch (error) {
console.error("获取风险信号error", error);
}
};
// 新闻资讯 // 新闻资讯
const newsList = ref([ const newsList = ref([
{ {
...@@ -644,6 +664,18 @@ const newsList = ref([ ...@@ -644,6 +664,18 @@ const newsList = ref([
from: "11-2 · ​福克斯新闻网" from: "11-2 · ​福克斯新闻网"
} }
]); ]);
const handleGetNews = async () => {
try {
const res = await getNews();
console.log("新闻资讯", res);
if (res.code === 200 && res.data) {
newsList.value = res.data
}
} catch (error) {
console.error("获取新闻资讯error", error);
}
};
// 社交媒体 // 社交媒体
const messageList = ref([ const messageList = ref([
...@@ -666,7 +698,17 @@ const messageList = ref([ ...@@ -666,7 +698,17 @@ const messageList = ref([
content: `提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。` content: `提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。`
} }
]); ]);
const handleGetSocialMediaInfo = async () => {
try {
const res = await getSocialMediaInfo();
console.log("社交媒体", res);
if (res.code === 200 && res.data) {
messageList.value = res.data
}
} catch (error) {
console.error("获取社交媒体error", error);
}
};
// 政令涉及领域 // 政令涉及领域
const chart1Data = ref([ const chart1Data = ref([
...@@ -884,6 +926,43 @@ const releaseTimeList = ref([ ...@@ -884,6 +926,43 @@ const releaseTimeList = ref([
]); ]);
const categoryList = ref(["创新主体排名", "研究布局"]); const categoryList = ref(["创新主体排名", "研究布局"]);
const activeCate = ref("创新主体排名"); const activeCate = ref("创新主体排名");
//研究领域布局情况
const barOptionData = ref([])
const handleGetResearchField = async () => {
try {
let params = {
year: releaseTime.value,
}
const res = await getResearchField(params);
console.log("研究领域布局情况", res);
if (res.code === 200 && res.data) {
// 提取 names 和 values
const names = res.data.map(item => item.areaName);
const values = res.data.map(item => item.amount); // 或者使用 item.percent,根据需求选择
const total = res.data.reduce((sum, item) => sum + item.amount, 0);
barOptionData.value = {
names, values, total
}
}
} catch (error) {
console.error("获取研究领域布局情况error", error);
}
};
const raderOptionData = ref([])
const handleGetResearchFieldSubjectType = async () => {
try {
let params = {
year: releaseTime.value,
}
const res = await getResearchFieldSubjectType(params);
console.log("研究领域布局情况", res);
if (res.code === 200 && res.data) {
raderOptionData.value = res.data
}
} catch (error) {
console.error("获取研究领域布局情况error", error);
}
};
const areaList = ref([ const areaList = ref([
{ {
...@@ -894,7 +973,6 @@ const areaList = ref([ ...@@ -894,7 +973,6 @@ const areaList = ref([
const categoryList1 = ref(["研究型大学", "国家实验室", "科技企业", "国防承包商"]); const categoryList1 = ref(["研究型大学", "国家实验室", "科技企业", "国防承包商"]);
const activeCate1 = ref(''); const activeCate1 = ref('');
//类型列表 //类型列表
const handleGetSubjectTypeList = async () => { const handleGetSubjectTypeList = async () => {
try { try {
...@@ -959,12 +1037,17 @@ const handleToPosi = id => { ...@@ -959,12 +1037,17 @@ const handleToPosi = id => {
}; };
onMounted(async () => { onMounted(async () => {
handleGetNews()
handleGetSocialMediaInfo()
handleGetBillRiskSignal()
await handleGetSubjectTypeList() await handleGetSubjectTypeList()
handleGetCountGeography() handleGetCountGeography()
handleGetCountSubjectType() handleGetCountSubjectType()
handleGetOverallRanking() handleGetOverallRanking()
handleFindListBySubjectTypeId() handleFindListBySubjectTypeId()
handleGetResearchField()
handleGetResearchFieldSubjectType()
let chart1 = getPieChart(chart1Data.value, colorList); let chart1 = getPieChart(chart1Data.value, colorList);
setChart(chart1, "chart1"); setChart(chart1, "chart1");
}); });
...@@ -1621,7 +1704,7 @@ onMounted(async () => { ...@@ -1621,7 +1704,7 @@ onMounted(async () => {
display: flex; display: flex;
.text { .text {
width: 348px; width: 310px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
......
...@@ -2,14 +2,14 @@ ...@@ -2,14 +2,14 @@
<div class="wrap"> <div class="wrap">
<div class="header"> <div class="header">
<div class="header-left"> <div class="header-left">
<img src="./assets/images/icon-harvard.png" alt="" /> <img :src="institutionInfo.logoUrl" alt="" />
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="title">{{ institutionInfo.name }}</div> <div class="title">{{ institutionInfo.orgName }}</div>
<div class="en-title">{{ institutionInfo.enName }}</div> <div class="en-title">{{ institutionInfo.orgNameEn }}</div>
<div class="desc">{{ institutionInfo.desc }}</div> <div class="desc">{{ institutionInfo.orgIntroduction }}</div>
<div class="tag-box"> <div class="tag-box">
<div class="tag" v-for="(tag, index) in institutionInfo.tagList" :key="index"> <div class="tag" v-for="(tag, index) in institutionInfo.taglist" :key="index">
{{ tag }} {{ tag }}
</div> </div>
</div> </div>
...@@ -18,17 +18,12 @@ ...@@ -18,17 +18,12 @@
<div class="icon"> <div class="icon">
<img src="@/assets/images/links-icon.png" alt="" /> <img src="@/assets/images/links-icon.png" alt="" />
</div> </div>
<div class="text">{{ "查看官网" }}</div> <div class="text" @click="toURL(institutionInfo.url)">{{ "查看官网" }}</div>
</div> </div>
</div> </div>
<div class="tab-box"> <div class="tab-box">
<div <div class="tab" @click="handleClickTab(item, index)" :class="{ tabActive: item.active }"
class="tab" v-for="(item, index) in tabList" :key="index">
@click="handleClickTab(item, index)"
:class="{ tabActive: item.active }"
v-for="(item, index) in tabList"
:key="index"
>
{{ item.name }} {{ item.name }}
</div> </div>
</div> </div>
...@@ -47,6 +42,11 @@ import overView from "./overView/index.vue"; ...@@ -47,6 +42,11 @@ import overView from "./overView/index.vue";
import researchStrength from "./researchStrength/index.vue"; import researchStrength from "./researchStrength/index.vue";
import cooperationStatus from "./cooperationStatus/index.vue"; import cooperationStatus from "./cooperationStatus/index.vue";
import otherStatus from "./otherStatus/index.vue"; import otherStatus from "./otherStatus/index.vue";
import { useRouter } from "vue-router";
import {
getInfo
} from "@/api/innovationSubject/overview.js";
const router = useRouter();
const institutionInfo = ref({ const institutionInfo = ref({
name: "哈佛大学", name: "哈佛大学",
...@@ -55,6 +55,23 @@ const institutionInfo = ref({ ...@@ -55,6 +55,23 @@ const institutionInfo = ref({
tagList: ["常春藤", "精英摇篮"] tagList: ["常春藤", "精英摇篮"]
}); });
const handleGetInfo = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getInfo(params);
console.log("创新主体详情", res);
if (res.code === 200 && res.data) {
institutionInfo.value = res.data
}
} catch (error) {
console.error("获取创新主体详情error", error);
}
};
const toURL = (url) => {
}
const activeTabName = ref("学校详情"); const activeTabName = ref("学校详情");
const tabList = ref([ const tabList = ref([
...@@ -83,6 +100,11 @@ const handleClickTab = (val, index) => { ...@@ -83,6 +100,11 @@ const handleClickTab = (val, index) => {
tabList.value[index].active = true; tabList.value[index].active = true;
activeTabName.value = val.name; activeTabName.value = val.name;
}; };
onMounted(async () => {
handleGetInfo()
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -92,7 +114,8 @@ const handleClickTab = (val, index) => { ...@@ -92,7 +114,8 @@ const handleClickTab = (val, index) => {
background-image: url("./assets/images/bg.png"); background-image: url("./assets/images/bg.png");
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: 100% auto; background-size: 100% auto;
padding-top: 16px; padding-top: 16px;
.header { .header {
width: 1600px; width: 1600px;
height: 200px; height: 200px;
...@@ -104,17 +127,21 @@ const handleClickTab = (val, index) => { ...@@ -104,17 +127,21 @@ const handleClickTab = (val, index) => {
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
display: flex; display: flex;
position: relative; position: relative;
.header-left { .header-left {
width: 160px; width: 160px;
height: 160px; height: 160px;
margin: 20px; margin: 20px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.header-right { .header-right {
margin-left: 24px; margin-left: 24px;
.title { .title {
margin-top: 26px; margin-top: 26px;
height: 42px; height: 42px;
...@@ -126,6 +153,7 @@ const handleClickTab = (val, index) => { ...@@ -126,6 +153,7 @@ const handleClickTab = (val, index) => {
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.en-title { .en-title {
margin-top: 8px; margin-top: 8px;
height: 24px; height: 24px;
...@@ -137,6 +165,7 @@ const handleClickTab = (val, index) => { ...@@ -137,6 +165,7 @@ const handleClickTab = (val, index) => {
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.desc { .desc {
margin-top: 6px; margin-top: 6px;
height: 24px; height: 24px;
...@@ -148,10 +177,12 @@ const handleClickTab = (val, index) => { ...@@ -148,10 +177,12 @@ const handleClickTab = (val, index) => {
letter-spacing: 0px; letter-spacing: 0px;
text-align: justify; text-align: justify;
} }
.tag-box { .tag-box {
margin-top: 14px; margin-top: 14px;
display: flex; display: flex;
gap: 8px; gap: 8px;
.tag { .tag {
height: 24px; height: 24px;
padding: 0px 8px; padding: 0px 8px;
...@@ -166,6 +197,7 @@ const handleClickTab = (val, index) => { ...@@ -166,6 +197,7 @@ const handleClickTab = (val, index) => {
} }
} }
} }
.header-btn { .header-btn {
position: absolute; position: absolute;
top: 26px; top: 26px;
...@@ -179,14 +211,17 @@ const handleClickTab = (val, index) => { ...@@ -179,14 +211,17 @@ const handleClickTab = (val, index) => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
.icon { .icon {
width: 16px; width: 16px;
height: 16px; height: 16px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.text { .text {
height: 22px; height: 22px;
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
...@@ -197,6 +232,7 @@ const handleClickTab = (val, index) => { ...@@ -197,6 +232,7 @@ const handleClickTab = (val, index) => {
} }
} }
} }
.tab-box { .tab-box {
width: 1600px; width: 1600px;
height: 64px; height: 64px;
...@@ -209,6 +245,7 @@ const handleClickTab = (val, index) => { ...@@ -209,6 +245,7 @@ const handleClickTab = (val, index) => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.tab { .tab {
width: 397px; width: 397px;
height: 54px; height: 54px;
...@@ -223,10 +260,12 @@ const handleClickTab = (val, index) => { ...@@ -223,10 +260,12 @@ const handleClickTab = (val, index) => {
font-weight: 400; font-weight: 400;
letter-spacing: 0px; letter-spacing: 0px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: rgba(231, 243, 255, 1); background: rgba(231, 243, 255, 1);
} }
} }
.tabActive { .tabActive {
border: 2px solid rgba(174, 214, 255, 1); border: 2px solid rgba(174, 214, 255, 1);
background: rgba(231, 243, 255, 1); background: rgba(231, 243, 255, 1);
...@@ -235,6 +274,7 @@ const handleClickTab = (val, index) => { ...@@ -235,6 +274,7 @@ const handleClickTab = (val, index) => {
font-weight: 700; font-weight: 700;
} }
} }
.main { .main {
width: 1600px; width: 1600px;
margin: 16px auto; margin: 16px auto;
......
<!--学校详情-->
<template> <template>
<div class="detail-wrap"> <div class="detail-wrap">
<div class="left box"> <div class="left box">
...@@ -5,9 +6,10 @@ ...@@ -5,9 +6,10 @@
<div class="header-left"></div> <div class="header-left"></div>
<div class="title">最新动态</div> <div class="title">最新动态</div>
<div class="header-right"> <div class="header-right">
<el-checkbox checked="true" label="只看涉华动态" /> <el-checkbox :checked="cRelated" label="只看涉华动态" @change="handleGetDynamics()" />
<div class="btnRightActive">机构动态</div> <div :class="dynamicsType === 'org' ? 'btnRightActive' : 'btnRight'" @click="changedynamicsType()">机构动态</div>
<div class="btnRight">主官动态</div> <div :class="dynamicsType === 'person' ? 'btnRightActive' : 'btnRight'" @click="changedynamicsType()">主官动态
</div>
<div class="icon"> <div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" /> <img src="@/assets/icons/box-header-icon2.png" alt="" />
</div> </div>
...@@ -18,10 +20,10 @@ ...@@ -18,10 +20,10 @@
</div> </div>
<div class="left-main"> <div class="left-main">
<div class="left-main-item" v-for="(item, index) in curList" :key="index"> <div class="left-main-item" v-for="(item, index) in curList" :key="index">
<div class="line" ></div> <div class="line"></div>
<div class="time"> <div class="time">
<div class="timetext">{{ item.time }}</div> <div class="timetext">{{ item.time }}</div>
<div class="timetext">{{ item.date }}</div> <div class="timetext">{{ item.date }}</div>
</div> </div>
<div class="icon"> <div class="icon">
<img src="./assets/images/small-harvard.png" alt="" /> <img src="./assets/images/small-harvard.png" alt="" />
...@@ -39,10 +41,11 @@ ...@@ -39,10 +41,11 @@
</div> </div>
<div class="left-footer"> <div class="left-footer">
<div class="info"> <div class="info">
{{ `共有153项动态` }} {{ `共有` + total + `项动态` }}
</div> </div>
<div class="page-box"> <div class="page-box">
<el-pagination background layout="prev, pager, next" :total="153" /> <el-pagination background layout="prev, pager, next" :total="total" v-model:current-page="currentPage"
@current-change="handleGetDynamics" />
</div> </div>
</div> </div>
</div> </div>
...@@ -62,24 +65,24 @@ ...@@ -62,24 +65,24 @@
</div> </div>
<div class="right-main"> <div class="right-main">
<div class="img-box"> <div class="img-box">
<img :src="basicInfo.image" alt="" /> <img :src="basicInfo.logoUrl" alt="" />
</div> </div>
<div class="info-box"> <div class="info-box">
<div class="info-item"> <div class="info-item">
<div class="info-item-left">{{ "成立时间:" }}</div> <div class="info-item-left">{{ "成立时间:" }}</div>
<div class="info-item-right">{{ basicInfo.shijian }}</div> <div class="info-item-right">{{ basicInfo.establishmentDate }}</div>
</div> </div>
<div class="info-item"> <div class="info-item">
<div class="info-item-left">{{ "总部地址:" }}</div> <div class="info-item-left">{{ "总部地址:" }}</div>
<div class="info-item-right">{{ basicInfo.dizhi }}</div> <div class="info-item-right">{{ basicInfo.address }}</div>
</div> </div>
<div class="info-item"> <div class="info-item">
<div class="info-item-left">{{ "组织性质:" }}</div> <div class="info-item-left">{{ "组织性质:" }}</div>
<div class="info-item-right">{{ basicInfo.xingzhi }}</div> <div class="info-item-right">{{ basicInfo.companyType }}</div>
</div> </div>
<div class="info-item"> <div class="info-item">
<div class="info-item-left">{{ "在校人数:" }}</div> <div class="info-item-left">{{ "在校人数:" }}</div>
<div class="info-item-right">{{ basicInfo.stuNum }}</div> <div class="info-item-right">{{ basicInfo.numberOfEmployees }}</div>
</div> </div>
<div class="info-item"> <div class="info-item">
<div class="info-item-left">{{ "教职工数:" }}</div> <div class="info-item-left">{{ "教职工数:" }}</div>
...@@ -89,7 +92,7 @@ ...@@ -89,7 +92,7 @@
<div class="info-item-left">{{ "QS排名:" }}</div> <div class="info-item-left">{{ "QS排名:" }}</div>
<div class="info-item-right">{{ basicInfo.rate }}</div> <div class="info-item-right">{{ basicInfo.rate }}</div>
</div> </div>
<div class="info-item"> <div class="info-item">
<div class="info-item-left">{{ "QS排名:" }}</div> <div class="info-item-left">{{ "QS排名:" }}</div>
<div class="taglist"> <div class="taglist">
...@@ -102,9 +105,9 @@ ...@@ -102,9 +105,9 @@
{{ "重点人物:" }} {{ "重点人物:" }}
</div> </div>
<div class="user-content"> <div class="user-content">
<div class="user-item" v-for="(item, index) in basicInfo.keyUser" :key="index"> <div class="user-item" v-for="(item, index) in personList" :key="index">
<div class="user-item-left"> <div class="user-item-left">
<img :src="item.img" alt="" /> <img :src="item.avatarUrl" alt="" />
</div> </div>
<div class="user-item-right"> <div class="user-item-right">
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
...@@ -139,9 +142,9 @@ ...@@ -139,9 +142,9 @@
<div class="timeline"></div> <div class="timeline"></div>
<div class="historyList"> <div class="historyList">
<div class="historyPoint" v-for="item in historyList"> <div class="historyPoint" v-for="item in historyList">
<div class="historytime">{{ item.time }}</div> <div class="historytime">{{ item.createTime }}</div>
<img src="./assets/images/timepoint.png" alt="" style="z-index: 2;" /> <img src="./assets/images/timepoint.png" alt="" style="z-index: 2;" />
<div class="historyitem">{{ item.event }}</div> <div class="historyitem">{{ item.content }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -152,22 +155,32 @@ ...@@ -152,22 +155,32 @@
<script setup> <script setup>
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { useRouter } from "vue-router";
import {
getDynamics,
getInfo,
getEventList,
getPersonList
} from "@/api/innovationSubject/overview.js";
import Img from "./assets/images/img.png"; import Img from "./assets/images/img.png";
import User1 from "./assets/images/user1.png"; import User1 from "./assets/images/user1.png";
import User2 from "./assets/images/user2.png"; import User2 from "./assets/images/user2.png";
import User3 from "./assets/images/user3.png"; import User3 from "./assets/images/user3.png";
import User4 from "./assets/images/user4.png"; import User4 from "./assets/images/user4.png";
const router = useRouter();
//只看涉华动态
const cRelated = ref(false)
const dynamicsType = ref('org')
const basicInfo = ref({ const basicInfo = ref({
image: Img, image: Img,
shijian: "1636年", shijian: "1636年",
dizhi: "剑桥市,马萨诸塞州,美国", dizhi: "剑桥市,马萨诸塞州,美国",
xingzhi:"私立研究型大学", xingzhi: "私立研究型大学",
stuNum:"约22,000人", stuNum: "约22,000人",
teaNum:"约2,400人", teaNum: "约2,400人",
rate:"#1", rate: "#1",
tag:["癌症精准医疗","气候变化解决方案","人工智能伦理","可持续发展能源"], tag: ["癌症精准医疗", "气候变化解决方案", "人工智能伦理", "可持续发展能源"],
keyUser: [ keyUser: [
{ {
name: "艾伦·M·加伯", name: "艾伦·M·加伯",
...@@ -290,51 +303,128 @@ const curList = ref([ ...@@ -290,51 +303,128 @@ const curList = ref([
} }
]); ]);
const changedynamicsType = () => {
dynamicsType.value === 'person' ? dynamicsType.value = 'org' : dynamicsType.value = 'person'
handleGetDynamics()
}
const handleGetInfo = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getInfo(params);
console.log("创新主体基本信息", res);
if (res.code === 200 && res.data) {
basicInfo.value = res.data
}
} catch (error) {
console.error("获取基本信息error", error);
}
};
const personList = ref([])
//重点人物
const handleGetPersonList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getPersonList(params);
console.log("重点人物", res);
if (res.code === 200 && res.data) {
personList.value = res.data
}
} catch (error) {
console.error("获取重点人物error", error);
}
};
const total = ref(0)
const currentPage = ref(1)
const handleGetDynamics = async () => {
try {
let params = {
currentPage: 1,
pageSize: 10,
cRelated: cRelated.value ? null : 'N',
dynamicsType: dynamicsType.value,
orgId: router.currentRoute._value.params.id
}
const res = await getDynamics(params);
console.log("创新主体最新动态", res);
if (res.code === 200 && res.data) {
curList.value = res.data.content
total.value = res.data.totalElements
}
} catch (error) {
console.error("获取最新动态error", error);
}
};
const awardsList = ref([ const awardsList = ref([
{ {
name:"诺贝尔奖", name: "诺贝尔奖",
num:161 num: 161
}, },
{ {
name:"图灵奖", name: "图灵奖",
num:18 num: 18
}, },
{ {
name:"菲尔兹奖", name: "菲尔兹奖",
num:14 num: 14
}, },
{ {
name:"美国院士", name: "美国院士",
num:273 num: 273
} }
]); ]);
const historyList = ref([ const historyList = ref([
{ {
time:"2023年", time: "2023年",
event:"克劳丁·盖伊成为首位非裔女校长" event: "克劳丁·盖伊成为首位非裔女校长"
}, },
{ {
time:"1999年", time: "1999年",
event:"拉德克利夫学院转型为“拉德克利夫高等研究院”" event: "拉德克利夫学院转型为“拉德克利夫高等研究院”"
}, },
{ {
time:"1977年", time: "1977年",
event:"哈佛与拉德克利夫学院正式合并招生" event: "哈佛与拉德克利夫学院正式合并招生"
}, },
{ {
time:"1950年", time: "1950年",
event:"逐步废除招生中的宗教、种族限制,学生群体多元化" event: "逐步废除招生中的宗教、种族限制,学生群体多元化"
}, },
{ {
time:"1908年", time: "1908年",
event:"哈佛商学院成立,首创MBA案例教学法" event: "哈佛商学院成立,首创MBA案例教学法"
}, },
{ {
time:"1869年", time: "1869年",
event:"查尔斯·W·艾略特任校长40年,推行选修制、重建法学院、改革医学院、新建商学院等" event: "查尔斯·W·艾略特任校长40年,推行选修制、重建法学院、改革医学院、新建商学院等"
} }
]); ]);
const handleGetEventList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getEventList(params);
console.log("历史动态", res);
if (res.code === 200 && res.data) {
historyList.value = res.data
}
} catch (error) {
console.error("获取历史动态error", error);
}
};
onMounted(async () => {
handleGetInfo()
handleGetDynamics()
handleGetEventList()
handleGetPersonList()
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -342,16 +432,19 @@ const historyList = ref([ ...@@ -342,16 +432,19 @@ const historyList = ref([
display: flex; display: flex;
gap: 16px; gap: 16px;
padding-bottom: 30px; padding-bottom: 30px;
.box { .box {
border: 1px solid rgba(234, 236, 238, 1); border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
} }
.box-header { .box-header {
height: 56px; height: 56px;
display: flex; display: flex;
position: relative; position: relative;
.header-left { .header-left {
margin-top: 18px; margin-top: 18px;
width: 8px; width: 8px;
...@@ -359,6 +452,7 @@ const historyList = ref([ ...@@ -359,6 +452,7 @@ const historyList = ref([
border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1); background: rgba(10, 87, 166, 1);
} }
.title { .title {
margin-left: 14px; margin-left: 14px;
margin-top: 14px; margin-top: 14px;
...@@ -370,11 +464,13 @@ const historyList = ref([ ...@@ -370,11 +464,13 @@ const historyList = ref([
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.header-btn-box { .header-btn-box {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 52px; right: 52px;
display: flex; display: flex;
.btn { .btn {
margin-left: 8px; margin-left: 8px;
height: 28px; height: 28px;
...@@ -391,12 +487,14 @@ const historyList = ref([ ...@@ -391,12 +487,14 @@ const historyList = ref([
font-weight: 400; font-weight: 400;
cursor: pointer; cursor: pointer;
} }
.btnActive { .btnActive {
border: 1px solid rgba(10, 87, 166, 1); border: 1px solid rgba(10, 87, 166, 1);
background: rgba(246, 250, 255, 1); background: rgba(246, 250, 255, 1);
color: rgba(10, 87, 166, 1); color: rgba(10, 87, 166, 1);
} }
} }
.header-info { .header-info {
height: 22px; height: 22px;
position: absolute; position: absolute;
...@@ -404,16 +502,19 @@ const historyList = ref([ ...@@ -404,16 +502,19 @@ const historyList = ref([
top: 17px; top: 17px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
margin-top: 3px; margin-top: 3px;
width: 14px; width: 14px;
height: 14px; height: 14px;
margin-right: 8px; margin-right: 8px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.text { .text {
height: 22px; height: 22px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -423,6 +524,7 @@ const historyList = ref([ ...@@ -423,6 +524,7 @@ const historyList = ref([
line-height: 22px; line-height: 22px;
} }
} }
.header-right { .header-right {
position: absolute; position: absolute;
top: 14px; top: 14px;
...@@ -430,15 +532,18 @@ const historyList = ref([ ...@@ -430,15 +532,18 @@ const historyList = ref([
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 8px; gap: 8px;
.icon { .icon {
width: 28px; width: 28px;
height: 28px; height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.checkboxRight{
.checkboxRight {
color: rgba(132, 136, 142, 1); color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
...@@ -447,7 +552,8 @@ const historyList = ref([ ...@@ -447,7 +552,8 @@ const historyList = ref([
letter-spacing: 0px; letter-spacing: 0px;
text-align: justify; text-align: justify;
} }
.btnRightActive{
.btnRightActive {
width: 80px; width: 80px;
height: 28px; height: 28px;
display: flex; display: flex;
...@@ -466,7 +572,8 @@ const historyList = ref([ ...@@ -466,7 +572,8 @@ const historyList = ref([
letter-spacing: 0px; letter-spacing: 0px;
text-align: center; text-align: center;
} }
.btnRight{
.btnRight {
width: 80px; width: 80px;
height: 28px; height: 28px;
display: flex; display: flex;
...@@ -487,12 +594,15 @@ const historyList = ref([ ...@@ -487,12 +594,15 @@ const historyList = ref([
} }
} }
} }
.left { .left {
width: 1064px; width: 1064px;
height: 2083px; height: 2083px;
.left-main { .left-main {
border-top: 1px solid rgba(234, 236, 238, 1); border-top: 1px solid rgba(234, 236, 238, 1);
height: 1905px; height: 1905px;
.left-main-item { .left-main-item {
display: flex; display: flex;
margin-top: 20px; margin-top: 20px;
...@@ -500,6 +610,7 @@ const historyList = ref([ ...@@ -500,6 +610,7 @@ const historyList = ref([
margin-left: 31px; margin-left: 31px;
height: 130px; height: 130px;
position: relative; position: relative;
.line { .line {
background: #e6e7e8; background: #e6e7e8;
width: 2px; width: 2px;
...@@ -508,10 +619,12 @@ const historyList = ref([ ...@@ -508,10 +619,12 @@ const historyList = ref([
top: 24px; top: 24px;
left: 106px; left: 106px;
} }
.time { .time {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.timetext{
.timetext {
width: 79px; width: 79px;
color: rgba(5, 95, 194, 1); color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -522,20 +635,25 @@ const historyList = ref([ ...@@ -522,20 +635,25 @@ const historyList = ref([
text-align: right; text-align: right;
} }
} }
.icon { .icon {
width: 24px; width: 24px;
height: 24px; height: 24px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.info { .info {
width: 862px; width: 862px;
.header { .header {
height: 26px; height: 26px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.title { .title {
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -544,6 +662,7 @@ const historyList = ref([ ...@@ -544,6 +662,7 @@ const historyList = ref([
line-height: 26px; line-height: 26px;
} }
} }
.content { .content {
margin-top: 8px; margin-top: 8px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -552,10 +671,12 @@ const historyList = ref([ ...@@ -552,10 +671,12 @@ const historyList = ref([
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
} }
.tag-box { .tag-box {
margin-top: 12px; margin-top: 12px;
display: flex; display: flex;
gap: 8px; gap: 8px;
.tag { .tag {
height: 28px; height: 28px;
padding: 0 8px; padding: 0 8px;
...@@ -571,6 +692,7 @@ const historyList = ref([ ...@@ -571,6 +692,7 @@ const historyList = ref([
} }
} }
} }
.left-footer { .left-footer {
height: 75px; height: 75px;
border-top: 1px solid rgba(234, 236, 238, 1); border-top: 1px solid rgba(234, 236, 238, 1);
...@@ -580,32 +702,40 @@ const historyList = ref([ ...@@ -580,32 +702,40 @@ const historyList = ref([
padding: 0 20px; padding: 0 20px;
} }
} }
.rightcontent{
.rightcontent {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 520px; width: 520px;
gap: 16px; gap: 16px;
.right { .right {
width: 520px; width: 520px;
height: 874px; height: 874px;
.right-main { .right-main {
width: 469px; width: 469px;
margin: 3px auto; margin: 3px auto;
.img-box { .img-box {
width: 469px; width: 469px;
height: 240px; height: 240px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.info-box { .info-box {
margin-top: 26px; margin-top: 26px;
padding-bottom: 50px; padding-bottom: 50px;
border-bottom: 1px solid rgba(234, 236, 238, 1); border-bottom: 1px solid rgba(234, 236, 238, 1);
.info-item { .info-item {
display: flex; display: flex;
margin-top: 12px; margin-top: 12px;
.info-item-left { .info-item-left {
width: 88px; width: 88px;
height: 24px; height: 24px;
...@@ -617,6 +747,7 @@ const historyList = ref([ ...@@ -617,6 +747,7 @@ const historyList = ref([
letter-spacing: 1px; letter-spacing: 1px;
text-align: left; text-align: left;
} }
.info-item-right { .info-item-right {
width: 356px; width: 356px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
...@@ -627,12 +758,14 @@ const historyList = ref([ ...@@ -627,12 +758,14 @@ const historyList = ref([
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.taglist{
.taglist {
width: 358px; width: 358px;
display: flex; display: flex;
gap: 8px; gap: 8px;
flex-wrap: wrap; flex-wrap: wrap;
.tagdirec{
.tagdirec {
height: 24px; height: 24px;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -652,8 +785,10 @@ const historyList = ref([ ...@@ -652,8 +785,10 @@ const historyList = ref([
} }
} }
} }
.user-box { .user-box {
padding-top: 19px; padding-top: 19px;
.user-header { .user-header {
height: 24px; height: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
...@@ -664,24 +799,29 @@ const historyList = ref([ ...@@ -664,24 +799,29 @@ const historyList = ref([
letter-spacing: 1px; letter-spacing: 1px;
text-align: left; text-align: left;
} }
.user-content { .user-content {
margin-top: 19px; margin-top: 19px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 16px 73px; gap: 16px 73px;
justify-content: start; justify-content: start;
.user-item { .user-item {
height: 49px; height: 49px;
display: flex; display: flex;
gap: 8px; gap: 8px;
.user-item-left { .user-item-left {
width: 48px; width: 48px;
height: 48px; height: 48px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.user-item-right { .user-item-right {
.name { .name {
height: 24px; height: 24px;
...@@ -693,6 +833,7 @@ const historyList = ref([ ...@@ -693,6 +833,7 @@ const historyList = ref([
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.position { .position {
height: 24px; height: 24px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -709,13 +850,14 @@ const historyList = ref([ ...@@ -709,13 +850,14 @@ const historyList = ref([
} }
} }
} }
.right-Num{
.right-Num {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
width: 520px; width: 520px;
gap: 8px; gap: 8px;
.numbox{ .numbox {
display: flex; display: flex;
width: 256px; width: 256px;
height: 80px; height: 80px;
...@@ -725,12 +867,14 @@ const historyList = ref([ ...@@ -725,12 +867,14 @@ const historyList = ref([
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
align-items: center; align-items: center;
.iconrec{
.iconrec {
width: 4px; width: 4px;
height: 49px; height: 49px;
background: rgba(5, 95, 194, 1); background: rgba(5, 95, 194, 1);
} }
.awards{
.awards {
margin-left: 24px; margin-left: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -740,8 +884,9 @@ const historyList = ref([ ...@@ -740,8 +884,9 @@ const historyList = ref([
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.awardsNum{
margin-left: 72px; .awardsNum {
margin-left: 72px;
color: rgba(5, 95, 194, 1); color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 30px; font-size: 30px;
...@@ -752,7 +897,8 @@ const historyList = ref([ ...@@ -752,7 +897,8 @@ const historyList = ref([
} }
} }
} }
.right-history{
.right-history {
width: 520px; width: 520px;
height: 1009px; height: 1009px;
border: 1px solid rgba(234, 236, 238, 1); border: 1px solid rgba(234, 236, 238, 1);
...@@ -760,30 +906,34 @@ const historyList = ref([ ...@@ -760,30 +906,34 @@ const historyList = ref([
/* 业务系统/模块阴影 */ /* 业务系统/模块阴影 */
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.historytimeline{
.historytimeline {
display: flex; display: flex;
margin-left: 37px; margin-left: 37px;
margin-top: 29px; margin-top: 29px;
.timeline{
.timeline {
position: absolute; position: absolute;
width: 8px; width: 8px;
height: 910px; height: 910px;
background: url("./assets/images/arrow.png") repeat; background: url("./assets/images/arrow.png") repeat;
} }
.historyList{
.historyList {
margin-left: -2px; margin-left: -2px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-top: 42px; margin-top: 42px;
gap: 56px; gap: 56px;
.historyPoint{ .historyPoint {
width: 458px; width: 458px;
height: 89px; height: 89px;
gap: 6px; gap: 6px;
.historytime{
.historytime {
margin-left: 24px; margin-left: 24px;
color: rgba(5, 95, 194, 1); color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -793,7 +943,8 @@ const historyList = ref([ ...@@ -793,7 +943,8 @@ const historyList = ref([
letter-spacing: 1px; letter-spacing: 1px;
text-align: left; text-align: left;
} }
.historyitem{
.historyitem {
margin-left: 24px; margin-left: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -813,14 +964,13 @@ const historyList = ref([ ...@@ -813,14 +964,13 @@ const historyList = ref([
::v-deep .el-checkbox__label{ ::v-deep .el-checkbox__label {
color: rgba(132, 136, 142, 1); color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
padding-left: 3px; padding-left: 3px;
padding-right: 10px; padding-right: 10px;
} }
</style> </style>
\ No newline at end of file
<!--科研实力-->
<template> <template>
<div class="detail-wrap"> <div class="detail-wrap">
<div class="row"> <div class="row">
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
</div> </div>
</div> </div>
<div class="statisticsChart"> <div class="statisticsChart">
<Echarts :option="barOption" height="100%"></Echarts> <Echarts :option="barOption(patentList)" height="100%"></Echarts>
</div> </div>
<div class="statisticsAI"> <div class="statisticsAI">
<div class="AIbox"> <div class="AIbox">
...@@ -39,7 +40,7 @@ ...@@ -39,7 +40,7 @@
</div> </div>
</div> </div>
<div class="statisticsChart"> <div class="statisticsChart">
<Echarts :option="lineChart" height="100%"></Echarts> <Echarts :option="lineChart(paperList)" height="100%"></Echarts>
</div> </div>
<div class="statisticsAI"> <div class="statisticsAI">
<div class="AIbox"> <div class="AIbox">
...@@ -89,7 +90,7 @@ ...@@ -89,7 +90,7 @@
</div> </div>
</div> </div>
<div class="statisticsChart"> <div class="statisticsChart">
<Echarts :option="lineChart1" height="100%"></Echarts> <Echarts :option="lineChart1(fundGrowth)" height="100%"></Echarts>
</div> </div>
<div class="statisticsAI"> <div class="statisticsAI">
<div class="AIbox"> <div class="AIbox">
...@@ -115,7 +116,7 @@ ...@@ -115,7 +116,7 @@
</div> </div>
</div> </div>
<div class="statisticsChart"> <div class="statisticsChart">
<Echarts :option="pieOption1" height="100%"></Echarts> <Echarts :option="pieOption1(fundFromList)" height="100%"></Echarts>
</div> </div>
<div class="statisticsAI"> <div class="statisticsAI">
<div class="AIbox"> <div class="AIbox">
...@@ -146,7 +147,7 @@ ...@@ -146,7 +147,7 @@
letter-spacing: 0px; letter-spacing: 0px;
text-align: right;">(亿美元)</div> text-align: right;">(亿美元)</div>
<div class="statisticsChart" style="height: 298px; "> <div class="statisticsChart" style="height: 298px; ">
<Echarts :option="horizontalBaroption" height="100%" ></Echarts> <Echarts :option="horizontalBaroption(fundToList)" height="100%"></Echarts>
</div> </div>
<div class="statisticsAI"> <div class="statisticsAI">
<div class="AIbox"> <div class="AIbox">
...@@ -164,8 +165,103 @@ ...@@ -164,8 +165,103 @@
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalBaroption } from "../../utils/charts.js"; import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalBaroption } from "../../utils/charts.js";
import {
getPatentList,
getPaperList, getFundGrowth, getFundFromList, getFundToList
} from "@/api/innovationSubject/overview.js";
import { useRouter } from "vue-router";
const router = useRouter();
//专利数量统计
const patentList = ref([])
const handleGetPatentList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getPatentList(params);
console.log("专利数量统计", res);
if (res.code === 200 && res.data) {
patentList.value = res.data
}
} catch (error) {
console.error("获取专利数量统计error", error);
}
};
//论文数量统计
const paperList = ref([])
const handleGetPaperList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getPaperList(params);
console.log("论文数量统计", res);
if (res.code === 200 && res.data) {
paperList.value = res.data
}
} catch (error) {
console.error("获取论文数量统计error", error);
}
};
//经费增长情况
const fundGrowth = ref([])
const handleGetFundGrowth = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getFundGrowth(params);
console.log("经费增长情况", res);
if (res.code === 200 && res.data) {
fundGrowth.value = res.data
}
} catch (error) {
console.error("获取经费增长情况error", error);
}
};
//经费来源
const fundFromList = ref([])
const handleGetFundFromList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getFundFromList(params);
console.log("经费来源", res);
if (res.code === 200 && res.data) {
fundFromList.value = res.data
}
} catch (error) {
console.error("获取经费来源error", error);
}
};
//学院经费分配排序
const fundToList = ref([])
const handlegGetFundToList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getFundToList(params);
console.log("学院经费分配排序", res);
if (res.code === 200 && res.data) {
fundToList.value = res.data
}
} catch (error) {
console.error("获取学院经费分配排序error", error);
}
};
onMounted(async () => {
handleGetPatentList()
handleGetPaperList()
handleGetFundGrowth()
handleGetFundFromList()
handlegGetFundToList()
});
</script> </script>
...@@ -175,16 +271,19 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -175,16 +271,19 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
padding-bottom: 30px; padding-bottom: 30px;
.box { .box {
border: 1px solid rgba(234, 236, 238, 1); border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
} }
.box-header { .box-header {
height: 56px; height: 56px;
display: flex; display: flex;
position: relative; position: relative;
.header-left { .header-left {
margin-top: 18px; margin-top: 18px;
width: 8px; width: 8px;
...@@ -192,6 +291,7 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -192,6 +291,7 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0;
background: rgba(10, 87, 166, 1); background: rgba(10, 87, 166, 1);
} }
.title { .title {
margin-left: 14px; margin-left: 14px;
margin-top: 14px; margin-top: 14px;
...@@ -203,11 +303,13 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -203,11 +303,13 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.header-btn-box { .header-btn-box {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 52px; right: 52px;
display: flex; display: flex;
.btn { .btn {
margin-left: 8px; margin-left: 8px;
height: 28px; height: 28px;
...@@ -224,12 +326,14 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -224,12 +326,14 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
font-weight: 400; font-weight: 400;
cursor: pointer; cursor: pointer;
} }
.btnActive { .btnActive {
border: 1px solid rgba(10, 87, 166, 1); border: 1px solid rgba(10, 87, 166, 1);
background: rgba(246, 250, 255, 1); background: rgba(246, 250, 255, 1);
color: rgba(10, 87, 166, 1); color: rgba(10, 87, 166, 1);
} }
} }
.header-info { .header-info {
height: 22px; height: 22px;
position: absolute; position: absolute;
...@@ -237,16 +341,19 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -237,16 +341,19 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
top: 17px; top: 17px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
margin-top: 3px; margin-top: 3px;
width: 14px; width: 14px;
height: 14px; height: 14px;
margin-right: 8px; margin-right: 8px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.text { .text {
height: 22px; height: 22px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -256,6 +363,7 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -256,6 +363,7 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
line-height: 22px; line-height: 22px;
} }
} }
.header-right { .header-right {
position: absolute; position: absolute;
top: 14px; top: 14px;
...@@ -263,15 +371,18 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -263,15 +371,18 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
gap: 8px; gap: 8px;
.icon { .icon {
width: 28px; width: 28px;
height: 28px; height: 28px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.checkboxRight{
.checkboxRight {
color: rgba(132, 136, 142, 1); color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
...@@ -280,7 +391,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -280,7 +391,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
letter-spacing: 0px; letter-spacing: 0px;
text-align: justify; text-align: justify;
} }
.btnRightActive{
.btnRightActive {
width: 80px; width: 80px;
height: 28px; height: 28px;
display: flex; display: flex;
...@@ -299,7 +411,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -299,7 +411,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
letter-spacing: 0px; letter-spacing: 0px;
text-align: center; text-align: center;
} }
.btnRight{
.btnRight {
width: 80px; width: 80px;
height: 28px; height: 28px;
display: flex; display: flex;
...@@ -320,20 +433,24 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -320,20 +433,24 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
} }
} }
} }
.row{
.row {
display: flex; display: flex;
width: 1600px; width: 1600px;
height: 500px; height: 500px;
gap: 16px; gap: 16px;
.statisticsItem{
.statisticsItem {
width: 792px; width: 792px;
height: 500px; height: 500px;
.statisticsChart{
.statisticsChart {
width: 736px; width: 736px;
height: 321px; height: 321px;
margin: 20px auto; margin: 20px auto;
} }
.statisticsAI{
.statisticsAI {
margin: 0 auto; margin: 0 auto;
width: 760px; width: 760px;
height: 64px; height: 64px;
...@@ -345,11 +462,12 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -345,11 +462,12 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
gap: 10; gap: 10;
padding: 6px 12px 6px 12px; padding: 6px 12px 6px 12px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1); border: 1px solid rgba(231, 243, 255, 1);
border-radius: 4px; border-radius: 4px;
background: rgba(246, 250, 255, 1); background: rgba(246, 250, 255, 1);
.AIbox{
.AIbox {
width: 736px; width: 736px;
height: 52px; height: 52px;
/* 自动布局 */ /* 自动布局 */
...@@ -359,7 +477,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -359,7 +477,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
align-items: center; align-items: center;
gap: 13px; gap: 13px;
padding: 2px 0px 2px 0px; padding: 2px 0px 2px 0px;
.AItext{
.AItext {
width: 667px; width: 667px;
height: 48px; height: 48px;
display: flex; display: flex;
...@@ -377,13 +496,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB ...@@ -377,13 +496,8 @@ import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalB
} }
} }
} }
} }
} }
</style> </style>
\ No newline at end of file
import * as echarts from "echarts"; import * as echarts from "echarts";
var data = [
{
name: "人工智能与信息技术",
value: 27
},
{
name: "生物医学与健康",
value: 22
},
{
name: "能源与环境技术",
value: 18
},
{
name: "先进制造与材料",
value: 15
},
{
name: "国家安全与国防",
value: 12
},
{
name: "航空航天",
value: 8
}
];
// 计算总和 // 计算总和
function getTotal(data) { function getTotal(data) {
return data.reduce((sum, item) => sum + item.value, 0); return data.reduce((sum, item) => sum + item.value, 0);
}; };
export const pieOption = (data) => {
export const pieOption = { console.log(data, 'datadatadata')
tooltip: { // 颜色数组
trigger: 'item' const colors = [
}, 'rgba(105, 177, 255, 1)',
legend: { 'rgba(255, 236, 61, 1)',
orient: 'vertical', 'rgba(135, 232, 222, 1)',
x: 'right', 'rgba(133, 165, 255, 1)',
y: 'center', 'rgba(255, 120, 117, 1)',
align: 'left', 'rgba(179, 127, 235, 1)',
left:'50%', 'rgba(255, 187, 120, 1)',
data: data.map(item => item.name), 'rgba(120, 255, 180, 1)',
textStyle: { // 图例字体样式 'rgba(255, 150, 150, 1)'
color: "rgba(59, 65, 75, 1)", ];
fontSize: 16 const seriesData = data.names.map((name, index) => ({
}, name,
formatter: function(name) { value: data.values[index],
var total = getTotal(data); itemStyle: { color: colors[index % colors.length] }
var item = data.find(item => item.name === name); }));
var percentage = ((item.value / total) * 100).toFixed(2); const option = {
return `${name} ${percentage}%`; tooltip: {
} trigger: 'item'
}, },
series: [ legend: {
{ orient: 'vertical',
name: '频度', x: 'right',
type: 'pie', y: 'center',
center: ['25%', '50%'], align: 'left',
radius: ['40%', '70%'], left: '50%',
avoidLabelOverlap: false, data: data.names,
label: { textStyle: { // 图例字体样式
show: false, color: "rgba(59, 65, 75, 1)",
position: 'center' fontSize: 16
},
labelLine: {
show: false
}, },
data: [ // formatter: function (name) {
{ // var total = data.total;
name: "人工智能与信息技术", // var item = data.find(item => item.name === name);
value: 27, // var percentage = ((item.value / total) * 100).toFixed(2);
itemStyle:{color: 'rgba(105, 177, 255, 1)'} // return `${name} ${percentage}%`;
}, // }
{ },
name: "生物医学与健康", series: [
value: 22, {
itemStyle:{color: 'rgba(255, 236, 61, 1)'} name: '频度',
}, type: 'pie',
{ center: ['25%', '50%'],
name: "能源与环境技术", radius: ['40%', '70%'],
value: 18, avoidLabelOverlap: false,
itemStyle:{color: 'rgba(135, 232, 222, 1)'} label: {
}, show: false,
{ position: 'center'
name: "先进制造与材料",
value: 15,
itemStyle:{color: 'rgba(133, 165, 255, 1)'}
}, },
{
name: "国家安全与国防", labelLine: {
value: 12, show: false
itemStyle:{color: 'rgba(255, 120, 117, 1)'}
}, },
{ data: seriesData
name: "航空航天", }
value: 8, ]
itemStyle:{color: 'rgba(179, 127, 235, 1)'} };
} return option
] }
}
]
};
var data1 = [ var data1 = [
{ {
...@@ -127,152 +91,120 @@ var data1 = [ ...@@ -127,152 +91,120 @@ var data1 = [
} }
]; ];
export const pieOption1 = (data) => {
// 提取部门名称和对应的金额
const colors = [
'rgba(105, 177, 255, 1)',
'rgba(255, 236, 61, 1)',
'rgba(135, 232, 222, 1)',
'rgba(133, 165, 255, 1)',
'rgba(255, 120, 117, 1)'
];
// 提取部门名称和对应的金额
const departmentNames = data.map(item => item.departmentName);
const amounts = data.map(item => item.amount);
export const pieOption1 = { // 计算总金额
legend: { const getTotal = (data) => {
orient: 'vertical', return data.reduce((total, item) => total + item.amount, 0);
x: 'right', };
y: 'center',
align: 'left',
left:'60%',
data: data1.map(item => item.name),
textStyle: { // 图例字体样式
color: "rgba(59, 65, 75, 1)",
fontSize: 16
},
formatter: function(name) {
var total = getTotal(data1);
var item = data1.find(item => item.name === name);
var percentage = ((item.value / total) * 100).toFixed(2);
return `${name} ${percentage}%`;
}
},
series: [
{
name: '频度',
type: 'pie',
center: ['30%', '50%'],
radius: ['40%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
labelLine: {
show: false
},
data: [
{
name: "捐赠基金",
value: 27,
itemStyle:{color: 'rgba(105, 177, 255, 1)'}
},
{
name: "政府拨款",
value: 22,
itemStyle:{color: 'rgba(255, 236, 61, 1)'}
},
{
name: "企业合作",
value: 18,
itemStyle:{color: 'rgba(135, 232, 222, 1)'}
},
{
name: "学费收入",
value: 15,
itemStyle:{color: 'rgba(133, 165, 255, 1)'}
},
{
name: "其他来源",
value: 12,
itemStyle:{color: 'rgba(255, 120, 117, 1)'}
}
]
}
]
};
export const raderOption = { // 饼图配置
title: { text: '' }, const option = {
legend: { legend: {
icon: 'circle', orient: 'vertical',
orient: 'vertical', // 纵向排列 x: 'right',
right: 50, // 贴右边 y: 'center',
top: 'center', // 垂直居中 align: 'left',
align: 'left', // 文字在图标左侧 left: '60%',
data: departmentNames,
textStyle: { // 图例字体样式 textStyle: { // 图例字体样式
color: "rgba(59, 65, 75, 1)", color: "rgba(59, 65, 75, 1)",
fontSize: "16px" fontSize: 16
} },
formatter: function (name) {
}, var total = getTotal(data);
radar: { var item = data.find(item => item.departmentName === name);
radius: '60%', // 关键:缩小整个雷达 var percentage = ((item.amount / total) * 100).toFixed(2);
indicator: [ return `${name} ${percentage}%`;
{ name: '能源领域', max: 6500 },
{ name: '集成电路', max: 16000 },
{ name: '人工智能', max: 30000 },
{ name: '通信网络', max: 38000 },
{ name: '量子科技', max: 52000 },
{ name: '生物科技', max: 25000 }
],
axisName: {
formatter: '{value}',
color: 'rgba(59, 65, 75, 1)',
fontSize: 16,
fontWeight: 700
} }
}, },
series: [ series: [
{ {
name: 'Budget vs spending', name: '频度',
type: 'radar', type: 'pie',
data: [ center: ['30%', '50%'],
{ radius: ['40%', '70%'],
value: [4200, 3000, 20000, 35000, 50000, 18000], avoidLabelOverlap: false,
name: '研究型大学', label: {
areaStyle: { color: 'rgba(5, 95, 194, 0.2)' } show: false,
}, position: 'center'
{ },
value: [5000, 14000, 28000, 26000, 42000, 21000], labelLine: {
name: '国家实验室', show: false
areaStyle: { color: 'rgba(250, 140, 22, 0.2)' } },
}, data: data.map((item, index) => ({
{ name: item.departmentName,
value: [4000, 14000, 18000, 21000, 32000, 10000], value: item.amount,
name: '科技企业', itemStyle: { color: colors[index % colors.length] } // 使用颜色列表
areaStyle: { color: 'rgba(179, 127, 235, 0.2)' } }))
},
{
value: [4000, 14000, 18000, 21000, 32000, 10000],
name: '国防承包商',
areaStyle: { color: 'rgba(33, 129, 57, 0.2)' }
}
]
} }
] ]
}; };
return option;
}
export const raderOption1 = { export const raderOption = (data) => {
grid: { // 提取所有可能的 areaName
top: '3%', const allAreaNames = new Set();
right: '3%', data.forEach(subject => {
bottom: '1%', subject.areaVoList.forEach(area => {
left: '1%', allAreaNames.add(area.areaName);
containLabel: true });
});
const indicatorNames = Array.from(allAreaNames);
// 定义雷达图的指标最大值(可以根据实际数据调整)
const indicatorMaxValues = {};
indicatorNames.forEach(name => {
indicatorMaxValues[name] = 5; // 假设每个指标的最大值为 5
});
// 生成雷达图的 indicator 配置
const radarIndicators = indicatorNames.map(name => ({
name,
max: indicatorMaxValues[name]
}));
// 为每个 subjectTypeName 生成雷达图数据
const radarSeriesData = data.map(subject => {
const values = indicatorNames.map(indicator => {
const area = subject.areaVoList.find(a => a.areaName === indicator);
return area ? area.amount : 0; // 如果存在该指标,取其 amount 值,否则为 0
});
return {
value: values,
name: subject.subjectTypeName,
areaStyle: { color: `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.2)` }
};
});
// 雷达图配置
const option = {
title: { text: '' },
legend: {
icon: 'circle',
orient: 'vertical',
right: 50,
top: 'center',
align: 'left',
textStyle: {
color: "rgba(59, 65, 75, 1)",
fontSize: "16px"
}
}, },
radar: { radar: {
radius: '60%', // 关键:缩小整个雷达 radius: '60%',
indicator: [ indicator: radarIndicators,
{ name: '能源领域', max: 6500 },
{ name: '集成电路', max: 16000 },
{ name: '人工智能', max: 30000 },
{ name: '通信网络', max: 38000 },
{ name: '量子科技', max: 52000 },
{ name: '生物科技', max: 25000 }
],
axisName: { axisName: {
formatter: '{value}', formatter: '{value}',
color: 'rgba(59, 65, 75, 1)', color: 'rgba(59, 65, 75, 1)',
...@@ -284,108 +216,147 @@ export const raderOption1 = { ...@@ -284,108 +216,147 @@ export const raderOption1 = {
{ {
name: 'Budget vs spending', name: 'Budget vs spending',
type: 'radar', type: 'radar',
data: [ data: radarSeriesData
{
value: [4200, 3000, 20000, 35000, 50000, 18000],
name: '哈佛大学',
areaStyle: { color: 'rgba(179, 127, 235, 0.1)' }
}
]
} }
] ]
}; };
return option;
export const barOption = { }
tooltip: { export const raderOption1 = {
trigger: "axis", grid: {
axisPointer: { top: '3%',
type: "shadow" right: '3%',
bottom: '1%',
left: '1%',
containLabel: true
},
radar: {
radius: '60%', // 关键:缩小整个雷达
indicator: [
{ name: '能源领域', max: 6500 },
{ name: '集成电路', max: 16000 },
{ name: '人工智能', max: 30000 },
{ name: '通信网络', max: 38000 },
{ name: '量子科技', max: 52000 },
{ name: '生物科技', max: 25000 }
],
axisName: {
formatter: '{value}',
color: 'rgba(59, 65, 75, 1)',
fontSize: 16,
fontWeight: 700
}
},
series: [
{
name: 'Budget vs spending',
type: 'radar',
data: [
{
value: [4200, 3000, 20000, 35000, 50000, 18000],
name: '哈佛大学',
areaStyle: { color: 'rgba(179, 127, 235, 0.1)' }
} }
]
}
]
};
export const barOption = (data) => {
// 提取年份和对应的专利数量
const years = data.map(item => item.year.toString());
const counts = data.map(item => item.countNum);
// 柱状图配置
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
}, },
grid: { grid: {
top: '3%', top: '3%',
right: '3%', right: '3%',
bottom: '1%', bottom: '1%',
left: '1%', left: '1%',
containLabel: true containLabel: true
}, },
xAxis: [{ xAxis: [{
axisLine: { axisLine: {
lineStyle: { lineStyle: {
width: 1, width: 1,
color: "rgba(231, 243, 255, 1)" color: "rgba(231, 243, 255, 1)"
} }
}, },
axisTick: axisTick: { show: false },
{ show: false }, type: "category",
type: "category", boundaryGap: [100, 100],
boundaryGap: [100, 100], axisLabel: {
axisLabel: { color: "rgba(95, 101, 108, 1)",
color: "rgba(95, 101, 108, 1)", // fontSize: 22,
// fontSize: 22, // fontWeight: 400
// fontWeight: 400 },
}, data: years, // 动态设置 xAxis 数据
data: ["2016","2017","2018","2019", "2020", "2021", "2022", "2023", "2024", "2025"],
}], }],
yAxis: { yAxis: {
type: "value", type: "value",
axisLine: { axisLine: {
lineStyle: { lineStyle: {
type: "dashed" type: "dashed"
}
},
axisLabel: {
color: "rgba(95, 101, 108, 1)",
// fontSize: 22,
// fontWeight: 400
},
splitNumber: 5,
splitLine: {
lineStyle: {
width: 1,
type: "dashed",
color: "rgba(231, 243, 255, 1)"
},
} }
},
axisLabel: {
color: "rgba(95, 101, 108, 1)",
// fontSize: 22,
// fontWeight: 400
},
splitNumber: 5,
splitLine: {
lineStyle: {
width: 1,
type: "dashed",
color: "rgba(231, 243, 255, 1)"
},
}
}, },
series: [ series: [
{ {
name: "专利数量", name: "专利数量",
data: [80, 90, 110, 130, 140, 160, 200,250,300,340], data: counts, // 动态设置 series 数据
type: "bar", type: "bar",
barWidth: 20, barWidth: 20,
itemStyle: { itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(46, 165, 255, 1)" }, { offset: 0, color: "rgba(46, 165, 255, 1)" },
// { offset: 0.5, color: '#188df0' }, { offset: 1, color: "rgba(46, 165, 255, 0)" }
{ offset: 1, color: "rgba(46, 165, 255, 0)" } ])
]) },
// borderRadius: [6, 6, 0, 0] label: {
}, show: false,
label:{ position: 'top',
show:false, textStyle: {
position:'top', fontSize: '20px',
textStyle:{ fontWeight: 400,
fontSize:'20px', color: 'rgba(255, 255, 255, 1)'
fontWeight:400, }
color:'rgba(255, 255, 255, 1)'
}
}
} }
}
] ]
}; };
return option;
export const lineChart = { }
tooltip: { export const lineChart = (data) => {
trigger: "axis", // 提取年份和对应的专利数量
axisPointer: { const years = data.map(item => item.year.toString());
type: "shadow" const counts = data.map(item => item.countNum);
} // 折线图配置
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
}, },
grid: { grid: {
left: '2%', left: '2%',
...@@ -403,12 +374,13 @@ export const lineChart = { ...@@ -403,12 +374,13 @@ export const lineChart = {
axisLine: { axisLine: {
show: false show: false
}, },
data: ["2016","2017","2018","2019", "2020", "2021", "2022", "2023", "2024", "2025"], data: years, // 动态设置 xAxis 数据
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
splitLine: { splitLine: {
show: true, lineStyle: { show: true,
lineStyle: {
type: "dashed", type: "dashed",
color: "#E7F3FF" color: "#E7F3FF"
} }
...@@ -416,36 +388,37 @@ export const lineChart = { ...@@ -416,36 +388,37 @@ export const lineChart = {
axisLine: { axisLine: {
show: false show: false
}, },
}, },
color: ['rgba(255, 149, 77, 1)'], color: ['rgba(255, 149, 77, 1)'],
series: [ series: [
{ {
data: [50,60,80,100,110,140,180,260,280,330], data: counts, // 动态设置 series 数据
type: 'line', type: 'line',
emphasis: { emphasis: {
focus: 'series' focus: 'series'
}, },
areaStyle: { areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
offset: 0, { offset: 0, color: 'rgba(255, 149, 77, 0.5)' }, // 起始颜色:深色
color: 'rgba(255, 149, 77, 0.5)' // 起始颜色:深色 { offset: 1, color: 'rgba(255, 149, 77, 0)' } // 结束颜色:浅色且透明度降低
}, { ])
offset: 1,
color: 'rgba(255, 149, 77, 0)' // 结束颜色:浅色且透明度降低
}])
}, },
} }
] ]
};
}; return option;
}
export const lineChart1 = { export const lineChart1 = (data) => {
tooltip: { // 提取年份和对应的 fundAmount
trigger: "axis", const years = data.map(item => item.year.toString());
axisPointer: { const fundAmounts = data.map(item => item.fundAmount);
type: "shadow" // 折线图配置
} const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
}, },
grid: { grid: {
left: '2%', left: '2%',
...@@ -463,12 +436,13 @@ export const lineChart1 = { ...@@ -463,12 +436,13 @@ export const lineChart1 = {
axisLine: { axisLine: {
show: false show: false
}, },
data: ["2016","2017","2018","2019", "2020", "2021", "2022", "2023", "2024", "2025"], data: years, // 动态设置 xAxis 数据
}, },
yAxis: { yAxis: {
type: 'value', type: 'value',
splitLine: { splitLine: {
show: true, lineStyle: { show: true,
lineStyle: {
type: "dashed", type: "dashed",
color: "#E7F3FF" color: "#E7F3FF"
} }
...@@ -476,111 +450,102 @@ export const lineChart1 = { ...@@ -476,111 +450,102 @@ export const lineChart1 = {
axisLine: { axisLine: {
show: false show: false
}, },
}, },
color: ['rgba(33, 129, 57, 1)'], color: ['rgba(33, 129, 57, 1)'],
series: [ series: [
{ {
data: [50,60,80,100,110,140,180,260,280,330], data: fundAmounts, // 动态设置 series 数据
type: 'line', type: 'line',
emphasis: { emphasis: {
focus: 'series' focus: 'series'
}, },
areaStyle: { areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
offset: 0, { offset: 0, color: 'rgba(33, 129, 57, 0.5)' }, // 起始颜色:深色
color: 'rgba(33, 129, 57, 0.5)' // 起始颜色:深色 { offset: 1, color: 'rgba(33, 129, 57, 0)' } // 结束颜色:浅色且透明度降低
}, { ])
offset: 1,
color: 'rgba(33, 129, 57, 0)' // 结束颜色:浅色且透明度降低
}])
}, },
} }
] ]
};
}; return option;
}
const nameList = ["教育学院","文理学院","法学院","商学院","工程学院","医学院"]; const nameList = ["教育学院", "文理学院", "法学院", "商学院", "工程学院", "医学院"];
const valueList = [21,21,25,79,95,109]; const valueList = [21, 21, 25, 79, 95, 109];
export const horizontalBaroption = (data) => {
// 提取部门名称和对应的金额
const departmentNames = data.map(item => item.departmentName);
const amounts = data.map(item => item.amount);
export const horizontalBaroption = { // 水平柱状图配置
const option = {
grid: { grid: {
top: '0', top: '0',
right: '3%', right: '3%',
bottom: '1%', bottom: '1%',
left: '1%', left: '1%',
containLabel: true containLabel: true
}, },
color: ['#ce4f51', '#1778ff'], color: ['#ce4f51', '#1778ff'],
xAxis: { xAxis: {
type: 'value', type: 'value',
splitLine: { splitLine: {
show: false
},
show: false show: false
},
show: false
}, },
yAxis: { yAxis: {
type: 'category', type: 'category',
data: nameList, data: departmentNames, // 动态设置 yAxis 数据
splitLine: { splitLine: {
show: false show: false
}, },
axisTick: { axisTick: {
show: false show: false
}, },
axisLine: { axisLine: {
show: false show: false
}, },
axisLabel: { axisLabel: {
show: true show: true
} }
}, },
series: [{ series: [{
type: 'bar', type: 'bar',
data: valueList.map((item, index) => { data: amounts.map((item, index) => {
return { return {
value: item, value: item,
label: { label: {
textStyle: { textStyle: {
color: index < 3 ? '#1778ff' : '#ce4f51' color: index < 3 ? '#1778ff' : '#ce4f51'
} }
} }
}; };
}), }),
label: { label: {
show: true, show: true,
position: [650, -2] position: [650, -2]
},
barWidth: 8,
itemStyle: {
color: function (params) {
if (params.dataIndex < 3) {
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(22, 119, 255, 0)' },
{ offset: 1, color: '#1778ff' }
]);
} else {
return new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(206, 79, 81, 0)' },
{ offset: 1, color: '#ce4f51' }
]);
}
}, },
barWidth: 8, barBorderRadius: 4,
itemStyle: { }
color: function (params) {
if (params.dataIndex < 3) {
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: 'rgba(22, 119, 255, 0)'
},
{
offset: 1,
color: '#1778ff'
}
]);
} else {
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: 'rgba(206, 79, 81, 0)'
},
{
offset: 1,
color: '#ce4f51'
}
]);
}
},
barBorderRadius: 4,
}
}] }]
}; };
\ No newline at end of file return option;
}
\ No newline at end of file
<template> <template>
<div class="coop-page"> <div class="coop-page">
<!-- 吸顶简易搜索框 -->
<div class="search-header" v-show="isShow">
<div class="home-main-header-center">
<input v-model="input" class="search-input" placeholder="搜索规则限制" />
<div class="search-btn-small" @click="handleSearch">
<div class="search-icon">
<img src="./assets/icons/search-icon.png" alt="" />
</div>
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-btn-box">
<div class="btn" @click="handleToPosi('position1')">
<div class="btn-text">最新动态</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
<div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
<div class="btn" @click="handleToPosi('position3')">
<div class="btn-text">数据总览</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
<div class="btn" @click="handleToPosi('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div>
</div>
</div>
</div>
<!-- 面包屑 --> <!-- 面包屑 -->
<div class="breadcrumb"> <div class="breadcrumb" v-show="!isShow">
<div class="breadcrumb-box"> <div class="breadcrumb-box">
<div class="breadcrumb-item">国家科技安全</div> <div class="breadcrumb-item">国家科技安全</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div> <div class="breadcrumb-item">&nbsp;>&nbsp;</div>
...@@ -11,9 +50,9 @@ ...@@ -11,9 +50,9 @@
</div> </div>
</div> </div>
<!-- 主页面 --> <!-- 主页面 -->
<div class="main-content"> <div class="main-content" ref="homeMainRef" :class="{ 'scroll-main': isShow }">
<!-- 搜索栏部分 --> <!-- 搜索栏部分 -->
<div class="search"> <div class="search" v-show="!isShow">
<div class="search-main"> <div class="search-main">
<input v-model="input" placeholder="搜索规则限制" class="search-input" /> <input v-model="input" placeholder="搜索规则限制" class="search-input" />
<div class="search-btn"> <div class="search-btn">
...@@ -40,25 +79,25 @@ ...@@ -40,25 +79,25 @@
</div> </div>
</div> --> </div> -->
<div class="search-bottom"> <div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')"> <div class="btn" @click="handleToPosi('position1')">
<div class="btn-text">最新动态</div> <div class="btn-text">最新动态</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div> </div>
</div> </div>
<div class="btn" @click="scrollToTop('position2')"> <div class="btn" @click="handleToPosi('position2')">
<div class="btn-text">咨询要闻</div> <div class="btn-text">咨询要闻</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div> </div>
</div> </div>
<div class="btn" @click="scrollToTop('position3')"> <div class="btn" @click="handleToPosi('position3')">
<div class="btn-text">数据总览</div> <div class="btn-text">数据总览</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
</div> </div>
</div> </div>
<div class="btn" @click="scrollToTop('position4')"> <div class="btn" @click="handleToPosi('position4')">
<div class="btn-text">资源库</div> <div class="btn-text">资源库</div>
<div class="btn-icon"> <div class="btn-icon">
<img src="@/assets/icons/arrow-right-icon.png" alt="" /> <img src="@/assets/icons/arrow-right-icon.png" alt="" />
...@@ -99,7 +138,7 @@ ...@@ -99,7 +138,7 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, nextTick } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import comTitle from "./common/comTitle.vue"; import comTitle from "./common/comTitle.vue";
import newData from "./components/dataNew/index.vue"; import newData from "./components/dataNew/index.vue";
...@@ -107,14 +146,44 @@ import askPage from "./components/askPage/index.vue"; ...@@ -107,14 +146,44 @@ import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue"; import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue"; import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
// 搜索框 // 搜索框
const input = ref(""); const input = ref("");
const homeMainRef = ref(null);
const { isShow } = useContainerScroll(homeMainRef);
const router = useRouter(); const router = useRouter();
// 搜索功能
const handleSearch = () => {
console.log("搜索内容:", input.value);
};
// 锚点跳转
const handleToPosi = id => {
const element = document.getElementById(id);
if (element && homeMainRef.value) {
// 如果当前还未显示吸顶搜索栏,先强制切换状态以稳定布局
if (!isShow.value) {
isShow.value = true;
}
// 使用 nextTick 确保 DOM 状态更新(高度变化生效)后再计算
nextTick(() => {
const containerRect = homeMainRef.value.getBoundingClientRect();
const elementRect = element.getBoundingClientRect();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const top = elementRect.top - containerRect.top + homeMainRef.value.scrollTop;
homeMainRef.value.scrollTo({
top: top,
behavior: "smooth"
});
});
}
};
// 返回首页 // 返回首页
const handleBackHome = () => { const handleBackHome = () => {
router.push({ router.push({
...@@ -157,12 +226,18 @@ const handleBackHome = () => { ...@@ -157,12 +226,18 @@ const handleBackHome = () => {
} }
} }
.main-content { .main-content {
position: relative;
overflow: auto; overflow: auto;
width: 100%; width: 100%;
height: calc(100% - 64px); height: calc(100% - 64px);
background: url("./assets/images/background.png"); background: url("./assets/images/background.png");
background-size: 100% 100%; background-size: 100% 100%;
padding: 44px 160px 30px 160px; padding: 44px 160px 30px 160px;
&.scroll-main {
height: calc(100% - 144px);
}
.search { .search {
width: 960px; width: 960px;
height: 168px; height: 168px;
...@@ -184,15 +259,19 @@ const handleBackHome = () => { ...@@ -184,15 +259,19 @@ const handleBackHome = () => {
.search-input { .search-input {
border: none; border: none;
outline: none; outline: none;
width: 800px; width: 838px;
height: 48px; height: 48px;
background-color: transparent; background-color: transparent;
font-size: 16px; font-size: 14px;
padding: 12px 16px; padding: 12px 16px;
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 22px;
color: rgb(132, 136, 142); color: rgba(59, 65, 75, 1);
&::placeholder {
color: #a8abb2;
}
} }
.search-btn { .search-btn {
cursor: pointer; cursor: pointer;
...@@ -204,53 +283,18 @@ const handleBackHome = () => { ...@@ -204,53 +283,18 @@ const handleBackHome = () => {
margin-right: -3px; margin-right: -3px;
border-radius: 8px; border-radius: 8px;
background-color: rgb(5, 95, 194); background-color: rgb(5, 95, 194);
font-size: 18px; font-size: 16px;
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 24px; line-height: 22px;
color: #fff; color: #fff;
img { img {
width: 22px; width: 18px;
height: 22px; height: 18px;
margin-right: 8px; margin-right: 8px;
} }
} }
} }
.search-center {
width: 600px;
height: 57px;
margin: 36px auto;
display: flex;
align-items: center;
justify-content: space-between;
.search-item {
box-sizing: border-box;
width: 120px;
height: 57px;
.search-item-num {
width: 120px;
height: 22px;
font-size: 36px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgb(5, 95, 194);
text-align: center;
cursor: pointer;
}
.search-item-name {
width: 120px;
height: 24px;
margin-top: 11px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
text-align: center;
}
}
}
.search-bottom { .search-bottom {
width: 688px; width: 688px;
height: 48px; height: 48px;
...@@ -339,5 +383,129 @@ const handleBackHome = () => { ...@@ -339,5 +383,129 @@ const handleBackHome = () => {
} }
} }
} }
.search-header {
width: 100%;
height: 144px;
background: #fff;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
overflow: hidden;
.home-main-header-center {
margin-top: 20px;
margin-left: 200px;
width: 800px;
height: 48px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
padding: 1px;
position: relative;
display: flex;
align-items: center;
border: 1px solid transparent;
&:hover {
border: 1px solid var(--color-main-active);
}
.search-input {
border: none;
outline: none;
width: 800px;
height: 46px;
background-color: transparent;
font-size: 14px;
padding: 12px 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgba(59, 65, 75, 1);
&::placeholder {
color: #a8abb2;
}
}
.search-btn-small {
position: absolute;
right: -1px;
top: 0px;
width: 120px;
height: 46px;
border-radius: 10px;
background: var(--color-main-active);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
.search-icon {
width: 18px;
height: 18px;
img {
width: 100%;
height: 100%;
}
}
.search-text {
margin-left: 8px;
height: 22px;
color: #fff;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 22px;
}
}
}
.home-main-header-btn-box {
margin-top: 20px;
margin-left: 200px;
display: flex;
gap: 16px;
.btn {
display: flex;
align-items: center;
gap: 9px;
width: 160px;
height: 48px;
border: 1px solid #aed6ff;
box-sizing: border-box;
border-radius: 24px;
background: #e7f3ff;
cursor: pointer;
position: relative;
&:hover {
background: #cae3fc;
}
.btn-text {
width: 80px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 48px;
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
top: 16px;
right: 19px;
width: 6px;
height: 12px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
} }
</style> </style>
...@@ -98,11 +98,11 @@ ...@@ -98,11 +98,11 @@
<div class="bottom-main"> <div class="bottom-main">
<div class="left"> <div class="left">
<div class="select-box"> <div class="select-box">
<div class="select-box-header"> <div class="select-box-header" style=" display: flex;">
<div class="icon"></div> <div class="icon"></div>
<div class="title">{{ "科技领域" }}</div> <div class="title">{{ "科技领域" }}</div>
</div> </div>
<div class="select-main"> <div class="select-main" style="padding: 25px;">
<div class="checkbox-group"> <div class="checkbox-group">
<!-- <el-checkbox v-for="(item, index) in areaList" :key="index" v-model="selectedAreaList" :label="item" <!-- <el-checkbox v-for="(item, index) in areaList" :key="index" v-model="selectedAreaList" :label="item"
class="filter-checkbox"> class="filter-checkbox">
...@@ -918,6 +918,7 @@ onMounted(() => { ...@@ -918,6 +918,7 @@ onMounted(() => {
.select-box { .select-box {
margin-top: 21px; margin-top: 21px;
.paixu-btn { .paixu-btn {
display: flex; display: flex;
width: 120px; width: 120px;
...@@ -970,6 +971,26 @@ onMounted(() => { ...@@ -970,6 +971,26 @@ onMounted(() => {
} }
} }
} }
.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;
}
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论