提交 4adce9b7 authored 作者: huhuiqing's avatar huhuiqing

Merge branch 'master' of http://8.140.26.4:10003/caijian/risk-monitor into dev_hhq

# Conflicts: # src/views/companyPages/component/Capability.vue # src/views/thinkTank/index.vue
import request from "@/api/request.js";
// 头部信息
/**
* @param { id }
*/
export function getGovOrgBasicInfo(params) {
return request({
method: 'GET',
url: `/api/governmentOrg/info/${params.id}`,
params
})
}
// 最新动态
/**
* @param { orgId, cRelated, currentPage, pageSize }
*/
export function getGovOrgLatestDynamics(params) {
return request({
method: 'GET',
url: `/api/governmentOrg/dynamics/${params.orgId}`,
params
})
}
// 基本信息-关键人物
/**
* @param { orgId }
*/
export function getGovOrgKeyPerson(params) {
return request({
method: 'GET',
url: `/api/governmentOrg/person/${params.orgId}`,
params
})
}
// 深度挖掘--------------------------------------------------
// 资助企业情况
/**
* @param { orgId }
*/
export function getGovOrgCompanyArea(params) {
return request({
method: 'GET',
url: `/api/governmentOrg/field/${params.orgId}`,
params
})
}
// 主要科技政策观点
/**
* @param { orgId }
*/
export function getGovOrgOpinions(params) {
return request({
method: 'GET',
url: `/api/governmentOrg/keyWord/${params.orgId}`,
params
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 今日要闻
export function getTodayNew() {
return request({
method: 'GET',
url: `/api/news/latestNews`,
})
}
// 今日要闻-带参
/**
* @param {industryId}
*/
export function getTodayNewByArea(params) {
return request({
method: 'GET',
url: `/api/news/latestNews`,
params
})
}
// 中美博弈专题
export function getHotNews() {
return request({
method: 'GET',
url: `/api/news/hotNews`,
})
}
// 今日要闻-带参
/**
* @param {industryId}
*/
export function getHotNewsByArea(params) {
return request({
method: 'GET',
url: `/api/news/hotNews`,
params
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 全局信息
/**
* @param {newsId}
*/
export function getNewsSummary(params) {
return request({
method: 'GET',
url: `/api/news/summary/${params.newsId}`,
params
})
}
// 新闻内容
/**
* @param {newsId}
*/
export function getNewsContent(params) {
return request({
method: 'GET',
url: `/api/news/newsContent/${params.newsId}`,
params
})
}
// 事件脉络
/**
* @param {newsId}
*/
export function getNewsEvent(params) {
return request({
method: 'GET',
url: `/api/news/newsEvent/${params.newsId}`,
params
})
}
// 相关新闻
/**
* @param {newsId}
*/
export function getRelationNews(params) {
return request({
method: 'GET',
url: `/api/news/relationNews/${params.newsId}`,
params
})
}
\ No newline at end of file
...@@ -266,7 +266,7 @@ ...@@ -266,7 +266,7 @@
class="box3-item" class="box3-item"
v-for="(news, index) in newsList" v-for="(news, index) in newsList"
:key="index" :key="index"
@click="handleClickToNewsDetail()" @click="handleClickToNewsDetail(news)"
> >
<div class="left"> <div class="left">
<img :src="getProxyUrl(news.newsImage) || News1" alt="" referrerpolicy="no-referrer" @error="e => e.target.src = News1" /> <img :src="getProxyUrl(news.newsImage) || News1" alt="" referrerpolicy="no-referrer" @error="e => e.target.src = News1" />
...@@ -884,9 +884,16 @@ const handleToMoreRiskSignal = () => { ...@@ -884,9 +884,16 @@ const handleToMoreRiskSignal = () => {
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
// 跳转新闻详情页 // 跳转新闻详情页
const handleClickToNewsDetail = () => { const handleClickToNewsDetail = (news) => {
// window.sessionStorage.setItem("newsId", "119_HR_1"); // window.sessionStorage.setItem("newsId", "119_HR_1");
const route = router.resolve("/newsAnalysis"); const route = router.resolve(
{
path: "/newsAnalysis",
query: {
newsId: news.newsId
}
}
);
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
......
<template> <template>
<div class="box-content"> <div class="box-content">
<div class="tab-box"> <div class="tab-box">
<div v-for="(tab, index) in tabList" :key="index" :class="activeTab === tab ? 'tab-active' : 'tab'"
<div v-for="(tab, index) in tabList" :class="activeTab === tab ? 'tab-active' : 'tab'"
@click="changeTab(tab, index)"> @click="changeTab(tab, index)">
{{ tab }} {{ tab }}
<div class="arrow-active"> <div class="arrow-active" v-show="activeTab === tab"></div>
</div>
</div> </div>
</div> </div>
<!--/*头部总览 */--> <!--/*头部总览 */-->
<div class="total"> <div class="total">
<div v-for="(item) in totalData[activeIndex]" class="total-box"> <div v-for="(item, index) in totalData[activeIndex]" :key="index" class="total-box">
<div class="line"> <div class="line"></div>
</div>
<div class="total-label"> <div class="total-label">
{{ item.label }} {{ item.label }}
</div> </div>
...@@ -28,123 +22,130 @@ ...@@ -28,123 +22,130 @@
{{ item.unit }} {{ item.unit }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!--/*图表 */--> <!--/*图表 */-->
<div class="chart"> <div class="chart">
<div class="chart-content"> <div class="chart-content">
<div class="section-header" style=" margin-top: 24px;"> <div class="section-header" style="margin-top: 24px">
<div style="display: flex;"> <div style="display: flex">
<div class="section-icon"></div> <div class="section-icon"></div>
<h3 class="section-title"> {{ activeTab === '研发投入' ? '年度研发投入对比' : activeTab === '研究人员' ? '研究人员数量增长趋势' : <h3 class="section-title">
'专利地域分布' }}</h3> {{
activeTab === "研发投入"
? "年度研发投入对比"
: activeTab === "研究人员"
? "研究人员数量增长趋势"
: "专利地域分布"
}}
</h3>
</div> </div>
<div class="action-icons"> <div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon"> <img src="@/assets/icons/download.png" alt="下载" class="action-icon" />
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon"> <img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon" />
</div> </div>
</div> </div>
<div id="chart1" class="chart-box" v-show="activeTab === '研发投入'"> <div id="chart1" class="chart-box" v-show="activeTab === '研发投入'"></div>
</div> <div id="chart3" class="chart-box" v-show="activeTab === '研究人员'"></div>
<div id="chart3" class="chart-box" v-show="activeTab === '研究人员'"> <div id="chart5" class="chart-box" v-show="activeTab === '专利情况'"></div>
</div>
<div id="chart5" class="chart-box" v-show="activeTab === '专利情况'">
</div>
<div class="chart-text"> <div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px;height: 20px;"> <img src="@/assets/icons/model.png" style="width: 19px; height: 20px" />
<div> <div>
近五年来,华为的研发投入在绝对金额和投入强度上均持续攀升。尤其是在收入因外部制裁而经历波动时,研发投入依然保持强劲增长,使其投入强度达到了历史高位。 近五年来,华为的研发投入在绝对金额和投入强度上均持续攀升。尤其是在收入因外部制裁而经历波动时,研发投入依然保持强劲增长,使其投入强度达到了历史高位。
</div> </div>
<div class="arrow-2"> <div class="arrow-2"></div>
</div>
</div> </div>
</div> </div>
<div class="chart-content"> <div class="chart-content">
<div class="section-header" style=" margin-top: 24px;"> <div class="section-header" style="margin-top: 24px">
<div style="display: flex;"> <div style="display: flex">
<div class="section-icon"></div> <div class="section-icon"></div>
<h3 class="section-title"> {{ activeTab === '研发投入' ? '研发投入增长对比' : activeTab === '研究人员' ? '研究人员学历分布' : <h3 class="section-title">
'专利技术领域分布' }}</h3> {{
activeTab === "研发投入"
? "研发投入增长对比"
: activeTab === "研究人员"
? "研究人员学历分布"
: "专利技术领域分布"
}}
</h3>
</div> </div>
<div class="action-icons"> <div class="action-icons">
<img src="@/assets/icons/download.png" alt="下载" class="action-icon"> <img src="@/assets/icons/download.png" alt="下载" class="action-icon" />
<img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon"> <img src="@/assets/icons/shoucang.png" alt="收藏" class="action-icon" />
</div> </div>
</div> </div>
<div id="chart2" class="chart-box" v-show="activeTab === '研发投入'"> <div id="chart2" class="chart-box" v-show="activeTab === '研发投入'"></div>
</div> <div id="chart4" class="chart-box" v-show="activeTab === '研究人员'"></div>
<div id="chart4" class="chart-box" v-show="activeTab === '研究人员'"> <div id="chart6" class="chart-box" v-show="activeTab === '专利情况'"></div>
</div>
<div id="chart6" class="chart-box" v-show="activeTab === '专利情况'">
</div>
<div class="chart-text"> <div class="chart-text">
<img src="@/assets/icons/model.png" style="width: 19px;height: 20px;"> <img src="@/assets/icons/model.png" style="width: 19px; height: 20px" />
<div> <div>
华为在巨大的外部压力下,研发投入不仅在绝对金额上持续增长,其占收入的比重更是大幅提升,特别是2021年后形成的“剪刀差”,体现了公司最高优先级的战略抉择。 </div> 华为在巨大的外部压力下,研发投入不仅在绝对金额上持续增长,其占收入的比重更是大幅提升,特别是2021年后形成的“剪刀差”,体现了公司最高优先级的战略抉择。
<div class="arrow-2">
</div> </div>
<div class="arrow-2"></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, onMounted, nextTick } from 'vue' import { ref, onMounted, nextTick } from 'vue'
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import getBarChart from "../js/barChart.js"; 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 getLineChart from "../js/lineChart.js";
import getRadarChart from '../js/radarChart.js' import getRadarChart from "../js/radarChart.js";
import * as echarts from "echarts"; import * as echarts from "echarts";
import { getEnterpriseStudy, getEnterpriseGrowth, getEnterpriseResearcherNum, getEnterpriseResearcherDegree, getEnterprisePatentRegion, getEnterprisPatentField } from "@/api/companyPages/index.js"; import { getEnterpriseStudy, getEnterpriseGrowth, getEnterpriseResearcherNum, getEnterpriseResearcherDegree, getEnterprisePatentRegion, getEnterprisPatentField } from "@/api/companyPages/index.js";
const router = useRouter(); const router = useRouter();
const tabList = ref(['研发投入', '研究人员', '专利情况']) const tabList = ref(["研发投入", "研究人员", "专利情况"]);
const activeTab = ref('研发投入') const activeTab = ref("研发投入");
const activeIndex = ref(0) const activeIndex = ref(0);
const totalData = ref([[ const totalData = ref([
{ [
"label": "累计研发投入", {
"value": 9854, label: "累计研发投入",
"unit": "亿元" value: 9854,
}, unit: "亿元"
{ },
"label": "年度研发投入", {
"value": 2153.9, label: "年度研发投入",
"unit": "亿元" value: 2153.9,
}, unit: "亿元"
{ },
"label": "研发强度", {
"value": 22.9, label: "研发强度",
"unit": "%" value: 22.9,
}, unit: "%"
{ },
"label": "研发投入排名", {
"value": "Top", label: "研发投入排名",
"unit": "" value: "Top",
} unit: ""
], [ }
{ label: '2025年拟招聘应届生', value: 11.4, unit: '万' }, ],
{ label: '研发人员占比', value: 55.4, unit: '%' }, [
{ label: '全年计划培养实习生', value: 1, unit: '万+' }, { label: "2025年拟招聘应届生", value: 11.4, unit: "万" },
{ label: '研发人员总数', value: 5000, unit: '+' } { label: "研发人员占比", value: 55.4, unit: "%" },
], [ { label: "全年计划培养实习生", value: 1, unit: "万+" },
{ label: '全球有效专利', value: 12, unit: '万+' }, { label: "研发人员总数", value: 5000, unit: "+" }
{ label: 'PCT申请量排名', value: 'Top', unit: '5' }, ],
{ label: '5G标准必要专利占比', value: 21.5, unit: '%' }, [
{ label: '家族专利', value: 4500, unit: '+' } { label: "全球有效专利", value: 12, unit: "万+" },
]]) { label: "PCT申请量排名", value: "Top", unit: "5" },
{ label: "5G标准必要专利占比", value: 21.5, unit: "%" },
{ label: "家族专利", value: 4500, unit: "+" }
]
]);
//年度研发投入对比 //年度研发投入对比
const chart1Data = ref({ const chart1Data = ref({
name: ['2020', '2021', '2022', '2023', '2024', '2025'], name: ["2020", "2021", "2022", "2023", "2024", "2025"],
value: [50, 100, 150, 200, 250, 300, 350, 400] value: [50, 100, 150, 200, 250, 300, 350, 400]
}); });
const handleGetEnterpriseStudy = async () => { const handleGetEnterpriseStudy = async () => {
...@@ -239,9 +240,9 @@ const handleGetEnterpriseResearcherNum = async () => { ...@@ -239,9 +240,9 @@ const handleGetEnterpriseResearcherNum = async () => {
// 学历分布数据 // 学历分布数据
const chart4Data = ref({ const chart4Data = ref({
name: ['博士', '硕士', '学士', '其他'], name: ["博士", "硕士", "学士", "其他"],
value: [28, 36, 22, 8], value: [28, 36, 22, 8]
}) });
const handleGetEnterpriseResearcherDegree = async () => { const handleGetEnterpriseResearcherDegree = async () => {
try { try {
...@@ -354,33 +355,28 @@ const setChart = (option, chartId) => { ...@@ -354,33 +355,28 @@ const setChart = (option, chartId) => {
return chart; return chart;
}; };
function char5() { function char5() {
console.log(chart5Data.value) console.log(chart5Data.value);
let char5 = getDonutChart(chart5Data.value.name, chart5Data.value.value, true); let char5 = getDonutChart(chart5Data.value.name, chart5Data.value.value, true);
setChart(char5, "chart5"); setChart(char5, "chart5");
} }
function chart6() { function chart6() {
let char6 = getRadarChart(); let char6 = getRadarChart();
setChart(char6, "chart6"); setChart(char6, "chart6");
} }
onMounted(() => { onMounted(() => {
handleGetEnterpriseStudy() handleGetEnterpriseStudy()
handleGetEnterpriseGrowth() handleGetEnterpriseGrowth()
}); });
</script> </script>
<style scoped> <style lang="scss" scoped>
.box-content { .box-content {
width: 100%; width: 100%;
height: calc(100vh - 220px); height: calc(100vh - 220px);
overflow: auto; overflow: auto;
} }
.tab-box { .tab-box {
...@@ -388,8 +384,7 @@ onMounted(() => { ...@@ -388,8 +384,7 @@ onMounted(() => {
width: 112px; width: 112px;
height: 128px; height: 128px;
position: absolute; position: absolute;
left: 0; left: 24px;
margin: 20px;
/* 自动布局 */ /* 自动布局 */
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -399,6 +394,7 @@ onMounted(() => { ...@@ -399,6 +394,7 @@ onMounted(() => {
.tab { .tab {
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
width: 104px;
height: 48px; height: 48px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
...@@ -406,7 +402,9 @@ onMounted(() => { ...@@ -406,7 +402,9 @@ onMounted(() => {
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
border-bottom: 0px solid rgba(5, 95, 194, 1); border-bottom: 0px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0; font-family: Microsoft YaHei;
cursor: pointer;
margin-bottom: 16px;
} }
.tab-active { .tab-active {
...@@ -416,25 +414,33 @@ onMounted(() => { ...@@ -416,25 +414,33 @@ onMounted(() => {
display: flex; display: flex;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
border-bottom: 2px solid rgba(5, 95, 194, 1);
margin: 6px 30px 0 0;
border-radius: 16px; border-radius: 16px;
background: rgba(5, 95, 194, 1); background: rgba(5, 95, 194, 1);
color: rgba(255, 255, 255, 1); color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
letter-spacing: 0px; letter-spacing: 0px;
text-align: left;
padding: 4px 12px; padding: 4px 12px;
position: relative;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
cursor: pointer;
margin-bottom: 16px;
} }
.arrow-active { .arrow-active {
position: absolute;
top: 12px;
right: 8px;
width: 0; width: 0;
height: 0; height: 0;
border-style: solid; border-style: solid;
border-width: 4px 0 4px 6px; border-width: 4px 0 4px 6px;
margin-left: 5px; // margin-left: 5px;
/* 上 右 下 左 */ /* 上 右 下 左 */
border-color: transparent transparent transparent #ffffff; border-color: transparent transparent transparent #ffffff;
/* 只给左边上色 */ /* 只给左边上色 */
...@@ -448,7 +454,6 @@ onMounted(() => { ...@@ -448,7 +454,6 @@ onMounted(() => {
height: 80px; height: 80px;
display: flex; display: flex;
gap: 16px; gap: 16px;
} }
.total-box { .total-box {
...@@ -482,8 +487,6 @@ onMounted(() => { ...@@ -482,8 +487,6 @@ onMounted(() => {
color: rgba(5, 95, 194, 1); color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
letter-spacing: 0px; letter-spacing: 0px;
text-align: right; text-align: right;
...@@ -519,7 +522,6 @@ onMounted(() => { ...@@ -519,7 +522,6 @@ onMounted(() => {
display: flex; display: flex;
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;
} }
.section-icon { .section-icon {
...@@ -528,7 +530,6 @@ onMounted(() => { ...@@ -528,7 +530,6 @@ onMounted(() => {
border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0;
background: rgba(5, 95, 194, 1); background: rgba(5, 95, 194, 1);
margin-right: 17px; margin-right: 17px;
} }
.section-title { .section-title {
...@@ -560,7 +561,6 @@ onMounted(() => { ...@@ -560,7 +561,6 @@ onMounted(() => {
} }
.chart-box { .chart-box {
width: 100%; width: 100%;
height: calc(100% - 130px); height: calc(100% - 130px);
} }
......
...@@ -242,7 +242,7 @@ ...@@ -242,7 +242,7 @@
</div> </div>
</div> </div>
<div class="box3-main"> <div class="box3-main">
<div class="box3-item" v-for="(news, index) in newsList" :key="index" @click="handleToNewsAnalysis()"> <div class="box3-item" v-for="(news, index) in newsList" :key="index" @click="handleToNewsAnalysis(news)">
<div class="left"> <div class="left">
<img :src="news.img" alt="" /> <img :src="news.img" alt="" />
</div> </div>
...@@ -540,7 +540,12 @@ import Message3 from "./assets/images/message-icon3.png"; ...@@ -540,7 +540,12 @@ import Message3 from "./assets/images/message-icon3.png";
// 跳转行政机构主页 // 跳转行政机构主页
const handleToInstitution = item => { const handleToInstitution = item => {
const curRoute = router.resolve("/institution"); const curRoute = router.resolve({
path: "/institution",
query: {
id: item.id
}
});
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
...@@ -763,6 +768,7 @@ const handleGetNews = async () => { ...@@ -763,6 +768,7 @@ const handleGetNews = async () => {
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
newsList.value = res.data.map(item => { newsList.value = res.data.map(item => {
return { return {
newsId: item.newsId,
img: item.newsImage, img: item.newsImage,
title: item.newsTitle, title: item.newsTitle,
content: item.newsContent, content: item.newsContent,
...@@ -776,8 +782,15 @@ const handleGetNews = async () => { ...@@ -776,8 +782,15 @@ const handleGetNews = async () => {
}; };
handleGetNews(); handleGetNews();
// 点击新闻条目,跳转到新闻分析页 // 点击新闻条目,跳转到新闻分析页
const handleToNewsAnalysis = () => { const handleToNewsAnalysis = (news) => {
const route = router.resolve("/newsAnalysis"); const route = router.resolve(
{
path: "/newsAnalysis",
query: {
newsId: news.newsId
}
}
);
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
......
...@@ -6,7 +6,7 @@ const getBarChart = (nameList, valueList) => { ...@@ -6,7 +6,7 @@ const getBarChart = (nameList, valueList) => {
tooltip: {}, tooltip: {},
grid: { grid: {
top: '3%', top: '3%',
right: '7%', right: 40,
bottom: '1%', bottom: '1%',
left: '1%', left: '1%',
containLabel: true containLabel: true
...@@ -55,7 +55,7 @@ const getBarChart = (nameList, valueList) => { ...@@ -55,7 +55,7 @@ const getBarChart = (nameList, valueList) => {
barWidth: 8, barWidth: 8,
label: { label: {
show: true, show: true,
position: [355, 0], position: [330, 0],
formatter: function(params) { formatter: function(params) {
return params.value return params.value
} }
......
...@@ -115,15 +115,21 @@ ...@@ -115,15 +115,21 @@
<div class="box4-main-right-main"> <div class="box4-main-right-main">
<div class="box4-main-right-item"> <div class="box4-main-right-item">
<div class="icon"></div> <div class="icon"></div>
<div class="text">{{ '在2016年和2024年的总统竞选中,卢特尼克利用其在金融界的影响力,为特朗普筹集了数千万美元的竞选资金,并个人捐赠了1000万美元。' }}</div> <div class="text">
{{
"在2016年和2024年的总统竞选中,卢特尼克利用其在金融界的影响力,为特朗普筹集了数千万美元的竞选资金,并个人捐赠了1000万美元。"
}}
</div>
</div> </div>
<div class="box4-main-right-item"> <div class="box4-main-right-item">
<div class="icon"></div> <div class="icon"></div>
<div class="text">{{ '提名霍华德·卢特尼克担任商务部长,赋予其直接监督美国贸易代表办公室(USTR)的权力。' }}</div> <div class="text">
{{ "提名霍华德·卢特尼克担任商务部长,赋予其直接监督美国贸易代表办公室(USTR)的权力。" }}
</div>
</div> </div>
<div class="box4-main-right-item"> <div class="box4-main-right-item">
<div class="icon"></div> <div class="icon"></div>
<div class="text">{{ '在接受CBS News采访时强调,特朗普政府的政策“是美国历史上最重要的”。' }}</div> <div class="text">{{ "在接受CBS News采访时强调,特朗普政府的政策“是美国历史上最重要的”。" }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -146,12 +152,15 @@ ...@@ -146,12 +152,15 @@
<script setup> <script setup>
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { useRoute } from "vue-router";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import getSankeyChart from "./utils/sankey"; import getSankeyChart from "./utils/sankey";
import getPieChart from "./utils/piechart"; import getPieChart from "./utils/piechart";
import getWordCloudChart from "./utils/worldCloudChart"; import getWordCloudChart from "./utils/worldCloudChart";
import getGraphChart from "./utils/graph"; import getGraphChart from "./utils/graph";
import { getGovOrgCompanyArea, getGovOrgOpinions } from "@/api/institution/index";
import Img from "./assets/images/9.png"; import Img from "./assets/images/9.png";
import Img1 from "./assets/images/1.png"; import Img1 from "./assets/images/1.png";
import Img2 from "./assets/images/2.png"; import Img2 from "./assets/images/2.png";
...@@ -162,6 +171,8 @@ import Img6 from "./assets/images/6.png"; ...@@ -162,6 +171,8 @@ import Img6 from "./assets/images/6.png";
import Img7 from "./assets/images/7.png"; import Img7 from "./assets/images/7.png";
import Img8 from "./assets/images/8.png"; import Img8 from "./assets/images/8.png";
const route = useRoute()
const box1ChartData = ref({ const box1ChartData = ref({
nodes: [ nodes: [
{ {
...@@ -289,6 +300,7 @@ const box1ChartData = ref({ ...@@ -289,6 +300,7 @@ const box1ChartData = ref({
] ]
}); });
// 资助企业情况
const box2ChartData = ref([ const box2ChartData = ref([
{ {
name: "集成电路", name: "集成电路",
...@@ -323,6 +335,29 @@ const box2ChartData = ref([ ...@@ -323,6 +335,29 @@ const box2ChartData = ref([
value: 24 value: 24
} }
]); ]);
const handleGetCompanyArea = async () => {
const params = {
orgId: route.query.id
};
try {
const res = await getGovOrgCompanyArea(params);
console.log("资助企业情况", res);
if (res.code === 200 && res.data) {
box2ChartData.value = res.data.map(item => {
return {
name: item.industry,
value: item.amount
};
});
}
} catch (error) {}
};
const handleBox2 = async () => {
await handleGetCompanyArea();
const box2Chart = getPieChart(box2ChartData.value);
setChart(box2Chart, "box2Chart");
};
const box3ChartData = ref([ const box3ChartData = ref([
{ name: "人工智能(AI)", value: 100 }, { name: "人工智能(AI)", value: 100 },
...@@ -344,6 +379,20 @@ const box3ChartData = ref([ ...@@ -344,6 +379,20 @@ const box3ChartData = ref([
{ name: "不得向中国机构提供援助", value: 62 }, { name: "不得向中国机构提供援助", value: 62 },
{ name: "开展先进生物能源计划", value: 51 } { name: "开展先进生物能源计划", value: 51 }
]); ]);
const handleGetOpinions = async () => {
const params = {
orgId: '50754570da464d0a81a5563dcb61d2ec'
}
try {
const res = await getGovOrgOpinions(params)
console.log('主要科技政策观点', res);
} catch (error) {
}
}
const box4ChartData = ref({ const box4ChartData = ref({
nodes: [ nodes: [
...@@ -371,10 +420,10 @@ const box4ChartData = ref({ ...@@ -371,10 +420,10 @@ const box4ChartData = ref({
}); });
onMounted(() => { onMounted(() => {
handleBox2();
handleGetOpinions()
const box1Chart = getSankeyChart(box1ChartData.value.nodes, box1ChartData.value.links); const box1Chart = getSankeyChart(box1ChartData.value.nodes, box1ChartData.value.links);
setChart(box1Chart, "box1Chart"); setChart(box1Chart, "box1Chart");
const box2Chart = getPieChart(box2ChartData.value);
setChart(box2Chart, "box2Chart");
const box3Chart = getWordCloudChart(box3ChartData.value); const box3Chart = getWordCloudChart(box3ChartData.value);
setChart(box3Chart, "box3Chart"); setChart(box3Chart, "box3Chart");
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="wrap"> <div class="wrap">
<div class="header"> <div class="header">
<div class="header-left"> <div class="header-left">
<img src="@/assets/images/decree-org.png" alt="" /> <img :src="institutionInfo.logo?institutionInfo.logo: DefaultIcon2" alt="" />
</div> </div>
<div class="header-right"> <div class="header-right">
<div class="title">{{ institutionInfo.name }}</div> <div class="title">{{ institutionInfo.name }}</div>
...@@ -42,17 +42,45 @@ ...@@ -42,17 +42,45 @@
<script setup> <script setup>
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { useRoute } from "vue-router";
import InsDetail from "./insDetail/index.vue"; import InsDetail from "./insDetail/index.vue";
import Deepdig from "./deepdig/index.vue"; import Deepdig from "./deepdig/index.vue";
import Sanction from "./sanction/index.vue"; import Sanction from "./sanction/index.vue";
import {getGovOrgBasicInfo} from '@/api/institution/index'
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
const route = useRoute()
const institutionInfo = ref({ const institutionInfo = ref({
name: "美国商务部", name: "",
enName: "United States Department of Commerce", enName: "",
desc: "美国联邦政府的重要经济部门,主要职责为国际贸易、进出口管制、经济数据统计及专利商标管理。", desc: "",
tagList: ["实体清单", "232调查", "行政令"] tagList: [],
logo: ''
}); });
const handleGetInfo = async () => {
const params = {
id: route.query.id
}
try {
const res = await getGovOrgBasicInfo(params)
console.log('机构信息', res);
if(res.code === 200 && res.data) {
institutionInfo.value.name = res.data.orgName
institutionInfo.value.enName = res.data.orgNameEn
institutionInfo.value.desc = res.data.orgIntroduction
institutionInfo.value.name = res.data.orgName
}
} catch (error) {
}
}
handleGetInfo()
const activeTabName = ref("机构详情"); const activeTabName = ref("机构详情");
const tabList = ref([ const tabList = ref([
......
...@@ -4,6 +4,15 @@ ...@@ -4,6 +4,15 @@
<div class="box-header"> <div class="box-header">
<div class="header-left"></div> <div class="header-left"></div>
<div class="title">最新动态</div> <div class="title">最新动态</div>
<div class="check-box"><el-checkbox :checked="isCrelated" label="只看涉华动态" /></div>
<div class="header-btn-box">
<div class="btn" :class="{ btnActive: dynamicsName === '机构动态' }" @click="handleClickBtn('机构动态')">
{{ "机构动态" }}
</div>
<div class="btn" :class="{ btnActive: dynamicsName === '主官动态' }" @click="handleClickBtn('主官动态')">
{{ "主官动态" }}
</div>
</div>
<div class="header-right"> <div class="header-right">
<div class="icon"> <div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" /> <img src="@/assets/icons/box-header-icon2.png" alt="" />
...@@ -18,13 +27,14 @@ ...@@ -18,13 +27,14 @@
<div class="line" v-if="index !== curList.length - 1"></div> <div class="line" v-if="index !== curList.length - 1"></div>
<div class="time">{{ item.time }}</div> <div class="time">{{ item.time }}</div>
<div class="icon"> <div class="icon">
<img src="@/assets/images/decree-org.png" alt="" /> <img :src="item.logoUrl ? item.logoUrl : DefaultIcon2" alt="" />
</div> </div>
<div class="info"> <div class="info">
<div class="header"> <div class="header">
<div class="title">{{ item.title }}</div> <div class="title">{{ item.title }}</div>
<div <div
class="type" class="type"
v-if="item.type"
:class="{ :class="{
type1: item.type.status === 2, type1: item.type.status === 2,
type2: item.type.status === 3, type2: item.type.status === 3,
...@@ -36,17 +46,24 @@ ...@@ -36,17 +46,24 @@
</div> </div>
<div class="content">{{ item.content }}</div> <div class="content">{{ item.content }}</div>
<div class="tag-box"> <div class="tag-box">
<div class="tag" v-for="(val, idx) in item.tagList" :key="idx">{{ val }}</div> <div class="tag" v-for="(val, idx) in item.industryList" :key="idx">{{ val }}</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="left-footer"> <div class="left-footer">
<div class="info"> <div class="info">
{{ `共有153项动态` }} {{ `共有${totalNum}项动态` }}
</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"
@current-change="handleCurrentChange"
:pageSize="pageSize"
:current-page="currentPage"
:total="totalNum"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -94,9 +111,9 @@ ...@@ -94,9 +111,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 keyUser" :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>
...@@ -112,12 +129,17 @@ ...@@ -112,12 +129,17 @@
<script setup> <script setup>
import { ref, computed, onMounted } from "vue"; import { ref, computed, onMounted } from "vue";
import { useRoute } from "vue-router";
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";
import DefaultIcon2 from "@/assets/icons/default-icon2.png";
import { getGovOrgLatestDynamics, getGovOrgKeyPerson } from "@/api/institution/index";
const route = useRoute()
const basicInfo = ref({ const basicInfo = ref({
image: Img, image: Img,
...@@ -125,142 +147,190 @@ const basicInfo = ref({ ...@@ -125,142 +147,190 @@ const basicInfo = ref({
dizhi: "华盛顿特区宪法大道1401号赫伯特·C·胡佛大楼 ", dizhi: "华盛顿特区宪法大道1401号赫伯特·C·胡佛大楼 ",
zhize: "国际贸易、进出口管制、经济数据统计及专利商标管理", zhize: "国际贸易、进出口管制、经济数据统计及专利商标管理",
xiashujigou: "工业与安全局、国际贸易管理局、专利商标局等", xiashujigou: "工业与安全局、国际贸易管理局、专利商标局等",
zhicaishouduan: "实体清单、军事最终用户清单、​​“301条款”关税、​​“232条款”关税、特别指定国民清单", zhicaishouduan: "实体清单、军事最终用户清单、​​“301条款”关税、​​“232条款”关税、特别指定国民清单"
keyUser: [
{
name: "霍华德·卢特尼克",
img: User1,
position: "部长"
},
{
name: "保罗·达巴尔",
img: User2,
position: "副部长"
},
{
name: "杰弗里·凯斯勒",
img: User3,
position: "工业与安全局局长"
},
{
name: "约翰·斯奎尔斯",
img: User4,
position: "专利商标局局长"
}
]
}); });
const curList = ref([ // 关键人物
{ const keyUser = ref([
title: "美国商务部:宣布对华全面加征100%关税", // {
time: "2025 10月10日", // name: "霍华德·卢特尼克",
content: // avatarUrl: User1,
"特朗普宣布自11月1日起对所有中国进口商品加征100%额外关税,叠加现有关税后总水平可达130%或更高。同时宣布将对“所有关键美国制造软件”实施严格的出口管制。", // position: "部长"
type: { // },
name: "行政令", // {
status: 2 // name: "保罗·达巴尔",
}, // avatarUrl: User2,
tagList: ["人工智能"] // position: "副部长"
}, // },
{ // {
title: "美国商务部:BIS更新“实体清单”", // name: "杰弗里·凯斯勒",
time: "2025 10月4日", // avatarUrl: User3,
content: // position: "工业与安全局局长"
"美国商务部工业与安全局公布对中国半导体出口管制措施新规则,将140家中国半导体公司列入“实体清单”,分别是136家中国实体和4家海外关联企业。", // },
type: { // {
name: "实体清单", // name: "约翰·斯奎尔斯",
status: 4 // avatarUrl: User4,
}, // position: "专利商标局局长"
tagList: ["集成电路"] // }
},
{
title: "美国商务部:​出台“50%穿透规则”(关联方规则)",
time: "2025 9月29日",
content:
"规定凡被列入“实体清单”或“军事最终用户清单”的企业,其直接或间接持股超过50%的子公司将自动受到同等出口管制限制。此规则极大地扩大了制裁范围,且未设过渡期。",
type: {
name: "行政令",
status: 2
},
tagList: ["生物科技"]
},
{
title: "美国商务部:对华港口设备加征高额关税",
time: "2025 9月21日",
content:
"美国贸易代表办公室(USTR)公告,作为“301条款”行动的一部分,对特定中国制造的港口设备加征额外关税,其中船到岸起重机(STS)和集装箱底盘车及零部件均加征100%关税,于11月9日生效。",
type: {
name: "301调查",
status: 3
},
tagList: ["先进制造"]
},
{
title: "美国商务部:BIS更新“实体清单”",
time: "2025 9月15日",
content:
"美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。",
type: {
name: "实体清单",
status: 4
},
tagList: ["集成电路"]
},
{
title: "美国商务部:BIS更新“实体清单”",
time: "2025 9月15日",
content:
"美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。",
type: {
name: "实体清单",
status: 4
},
tagList: ["集成电路"]
},
{
title: "美国商务部:加强对华AI芯片出口限制",
time: "2025 9月10日",
content:
"美国政府要求英特尔、AMD、英伟达等公司对向中国出口的先进AI处理器实施严格的许可证制度。英特尔Gaudi系列芯片等因性能超标明确受限。同时,考虑对中国AI初创企业DeepSeek实施制裁。",
type: {
name: "行政令",
status: 2
},
tagList: ["人工智能", "集成电路"]
},
{
title: "美国商务部:BIS更新“实体清单”",
time: "2025 9月15日",
content:
"美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。",
type: {
name: "实体清单",
status: 4
},
tagList: ["集成电路"]
},
{
title: "美国商务部:​发布针对中国网联汽车的禁令",
time: "2025 8月25日",
content: "美国商务部工业与安全局(BIS)发布一项最终规则,禁止涉及销售或进口其认定软件与中国有关联的联网汽车的交易。",
type: {
name: "行政令",
status: 2
},
tagList: ["能源", "先进制造"]
},
{
title: "美国商务部:考虑对中国无人机实施新限制",
time: "2025 8月19日",
content:
"美国商务部表示正在考虑制定新规则,以限制或禁止中国无人机在美国境内使用,并就所谓“保护无人机供应链”的潜在规则征求公众意见。",
type: {
name: "行政令",
status: 2
},
tagList: ["先进制造"]
}
]); ]);
const handleGetKeyUser = async () => {
const params = {
orgId: route.query.id
};
try {
const res = await getGovOrgKeyPerson(params);
console.log("关键人物", res);
keyUser.value = res.data;
} catch (error) {}
};
handleGetKeyUser();
// const curList = ref([
// {
// title: "美国商务部:宣布对华全面加征100%关税",
// time: "2025 10月10日",
// content:
// "特朗普宣布自11月1日起对所有中国进口商品加征100%额外关税,叠加现有关税后总水平可达130%或更高。同时宣布将对“所有关键美国制造软件”实施严格的出口管制。",
// type: {
// name: "行政令",
// status: 2
// },
// tagList: ["人工智能"]
// },
// {
// title: "美国商务部:BIS更新“实体清单”",
// time: "2025 10月4日",
// content:
// "美国商务部工业与安全局公布对中国半导体出口管制措施新规则,将140家中国半导体公司列入“实体清单”,分别是136家中国实体和4家海外关联企业。",
// type: {
// name: "实体清单",
// status: 4
// },
// tagList: ["集成电路"]
// },
// {
// title: "美国商务部:​出台“50%穿透规则”(关联方规则)",
// time: "2025 9月29日",
// content:
// "规定凡被列入“实体清单”或“军事最终用户清单”的企业,其直接或间接持股超过50%的子公司将自动受到同等出口管制限制。此规则极大地扩大了制裁范围,且未设过渡期。",
// type: {
// name: "行政令",
// status: 2
// },
// tagList: ["生物科技"]
// },
// {
// title: "美国商务部:对华港口设备加征高额关税",
// time: "2025 9月21日",
// content:
// "美国贸易代表办公室(USTR)公告,作为“301条款”行动的一部分,对特定中国制造的港口设备加征额外关税,其中船到岸起重机(STS)和集装箱底盘车及零部件均加征100%关税,于11月9日生效。",
// type: {
// name: "301调查",
// status: 3
// },
// tagList: ["先进制造"]
// },
// {
// title: "美国商务部:BIS更新“实体清单”",
// time: "2025 9月15日",
// content:
// "美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。",
// type: {
// name: "实体清单",
// status: 4
// },
// tagList: ["集成电路"]
// },
// {
// title: "美国商务部:BIS更新“实体清单”",
// time: "2025 9月15日",
// content:
// "美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。",
// type: {
// name: "实体清单",
// status: 4
// },
// tagList: ["集成电路"]
// },
// {
// title: "美国商务部:加强对华AI芯片出口限制",
// time: "2025 9月10日",
// content:
// "美国政府要求英特尔、AMD、英伟达等公司对向中国出口的先进AI处理器实施严格的许可证制度。英特尔Gaudi系列芯片等因性能超标明确受限。同时,考虑对中国AI初创企业DeepSeek实施制裁。",
// type: {
// name: "行政令",
// status: 2
// },
// tagList: ["人工智能", "集成电路"]
// },
// {
// title: "美国商务部:BIS更新“实体清单”",
// time: "2025 9月15日",
// content:
// "美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。",
// type: {
// name: "实体清单",
// status: 4
// },
// tagList: ["集成电路"]
// },
// {
// title: "美国商务部:​发布针对中国网联汽车的禁令",
// time: "2025 8月25日",
// content: "美国商务部工业与安全局(BIS)发布一项最终规则,禁止涉及销售或进口其认定软件与中国有关联的联网汽车的交易。",
// type: {
// name: "行政令",
// status: 2
// },
// tagList: ["能源", "先进制造"]
// },
// {
// title: "美国商务部:考虑对中国无人机实施新限制",
// time: "2025 8月19日",
// content:
// "美国商务部表示正在考虑制定新规则,以限制或禁止中国无人机在美国境内使用,并就所谓“保护无人机供应链”的潜在规则征求公众意见。",
// type: {
// name: "行政令",
// status: 2
// },
// tagList: ["先进制造"]
// }
// ]);
const dynamicsName = ref("机构动态");
const isCrelated = ref(false);
const currentPage = ref(1);
const pageSize = ref(10);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
};
const latestDynamicsList = ref([]);
const totalNum = ref(0);
const curList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return latestDynamicsList.value.slice(startIndex, endIndex);
});
const handleClickBtn = name => {
dynamicsName.value = name;
};
const handleGetLatestDynamics = async () => {
const params = {
orgId: route.query.id,
cRelated: isCrelated.value ? "Y" : "N",
currentPage: 1,
pageSize: 9999999
};
try {
const res = await getGovOrgLatestDynamics(params);
console.log("最新动态", res);
if (res.code === 200 && res.data) {
latestDynamicsList.value = res.data.content;
totalNum.value = res.data.totalElements;
}
} catch (error) {}
};
handleGetLatestDynamics();
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -295,10 +365,15 @@ const curList = ref([ ...@@ -295,10 +365,15 @@ const curList = ref([
font-size: 18px; font-size: 18px;
font-weight: 700; font-weight: 700;
} }
.check-box {
position: absolute;
top: 15px;
right: 275px;
}
.header-btn-box { .header-btn-box {
position: absolute; position: absolute;
top: 14px; top: 14px;
right: 52px; right: 91px;
display: flex; display: flex;
.btn { .btn {
margin-left: 8px; margin-left: 8px;
...@@ -367,10 +442,11 @@ const curList = ref([ ...@@ -367,10 +442,11 @@ const curList = ref([
} }
.left { .left {
width: 1064px; width: 1064px;
height: 1683px; max-height: 1683px;
.left-main { .left-main {
border-top: 1px solid rgba(234, 236, 238, 1); border-top: 1px solid rgba(234, 236, 238, 1);
height: 1551px; max-height: 1551px;
min-height: 660px;
.left-main-item { .left-main-item {
display: flex; display: flex;
margin-top: 16px; margin-top: 16px;
...@@ -437,12 +513,19 @@ const curList = ref([ ...@@ -437,12 +513,19 @@ const curList = ref([
} }
} }
.content { .content {
height: 100px;
overflow: hidden;
margin-top: 8px; margin-top: 8px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 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;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4; /* 控制显示的行数 */
overflow: hidden;
text-overflow: ellipsis;
} }
.tag-box { .tag-box {
margin-top: 9px; margin-top: 9px;
...@@ -464,7 +547,8 @@ const curList = ref([ ...@@ -464,7 +547,8 @@ const curList = ref([
} }
} }
.left-footer { .left-footer {
height: 75px; margin-top: 10px;
height: 65px;
border-top: 1px solid rgba(234, 236, 238, 1); border-top: 1px solid rgba(234, 236, 238, 1);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
...@@ -530,19 +614,24 @@ const curList = ref([ ...@@ -530,19 +614,24 @@ const curList = ref([
text-align: left; text-align: left;
} }
.user-content { .user-content {
margin-top: 19px; height: 120px;
margin-top: 19px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 16px 39px; gap: 16px 20px;
justify-content: center; justify-content: flex-start;
overflow: hidden;
overflow-y: auto;
.user-item { .user-item {
width: 185px; width: 200px;
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;
border-radius: 24px;
overflow: hidden;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -550,6 +639,8 @@ const curList = ref([ ...@@ -550,6 +639,8 @@ const curList = ref([
} }
.user-item-right { .user-item-right {
.name { .name {
width: 142px;
height: 24px; height: 24px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -558,6 +649,9 @@ const curList = ref([ ...@@ -558,6 +649,9 @@ const curList = ref([
line-height: 24px; line-height: 24px;
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.position { .position {
height: 24px; height: 24px;
......
<template> <template>
<div class="header-btn" style="width: 100px;display: flex;" @click="back"> <div class="back-btn" @click="back">
<img :src="`src/assets/icons/arrow-left.png`" style="width: 24px;height: 24px;" /> 返回 <div class="icon">
</div> <img src="@/assets/icons/arrow-left.png" alt="" />
<div style="width: 100%;height: 100%;padding:0 20% "> </div>
<div> <div class="text">{{ "返回" }}</div>
<div class=" news-header" style="text-align: left;"> </div>
今日要闻 <div class="wrapper">
</div> <div>
<div class="content" style="margin-bottom: 20px;"> <div class="news-header" style="text-align: left">今日要闻</div>
基于情报价值评估预测算法,掌握全球重要潜在动向 <div class="news-desc" style="margin-bottom: 20px">基于情报价值评估预测算法,掌握全球重要潜在动向</div>
</div> </div>
<div class="main">
</div> <div class="main-header">
<div class="box" style="width: 100%;height: 90%;"> <div
<div class="box-header" style="height: 5vh;"> v-for="(item, index) in btnList"
<div style="display: flex; justify-content: center; "> :key="index"
<div v-for="item in btnList" :class="btnSelect !== item ? 'header-btn-gray' : 'header-btn-select'" class="header-btn"
@click="changeBtn(item)"> :class="{ headerBtnSelect: btnSelect === item }"
{{ item }} > @click="changeBtn(item)"
</div> >
{{ item }}
</div> </div>
</div> </div>
<div class="divider"></div> <div class="content-box">
<div v-for="item in HeadlinesData"> <div class="item" v-for="(item, index) in HeadlinesData" :key="index">
<div style="display: flex;"> <div class="item-left">
<div> <div class="title">{{ item.title }}</div>
<div class="title-blob"> <div class="content">
{{ item.title }} <div class="source">新闻来源: {{ item.from }}</div>
</div> <div class="time">发表时间:{{ item.time }}</div>
<div class="content"> </div>
新闻来源: {{ item.from }} 发表时间:{{ item.time }} <div class="tag-box">
</div> <div v-for="(tag, index) in item.tag" class="tag" :key="index">
<div style="display: flex;"> {{ tag }}
<div v-for="tag in item.tag" class="tag"> </div>
{{ tag }} </div>
</div> </div>
</div> <div class="item-right">
</div> <img :src="item.image" />
<div style="margin-left: auto;padding: 10px;"> </div>
<img :src="item.image" /> </div>
</div> </div>
</div> </div>
</div>
<div class="divider">
</div>
</div>
</div>
</div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import Index from "../innovationSubject/index.vue";
const btnList = ref(["全部", "军事", "政治", "经济", "敌我"]) const btnList = ref(["全部", "军事", "政治", "经济", "科技", "涉我"]);
const btnSelect = ref('新闻纵览') const btnSelect = ref("全部");
const HeadlinesData = ref([ const HeadlinesData = ref([
{ {
"title": "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”", title: "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”",
"from": "人民网", from: "人民网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["以色列", "美国"], tag: ["以色列", "美国"],
"image": '/testData/HeadlinesData-img.png', image: "/testData/HeadlinesData-img.png"
}, },
{ {
"title": "IMF上调中东和北非地区经济增长预期", title: "IMF上调中东和北非地区经济增长预期",
"from": "CNN", from: "CNN",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["经济", "中东", "IMF"], tag: ["经济", "中东", "IMF"],
"image": '/testData/HeadlinesData-img.png', image: "/testData/HeadlinesData-img.png"
}, },
{ {
"title": "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面", title: "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面",
"from": "人民网", from: "人民网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["日本", "访华"], "image": '/testData/HeadlinesData-img.png', tag: ["日本", "访华"],
}, image: "/testData/HeadlinesData-img.png"
{ },
"title": "韩日因独岛主权争议暂停本月联合搜救演习", {
"from": "凤凰网", title: "韩日因独岛主权争议暂停本月联合搜救演习",
"time": "2025-10-05", from: "凤凰网",
"tag": ["独岛", "联合军演", "韩国", "日本"], "image": '/testData/HeadlinesData-img.png', time: "2025-10-05",
}, tag: ["独岛", "联合军演", "韩国", "日本"],
{ image: "/testData/HeadlinesData-img.png"
"title": "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结", },
"from": "央视网", {
"time": "2025-10-05", title: "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结",
"tag": ["美国", "航母", "加勒比海"], "image": '/testData/HeadlinesData-img.png', from: "央视网",
} time: "2025-10-05",
]) tag: ["美国", "航母", "加勒比海"],
image: "/testData/HeadlinesData-img.png"
}
]);
function changeBtn(btn) { function changeBtn(btn) {
btnSelect.value = btn btnSelect.value = btn;
} }
const emit = defineEmits(["back"]); const emit = defineEmits(["back"]);
function back() { function back() {
emit('back', 'home') emit("back", "home");
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
@import url('./style.css'); // @import url("./style.css");
.newsBrief-page { .newsBrief-page {
max-width: 100vw; height: 100%;
height: 100%; background: url("@/assets/images/background.png") no-repeat;
overflow: hidden; background-position: center -100px;
margin: 0 auto; background-size: 100% 100%;
padding: 5vh 10vw 20vh 10vw; position: relative;
background: url('@/assets/images/background.png') no-repeat; .back-btn {
background-position: center -100px; position: absolute;
background-size: 100% 100%; top: 24px;
min-height: 100vh; left: 40px;
width: 92px;
height: 40px;
display: flex;
gap: 4px;
align-items: center;
justify-content: center;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 32px;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 10px 10px var(--color-bg-hover);
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: center;
}
}
.wrapper {
height: 930px;
position: relative;
.news-header {
margin-top: 80px;
margin-left: 484px;
height: 60px;
color: rgba(34, 41, 52, 1);
font-family: YouSheBiaoTiHei;
font-size: 46px;
font-weight: 400;
line-height: 60px;
letter-spacing: 0px;
text-align: left;
}
.news-desc {
margin-top: 2px;
margin-left: 484px;
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.main {
margin: 0 auto;
width: 1000px;
height: 778px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 10px;
background: rgba(255, 255, 255, 0.8);
.main-header {
height: 64px;
display: flex;
gap: 16px;
padding-top: 24px;
padding-left: 24px;
.header-btn {
height: 40px;
line-height: 40px;
padding: 0 20px;
border-radius: 32px;
background: rgba(32, 33, 35, 0.07);
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
letter-spacing: 0px;
text-align: center;
}
.headerBtnSelect {
box-sizing: border-box;
border: 1px solid rgba(174, 214, 255, 1);
border-radius: 32px;
background: rgba(231, 243, 255, 1);
color: var(--color-main-active);
}
}
.content-box {
margin: 0 auto;
width: 952px;
height: 674px;
overflow: hidden;
overflow-y: auto;
.item {
width: 952px;
height: 114px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding-top: 16px;
.item-left {
width: 710px;
.title {
height: 30px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.content {
margin-top: 2px;
display: flex;
gap: 16px;
height: 22px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.tag-box {
margin-top: 4px;
display: flex;
gap: 4px;
.tag {
height: 24px;
padding: 0 8px;
border-radius: 4px;
background: rgba(223, 226, 231, 0.41);
line-height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
}
}
}
}
}
}
}
} }
</style> </style>
<template> <template>
<div class="header-btn" style="width: 100px;display: flex;" @click="back"> <div class="back-btn" @click="back">
<img :src="`src/assets/icons/arrow-left.png`" style="width: 24px;height: 24px;" /> 返回 <div class="icon">
</div> <img src="@/assets/icons/arrow-left.png" alt="" />
<div style="width: 100%;height: 100%;padding:0 20% "> </div>
<div> <div class="text">{{ "返回" }}</div>
<div class=" news-header" style="text-align: left;"> </div>
中美博弈专题 <div class="wrapper">
</div> <div>
<div class="content" style="margin-bottom: 20px;"> <div class="news-header">中美博弈专题</div>
汇聚全球资讯,呈现全球动态,掌握时事脉搏 <div class="news-desc">汇聚全球资讯,呈现全球动态,掌握时事脉搏</div>
</div> </div>
<div class="main">
</div> <div class="main-header">
<div class="box" style="width: 100%;height: 90%;"> <div
<div class="box-header" style="height: 5vh;"> v-for="(item, index) in btnList"
<div style="display: flex; justify-content: center; "> :key="index"
<div v-for="item in btnList" :class="btnSelect !== item ? 'header-btn-gray' : 'header-btn-select'" class="header-btn"
@click="changeBtn(item)"> :class="{ headerBtnSelect: btnSelect === item }"
{{ item }} > @click="changeBtn(item)"
</div> >
{{ item }}
</div> </div>
</div> </div>
<div class="divider"></div> <div class="content-box">
<div v-for="item in HeadlinesData"> <div class="item" v-for="(item, index) in HeadlinesData" :key="index">
<div style="display: flex;"> <div class="item-left">
<div> <div class="title">{{ item.title }}</div>
<div class="title-blob"> <div class="content">
{{ item.title }} <div class="source">新闻来源: {{ item.from }}</div>
</div> <div class="time">发表时间:{{ item.time }}</div>
<div class="content"> </div>
新闻来源: {{ item.from }} 发表时间:{{ item.time }} <div class="tag-box">
</div> <div v-for="(tag, index) in item.tag" class="tag" :key="index">
<div style="display: flex;"> {{ tag }}
<div v-for="tag in item.tag" class="tag"> </div>
{{ tag }} </div>
</div> </div>
</div> <div class="item-right">
</div> <img :src="`src/assets/icons/arrow-${item.arrow}.png`" />
<div style="margin-left: auto;padding: 10px;"> </div>
<img :src="`src/assets/icons/arrow-${item.arrow}.png`" /> </div>
</div> </div>
</div> </div>
</div>
<div class="divider">
</div>
</div>
</div>
</div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
// const props = defineProps({ const btnList = ref(["全部", "军事", "政治", "经济", "敌我"]);
const btnSelect = ref("新闻纵览");
// type: {
// type: String,
// default: 'home'
// }
// })
const btnList = ref(["全部", "军事", "政治", "经济", "敌我"])
const btnSelect = ref('新闻纵览')
const HeadlinesData = ref([ const HeadlinesData = ref([
{ {
"title": "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”", title: "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”",
"from": "人民网", from: "人民网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["以色列", "美国"], tag: ["以色列", "美国"],
"arrow": '0', arrow: "0"
}, },
{ {
"title": "IMF上调中东和北非地区经济增长预期", title: "IMF上调中东和北非地区经济增长预期",
"from": "CNN", from: "CNN",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["经济", "中东", "IMF"], tag: ["经济", "中东", "IMF"],
"arrow": '1', arrow: "1"
}, },
{ {
"title": "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面", title: "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面",
"from": "人民网", from: "人民网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["日本", "访华"], tag: ["日本", "访华"],
"arrow": '1', arrow: "1"
}, },
{ {
"title": "韩日因独岛主权争议暂停本月联合搜救演习", title: "韩日因独岛主权争议暂停本月联合搜救演习",
"from": "凤凰网", from: "凤凰网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["独岛", "联合军演", "韩国", "日本"], tag: ["独岛", "联合军演", "韩国", "日本"],
"arrow": '0', arrow: "0"
}, },
{ {
"title": "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结", title: "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结",
"from": "央视网", from: "央视网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["美国", "航母", "加勒比海"], tag: ["美国", "航母", "加勒比海"],
"arrow": '0', arrow: "0"
} }
]) ]);
function changeBtn(btn) { function changeBtn(btn) {
btnSelect.value = btn btnSelect.value = btn;
} }
const emit = defineEmits(["back"]); const emit = defineEmits(["back"]);
function back() { function back() {
emit('back', 'home') emit("back", "home");
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
@import url('./style.css');
.newsBrief-page { .newsBrief-page {
max-width: 100vw; max-width: 100vw;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
margin: 0 auto; margin: 0 auto;
padding: 5vh 10vw 20vh 10vw; padding: 5vh 10vw 20vh 10vw;
background: url('@/assets/images/background.png') no-repeat; background: url("@/assets/images/background.png") no-repeat;
background-position: center -100px; background-position: center -100px;
background-size: 100% 100%; background-size: 100% 100%;
min-height: 100vh; min-height: 100vh;
.back-btn {
position: absolute;
top: 24px;
left: 40px;
width: 92px;
height: 40px;
display: flex;
gap: 4px;
align-items: center;
justify-content: center;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 32px;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 10px 10px var(--color-bg-hover);
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: center;
}
}
.wrapper {
height: 930px;
position: relative;
.news-header {
margin-top: 80px;
margin-left: 484px;
height: 60px;
color: rgba(34, 41, 52, 1);
font-family: YouSheBiaoTiHei;
font-size: 46px;
font-weight: 400;
line-height: 60px;
letter-spacing: 0px;
text-align: left;
}
.news-desc {
margin-top: 2px;
margin-left: 484px;
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.main {
margin: 30px auto;
width: 1000px;
height: 778px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
border-radius: 10px;
background: rgba(255, 255, 255, 0.8);
.main-header {
height: 64px;
display: flex;
gap: 16px;
padding-top: 24px;
padding-left: 24px;
.header-btn {
height: 40px;
line-height: 40px;
padding: 0 20px;
border-radius: 32px;
background: rgba(32, 33, 35, 0.07);
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
letter-spacing: 0px;
text-align: center;
}
.headerBtnSelect {
box-sizing: border-box;
border: 1px solid rgba(174, 214, 255, 1);
border-radius: 32px;
background: rgba(231, 243, 255, 1);
color: var(--color-main-active);
}
}
.content-box {
margin: 0 auto;
width: 952px;
height: 674px;
overflow: hidden;
overflow-y: auto;
.item {
width: 952px;
height: 114px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding-top: 16px;
.item-left {
width: 710px;
.title {
height: 30px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.content {
margin-top: 2px;
display: flex;
gap: 16px;
height: 22px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
}
.tag-box {
margin-top: 4px;
display: flex;
gap: 4px;
.tag {
height: 24px;
padding: 0 8px;
border-radius: 4px;
background: rgba(223, 226, 231, 0.41);
line-height: 24px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
}
}
}
}
}
}
}
} }
</style> </style>
<template> <template>
<div class="newsBrief-page"> <div class="newsBrief-page">
<div v-if="showPage === 'home'"> <div v-if="showPage === 'home'">
<div style="justify-content: space-between;"> <div style="justify-content: space-between">
<div class="news-header"> <div class="news-header">新闻速览</div>
新闻速览 <div class="input-box">
</div> <el-input placeholder="请输入关键词" :suffix-icon="searchInput" clearable style="width: 800px; height: 48px">
<div style="display: flex;padding: 3vh;justify-content: center; "> </el-input>
<el-input placeholder="请输入关键词" :suffix-icon="searchInput" clearable style="width: 60vw;height: 5vh;"> </div>
</el-input>
</div>
<div style="display: flex;padding: 3vh;justify-content: center; "> <div class="btn-box">
<div v-for="item in btnList" :class="btnSelect !== item ? 'header-btn' : 'header-btn-select'" <div
@click="changeBtn(item)"> v-for="(item, index) in btnList"
{{ item }} > :key="index"
</div> :class="btnSelect !== item ? 'header-btn' : 'header-btn-select'"
<div class="header-btn-more"> @click="changeBtn(item)"
<img src="@/assets/icons/adjustment.png" /> >
</div> <div class="btn-box-text">{{ item }}</div>
</div> <div class="btn-box-icon">
<img v-if="btnSelect === item" src="@/assets/icons/btn-arrow-right-active.png" alt="" />
</div> <img v-else src="@/assets/icons/btn-arrow-right.png" alt="" />
<div style="display: flex;"> </div>
<div class="box"> </div>
<div class="box-header"> <div class="header-btn-more">
<img class="box-header-img" src="@/assets/icons/Headlines-icon.svg"></img> <img src="@/assets/icons/adjustment.png" />
<div style="cursor: pointer;" @click="changePage('headlines')"> </div>
今日要闻 > </div>
</div> </div>
</div> <div class="main">
<div class="divider"></div> <div class="box">
<div v-for="item in HeadlinesData"> <div class="box-header">
<div style="display: flex;"> <div class="box-header-img">
<div> <img src="@/assets/icons/Headlines-icon.svg" />
<div class="title-blob"> </div>
{{ item.title }} <div class="box-header-title" @click="changePage('headlines')">今日要闻 ></div>
</div> </div>
<div class="content"> <div class="divider"></div>
新闻来源: {{ item.from }} 发表时间:{{ item.time }} <div v-for="(item, index) in HeadlinesData" :key="index">
</div> <div class="box1-item">
<div style="display: flex;"> <div class="box1-item-left">
<div v-for="tag in item.tag" class="tag"> <div class="box1-item-title">
{{ tag }} {{ item.title }}
</div> </div>
<div class="box1-item-content">
<div class="source">新闻来源: {{ item.from }}</div>
<div class="time">发表时间:{{ item.time }}</div>
</div> </div>
</div> <div class="tag-box">
<div style="margin-left: auto;padding: 10px;"> <div v-for="(tag, index) in item.tag" :key="index" class="tag">
<img :src="item.image" /> {{ tag }}
</div> </div>
</div> </div>
</div>
<div style="margin-left: auto; padding: 10px">
<img :src="item.image" />
</div>
</div>
<div class="divider"> <div class="divider"></div>
</div> </div>
</div> </div>
</div> <div class="box">
<div class="box" style=" margin-left: 4%;"> <div class="box-header">
<div class="box-header"> <div class="box-header-img"><img src="@/assets/icons/subject-icon.png" /></div>
<img class="box-header-img" src="@/assets/icons/subject-icon.png"></img> <div class="box-header-title" @click="changePage('subject')">中美博弈专题</div>
<div style="cursor: pointer;" @click="changePage('subject')"> </div>
中美博弈专题 <div class="divider"></div>
</div> <div v-for="(item, index) in subjectData" :key="index">
</div> <div class="subject-line">
<div class="divider"> <div style="display: flex; align-items: center">
<div class="subject-line-id" :class="{ subjectLineId1: index===0, subjectLineId2: index === 1, subjectLineId3: index === 2 }">
</div> {{ index <= 2 ? index + 1 : "•" }}
<div v-for="(item, index) in subjectData"> </div>
<div class="subject-line"> <div class="text" :class="{ textTop: index < 3 }">
<!-- 左侧:序号 + 文字 --> {{ item.text }}
<div style="display: flex; align-items: center;"> </div>
<div :style="{ </div>
color: <img :src="`src/assets/icons/arrow-${item.arrow}.png`" />
index === 0 ? '#CF4F51' </div>
: index === 1 ? '#FF964D' </div>
: index === 2 ? '#E8BD0D' </div>
: '#3B414B' </div>
}"> </div>
{{ index <= 2 ? index + 1 : "." }} </div>
<div
style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;width: 32vw ;margin-left: 20px;"
:class="index <= 2 ? 'title-blob' : 'content'">{{ item.text }}
</div>
</div>
<!-- 右侧:箭头 --> <Headlines v-if="showPage === 'headlines'" @type="showPage" @back="changePage" />
<img :src="`src/assets/icons/arrow-${item.arrow}.png`" /> <Subject v-if="showPage === 'subject'" @back="changePage" />
</div> </div>
</div>
</div>
</div>
</div>
<Headlines v-if="showPage === 'headlines'" @type="showPage" @back="changePage" />
<Subject v-if="showPage === 'subject'" @back="changePage" />
</div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import Headlines from './Headlines.vue' import Headlines from "./Headlines.vue";
import Subject from './Subject.vue' import Subject from "./Subject.vue";
// import style from './style.css' // import style from './style.css'
//顶部数据搜索 //顶部数据搜索
const searchInput = ref('') const searchInput = ref("");
const btnList = ref(["新闻纵览", "焦点新闻", "全球热点", "军事热点", "台湾动向", "美国政治", "亚洲局势", "东亚动态"]) const btnList = ref(["新闻纵览", "焦点新闻", "全球热点", "军事热点", "台湾动向", "美国政治", "亚洲局势", "东亚动态"]);
const btnSelect = ref('新闻纵览') const btnSelect = ref("新闻纵览");
const HeadlinesData = ref([ const HeadlinesData = ref([
{ {
"title": "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”", title: "黎巴嫩真主党指责美国破坏黎稳定 谴责以色列“蓄意挑衅”",
"from": "人民网", from: "人民网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["以色列", "美国"], tag: ["以色列", "美国"],
"image": '/testData/HeadlinesData-img.png', image: "/testData/HeadlinesData-img.png"
}, },
{ {
"title": "IMF上调中东和北非地区经济增长预期", title: "IMF上调中东和北非地区经济增长预期",
"from": "CNN", from: "CNN",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["经济", "中东", "IMF"], tag: ["经济", "中东", "IMF"],
"image": '/testData/HeadlinesData-img.png', image: "/testData/HeadlinesData-img.png"
}, },
{ {
"title": "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面", title: "日本外务省亚洲大洋洲局局长金井正彰启程访华 预计18日与中方会面",
"from": "人民网", from: "人民网",
"time": "2025-10-05", time: "2025-10-05",
"tag": ["日本", "访华"], "image": '/testData/HeadlinesData-img.png', tag: ["日本", "访华"],
}, image: "/testData/HeadlinesData-img.png"
{ },
"title": "韩日因独岛主权争议暂停本月联合搜救演习", {
"from": "凤凰网", title: "韩日因独岛主权争议暂停本月联合搜救演习",
"time": "2025-10-05", from: "凤凰网",
"tag": ["独岛", "联合军演", "韩国", "日本"], "image": '/testData/HeadlinesData-img.png', time: "2025-10-05",
}, tag: ["独岛", "联合军演", "韩国", "日本"],
{ image: "/testData/HeadlinesData-img.png"
"title": "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结", },
"from": "央视网", {
"time": "2025-10-05", title: "美“福特”号航母抵达加勒比海 于委内瑞拉附近展开大规模军事集结",
"tag": ["美国", "航母", "加勒比海"], "image": '/testData/HeadlinesData-img.png', from: "央视网",
} time: "2025-10-05",
]) tag: ["美国", "航母", "加勒比海"],
image: "/testData/HeadlinesData-img.png"
}
]);
function changeBtn(btn) { function changeBtn(btn) {
btnSelect.value = btn btnSelect.value = btn;
} }
//当前页面显示 //当前页面显示
const showPage = ref('home') const showPage = ref("home");
function changePage(page) { function changePage(page) {
console.log(page) console.log(page);
showPage.value = page showPage.value = page;
} }
//博弈专题新闻数据 //博弈专题新闻数据
const subjectData = ref([ const subjectData = ref([
{ id: 1, text: "乌克兰与法国签署意向书 将获 100 架“阵风”战机及多套防空系统", arrow: 0 }, { id: 1, text: "乌克兰与法国签署意向书 将获 100 架“阵风”战机及多套防空系统", arrow: 0 },
{ id: 2, text: "安理会通过涉加沙决议 建立和平委员会作为过渡行政机构", arrow: 1 }, { id: 2, text: "安理会通过涉加沙决议 建立和平委员会作为过渡行政机构", arrow: 1 },
{ id: 3, text: "日本首相高市早苗涉台及修“无核三原则”言论遭多方强烈反对", arrow: 1 }, { id: 3, text: "日本首相高市早苗涉台及修“无核三原则”言论遭多方强烈反对", arrow: 1 },
{ id: 4, text: "美“福特”号航母打击群进入加勒比海 委方谴责其意图策动政权更迭", arrow: 1 }, { id: 4, text: "美“福特”号航母打击群进入加勒比海 委方谴责其意图策动政权更迭", arrow: 1 },
{ id: 5, text: "BBC回应特朗普10亿-50亿美元索赔诉讼 称诽谤指控无依据", arrow: 1 }, { id: 5, text: "BBC回应特朗普10亿-50亿美元索赔诉讼 称诽谤指控无依据", arrow: 1 },
{ id: 6, text: "俄军打击乌142个区域设施 乌军击落或压制91架俄无人机", arrow: 1 }, { id: 6, text: "俄军打击乌142个区域设施 乌军击落或压制91架俄无人机", arrow: 1 },
{ id: 7, text: "中国女法官张玲玲以第一高票当选联合国上诉法庭法官", arrow: 0 }, { id: 7, text: "中国女法官张玲玲以第一高票当选联合国上诉法庭法官", arrow: 0 },
{ id: 8, text: "美股三大股指17日收盘普跌 比特币跌破92000美元", arrow: 1 }, { id: 8, text: "美股三大股指17日收盘普跌 比特币跌破92000美元", arrow: 1 },
{ id: 9, text: "高盛大幅下调2026年布伦特和WTI原油价格预测", arrow: 1 }, { id: 9, text: "高盛大幅下调2026年布伦特和WTI原油价格预测", arrow: 1 },
{ id: 10, text: "2026米兰冬奥会火炬传递完整路线公布 将穿越意大利全部20个大区", arrow: 1 }, { id: 10, text: "2026米兰冬奥会火炬传递完整路线公布 将穿越意大利全部20个大区", arrow: 1 },
{ id: 11, text: "特朗普宣称若重掌白宫将推动美国开展自1992年以来首次核试验", arrow: 1 }, { id: 11, text: "特朗普宣称若重掌白宫将推动美国开展自1992年以来首次核试验", arrow: 1 },
{ id: 12, text: "欧盟发布2025年秋季经济预测 欧元区今年GDP预计增长1.3%", arrow: 1 } { id: 12, text: "欧盟发布2025年秋季经济预测 欧元区今年GDP预计增长1.3%", arrow: 1 }
]) ]);
</script> </script>
<style scoped> <style lang="scss" scoped>
@import url('./style.css'); @import url("./style.css");
.newsBrief-page { .newsBrief-page {
max-width: 100vw; height: 100%;
height: 100%; background: url("@/assets/images/background.png") no-repeat;
overflow: hidden; background-position: center -100px;
margin: 0 auto; background-size: 100% 100%;
padding: 5vh 10vw 20vh 10vw; padding-top: 50px;
background: url('@/assets/images/background.png') no-repeat;
background-position: center -100px;
background-size: 100% 100%;
min-height: 100vh;
} }
</style> </style>
/* 分割线 */
/* 左右横线 + 中间文字 */
.news-header { .news-header {
color: rgba(34, 41, 52, 1); color: rgba(34, 41, 52, 1);
font-family: "YouSheBiaoTiHei", sans-serif; font-family: YouSheBiaoTiHei;
font-size: 46px; font-size: 46px;
font-weight: 400; font-weight: 400;
line-height: 60px; line-height: 60px;
letter-spacing: 0px; letter-spacing: 0px;
text-align: center; 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 { .header-btn {
cursor: pointer; cursor: pointer;
padding: 2px 20px; padding: 0px 20px;
box-sizing: border-box; box-sizing: border-box;
margin: 5px;
border: 1px solid rgba(255, 255, 255, 1); border: 1px solid rgba(255, 255, 255, 1);
border-radius: 32px; border-radius: 32px;
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 30px;
letter-spacing: 0px; letter-spacing: 0px;
text-align: center; 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 { .header-btn-gray {
cursor: pointer; cursor: pointer;
padding: 2px 20px; padding: 2px 20px;
...@@ -40,21 +67,36 @@ ...@@ -40,21 +67,36 @@
letter-spacing: 0px; letter-spacing: 0px;
text-align: center; text-align: center;
} }
.header-btn-select { .header-btn-select {
cursor: pointer; cursor: pointer;
padding: 2px 20px; padding: 0px 20px;
margin: 5px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(174, 214, 255, 1); border: 1px solid rgba(174, 214, 255, 1);
border-radius: 32px; border-radius: 32px;
background: rgba(231, 243, 255, 1); background: rgba(231, 243, 255, 1);
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 30px; color: var(--color-main-active);
letter-spacing: 0px; letter-spacing: 0px;
text-align: center; 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 { .header-btn-more {
cursor: pointer; cursor: pointer;
width: 34px; width: 34px;
...@@ -64,54 +106,71 @@ ...@@ -64,54 +106,71 @@
border: 1px solid, rgba(255, 255, 255, 1); border: 1px solid, rgba(255, 255, 255, 1);
border-radius: 32px; border-radius: 32px;
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
display: flex; /* 开启 flex */ display: flex;
justify-content: center; /* 水平居中 */ /* 开启 flex */
align-items: center; /* 垂直居中 */ justify-content: center;
/* 水平居中 */
align-items: center;
/* 垂直居中 */
}
.main {
width: 1440px;
height: 714px;
margin: 0 auto;
display: flex;
gap: 16px;
} }
.box { .box {
width: 48%; width: 712px;
height: 55vh; height: 656px;
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: 10px; border-radius: 10px;
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
padding: 1vw; padding: 0 24px;
.box-header {
height: 4vh; }
display: flex;
text-align: left; .box-header {
font-size: 24px; height: 56px;
font-weight: 700; display: flex;
align-items: center; align-items: center;
.box-header-img { }
height: 24px;
width: 24px; .box-header-img {
margin: 0 5px; height: 20px;
} width: 20px;
} border-radius: 2px;
.title-blob { background: rgba(5, 95, 194, 0.16);
font-size: 16px; box-sizing: border-box;
font-weight: 400; padding: 2px;
line-height: 30px; }
letter-spacing: 0px;
text-align: left; .box-header-img img {
} width: 16px;
height: 16px;
.tag { }
margin: 2px;
padding: 2px 8px 2px 8px; .box-header-title {
border-radius: 4px; margin-left: 10px;
background: rgba(223, 226, 231, 0.41); height: 24px;
color: rgba(132, 136, 142, 1); color: rgba(59, 65, 75, 1);
font-size: 14px; font-family: Microsoft YaHei;
font-weight: 400; font-size: 18px;
line-height: 22px; font-weight: 700;
letter-spacing: 0px; line-height: 24px;
text-align: left; letter-spacing: 0px;
} text-align: left;
} cursor: pointer;
}
.content {
.tag {
margin: 2px;
padding: 2px 8px 2px 8px;
border-radius: 4px;
background: rgba(223, 226, 231, 0.41);
color: rgba(132, 136, 142, 1); color: rgba(132, 136, 142, 1);
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
...@@ -119,17 +178,116 @@ ...@@ -119,17 +178,116 @@
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.divider { .divider {
width: 100%; width: 100%;
height: 1px; height: 1px;
background: #eaecee; background: #eaecee;
} }
.box1-item {
display: flex;
height: 114px;
}
.box1-item-left {
margin-top: 16px;
width: 500px;
}
.box1-item-title {
width: 500px;
height: 30px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.box1-item-content {
margin-top: 2px;
height: 22px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
display: flex;
gap: 16px;
}
.tag-box {
margin-top: 4px;
display: flex;
gap: 4px;
}
.subject-line { .subject-line {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
width: 100%; height: 30px;
height: 2.7vh; margin: 16px 0;
margin: 1vh 0; }
.subject-line-id {
width: 20px;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
color: rgba(59, 65, 75, 1);
}
.subjectLineId1 {
color: #CE4F51 !important;
}
.subjectLineId2 {
color: #FF954D !important;
}
.subjectLineId3 {
color: #E8BD0B !important;
}
.text {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
}
.textTop {
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 30px;
letter-spacing: 0px;
text-align: left;
} }
: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
...@@ -336,7 +336,8 @@ ...@@ -336,7 +336,8 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange"> <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" class="all-checkbox"
@change="handleCheckAllChange">
全部领域 全部领域
</el-checkbox> </el-checkbox>
<el-checkbox v-for="research in areaList" :key="research.id" v-model="selectedAreaList" <el-checkbox v-for="research in areaList" :key="research.id" v-model="selectedAreaList"
...@@ -354,7 +355,7 @@ ...@@ -354,7 +355,7 @@
</div> </div>
<div class="select-main"> <div class="select-main">
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-model="checkAllTime" :indeterminate="isIndeterminateTime" <el-checkbox v-model="checkAllTime" class="all-checkbox" :indeterminate="isIndeterminateTime"
@change="handleCheckAllChangeTime"> @change="handleCheckAllChangeTime">
全部时间 全部时间
</el-checkbox> </el-checkbox>
...@@ -385,7 +386,7 @@ ...@@ -385,7 +386,7 @@
</div> </div>
</div> </div>
<div class="right-footer"> <div class="right-footer">
<div class="info">{{ total }}调查</div> <div class="info">{{ total }}智库报告</div>
<div class="page-box"> <div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total" <el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="currentPage" /> @current-change="handleCurrentChange" :current-page="currentPage" />
...@@ -453,6 +454,7 @@ import Img12 from "./assets/images/img12.png"; ...@@ -453,6 +454,7 @@ import Img12 from "./assets/images/img12.png";
import Box1Img from "./assets/images/box1-img.png"; import Box1Img from "./assets/images/box1-img.png";
import Box1Logo from "./assets/images/box1-logo.png"; import Box1Logo from "./assets/images/box1-logo.png";
import { setCanvasCreator } from "echarts/core"; import { setCanvasCreator } from "echarts/core";
import { ElMessage } from "element-plus";
const input = ref(""); //搜索科技人物及观点 const input = ref(""); //搜索科技人物及观点
// 智库列表 // 智库列表
...@@ -727,12 +729,11 @@ function changeBox5Data(value) { ...@@ -727,12 +729,11 @@ function changeBox5Data(value) {
} }
// 政策建议趋势分布 // 政策建议趋势分布
const handleGetThinkTankPolicyIndustryChange = async date => { const handleGetThinkTankPolicyIndustryChange = async date => {
try { try {
const res = await getThinkTankPolicyIndustryChange(date); const res = await getThinkTankPolicyIndustryChange(date);
console.log("政策建议趋势分布", res); console.log("政策建议趋势分布", res);
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
const originalData = res.data const originalData = res.data;
// 提取年份 // 提取年份
const years = originalData.map(item => item.year); const years = originalData.map(item => item.year);
// 提取所有行业名称 // 提取所有行业名称
...@@ -762,9 +763,8 @@ const handleGetThinkTankPolicyIndustryChange = async date => { ...@@ -762,9 +763,8 @@ const handleGetThinkTankPolicyIndustryChange = async date => {
result.data.push(industryData); result.data.push(industryData);
}); });
box5Data.value = result; box5Data.value = result;
} else { } else {
box5Data.value = [] box5Data.value = [];
} }
} catch (error) { } catch (error) {
console.error("获取政策建议趋势分布error", error); console.error("获取政策建议趋势分布error", error);
...@@ -773,9 +773,7 @@ const handleGetThinkTankPolicyIndustryChange = async date => { ...@@ -773,9 +773,7 @@ const handleGetThinkTankPolicyIndustryChange = async date => {
const handleBox5 = async date => { const handleBox5 = async date => {
await handleGetThinkTankPolicyIndustryChange(date); await handleGetThinkTankPolicyIndustryChange(date);
let box5Chart = box5Data.value ? getMultiLineChart( let box5Chart = box5Data.value ? getMultiLineChart(box5Data.value) : "";
box5Data.value
) : ''
setChart(box5Chart, "box5Chart"); setChart(box5Chart, "box5Chart");
}; };
...@@ -1142,7 +1140,6 @@ const handleCheckedAreaChange = () => { ...@@ -1142,7 +1140,6 @@ const handleCheckedAreaChange = () => {
}; };
const pubTimeList = ref([ const pubTimeList = ref([
{ {
id: 2025, id: 2025,
name: "2025" name: "2025"
...@@ -1172,7 +1169,6 @@ const selectedPubTimeList = ref([""]); ...@@ -1172,7 +1169,6 @@ const selectedPubTimeList = ref([""]);
const checkAllTime = ref(false); const checkAllTime = ref(false);
const isIndeterminateTime = ref(true); const isIndeterminateTime = ref(true);
const handleCheckAllChangeTime = val => { const handleCheckAllChangeTime = val => {
// console.log(val, "handleCheckAllChange"); // console.log(val, "handleCheckAllChange");
if (val) { if (val) {
...@@ -1196,7 +1192,6 @@ const handleCheckedAreaChangeTime = () => { ...@@ -1196,7 +1192,6 @@ const handleCheckedAreaChangeTime = () => {
handleGetetThinkTankReport(); handleGetetThinkTankReport();
}; };
const curFooterList = ref([ const curFooterList = ref([
{ {
title: "中国对AI的转型产业政策", title: "中国对AI的转型产业政策",
...@@ -1275,10 +1270,10 @@ const currentPage = ref(1); ...@@ -1275,10 +1270,10 @@ const currentPage = ref(1);
const total = ref(0); const total = ref(0);
// 处理页码改变事件 // 处理页码改变事件
const handleCurrentChange = page => { const handleCurrentChange = page => {
console.log(page, 'pagepagepage') console.log(page, "pagepagepage");
currentPage.value = page; currentPage.value = page;
handleGetetThinkTankReport(); handleGetetThinkTankReport();
} };
function arrayToString(arr) { function arrayToString(arr) {
return arr.reduce((acc, item) => { return arr.reduce((acc, item) => {
if (item !== null && item !== undefined && item !== "") { if (item !== null && item !== undefined && item !== "") {
...@@ -1311,6 +1306,10 @@ const handleGetetThinkTankReport = async () => { ...@@ -1311,6 +1306,10 @@ const handleGetetThinkTankReport = async () => {
const handleClick = tank => { const handleClick = tank => {
console.log(tank); console.log(tank);
// router.push({ name: "ThinkTankDetail", params: { id: tank.id } }); // router.push({ name: "ThinkTankDetail", params: { id: tank.id } });
if (!tank.id) {
ElMessage.warning("当前智库id为空,无法进入详情页");
return;
}
const curRoute = router.resolve({ name: "ThinkTankDetail", params: { id: tank.id, name: tank.name } }); const curRoute = router.resolve({ name: "ThinkTankDetail", params: { id: tank.id, name: tank.name } });
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
...@@ -1328,15 +1327,15 @@ const handleToMoreRiskSignal = () => { ...@@ -1328,15 +1327,15 @@ const handleToMoreRiskSignal = () => {
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
const handleToReportDetail = (id) => { const handleToReportDetail = id => {
const route = router.resolve({ const route = router.resolve({
name: 'ReportDetail', name: "ReportDetail",
params: { params: {
id: id id: id
} }
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
onMounted(async () => { onMounted(async () => {
handleGetThinkTankList(); handleGetThinkTankList();
...@@ -2951,14 +2950,15 @@ onMounted(async () => { ...@@ -2951,14 +2950,15 @@ onMounted(async () => {
.right { .right {
width: 1284px; width: 1284px;
height: 1377px; max-height: 1377px;
.card-box { .card-box {
width: 1226px; width: 1226px;
height: 1248px; max-height: 1248px;
min-height: 616px;
display: flex; display: flex;
justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
gap: 16px 16px;
.footer-card { .footer-card {
width: 398px; width: 398px;
...@@ -3019,6 +3019,7 @@ onMounted(async () => { ...@@ -3019,6 +3019,7 @@ onMounted(async () => {
} }
.right-footer { .right-footer {
height: 50px;
margin-top: 43px; margin-top: 43px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
...@@ -3046,6 +3047,10 @@ onMounted(async () => { ...@@ -3046,6 +3047,10 @@ onMounted(async () => {
margin-bottom: 36px; margin-bottom: 36px;
} }
.all-checkbox {
width: 220px;
}
.filter-checkbox { .filter-checkbox {
width: 105px; width: 105px;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论