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

update

......@@ -192,6 +192,16 @@ export function getThinkTankPerson(params) {
})
}
//智库报告:获取报告全局信息
export const getThinkTankReportSummary = (params) => {
return request(
{
method: 'GET',
url: `/api/thinkTankReport/summary/${params}`,
}
);
}
//获取报告内容摘要
export function getThinkTankReportAbstract(params) {
return request({
......
<template>
<div class="box-content">
<div class="tab-box">
<div v-for="(tab, index) in tabList" :class="activeTab === tab ? 'tab-active' : 'tab'"
@click="changeTab(tab, index)">
{{ tab }}
<div class="arrow-active">
</div>
</div>
</div>
<!--/*头部总览 */-->
<div class="total">
<div v-for="(item) in totalData[activeIndex]" class="total-box">
<div class="line">
</div>
<div class="total-label">
{{ item.label }}
</div>
<div class="total-content">
<div class="total-value">
{{ item.value }}
</div>
<div class="total-unit">
{{ item.unit }}
</div>
</div>
</div>
</div>
<!--/*图表 */-->
<div class="chart">
<div class="chart-content">
<div class="section-header" style=" margin-top: 24px;">
<div style="display: flex;">
<div class="section-icon"></div>
<h3 class="section-title"> {{ activeTab === '研发投入' ? '年度研发投入对比' : activeTab === '研究人员' ? '研究人员数量增长趋势' :
'专利地域分布' }}</h3>
</div>
<div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon">
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<div id="chart1" class="chart-box" v-show="activeTab === '研发投入'">
</div>
<div id="chart3" class="chart-box" v-show="activeTab === '研究人员'">
</div>
<div id="chart5" class="chart-box" v-show="activeTab === '专利情况'">
</div>
<div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px;height: 20px;">
<div>
近五年来,华为的研发投入在绝对金额和投入强度上均持续攀升。尤其是在收入因外部制裁而经历波动时,研发投入依然保持强劲增长,使其投入强度达到了历史高位。
</div>
<div class="arrow-2">
</div>
</div>
</div>
<div class="chart-content">
<div class="section-header" style=" margin-top: 24px;">
<div style="display: flex;">
<div class="section-icon"></div>
<h3 class="section-title"> {{ activeTab === '研发投入' ? '研发投入增长对比' : activeTab === '研究人员' ? '研究人员学历分布' :
'专利技术领域分布' }}</h3>
</div>
<div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon">
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon">
</div>
</div>
<div id="chart2" class="chart-box" v-show="activeTab === '研发投入'">
</div>
<div id="chart4" class="chart-box" v-show="activeTab === '研究人员'">
</div>
<div id="chart6" class="chart-box" v-show="activeTab === '专利情况'">
</div>
<div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px;height: 20px;">
<div>
华为在巨大的外部压力下,研发投入不仅在绝对金额上持续增长,其占收入的比重更是大幅提升,特别是2021年后形成的“剪刀差”,体现了公司最高优先级的战略抉择。 </div>
<div class="arrow-2">
</div>
</div>
</div>
</div>
</div>
<div class="box-content">
<div class="tab-box">
<div
v-for="(tab, index) in tabList"
:key="index"
:class="activeTab === tab ? 'tab-active' : 'tab'"
@click="changeTab(tab, index)"
>
{{ tab }}
<div class="arrow-active" v-show="activeTab === tab"></div>
</div>
</div>
<!--/*头部总览 */-->
<div class="total">
<div v-for="(item, index) in totalData[activeIndex]" :key="index" class="total-box">
<div class="line"></div>
<div class="total-label">
{{ item.label }}
</div>
<div class="total-content">
<div class="total-value">
{{ item.value }}
</div>
<div class="total-unit">
{{ item.unit }}
</div>
</div>
</div>
</div>
<!--/*图表 */-->
<div class="chart">
<div class="chart-content">
<div class="section-header" style="margin-top: 24px">
<div style="display: flex">
<div class="section-icon"></div>
<h3 class="section-title">
{{
activeTab === "研发投入"
? "年度研发投入对比"
: activeTab === "研究人员"
? "研究人员数量增长趋势"
: "专利地域分布"
}}
</h3>
</div>
<div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon" />
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon" />
</div>
</div>
<div id="chart1" class="chart-box" v-show="activeTab === '研发投入'"></div>
<div id="chart3" class="chart-box" v-show="activeTab === '研究人员'"></div>
<div id="chart5" class="chart-box" v-show="activeTab === '专利情况'"></div>
<div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px; height: 20px" />
<div>
近五年来,华为的研发投入在绝对金额和投入强度上均持续攀升。尤其是在收入因外部制裁而经历波动时,研发投入依然保持强劲增长,使其投入强度达到了历史高位。
</div>
<div class="arrow-2"></div>
</div>
</div>
<div class="chart-content">
<div class="section-header" style="margin-top: 24px">
<div style="display: flex">
<div class="section-icon"></div>
<h3 class="section-title">
{{
activeTab === "研发投入"
? "研发投入增长对比"
: activeTab === "研究人员"
? "研究人员学历分布"
: "专利技术领域分布"
}}
</h3>
</div>
<div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon" />
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon" />
</div>
</div>
<div id="chart2" class="chart-box" v-show="activeTab === '研发投入'"></div>
<div id="chart4" class="chart-box" v-show="activeTab === '研究人员'"></div>
<div id="chart6" class="chart-box" v-show="activeTab === '专利情况'"></div>
<div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px; height: 20px" />
<div>
华为在巨大的外部压力下,研发投入不仅在绝对金额上持续增长,其占收入的比重更是大幅提升,特别是2021年后形成的“剪刀差”,体现了公司最高优先级的战略抉择。
</div>
<div class="arrow-2"></div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { ref, onMounted, nextTick } from "vue";
import getBarChart from "../js/barChart.js";
import getDonutChart from '../js/donutChart.js';
import getDonutChart from "../js/donutChart.js";
import getLineChart from "../js/lineChart.js";
import getRadarChart from '../js/radarChart.js'
import getRadarChart from "../js/radarChart.js";
import * as echarts from "echarts";
const tabList = ref(['研发投入', '研究人员', '专利情况'])
const activeTab = ref('研发投入')
const activeIndex = ref(0)
const totalData = ref([[
{
"label": "累计研发投入",
"value": 9854,
"unit": "亿元"
},
{
"label": "年度研发投入",
"value": 2153.9,
"unit": "亿元"
},
{
"label": "研发强度",
"value": 22.9,
"unit": "%"
},
{
"label": "研发投入排名",
"value": "Top",
"unit": ""
}
], [
{ label: '2025年拟招聘应届生', value: 11.4, unit: '万' },
{ label: '研发人员占比', value: 55.4, unit: '%' },
{ label: '全年计划培养实习生', value: 1, unit: '万+' },
{ label: '研发人员总数', value: 5000, unit: '+' }
], [
{ label: '全球有效专利', value: 12, unit: '万+' },
{ label: 'PCT申请量排名', value: 'Top', unit: '5' },
{ label: '5G标准必要专利占比', value: 21.5, unit: '%' },
{ label: '家族专利', value: 4500, unit: '+' }
]])
const tabList = ref(["研发投入", "研究人员", "专利情况"]);
const activeTab = ref("研发投入");
const activeIndex = ref(0);
const totalData = ref([
[
{
label: "累计研发投入",
value: 9854,
unit: "亿元"
},
{
label: "年度研发投入",
value: 2153.9,
unit: "亿元"
},
{
label: "研发强度",
value: 22.9,
unit: "%"
},
{
label: "研发投入排名",
value: "Top",
unit: ""
}
],
[
{ label: "2025年拟招聘应届生", value: 11.4, unit: "万" },
{ label: "研发人员占比", value: 55.4, unit: "%" },
{ label: "全年计划培养实习生", value: 1, unit: "万+" },
{ label: "研发人员总数", value: 5000, unit: "+" }
],
[
{ label: "全球有效专利", value: 12, unit: "万+" },
{ label: "PCT申请量排名", value: "Top", unit: "5" },
{ label: "5G标准必要专利占比", value: 21.5, unit: "%" },
{ label: "家族专利", value: 4500, unit: "+" }
]
]);
//年度研发投入对比
const chart1Data = ref({
name: ['2020', '2021', '2022', '2023', '2024', '2025'],
value: [50, 100, 150, 200, 250, 300, 350, 400]
name: ["2020", "2021", "2022", "2023", "2024", "2025"],
value: [50, 100, 150, 200, 250, 300, 350, 400]
});
//研发投入增长对比
const chart2Data = {
dataX: ["2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08"],
dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4]
dataX: ["2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08"],
dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4]
};
const chart3Data = ref({
name: ['2020', '2021', '2022', '2023', '2024', '2025'],
value: [50, 100, 150, 200, 250, 300, 350, 400]
name: ["2020", "2021", "2022", "2023", "2024", "2025"],
value: [50, 100, 150, 200, 250, 300, 350, 400]
});
// 学历分布数据(对应图片)
const chart4Data = ref({
name: ['博士', '硕士', '学士', '其他'],
value: [28, 36, 22, 8],
})
name: ["博士", "硕士", "学士", "其他"],
value: [28, 36, 22, 8]
});
// 学历分布数据(对应图片)
const chart5Data = ref({
name: ['博士', '硕士', '学士', '其他'],
value: [28, 36, 22, 8],
})
name: ["博士", "硕士", "学士", "其他"],
value: [28, 36, 22, 8]
});
function changeTab(tab, index) {
console.log(tab, activeTab.value)
activeTab.value = tab
activeIndex.value = index
console.log(tab, activeTab.value, activeIndex.value)
// 保证 DOM 更新完再画
nextTick(() => {
if (tab === '研发投入') {
chart1()
chart2()
} else if (tab === '研究人员') {
chart3()
char4()
} if (tab === '专利情况') {
char5()
chart6()
}
// 其它 tab 同理 …
})
console.log(tab, activeTab.value);
activeTab.value = tab;
activeIndex.value = index;
console.log(tab, activeTab.value, activeIndex.value);
// 保证 DOM 更新完再画
nextTick(() => {
if (tab === "研发投入") {
chart1();
chart2();
} else if (tab === "研究人员") {
chart3();
char4();
}
if (tab === "专利情况") {
char5();
chart6();
}
// 其它 tab 同理 …
});
}
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
let chartDom = document.getElementById(chartId);
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
return chart;
};
function chart1() {
let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true);
setChart(char1, "chart1");
let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true);
setChart(char1, "chart1");
}
function chart2() {
let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2");
let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2");
}
function chart3() {
let char3 = getBarChart(chart3Data.value.name, chart3Data.value.value, true);
setChart(char3, "chart3");
let char3 = getBarChart(chart3Data.value.name, chart3Data.value.value, true);
setChart(char3, "chart3");
}
function char4() {
console.log(chart4Data.value)
let char4 = getDonutChart(chart4Data.value.name, chart4Data.value.value, true);
setChart(char4, "chart4");
console.log(chart4Data.value);
let char4 = getDonutChart(chart4Data.value.name, chart4Data.value.value, true);
setChart(char4, "chart4");
}
function char5() {
console.log(chart5Data.value)
let char5 = getDonutChart(chart5Data.value.name, chart5Data.value.value, true);
setChart(char5, "chart5");
console.log(chart5Data.value);
let char5 = getDonutChart(chart5Data.value.name, chart5Data.value.value, true);
setChart(char5, "chart5");
}
function chart6() {
let char6 = getRadarChart();
setChart(char6, "chart6");
let char6 = getRadarChart();
setChart(char6, "chart6");
}
onMounted(() => {
chart1()
chart2()
chart1();
chart2();
});
</script>
<style scoped>
<style lang="scss" scoped>
.box-content {
width: 100%;
height: calc(100vh - 220px);
overflow: auto;
width: 100%;
height: calc(100vh - 220px);
overflow: auto;
}
.tab-box {
/* 左侧导航 */
width: 112px;
height: 128px;
position: absolute;
left: 0;
margin: 20px;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 16;
.tab {
color: rgba(59, 65, 75, 1);
height: 48px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-bottom: 0px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
}
.tab-active {
/* 容器 7 */
width: 104px;
height: 32px;
display: flex;
align-items: center;
box-sizing: border-box;
border-bottom: 2px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
border-radius: 16px;
background: rgba(5, 95, 194, 1);
color: rgba(255, 255, 255, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
padding: 4px 12px;
}
.arrow-active {
width: 0;
height: 0;
border-style: solid;
border-width: 4px 0 4px 6px;
margin-left: 5px;
/* 上 右 下 左 */
border-color: transparent transparent transparent #ffffff;
/* 只给左边上色 */
/* background: rgba(255, 255, 255, 1); */
}
/* 左侧导航 */
width: 112px;
height: 128px;
position: absolute;
left: 24px;
/* 自动布局 */
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 16;
.tab {
color: rgba(59, 65, 75, 1);
width: 104px;
height: 48px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
box-sizing: border-box;
border-bottom: 0px solid rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
cursor: pointer;
margin-bottom: 16px;
}
.tab-active {
/* 容器 7 */
width: 104px;
height: 32px;
display: flex;
align-items: center;
box-sizing: border-box;
border-radius: 16px;
background: rgba(5, 95, 194, 1);
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
padding: 4px 12px;
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
cursor: pointer;
margin-bottom: 16px;
}
.arrow-active {
position: absolute;
top: 12px;
right: 8px;
width: 0;
height: 0;
border-style: solid;
border-width: 4px 0 4px 6px;
// margin-left: 5px;
/* 上 右 下 左 */
border-color: transparent transparent transparent #ffffff;
/* 只给左边上色 */
/* background: rgba(255, 255, 255, 1); */
}
}
/*头部总览 */
.total {
height: 80px;
display: flex;
gap: 16px;
height: 80px;
display: flex;
gap: 16px;
}
.total-box {
border-radius: 4px;
background: rgba(255, 255, 255, 1);
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
.line {
/* 矩形 214 */
width: 4px;
height: 49px;
background: rgba(5, 95, 194, 1);
}
.total-label {
color: rgba(59, 65, 75, 1);
margin: 0px 30px;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
.total-content {
display: flex;
margin-right: 35px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
letter-spacing: 0px;
text-align: right;
.total-value {
font-size: 24px;
font-weight: 700;
line-height: 24px;
}
.total-unit {
font-size: 16px;
font-weight: 500;
line-height: 16px;
margin-top: 8px;
}
}
border-radius: 4px;
background: rgba(255, 255, 255, 1);
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
.line {
/* 矩形 214 */
width: 4px;
height: 49px;
background: rgba(5, 95, 194, 1);
}
.total-label {
color: rgba(59, 65, 75, 1);
margin: 0px 30px;
font-size: 16px;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
.total-content {
display: flex;
margin-right: 35px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
letter-spacing: 0px;
text-align: right;
.total-value {
font-size: 24px;
font-weight: 700;
line-height: 24px;
}
.total-unit {
font-size: 16px;
font-weight: 500;
line-height: 16px;
margin-top: 8px;
}
}
}
.chart {
margin-top: 16px;
height: calc(100vh - 320px);
display: flex;
gap: 16px;
.chart-content {
border-radius: 4px;
background: rgba(255, 255, 255, 1);
flex: 1;
justify-content: space-between;
.section-header {
display: flex;
width: 100%;
justify-content: space-between;
}
.section-icon {
width: 7px;
height: 18px;
border-radius: 0 4px 4px 0;
background: rgba(5, 95, 194, 1);
margin-right: 17px;
}
.section-title {
font-size: 18px;
color: #1d2129;
margin: 0;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.action-icons {
display: flex;
margin-left: auto;
}
.action-icon {
/* 收藏按钮 */
width: 28px;
height: 28px;
cursor: pointer;
margin-right: 12px;
}
.chart-box {
width: 100%;
height: calc(100% - 130px);
}
.chart-text {
/* 大模型对话结果 */
height: 52px;
margin: 12px 20px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 10;
padding: 0px 12px 0px 12px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
color: rgba(5, 95, 194, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
gap: 13px;
}
.arrow-2 {
border-radius: 50%;
width: 24px;
height: 24px;
font-size: 24px;
background: rgba(231, 243, 255, 1);
}
margin-top: 16px;
height: calc(100vh - 320px);
display: flex;
gap: 16px;
.chart-content {
border-radius: 4px;
background: rgba(255, 255, 255, 1);
flex: 1;
justify-content: space-between;
.section-header {
display: flex;
width: 100%;
justify-content: space-between;
}
.section-icon {
width: 7px;
height: 18px;
border-radius: 0 4px 4px 0;
background: rgba(5, 95, 194, 1);
margin-right: 17px;
}
.section-title {
font-size: 18px;
color: #1d2129;
margin: 0;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-weight: 700;
line-height: 24px;
letter-spacing: 1px;
text-align: left;
}
}
.action-icons {
display: flex;
margin-left: auto;
}
.action-icon {
/* 收藏按钮 */
width: 28px;
height: 28px;
cursor: pointer;
margin-right: 12px;
}
.chart-box {
width: 100%;
height: calc(100% - 130px);
}
.chart-text {
/* 大模型对话结果 */
height: 52px;
margin: 12px 20px;
/* 自动布局 */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 10;
padding: 0px 12px 0px 12px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
color: rgba(5, 95, 194, 1);
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: justify;
gap: 13px;
}
.arrow-2 {
border-radius: 50%;
width: 24px;
height: 24px;
font-size: 24px;
background: rgba(231, 243, 255, 1);
}
}
</style>
\ No newline at end of file
......@@ -5,15 +5,20 @@
<div class="news-header">
新闻速览
</div>
<div style="display: flex;padding: 3vh;justify-content: center; ">
<el-input placeholder="请输入关键词" :suffix-icon="searchInput" clearable style="width: 60vw;height: 5vh;">
<div class="input-box">
<el-input placeholder="请输入关键词" :suffix-icon="searchInput" clearable style="width: 800px;height: 48px;">
</el-input>
</div>
<div style="display: flex;padding: 3vh;justify-content: center; ">
<div v-for="item in btnList" :class="btnSelect !== item ? 'header-btn' : 'header-btn-select'"
<div class="btn-box">
<div v-for="item,index in btnList" :key="index" :class="btnSelect !== item ? 'header-btn' : 'header-btn-select'"
@click="changeBtn(item)">
{{ item }} >
<div class="btn-box-text">{{ item }}</div>
<div class="btn-box-icon">
<img v-if="btnSelect === item" src="@/assets/icons/btn-arrow-right-active.png" alt="">
<img v-else src="@/assets/icons/btn-arrow-right.png" alt="">
</div>
</div>
<div class="header-btn-more">
<img src="@/assets/icons/adjustment.png" />
......@@ -21,7 +26,7 @@
</div>
</div>
<div style="display: flex;">
<div class="main" style="display: flex;">
<div class="box">
<div class="box-header">
<img class="box-header-img" src="@/assets/icons/Headlines-icon.svg"></img>
......@@ -30,7 +35,7 @@
</div>
</div>
<div class="divider"></div>
<div v-for="item in HeadlinesData">
<div v-for="item,index in HeadlinesData" :key="index">
<div style="display: flex;">
<div>
<div class="title-blob">
......@@ -40,7 +45,7 @@
新闻来源: {{ item.from }} 发表时间:{{ item.time }}
</div>
<div style="display: flex;">
<div v-for="tag in item.tag" class="tag">
<div v-for="tag,index in item.tag" :key="index" class="tag">
{{ tag }}
</div>
</div>
......@@ -64,7 +69,7 @@
<div class="divider">
</div>
<div v-for="(item, index) in subjectData">
<div v-for="(item, index) in subjectData" :key="index">
<div class="subject-line">
<!-- 左侧:序号 + 文字 -->
<div style="display: flex; align-items: center;">
......@@ -99,88 +104,87 @@
<script setup>
import { ref } from "vue";
import Headlines from './Headlines.vue'
import Subject from './Subject.vue'
import Headlines from "./Headlines.vue";
import Subject from "./Subject.vue";
// import style from './style.css'
//顶部数据搜索
const searchInput = ref('')
const btnList = ref(["新闻纵览", "焦点新闻", "全球热点", "军事热点", "台湾动向", "美国政治", "亚洲局势", "东亚动态"])
const btnSelect = ref('新闻纵览')
const searchInput = ref("");
const btnList = ref(["新闻纵览", "焦点新闻", "全球热点", "军事热点", "台湾动向", "美国政治", "亚洲局势", "东亚动态"]);
const btnSelect = ref("新闻纵览");
const HeadlinesData = ref([
{
"title": "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”",
"from": "人民网",
"time": "2025-10-05",
"tag": ["以色列", "美国"],
"image": '/testData/HeadlinesData-img.png',
},
{
"title": "IMF上调中东和北非地区经济增长预期",
"from": "CNN",
"time": "2025-10-05",
"tag": ["经济", "中东", "IMF"],
"image": '/testData/HeadlinesData-img.png',
},
{
"title": "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面",
"from": "人民网",
"time": "2025-10-05",
"tag": ["日本", "访华"], "image": '/testData/HeadlinesData-img.png',
},
{
"title": "韩日因独岛主权争议暂停本月联合搜救演习",
"from": "凤凰网",
"time": "2025-10-05",
"tag": ["独岛", "联合军演", "韩国", "日本"], "image": '/testData/HeadlinesData-img.png',
},
{
"title": "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结",
"from": "央视网",
"time": "2025-10-05",
"tag": ["美国", "航母", "加勒比海"], "image": '/testData/HeadlinesData-img.png',
}
])
{
title: "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”",
from: "人民网",
time: "2025-10-05",
tag: ["以色列", "美国"],
image: "/testData/HeadlinesData-img.png"
},
{
title: "IMF上调中东和北非地区经济增长预期",
from: "CNN",
time: "2025-10-05",
tag: ["经济", "中东", "IMF"],
image: "/testData/HeadlinesData-img.png"
},
{
title: "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面",
from: "人民网",
time: "2025-10-05",
tag: ["日本", "访华"],
image: "/testData/HeadlinesData-img.png"
},
{
title: "韩日因独岛主权争议暂停本月联合搜救演习",
from: "凤凰网",
time: "2025-10-05",
tag: ["独岛", "联合军演", "韩国", "日本"],
image: "/testData/HeadlinesData-img.png"
},
{
title: "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结",
from: "央视网",
time: "2025-10-05",
tag: ["美国", "航母", "加勒比海"],
image: "/testData/HeadlinesData-img.png"
}
]);
function changeBtn(btn) {
btnSelect.value = btn
btnSelect.value = btn;
}
//当前页面显示
const showPage = ref('home')
const showPage = ref("home");
function changePage(page) {
console.log(page)
showPage.value = page
console.log(page);
showPage.value = page;
}
//博弈专题新闻数据
const subjectData = ref([
{ id: 1, text: "乌克兰与法国签署意向书 将获 100 架“阵风”战机及多套防空系统", arrow: 0 },
{ id: 2, text: "安理会通过涉加沙决议 建立和平委员会作为过渡行政机构", arrow: 1 },
{ id: 3, text: "日本首相高市早苗涉台及修“无核三原则”言论遭多方强烈反对", arrow: 1 },
{ id: 4, text: "美“福特”号航母打击群进入加勒比海 委方谴责其意图策动政权更迭", arrow: 1 },
{ id: 5, text: "BBC回应特朗普10亿-50亿美元索赔诉讼 称诽谤指控无依据", arrow: 1 },
{ id: 6, text: "俄军打击乌142个区域设施 乌军击落或压制91架俄无人机", arrow: 1 },
{ id: 7, text: "中国女法官张玲玲以第一高票当选联合国上诉法庭法官", arrow: 0 },
{ id: 8, text: "美股三大股指17日收盘普跌 比特币跌破92000美元", arrow: 1 },
{ id: 9, text: "高盛大幅下调2026年布伦特和WTI原油价格预测", arrow: 1 },
{ id: 10, text: "2026米兰冬奥会火炬传递完整路线公布 将穿越意大利全部20个大区", arrow: 1 },
{ id: 11, text: "特朗普宣称若重掌白宫将推动美国开展自1992年以来首次核试验", arrow: 1 },
{ id: 12, text: "欧盟发布2025年秋季经济预测 欧元区今年GDP预计增长1.3%", arrow: 1 }
])
{ id: 1, text: "乌克兰与法国签署意向书 将获 100 架“阵风”战机及多套防空系统", arrow: 0 },
{ id: 2, text: "安理会通过涉加沙决议 建立和平委员会作为过渡行政机构", arrow: 1 },
{ id: 3, text: "日本首相高市早苗涉台及修“无核三原则”言论遭多方强烈反对", arrow: 1 },
{ id: 4, text: "美“福特”号航母打击群进入加勒比海 委方谴责其意图策动政权更迭", arrow: 1 },
{ id: 5, text: "BBC回应特朗普10亿-50亿美元索赔诉讼 称诽谤指控无依据", arrow: 1 },
{ id: 6, text: "俄军打击乌142个区域设施 乌军击落或压制91架俄无人机", arrow: 1 },
{ id: 7, text: "中国女法官张玲玲以第一高票当选联合国上诉法庭法官", arrow: 0 },
{ id: 8, text: "美股三大股指17日收盘普跌 比特币跌破92000美元", arrow: 1 },
{ id: 9, text: "高盛大幅下调2026年布伦特和WTI原油价格预测", arrow: 1 },
{ id: 10, text: "2026米兰冬奥会火炬传递完整路线公布 将穿越意大利全部20个大区", arrow: 1 },
{ id: 11, text: "特朗普宣称若重掌白宫将推动美国开展自1992年以来首次核试验", arrow: 1 },
{ id: 12, text: "欧盟发布2025年秋季经济预测 欧元区今年GDP预计增长1.3%", arrow: 1 }
]);
</script>
<style scoped>
@import url('./style.css');
<style lang="scss" scoped>
@import url("./style.css");
.newsBrief-page {
max-width: 100vw;
height: 100%;
overflow: hidden;
margin: 0 auto;
padding: 5vh 10vw 20vh 10vw;
background: url('@/assets/images/background.png') no-repeat;
background-position: center -100px;
background-size: 100% 100%;
min-height: 100vh;
height: 100%;
background: url("@/assets/images/background.png") no-repeat;
background-position: center -100px;
background-size: 100% 100%;
padding-top: 50px;
}
</style>
/* 分割线 */
/* 左右横线 + 中间文字 */
.news-header {
color: rgba(34, 41, 52, 1);
font-family: "YouSheBiaoTiHei", sans-serif;
font-family: YouSheBiaoTiHei;
font-size: 46px;
font-weight: 400;
line-height: 60px;
letter-spacing: 0px;
text-align: center;
margin: 0 auto;
}
.input-box {
width: 800px;
height: 48px;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 0.65);
margin: 20px auto 0;
}
.btn-box {
display: flex;
justify-content: center;
gap: 16px;
margin-top: 60px;
margin-bottom: 24px;
}
.header-btn {
cursor: pointer;
padding: 2px 20px;
padding: 0px 20px;
box-sizing: border-box;
margin: 5px;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 32px;
background: rgba(255, 255, 255, 0.8);
color: rgba(95, 101, 108, 1);
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: center;
position: relative;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
.header-btn:hover {
background: rgba(231, 243, 255, 1);
}
.header-btn-gray {
cursor: pointer;
padding: 2px 20px;
......@@ -40,21 +67,36 @@
letter-spacing: 0px;
text-align: center;
}
.header-btn-select {
cursor: pointer;
padding: 2px 20px;
margin: 5px;
padding: 0px 20px;
box-sizing: border-box;
border: 1px solid rgba(174, 214, 255, 1);
border-radius: 32px;
background: rgba(231, 243, 255, 1);
font-size: 16px;
font-weight: 400;
line-height: 30px;
color: var(--color-main-active);
letter-spacing: 0px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
.btn-box-icon {
width: 6px;
height: 12px;
}
.btn-box-icon img {
width: 100%;
height: 100%;
}
.header-btn-more {
cursor: pointer;
width: 34px;
......@@ -64,51 +106,65 @@
border: 1px solid, rgba(255, 255, 255, 1);
border-radius: 32px;
background: rgba(255, 255, 255, 0.8);
display: flex; /* 开启 flex */
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
display: flex;
/* 开启 flex */
justify-content: center;
/* 水平居中 */
align-items: center;
/* 垂直居中 */
}
.main {
width: 1440px;
height: 714px;
margin: 0 auto;
}
.box {
width: 48%;
height: 55vh;
width: 712px;
height: 656px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 10px;
background: rgba(255, 255, 255, 0.8);
padding: 1vw;
.box-header {
height: 4vh;
display: flex;
text-align: left;
font-size: 24px;
font-weight: 700;
align-items: center;
.box-header-img {
height: 24px;
width: 24px;
margin: 0 5px;
}
}
.title-blob {
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.tag {
margin: 2px;
padding: 2px 8px 2px 8px;
border-radius: 4px;
background: rgba(223, 226, 231, 0.41);
color: rgba(132, 136, 142, 1);
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
}
.box-header {
height: 56px;
display: flex;
text-align: left;
font-size: 24px;
font-weight: 700;
align-items: center;
}
.box-header-img {
height: 24px;
width: 24px;
margin: 0 5px;
}
.title-blob {
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.tag {
margin: 2px;
padding: 2px 8px 2px 8px;
border-radius: 4px;
background: rgba(223, 226, 231, 0.41);
color: rgba(132, 136, 142, 1);
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.content {
......@@ -119,6 +175,7 @@
letter-spacing: 0px;
text-align: left;
}
.divider {
width: 100%;
height: 1px;
......@@ -133,3 +190,16 @@
height: 2.7vh;
margin: 1vh 0;
}
:deep(.el-input__wrapper) {
box-shadow: none;
border-radius: 10px;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
:deep(.el-input__wrapper.is-focus) {
box-shadow: none !important;
}
\ No newline at end of file
......@@ -46,7 +46,7 @@
<div class="icon">
<img src="./images/btn-icon2.png" alt="" />
</div>
<div class="text">{{ "报告原文" }}</div>
<div class="text" @click="toReport()">{{ "报告原文" }}</div>
</div>
<div class="btn">
<div class="icon">
......@@ -71,16 +71,41 @@
</template>
<script setup>
import { ref } from "vue";
import { ref, onMounted } from "vue";
import ReportAnalysis from './reportAnalysis/index.vue'
import PolicyTracking from './policyTracking/index.vue'
import {
getThinkTankReportSummary
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
const reportUrl = ref('')
// 获取报告全局信息
const handleGetThinkTankReportSummary = async () => {
try {
const res = await getThinkTankReportSummary(router.currentRoute._value.params.id);
console.log("报告全局信息", res);
if (res.code === 200 && res.data) {
reportUrl.value = res.data.reportUrl
}
} catch (error) {
console.error("获取报告全局信息error", error);
}
};
const toReport = () => {
window.open(reportUrl.value, "_blank");
}
const tabActiveName = ref("报告分析");
const switchTab = name => {
tabActiveName.value = name;
};
onMounted(async () => {
handleGetThinkTankReportSummary()
});
</script>
<style lang="scss" scoped>
......
......@@ -39,13 +39,8 @@
</div>
<div class="box2-main">
<div class="box2-main-tag-box">
<div
class="tag"
:class="{ tagActive: activeArea === item }"
v-for="(item, index) in areaList"
:key="index"
@click="handleClickArea(item.status)"
>
<div class="tag" :class="{ tagActive: activeArea === item }" v-for="(item, index) in areaList" :key="index"
@click="handleClickArea(item.status)">
{{ item.industryName }}
</div>
</div>
......@@ -79,7 +74,7 @@
<div class="box3-main-main">
<div class="box3-item" v-for="(item, index) in majorOpinions" :key="index">
<div class="left">
{{ item.id }}
{{ index + 1 }}
</div>
<div class="center">
<div class="title">{{ item.content }}</div>
......@@ -101,14 +96,8 @@
<div class="box3-main-footer">
<div class="info">{{ total }}项调查</div>
<div class="page-box">
<el-pagination
:page-size="12"
background
layout="prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="currentPage"
/>
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
......
......@@ -12,13 +12,8 @@
<div class="box-main">
<div class="select-box">
<el-select v-model="box1SelectYear" placeholder="选择时间" style="width: 100px">
<el-option
v-for="(item, index) in box1YearList"
:key="index"
:label="item.label"
:value="item.value"
@click="handleGetThinkPolicyIndustry()"
/>
<el-option v-for="(item, index) in box1YearList" :key="index" :label="item.label" :value="item.value"
@click="handleGetThinkPolicyIndustry()" />
</el-select>
</div>
<div id="box1Chart"></div>
......@@ -35,26 +30,16 @@
<div class="box-main">
<div class="select-box">
<el-select v-model="box2SelectYear" placeholder="选择时间" style="width: 100px">
<el-option
v-for="item in box2YearList"
:key="item.value"
:label="item.label"
:value="item.value"
@click="handleGetThinkPolicyIndustryTotal()"
/>
<el-option v-for="item in box2YearList" :key="item.value" :label="item.label" :value="item.value"
@click="handleGetThinkPolicyIndustryTotal()" />
</el-select>
</div>
<div id="box2Chart">
<div class="box2-item" v-for="(item, index) in box2Data" :key="index">
<div class="icon" :style="{ background: item.color }"></div>
<div class="name">{{ item.industry }}</div>
<el-progress
:show-text="false"
:color="box2ColorList[index]"
style="width: 170px"
stroke-width="8"
:percentage="item.percent"
/>
<el-progress :show-text="false" :color="box2ColorList[index]" style="width: 170px" stroke-width="8"
:percentage="item.percent" />
<div class="num">{{ item.amount + "项" }} / {{ item.totalAmount + "项" }}</div>
<div class="per">{{ item.percent + "%" }}</div>
</div>
......@@ -75,13 +60,8 @@
<div class="box-main">
<div class="select-box">
<el-select v-model="box3SelectYear" placeholder="选择时间" style="width: 100px">
<el-option
v-for="item in box3YearList"
:key="item.value"
:label="item.label"
:value="item.value"
@click="handleGetThinkPolicyIndustryChange()"
/>
<el-option v-for="item in box3YearList" :key="item.value" :label="item.label" :value="item.value"
@click="handleGetThinkPolicyIndustryChange()" />
</el-select>
</div>
<div id="box3Chart"></div>
......@@ -119,14 +99,8 @@
class="filter-checkbox">
{{ item }}
</el-checkbox> -->
<el-checkbox
style="width: 180px"
v-for="research in areaList"
:key="research.id"
v-model="selectedAreaList"
:label="research.id"
class="filter-checkbox"
>
<el-checkbox style="width: 180px" v-for="research in areaList" :key="research.id"
v-model="selectedAreaList" :label="research.id" class="filter-checkbox">
{{ research.name }}
</el-checkbox>
</div>
......@@ -140,8 +114,8 @@
<img :src="item.imageUrl" alt="" />
</div>
<div class="item-right">
<div class="title">{{ item.name }}</div>
<div class="info">{{ item.times }} · {{ item.content }}</div>
<div class="title">{{ item.content }}</div>
<div class="info">{{ item.times }} · {{ item.name }}</div>
<div class="tag-box">
<div class="tag" v-for="(tag, idx) in item.tagList" :key="idx">
{{ tag }}
......@@ -169,14 +143,8 @@
<div class="right-footer">
<div class="info">{{ total }}项调查</div>
<div class="page-box">
<el-pagination
:page-size="12"
background
layout="prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="currentPage"
/>
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
......@@ -797,6 +765,7 @@ onMounted(() => {
.select-box {
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
......
......@@ -69,7 +69,7 @@
<img :src="item.logo" alt="" />
</div>
<div class="rank" :class="{ rank1: item.rank === 1, rank2: item.rank === 2, rank3: item.rank === 3 }">
{{ "No." + item.rank }}
{{ "No." + (index + 1) }}
</div>
</div>
<div class="card-title">
......@@ -673,21 +673,21 @@ const messageList = ref([
// 政策建议趋势分布
const box5Data = ref({
title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
data: [
{
name: "人工智能",
value: [73, 32, 42, 48, 38, 49, 63, 75, 70, 86, 95, 87]
},
{
name: "集成电路",
value: [8, 3, 2, 8, 9, 10, 12, 18, 16, 18, 20, 22]
},
{
name: "量子科技",
value: [1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3]
}
]
// title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
// data: [
// {
// name: "人工智能",
// value: [73, 32, 42, 48, 38, 49, 63, 75, 70, 86, 95, 87]
// },
// {
// name: "集成电路",
// value: [8, 3, 2, 8, 9, 10, 12, 18, 16, 18, 20, 22]
// },
// {
// name: "量子科技",
// value: [1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3]
// }
// ]
});
//获取当前时间x年前的日期
......@@ -723,12 +723,45 @@ function changeBox5Data(value) {
}
// 政策建议趋势分布
const handleGetThinkTankPolicyIndustryChange = async date => {
try {
const res = await getThinkTankPolicyIndustryChange(date);
console.log("政策建议趋势分布", res);
if (res.code === 200 && res.data) {
const originalData = res.data
// 提取年份
const years = originalData.map(item => item.year);
// 提取所有行业名称
const industries = new Set();
originalData.forEach(item => {
item.industryList.forEach(industry => {
industries.add(industry.industry);
});
});
// 初始化目标数据结构
const result = {
title: years,
data: []
};
// 遍历每个行业,生成对应的 value 数组
industries.forEach(industry => {
const industryData = {
name: industry,
value: []
};
originalData.forEach(yearData => {
const amount = yearData.industryList.find(i => i.industry === industry)?.amount || 0;
industryData.value.push(amount);
});
result.data.push(industryData);
});
box5Data.value = result;
console.log(box5Data.value, 'console.log(box5Data.value)console.log(box5Data.value)')
} else {
box5Data.value = [];
box5Data.value = []
}
} catch (error) {
console.error("获取政策建议趋势分布error", error);
......@@ -736,12 +769,11 @@ const handleGetThinkTankPolicyIndustryChange = async date => {
};
const handleBox5 = async date => {
await handleGetThinkTankPolicyIndustryChange(date);
let box5Chart = getMultiLineChart(
box5Data.value.title,
box5Data.value.data[0].value,
box5Data.value.data[1].value,
box5Data.value.data[2].value
);
console.log(box5Data.value, 'console.log(box5Data.value)console.log(box5Data.value)')
let box5Chart = box5Data.value ? getMultiLineChart(
box5Data.value
) : ''
setChart(box5Chart, "box5Chart");
};
......@@ -812,6 +844,13 @@ const handleGetThinkTankPolicyIndustry = async () => {
const res = await getThinkTankPolicyIndustry(params);
console.log("政策建议领域分布", res);
if (res.code === 200 && res.data) {
box6Data.value = res.data.map((item, index) => ({
name: item.industry,
value: item.amount,
color: colors[index % colors.length] // 循环使用颜色数组
}));
} else {
box6Data.value = [];
}
......
import * as echarts from 'echarts'
import * as echarts from 'echarts';
const getMultiLineChart = (data) => {
// 提取标题和系列数据
// const { title, series } = data;
const title = data.title
const series = data.data
// 动态生成 series 配置
const echartsSeries = series.map((item, index) => ({
name: item.name,
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: item.color || `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.7)` // 随机颜色
},
{
offset: 1,
color: item.color ? `${item.color.replace('0.7', '0')}` : `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0)` // 随机颜色
}
])
},
emphasis: {
focus: 'series'
},
data: item.value
}));
const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
return {
tooltip: {
trigger: 'axis',
......@@ -21,14 +48,14 @@ const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
legend: {
show: true,
top: 10,
left:'center'
left: 'center'
},
color: ['rgba(10, 87, 166, 0.7)', 'rgba(255, 172, 77, 0.7)','rgba(114, 46, 209, 0.7)'],
color: series.map(item => item.color || `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.7)`), // 动态颜色
xAxis: [
{
type: 'category',
boundaryGap: false,
data: dataX
data: title
}
],
yAxis: [
......@@ -36,61 +63,8 @@ const getMultiLineChart = (dataX, dataY1, dataY2, dataY3) => {
type: 'value'
}
],
series: [
{
name: '人工智能',
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(10, 87, 166, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(10, 87, 166, 0)' // 结束颜色
}])
},
emphasis: {
focus: 'series'
},
data: dataY1
},
{
name: '集成电路',
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(255, 172, 77, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(255, 172, 77, 0)' // 结束颜色
}])
},
emphasis: {
focus: 'series'
},
data: dataY2
},
{
name: '量子科技',
type: 'line',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(114, 46, 209, 0.7)' // 起始颜色
}, {
offset: 1,
color: 'rgba(114, 46, 209, 0)' // 结束颜色
}])
},
emphasis: {
focus: 'series'
},
data: dataY3
}
]
}
}
series: echartsSeries
};
};
export default getMultiLineChart
\ No newline at end of file
export default getMultiLineChart;
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论