提交 7d3d5648 authored 作者: 胡卉清's avatar 胡卉清

合并分支 'dev_hhq' 到 'master'

Dev hhq 查看合并请求 !83
......@@ -94,6 +94,14 @@ export function getResearchFieldSubjectType(params) {
params
})
}
// 获取行业领域列表
export function getAreaType() {
return request({
method: 'GET',
url: `/api/commonDict/areaType`,
})
}
/***********详情页 */
//创新主体详情:基本信息
export function getInfo(params) {
......@@ -150,6 +158,14 @@ export function getPaperList(params) {
})
}
//创新主体科研实力:领域实力分布
export function getStudyFieldList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/studyFieldList/${params.id}`,
})
}
//创新主体科研实力:经费增长情况
export function getFundGrowth(params) {
return request({
......@@ -177,3 +193,65 @@ export function getFundToList(params) {
})
}
//合作情况:与中国合作数量变化
export function getCooperateNumWithChina(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/cooperateNumWithChina/${params.id}`,
params
})
}
// 合作情况:与中国合作类型变化
export function getCooperateTypeWithChina(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/cooperateTypeWithChina/${params.year}/${params.id}`,
params
})
}
// 合作情况:与中国合作领域变化
export function getCooperateAreaWithChina(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/cooperateAreaWithChina/${params.id}`,
params
})
}
//合作情况:与中国合作经费变化
export function getCooperateFundWithChina(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/cooperateFundWithChina/${params.id}`,
params
})
}
//合作情况:与中国合作事例
export function getCooperateExampleWithChina(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/cooperateExampleWithChina/${params.id}`,
params
})
}
//创新主体其他情况:重点实验室
export function getLabList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/labList/${params.id}`,
})
}
//创新主体其他情况:政策文件
export function getPolicyList(params) {
return request({
method: 'GET',
url: `/api/innovateSubject/policyList/${params.id}`,
params
})
}
\ No newline at end of file
......@@ -361,8 +361,9 @@
</div>
</div>
<div class="select-box">
<el-select v-model="value" placeholder="全部领域" style="width: 120px">
<el-option v-for="item in areaList" :key="item.value" :label="item.label" :value="item.value" />
<el-select v-model="areaSelect" placeholder="全部领域" style="width: 120px"
@change="handleFindListBySubjectTypeId">
<el-option v-for="item in areaList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
</div>
......@@ -415,6 +416,7 @@ import getCalendarHeatChart from "./utils/cleandarHeat";
import EChart from "@/components/Chart/index.vue";
import { pieOption, raderOption } from "./utils/charts";
import {
getAreaType,
getNews,
getSocialMediaInfo,
getBillRiskSignal,
......@@ -973,6 +975,19 @@ const areaList = ref([
value: "全部领域"
}
]);
const areaSelect = ref([])
//获取行业领域列表
const handleGetAreaType = async () => {
try {
const res = await getAreaType();
console.log("行业领域列表 ", res);
if (res.code === 200 && res.data) {
areaList.value = res.data
}
} catch (error) {
console.error("获取行业领域列表 error", error);
}
};
const categoryList1 = ref(["研究型大学", "国家实验室", "科技企业", "国防承包商"]);
const activeCate1 = ref('');
......@@ -1005,7 +1020,7 @@ const handleFindListBySubjectTypeId = async () => {
try {
let params = {
subjectTypeId: activeCate1.value,
// arealist:
arealist: areaSelect.value,
currentPage: currentPage.value,
pageSize: 16,
......@@ -1040,6 +1055,7 @@ const handleToPosi = id => {
};
onMounted(async () => {
handleGetAreaType()
handleGetNews()
handleGetSocialMediaInfo()
handleGetBillRiskSignal()
......
<template>
<div class="timeline-wrapper">
<button class="arrow left" :disabled="index <= 0" @click="index--">
{{ '<' }} </button>
<div class="timeline-box">
<div class="line"></div>
<div v-for="(item, i) in showList" :key="item[idKey]" class="node" :style="leftOffset(i)">
<div class="node" :style="leftOffset(i)">
<div class="time">
{{ item.cooperateDate }}
</div>
<!-- 圆环 -->
<div class="dot" :class="linePos(i, flip)"></div>
<!-- 卡片:放到线右侧 -->
<div class="card" :class="[cardPos(i, flip), 'right-side']" @click="$emit('click-card', item)">
<div class="tag">
{{ item.typeName }}
</div>
<div class="title">
{{ '合作主体:' + item.subjectlist.join(',') }}
<img class="item-header-icon" src="@/assets/images/icon/copy.png" style="cursor: pointer;" />
</div>
<div class="content">
{{ item.cooperateName }}
</div>
</div>
</div>
</div>
</div>
<button class="arrow right" :disabled="index >= total - 5" @click="index++">
{{ '>' }}
</button>
</div>
</template>
<script>
export default {
name: 'TimeLine',
props: {
data: { // 父组件传入的数组
type: Array,
required: true
},
textKey: { // 要显示的文本字段
type: String,
default: 'text'
},
idKey: { // 唯一标识字段
type: String,
default: 'id'
}
},
data() {
return { index: 0 };
},
computed: {
total() {
return this.data.length;
},
showList() {
return this.data.slice(this.index, this.index + 5);
},
flip() { return this.index % 2 === 1; }
},
methods: {
leftOffset(i) {
return { left: `${(i * 100) / 5}%` };
},
/* 上下层翻转(保留上次逻辑) */
cardPos(i, flip = false) {
// return (i % 2) ^ flip ? 'down' : 'up';
return 'down';
},
/* 线延伸方向 = 卡片出现方向 */
linePos(i, flip = false) {
return this.cardPos(i, flip); // up / down
}
}
};
</script>
<style scoped>
/* 样式与之前完全一致,不再重复 */
.timeline-wrapper {
display: flex;
align-items: center;
width: 100%;
position: relative;
padding: 0 40px;
}
.arrow {
position: absolute;
top: 45px;
/* 左右切换按钮 */
width: 24px;
height: 48px;
font-size: 24px;
border-color: #E7F3FF;
border: 0;
background: #E7F3FF;
cursor: pointer;
z-index: 10;
color: #3E84D1;
}
.arrow:disabled {
color: #c0c4cc;
cursor: not-allowed;
}
.left {
left: 0;
border-radius: 0px 4px 4px 0px;
}
.right {
right: 0;
border-radius: 4px 0px 0px 4px;
}
.timeline-box {
flex: 1;
height: 100%;
position: relative;
}
.line {
position: absolute;
left: 0;
right: 0;
top: 50%;
height: 6px;
background-image: url("@/assets/images/bg/timeLine-bg.jpg");
transform: translateY(-50%);
background-size: auto 100%;
}
.node {
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
z-index: 2;
}
/* ===== 圆环基础 ===== */
.dot {
top: -30px;
width: 14px;
height: 14px;
border-radius: 50%;
border: 3px solid #409eff;
background: #fff;
position: relative;
margin: 0 auto;
z-index: 2;
}
/* ===== 延伸线 ===== */
.dot::after {
content: '';
position: absolute;
left: 50%;
transform: translateX(-1px);
/* 居中细线 */
width: 1px;
background: #409eff;
}
/* 向上节点:线往下伸 */
.dot.up::after {
bottom: 100%;
height: 165px;
/* 圆环底部 → 卡片顶 */
}
/* 向下节点:线往上伸 */
.dot.down::after {
top: 100%;
height: 165px;
}
.card {
position: absolute;
padding: 8px 12px;
text-align: left;
cursor: pointer;
font-size: 14px;
/* 容器 299 */
width: 273px;
height: 210px;
border-radius: 4px;
/* 业务系统/模块阴影 */
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: var(--主色/白色主色, rgba(255, 255, 255, 1));
}
.time {
width: 125px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 35px;
margin-left: 125px;
}
.title {
color: rgba(59, 65, 75, 1);
height: 85px;
font-family: Microsoft YaHei;
font-style: Regular;
font-size: 18px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.content {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-style: Bold;
font-size: 18px;
font-weight: 700;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.card.up {
bottom: 20px;
}
.card.down {
top: 55px;
left: 115px;
}
</style>
\ No newline at end of file
......@@ -65,8 +65,8 @@
</div>
</div>
</div>
<div class="statisticsChart">
<Echarts :option="raderOption1" height="100%"></Echarts>
<div class="statisticsChart" v-if="studyFieldList.length > 0">
<Echarts :option="raderOption1(studyFieldList)" height="100%"></Echarts>
</div>
<div class="statisticsAI">
<div class="AIbox">
......@@ -167,7 +167,7 @@ import Echarts from "@/components/Chart/index.vue";
import { barOption, lineChart, raderOption1, lineChart1, pieOption1, horizontalBaroption } from "../../utils/charts.js";
import {
getPatentList,
getPaperList, getFundGrowth, getFundFromList, getFundToList
getPaperList, getFundGrowth, getFundFromList, getFundToList, getStudyFieldList
} from "@/api/innovationSubject/overview.js";
import { useRouter } from "vue-router";
const router = useRouter();
......@@ -221,6 +221,22 @@ const handleGetFundGrowth = async () => {
}
};
//创新主体科研实力:领域实力分布
const studyFieldList = ref([])
const handleGetStudyFieldList = async () => {
try {
let params = {
id: router.currentRoute._value.params.id
}
const res = await getStudyFieldList(params);
console.log("领域实力分布", res);
if (res.code === 200 && res.data) {
studyFieldList.value = res.data
}
} catch (error) {
console.error("获取领域实力分布error", error);
}
};
//经费来源
const fundFromList = ref([])
const handleGetFundFromList = async () => {
......@@ -256,9 +272,11 @@ const handlegGetFundToList = async () => {
};
onMounted(async () => {
handleGetFundGrowth()
handleGetPatentList()
handleGetPaperList()
handleGetFundGrowth()
handleGetStudyFieldList()
handleGetFundFromList()
handlegGetFundToList()
});
......
......@@ -223,45 +223,8 @@ export const raderOption = (data) => {
return option;
}
export const raderOption1 = {
grid: {
top: '3%',
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());
......@@ -344,7 +307,6 @@ export const barOption = (data) => {
]
};
return option;
}
export const lineChart = (data) => {
// 提取年份和对应的专利数量
......@@ -549,3 +511,57 @@ export const horizontalBaroption = (data) => {
};
return option;
}
export const raderOption1 = (data) => {
// 提取指标名称和对应的值
const indicatorNames = data.map(item => item.areaName);
const indicatorValues = data.map(item => item.areaValue);
// 动态生成雷达图的 indicator 配置
const indicators = indicatorNames.map((name, index) => ({
name,
max: Math.max(...indicatorValues) * 1.2 // 设置最大值为所有值的最大值的1.2倍
}));
let radarData = {
color:
"rgba(215, 27, 56, 0.2)",
name: '',
value: indicatorValues
}
console.log(indicators, 'indicators', radarData, 'radarDataradarData')
// 雷达图配置
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: {
radius: '60%',
indicator: indicators,
axisName: {
formatter: '{value}',
color: 'rgba(59, 65, 75, 1)',
fontSize: 16,
fontWeight: 700
}
},
series: [
{
name: 'Budget vs spending',
type: 'radar',
data: [radarData]
}
]
};
return option;
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论