提交 2cc1c9e6 authored 作者: coderBryanFu's avatar coderBryanFu

feat:新增组件:GraphChart

......@@ -54,4 +54,11 @@ export function getAreaList() {
method: 'GET',
url: `/api/commonDict/areaType`,
})
}
\ No newline at end of file
}
export function getNewsDetail(params) {
return request({
method: 'GET',
url: `/api/news/findById/${params.newsId}`,
params
})
}
......@@ -21,9 +21,10 @@ const props = defineProps({
// SVG颜色
color: {
type: String,
default: '#000'
default: null
}
, size: {
,
size: {
type: Number,
default: null
}
......@@ -43,40 +44,44 @@ const processedSvgContent = computed(() => {
// 替换SVG中的颜色
let processed = svgContent.value;
if (props.color) {
// 替换fill属性
processed = processed.replace(/fill="([^"]*)"/g, (match, p1) => {
// 保留透明和none值
if (p1 === 'none' || p1 === 'transparent') {
return match;
}
return `fill="${props.color}"`;
});
// 替换stroke属性
processed = processed.replace(/stroke="([^"]*)"/g, (match, p1) => {
// 保留透明和none值
if (p1 === 'none' || p1 === 'transparent') {
return match;
}
return `stroke="${props.color}"`;
});
}
// 替换fill属性
processed = processed.replace(/fill="([^"]*)"/g, (match, p1) => {
// 保留透明和none值
if (p1 === 'none' || p1 === 'transparent') {
if (props.size) {
// 替换width属性
processed = processed.replace(/width="([^"]*)"/g, (match, p1) => {
if (props.size !== null) {
return `width="${props.size}"`;
}
return match;
}
return `fill="${props.color}"`;
});
});
// 替换stroke属性
processed = processed.replace(/stroke="([^"]*)"/g, (match, p1) => {
// 保留透明和none值
if (p1 === 'none' || p1 === 'transparent') {
// 替换height属性
processed = processed.replace(/height="([^"]*)"/g, (match, p1) => {
if (props.size !== null) {
return `height="${props.size}"`;
}
return match;
}
return `stroke="${props.color}"`;
});
// 替换width属性
processed = processed.replace(/width="([^"]*)"/g, (match, p1) => {
if (props.size !== null) {
return `width="${props.size}"`;
}
return match;
});
// 替换height属性
processed = processed.replace(/height="([^"]*)"/g, (match, p1) => {
if (props.size !== null) {
return `height="${props.size}"`;
}
return match;
});
});
}
console.log(processed)
return processed;
......@@ -131,10 +136,14 @@ onMounted(() => {
<style scoped>
.color-svg {
display: inline-block;
/* svg垂直居中 */
vertical-align: middle;
}
.svg-container {
display: inline-block;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
......
<template>
<div class="news-item">
<el-space direction="vertical" class="flex-fill" alignment='flex-start'>
<common-text :lineLimit="1" class="text-bold" color="var(--text-primary-80-color)">{{
props.title
}}</common-text>
<common-text class="text-tip-2" color="var(--text-primary-65-color)">
{{ props.from }}
</common-text>
<el-space v-if="props.aeraTags">
<area-tag v-for="(tag, index) in props.aeraTags" :key="index" :tagName="tag" />
</el-space>
</el-space>
<img style="width: 122px; height: 82px" :src="props.img">
<!-- <img v-else style="width: 122px; height: 82px" :src="DefaultIconNews"> -->
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElSpace } from 'element-plus'
import AreaTag from '@/components/base/AreaTag/index.vue'
import DefaultIconNews from "@/assets/icons/default-icon-news.png";
import CommonText from '../texts/CommonText.vue';
const props = defineProps({
img: {
type: String,
default: 'img'
},
title: {
type: String,
default: "title"
},
from: {
type: String,
default: "from"
},
aeraTags: {
type: Array,
default: []
},
content: {
type: String,
default: "content"
},
});
const emit = defineEmits(['item-click', 'more-click']);
</script>
<style lang="scss" scoped>
@use '@/styles/common.scss';
.news-item {
display: flex;
margin-top: 10px;
}
</style>
\ No newline at end of file
<template>
<el-space :size="16" class="text-tip-1-bold box">
<el-space :size="16" class="text-tip-1-bold box-color-prefix">
<div class="color-prefix"></div>
<slot></slot>
</el-space>
......@@ -11,6 +11,10 @@ const props = defineProps({
color: {
type: String,
default: 'var(--color-primary-100)'
},
height: {
type: String,
default: '16px'
}
})
</script>
......@@ -18,11 +22,11 @@ const props = defineProps({
<style lang="scss" scoped>
.color-prefix {
width: 8px;
height: 16px;
height: v-bind(height);
background-color: v-bind(color);
}
.box {
.box-color-prefix {
color: v-bind(color);
}
</style>
\ No newline at end of file
<template>
<div class="common-text">
<slot></slot>
</div>
</template>
<script setup lang="js">
const props = defineProps({
color: {
type: String,
default: "#000"
},
lineLimit: {
type: Number,
default: null
}
});
</script>
<style lang="scss" scoped>
@use '@/styles/common.scss';
.common-text {
color: v-bind(color);
@if('v-bind(lineLimit) !==null') {
@include common.text-ellipsis(v-bind(lineLimit));
}
}
</style>
import { useRouter } from "vue-router";
export function useGotoPage() {
const router = useRouter();
return (path, data, isNewTabs = true) => {
console.log('path', path);
if (isNewTabs) {
// 打开新页面
const url = new URL(window.location.origin + path);
if (data) {
Object.entries(data).forEach(([key, value]) => {
url.searchParams.append(key, value);
});
}
window.open(url.toString(), '_blank');
} else {
// 当前页面打开
router.push({ path, query: data });
}
}
}
\ No newline at end of file
const newsBrief = () => import('@/views/newsBrief/index.vue')
const ModeuleNews = () => import('@/views/newsBrief/ModeuleNews.vue')
const NewsDetial = () => import('@/views/newsBrief/NewsDetial.vue')
const NewsAnalysis = () => import('@/views/newsAnalysis/index.vue')
const newsRoutes = [
......@@ -11,6 +13,25 @@ const newsRoutes = [
title: "新闻速览"
}
},
//新闻模块页面路由
{
path: "/newsModeule/:id",
name: "newsModeule",
component: ModeuleNews,
meta: {
title: "新闻模块"
}
},
//新闻详情页面路由
{
path: "/newsDetail/:id",
name: "newsDetail",
component: NewsDetial,
meta: {
title: "新闻详情"
}
},
// 新闻事件分析
{
......@@ -22,5 +43,21 @@ const newsRoutes = [
}
}
];
import { useGotoPage } from "../common.js";
export function useGotoNewsBrief() {
const gotoPage = useGotoPage();
return (isNewTabs = true) => gotoPage("/newsBrief/", {}, isNewTabs)
}
export function useGotoNewsDetail() {
const gotoPage = useGotoPage();
return (id, isNewTabs = true) => gotoPage("/newsDetail/" + id, {}, isNewTabs)
}
export function useGotoNewsModule() {
const gotoPage = useGotoPage();
return (id, name, isNewTabs = true) =>
gotoPage("/newsModeule/" + id, { name }, isNewTabs)
}
export default newsRoutes;
......@@ -11,19 +11,19 @@
display: flex;
}
.flex-display-center{
.flex-display-center {
@extend .flex-display;
justify-content: center;
align-items: center;
}
.flex-display-end{
.flex-display-end {
@extend .flex-display;
justify-content: flex-end;
align-items: center;
}
.flex-display-start{
.flex-display-start {
@extend .flex-display;
justify-content: flex-start;
align-items: center;
......@@ -37,6 +37,13 @@
width: 100%;
}
.mouse-hover:hover {
cursor: pointer;
box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.082);
// margin-top: 1px;
// margin-left: 1px;
}
// 文本超出指定行数省略号显示
@mixin text-ellipsis($line-clamp) {
overflow: hidden;
......
......@@ -14,12 +14,30 @@ const span = 12
</template>
`}}
</pre>
<div class="background-as-card">
<div v-for="item in [1, 2, 3, 4]" :key="item">
{{ item }}
<div class="common-padding">
<div class="background-as-card">
<div v-for="item in [1, 2, 3, 4]" :key="item">
{{ item }}
</div>
</div>
</div>
</el-col>
<el-col :span="span">
<pre>{{ `import '@/styles/container.scss';\n<template>
<div class="common-page"></div>
</template>
`}}
</pre>
通用的页面容器,限定了页面宽度为1600px,居中显示
</el-col>
<el-col :span="span">
<pre>{{ `import '@/styles/common.scss';\n<template>
<div class="mouse-hover"></div>
</template>
`}}
</pre>
<div class="mouse-hover">鼠标悬停</div>
</el-col>
</el-row>
</template>
......
......@@ -24,6 +24,19 @@ const span = 12
<el-radio-button :value="3">选项3</el-radio-button>
</el-radio-group>
</el-col>
<el-col :span="span">
<pre>{{ `import '@/styles/radio.scss';\n <template>
<el-radio-group class="radio-group-as-radius-btn">
</el-radio-group>
</template>
`}}
</pre>
<el-radio-group v-model="radio" class="radio-group-as-radius-btn">
<el-space>
<el-radio-button v-for="item in 3" :key="item" :value="item">选项{{ item }} ></el-radio-button>
</el-space>
</el-radio-group>
</el-col>
</el-row>
</template>
......
......@@ -3,6 +3,7 @@ import { ElSpace, ElRow, ElCol } from 'element-plus';
import '@/styles/tabs.scss'
import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';
import AiTipPane from '@/components/base/panes/AiTipPane.vue';
import CommonText from '@/components/base/texts/CommonText.vue';
const span = 12
</script>
......@@ -10,20 +11,37 @@ const span = 12
<el-row class="layout-grid-line">
<el-col :span="span">
<pre>
{{ `import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';
{{ `import CommonText from '@/components/base/texts/CommonText.vue';
<template>
<common-text>科技领域</common-text>
<common-text class="text-title-1-show" color="var(--color-yellow-100)">科技领域</common-text>
<common-text color="red" :lineLimit="1">科技领域</common-text>
</template>
`}}
</pre>
<el-space direction="vertical">
<common-text>科技领域</common-text>
<common-text class="text-title-1-show" color="var(--color-yellow-100)">科技领域</common-text>
<common-text color="red"
:lineLimit="1">超出行数则省略号。超出行数则省略号。超出行数则省略号。超出行数则省略号。超出行数则省略号。超出行数则省略号。超出行数则省略号。超出行数则省略号。超出行数则省略号。</common-text>
</el-space>
</el-col>
<el-col :span="span">
<pre>{{ `import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';\n <template>
<color-prefix-title>科技领域</color-prefix-title>
<color-prefix-title color="var(--color-yellow-100)">科技领域</color-prefix-title>
<color-prefix-title color="red">科技领域</color-prefix-title>
</template>
`}}
</pre>
`}}
</pre>
<el-space direction="vertical">
<color-prefix-title>科技领域</color-prefix-title>
<color-prefix-title color="var(--color-yellow-100)">科技领域</color-prefix-title>
<color-prefix-title color="red">科技领域</color-prefix-title>
</el-space>
</el-col>
<el-col :span="span">
<pre>{{ `import AiTipPane from '@/components/base/panes/AiTipPane.vue';\n<template>
<ai-tip-pane>huidadadadadasda</ai-tip-pane>
......
......@@ -5,4 +5,15 @@
padding: 16px 160px;
// width: 1600px;
align-items: center;
}
//水平居中
.h-center {
//水平居中
margin: 0 auto;
display: block; // 强制设置为块级元素
}
.common-padding {
padding: 20px 24px;
}
\ No newline at end of file
......@@ -16,4 +16,35 @@
--el-radio-button-checked-border-color: var(--color-primary-5);
border-radius: 4px;
}
}
.radio-group-as-radius-btn {
.el-radio-button {
--el-radio-button-checked-bg-color: transparent;
--el-radio-button-checked-border-color: transparent;
.el-radio-button__inner {
border-radius: 32px !important;
// height: 40px;
@extend .text-regular;
background-color: var(--bg-white-65);
border-color: var(--bg-white-100);
border-width: 1px;
color: var(--text-primary-65-color);
//垂直居中
// display: flex;
// justify-content: center;
}
}
.el-radio-button.is-active {
--el-radio-button-checked-text-color: var(--color-primary-100);
.el-radio-button__inner {
background-color: var(--color-primary-10) !important;
border-color: var(--color-primary-35) !important;
}
}
}
\ No newline at end of file
......@@ -438,7 +438,7 @@ import {
getDecreehylyList,
getDecreeTypeList
} from "@/api/decree/home";
import RiskSignal from "@/components/base/RiskSignal/index.vue";
import RiskSignal from "@/components/base/riskSignal/index.vue";
// import RiskSignal from "@/components/base/RiskSignal/index.vue";
import { getPersonSummaryInfo } from "@/api/common/index";
import { getNews, getSocialMedia } from "@/api/general/index";
......@@ -2059,7 +2059,7 @@ onMounted(async () => {
margin-top: 21px;
height: 450px;
display: flex;
gap:16px;
gap: 16px;
.box3 {
width: 792px;
......
<template>
<el-space direction="vertical" class="full-width news-image-background">
<el-button class="float-btn" @click="gotoNewsBrief(false)"><el-icon>
<back />
</el-icon> 返回</el-button>
<el-space style="width: 993px;" direction="vertical" alignment="flex-start">
<div style="margin-top: 50px; margin-bottom: 24px; margin-left: 24px;">
<common-text class="text-title-0-show" color="var(--text-primary-90-color)">{{
moduleName
}}</common-text>
<common-text class="text-regular"
color="var(--text-primary-65-color)">基于情报价值评估预测算法,掌握全球重要潜在动向</common-text>
</div>
<el-space direction="vertical" fill alignment="flex-start" class="background-as-card common-padding">
<el-radio-group v-model="currentAreaId" class="radio-group-as-gap-btn">
<el-space direction="horizontal" wrap alignment="center">
<el-radio-button :label="''" @click="changeArea('')">全部</el-radio-button>
<el-radio-button v-for="(t, i) in AreaList" :key="i" :label="t.id" @click="changeArea(t.id)">{{
t.name }}
</el-radio-button>
</el-space>
</el-radio-group>
<el-divider style="margin: 10px 0px;"></el-divider>
<div class="">
<news-list :news="NewsData" />
</div>
</el-space>
</el-space>
</el-space>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from 'vue-router';
import '@/styles/container.scss';
import '@/styles/radio.scss';
import NewsList from "./NewsList.vue";
import { getAreaList, getHotNewsByArea } from "@/api/news/newsBrief";
import { ElSpace, ElDivider, ElRadioButton, ElRadioGroup, ElButton, ElIcon } from "element-plus";
import CommonText from "@/components/base/texts/CommonText.vue";
import { useGotoNewsBrief } from "@/router/modules/news";
const route = useRoute();
const gotoNewsBrief = useGotoNewsBrief();
const moduleId = ref(route.params.id);
const moduleName = ref(route.query.name ?? "");
const NewsData = ref([]);
const AreaList = ref([]);
const currentAreaId = ref("");
onMounted(async () => {
console.log(route.query.name, moduleId.value, moduleName.value);
const { data: areaList } = await getAreaList();
AreaList.value = areaList ?? [];
await changeArea("")
});
async function changeArea(id) {
const { data } = await getHotNewsByArea({
moduleId: moduleId.value,
industryId: id,
});
NewsData.value = data ?? [];
}
</script>
<style lang="scss" scoped>
@use '@/styles/common.scss' as *;
@import url("./style.css");
.float-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;
@extend .text-regular;
color: var(--text-primary-65-color);
}
</style>
\ No newline at end of file
<template>
<el-scrollbar>
<div class="flex-display common-page top-box-news-deatail" style="align-items: center;">
<!-- <color-svg :svg-url="NewsLogo" :size="72" style="margin-right:10px"></color-svg> -->
<img :src="NewsLogo" style="margin-right:24px">
<el-space direction="vertical" class="flex-fill" alignment="flex-start">
<common-text class="text-title-1-bold" color="var(--text-primary-80-color)">
{{ newsDetail.titleZh }}
</common-text>
<common-text class="text-tip-1-bold" color="var(--text-primary-80-color)">
{{ newsDetail.title }}
</common-text>
<common-text class="text-tip-1-bold" color="var(--text-primary-65-color)">
{{ `${newsDetail.publishedTime} · ${newsDetail.source}` }}
<el-space>
<area-tag :area-name="newsDetail.areaName" />
</el-space>
</common-text>
</el-space>
<!-- <el-button type="primary" @click="() => gotoNewsDetail(newsDetail.newsId)">
<el-icon class="icon">
<el-icon>
<top-right />
</el-icon>
</el-icon>
查看原网页
</el-button> -->
</div>
<div class="flex-display common-page content-box-news-detail">
<el-space direction="vertical" class="background-as-card flex-fill" fill alignment="flex-start">
<div style="margin-top: 10px; margin-right: 24px;" class="flex-display">
<color-prefix-title height="20px">
<div class="text-title-2-bold">新闻内容</div>
</color-prefix-title>
<div class="flex-fill"></div>
<el-button v-if="hasTranslation" :type="isOpenTranslation ? 'primary' : ''" plain
@click="handleTranslation">
<color-svg :svg-url="TranslationSvg" color="var(--color-primary-100)" :size="18"
style="margin-right:10px"></color-svg>
译文
</el-button>
</div>
<div class="common-padding">
<div class="flex-display" style="align-items: center;">
<common-text class="text-title-3-bold" color="var(--text-primary-80-color)">中文</common-text>
<div class="flex-fill" style="margin: 0 10px;">
<el-divider></el-divider>
</div>
<el-button @click="() => showMore = !showMore">
{{ showMore ? '收起' : '展开' }}
<el-icon>
<arrow-down v-if="showMore" />
<arrow-up v-else />
</el-icon>
</el-button>
</div>
<el-row :gutter="32">
<el-col :span="znEnColSpan"
v-for="(item, index) in showMore ? zhEnTexts : zhEnTexts.slice(0, 6)" :key="index">
<p class="p-news-content"> {{ item }}</p>
</el-col>
</el-row>
</div>
</el-space>
<el-space direction="vertical" class="background-as-card relation-news-box" alignment="flex-start">
<el-space style="margin-top: 10px;">
<color-prefix-title height="20px">
<div class="text-title-2-bold">相关新闻</div>
</color-prefix-title>
</el-space>
<el-space style="margin-top: 10px;">
<news-item v-for="item in relationNews" :key="item.newsId" :news-item="item" />
</el-space>
</el-space>
</div>
</el-scrollbar>
</template>
<script setup>
import { getNewsDetail } from "@/api/news/newsBrief";
import '@/styles/container.scss';
import '@/styles/common.scss';
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import { ElSpace, ElImage, ElButton, ElIcon, ElScrollbar, ElRow, ElCol, ElDivider } from "element-plus";
import CommonText from "@/components/base/texts/CommonText.vue";
import AreaTag from "@/components/base/AreaTag/index.vue";
import ColorPrefixTitle from '@/components/base/texts/ColorPrefixTitle.vue';
import { getRelationNews } from "@/api/news/newsDetail";
import NewsItem from "@/components/base/newsList/NewsItem.vue";
import ColorSvg from "@/components/base/images/ColorSvg.vue";
import TranslationSvg from './assets/images/翻译 1.svg';
import NewsLogo from './assets/images/组合 293.svg';
const newsDetail = ref({});
const relationNews = ref([]);
const zhEnTexts = ref([]);
const znEnColSpan = ref(12);
const hasTranslation = ref(false);
const isOpenTranslation = ref(true);
const showMore = ref(false);
const route = useRoute();
onMounted(async () => {
const params = {
newsId: route.params.id
}
const { data: newsDetailData } = await getNewsDetail(params);
newsDetail.value = newsDetailData ?? {};
const { data: relationNewsData } = await getRelationNews(params);
relationNews.value = relationNewsData ?? [];
updateText();
});
function handleTranslation() {
isOpenTranslation.value = !isOpenTranslation.value;
updateText();
}
function updateText() {
const enTexts = newsDetail.value.content?.split('\n')
const zhTexts = newsDetail.value.contentZh?.split('\n')
console.log(enTexts.length, zhTexts.length)
const tempZhEnTexts = []
hasTranslation.value = enTexts.length === zhTexts.length
if (hasTranslation.value && isOpenTranslation.value) {
for (let i = 0; i < enTexts.length; i++) {
tempZhEnTexts.push(zhTexts[i]);
tempZhEnTexts.push(enTexts[i]);
}
znEnColSpan.value = 12;
} else {
for (let i = 0; i < enTexts.length; i++) {
tempZhEnTexts.push(enTexts[i]);
}
znEnColSpan.value = 24;
}
zhEnTexts.value = tempZhEnTexts;
}
</script>
<style lang="scss" scoped>
@import url("./style.css");
.top-box-news-deatail {
background-color: var(--bg-white-100);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
}
.content-box-news-detail {
align-items: flex-start;
gap: 16px;
}
.relation-news-box {
width: 520px;
}
.p-news-content {
//首行缩进
text-indent: 2em;
}
</style>
\ No newline at end of file
<template>
<el-space direction="vertical" fill class="full-width mouse-hover" v-for="(item, index) in props.news" :key="index">
<news-item2 :img="item.newsImage" :title="item.newsTitle" :from="`新闻来源:${item.newsOrg} 发表时间:${item.newsDate}`"
:aeraTags="item.industryList?.map(t => t.industryName)" @click="gotoNewsDetail(item.newsId)" />
<div class="divider-news-list"></div>
</el-space>
</template>
<script setup>
import NewsItem2 from '@/components/base/newsList/NewsItem2.vue';
import { useGotoNewsDetail } from '@/router/modules/news';
import { ElSpace } from 'element-plus';
const gotoNewsDetail = useGotoNewsDetail();
const props = defineProps({
news: {
type: Array,
default: () => []
}
})
</script>
<style lang="css" scoped>
.divider-news-list {
width: 100%;
height: 1px;
background: #eaecee;
}
</style>
\ No newline at end of file
<template>
<el-space direction="vertical" class="full-width" :size=24>
<el-radio-group class="radio-group-as-radius-btn">
<el-space>
<el-radio-button v-for="item in moduleList" :key="item.moduleId" :value="item.moduleId"
@click="() => gotoNewsModule(item.moduleId, item.moduleName, false)">{{
item.moduleName
}} ></el-radio-button>
<!-- <el-radio-button value="nul"><img src="@/assets/icons/adjustment.png" /></el-radio-button> -->
</el-space>
</el-radio-group>
<el-space :size="16" alignment="flex-start">
<box-background width="712px" height="100%" title="今日要闻">
<template #header-icon>
<img src="@/assets/icons/Headlines-icon.svg" />
</template>
<div class="common-padding">
<news-list :news="HeadlinesData" />
</div>
</box-background>
<box-background width="712px" title="中美博弈专题">
<template #header-icon>
<img src="@/assets/icons/subject-icon.png" />
</template>
<el-space :size="16" direction="vertical" fill class="full-width common-padding">
<el-space v-for="(item, index) in subjectData.slice(0, 3)" :key="index" class="mouse-hover"
@click="() => gotoNewsDetail(item.newsId)" alignment="center">
<common-text class="text-bold"
:color="index === 0 ? 'var(--color-red-100)' : (index === 1 ? 'var(--color-orange-100)' : 'var(--text-primary-65-color)')">
{{ `${index + 1}` }}
</common-text>
<common-text class="text-bold" color="var(--text-primary-80-color)">{{
item.newsTitle
}}</common-text>
</el-space>
<el-space v-for="(item, index) in subjectData.slice(3)" :key="index" class="mouse-hover">
<common-text class="text-regular" color="var(--text-primary-80-color)">{{
"• " + item.newsTitle
}}</common-text>
</el-space>
</el-space>
</box-background>
</el-space>
</el-space>
</template>
<script setup>
import { ref, onMounted } from "vue";
import '@/styles/container.scss';
import '@/styles/radio.scss';
import { useGotoNewsModule, useGotoNewsDetail } from "@/router/modules/news";
import { getMoudleType, getTodayNews, getHotNews } from "@/api/news/newsBrief";
import { ElInput, ElSpace, ElImage, ElDivider, ElCol, ElRow, ElRadioButton, ElRadioGroup } from "element-plus";
import CommonText from "@/components/base/texts/CommonText.vue";
import BoxBackground from '@/components/base/boxBackground/overviewNormalBox.vue'
import NewsList from "./NewsList.vue";
//博弈专题新闻数据
const subjectData = ref([]);
// 今日要闻
const HeadlinesData = ref([
]);
const moduleList = ref([]);
const gotoNewsDetail = useGotoNewsDetail();
const gotoNewsModule = useGotoNewsModule();
onMounted(async () => {
await initData();
});
const handleGetModuleType = async () => {
try {
const res = await getMoudleType();
console.log("模块类别", res);
if (res.code === 200 && res.data) {
moduleList.value = res.data;
}
} catch (error) { }
};
async function updateToday() {
const { data: todayNews } = await getTodayNews();
HeadlinesData.value = todayNews ?? [];
}
async function updateHotNews() {
const { data: hotNews } = await getHotNews();
subjectData.value = hotNews ?? [];
}
async function initData() {
await handleGetModuleType();
await updateToday();
await updateHotNews();
}
</script>
<style lang="scss" scoped>
@import url("./style.css");
</style>
\ No newline at end of file
<svg viewBox="0 0 71 72" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="71.000000" height="72.000000" fill="none" customFrame="#000000">
<defs>
<linearGradient id="paint_linear_0" x1="30.3467731" x2="30.3467731" y1="0" y2="72" gradientUnits="userSpaceOnUse">
<stop stop-color="rgb(5,95,194)" offset="0" stop-opacity="1" />
<stop stop-color="rgb(137,193,255)" offset="1" stop-opacity="1" />
</linearGradient>
</defs>
<g id="组合 293">
<path id="矩形 396" d="M63 31C63 28.7909 64.7909 27 67 27C69.2091 27 71 28.7909 71 31L71 64C71 68.4183 67.4183 72 63 72L63 31Z" fill="rgb(185,220,255)" fill-rule="evenodd" />
<path id="矩形 395" d="M56.6935 0C58.9027 0 60.6935 1.79086 60.6935 4L60.6935 72L4 72C1.79086 72 0 70.2091 0 68L0 4C0 1.79086 1.79086 0 4 0L56.6935 0Z" fill="url(#paint_linear_0)" fill-rule="evenodd" />
<path id="矢量 625" d="M25.3392 29.7137L22.2712 29.7137C21.9571 29.7137 21.6612 29.5661 21.4723 29.3152L14.8878 20.5694L14.8873 28.7138C14.8873 29.266 14.4396 29.7137 13.8873 29.7137L11.3066 29.7137C10.7544 29.7137 10.3066 29.266 10.3066 28.7137L10.3066 15.8555C10.3066 15.3032 10.7544 14.8555 11.3066 14.8555L14.8873 14.8555L21.773 23.9991L21.773 23.9991L21.773 23.9991L21.7729 15.8574C21.7729 15.3051 22.2207 14.8573 22.7729 14.8573L25.3391 14.8574C25.8914 14.8574 26.3391 15.3051 26.3391 15.8574L26.3393 28.7137C26.3393 29.266 25.8915 29.7137 25.3392 29.7137Z" fill="rgb(255,255,255)" fill-rule="evenodd" />
<rect id="矩形 397" width="20.612902" height="4.571429" x="30.919922" y="14.855469" rx="1.000000" fill="rgb(255,255,255)" />
<rect id="矩形 398" width="20.612902" height="4.571429" x="30.919922" y="25.144531" rx="1.000000" fill="rgb(255,255,255)" />
<rect id="矩形 399" width="41.225803" height="4.571429" x="10.306641" y="35.429688" rx="1.000000" fill="rgb(255,255,255)" />
<rect id="矩形 400" width="41.225803" height="4.571429" x="10.306641" y="45.714844" rx="1.000000" fill="rgb(255,255,255)" />
<rect id="矩形 401" width="41.225803" height="4.571429" x="10.306641" y="56.000000" rx="1.000000" fill="rgb(255,255,255)" />
</g>
</svg>
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.000000" height="16.000000" fill="none">
<rect id="翻译 1" width="16.000000" height="16.000000" x="0.000000" y="0.000000" />
<path id="矢量 455" d="M3.33301 9.9987L3.33301 11.332C3.33299 11.3736 3.33492 11.4151 3.33879 11.4565C3.34266 11.4979 3.34846 11.5391 3.35618 11.5799C3.36389 11.6208 3.3735 11.6612 3.385 11.7012C3.3965 11.7411 3.40985 11.7805 3.42503 11.8192C3.44021 11.8579 3.45717 11.8958 3.4759 11.933C3.49463 11.9701 3.51505 12.0063 3.53716 12.0415C3.55928 12.0767 3.58299 12.1108 3.6083 12.1438C3.6336 12.1768 3.6604 12.2086 3.68867 12.2391C3.71695 12.2696 3.74659 12.2987 3.77759 12.3264C3.80859 12.3541 3.84082 12.3803 3.87427 12.405C3.90773 12.4297 3.94226 12.4528 3.97787 12.4743C4.01349 12.4958 4.05003 12.5155 4.08749 12.5336C4.12495 12.5516 4.16318 12.5679 4.20216 12.5824C4.24115 12.5969 4.28073 12.6095 4.32089 12.6203C4.36106 12.631 4.40164 12.6399 4.44264 12.6469C4.48364 12.6539 4.52487 12.6589 4.56634 12.662L4.66634 12.6654L6.66634 12.6654L6.66634 13.9987L4.66634 13.9987C4.579 13.9987 4.49188 13.9944 4.40496 13.9859C4.31805 13.9773 4.23176 13.9645 4.1461 13.9475C4.06044 13.9304 3.97582 13.9092 3.89225 13.8839C3.80867 13.8585 3.72654 13.8291 3.64585 13.7957C3.56516 13.7623 3.48631 13.725 3.40928 13.6838C3.33226 13.6427 3.25744 13.5978 3.18482 13.5493C3.1122 13.5008 3.04214 13.4488 2.97463 13.3934C2.90711 13.338 2.84248 13.2794 2.78072 13.2176C2.71897 13.1559 2.66039 13.0913 2.60498 13.0237C2.54957 12.9562 2.49761 12.8862 2.44909 12.8136C2.40057 12.7409 2.35572 12.6661 2.31455 12.5891C2.27338 12.5121 2.23608 12.4332 2.20266 12.3525C2.16924 12.2718 2.13985 12.1897 2.1145 12.1061C2.08915 12.0225 2.06795 11.9379 2.05091 11.8523C2.03387 11.7666 2.02108 11.6803 2.01252 11.5934C2.00395 11.5065 1.99967 11.4194 1.99967 11.332L1.99967 9.9987L3.33301 9.9987L3.33301 9.9987ZM11.9997 6.66536L14.933 13.9987L13.4963 13.9987L12.6957 11.9987L9.96901 11.9987L9.16967 13.9987L7.73367 13.9987L10.6663 6.66536L11.9997 6.66536L11.9997 6.66536ZM11.333 8.5887L10.5017 10.6654L12.163 10.6654L11.333 8.5887ZM5.33301 1.33203L5.33301 2.66536L7.99967 2.66536L7.99967 7.33203L5.33301 7.33203L5.33301 9.33203L3.99967 9.33203L3.99967 7.33203L1.33301 7.33203L1.33301 2.66536L3.99967 2.66536L3.99967 1.33203L5.33301 1.33203ZM11.333 1.9987C11.4203 1.9987 11.5075 2.00298 11.5944 2.01154C11.6813 2.0201 11.7676 2.0329 11.8532 2.04994C11.9389 2.06698 12.0235 2.08817 12.1071 2.11352C12.1907 2.13888 12.2728 2.16826 12.3535 2.20169C12.4342 2.23511 12.513 2.2724 12.5901 2.31357C12.6671 2.35474 12.7419 2.39959 12.8145 2.44811C12.8871 2.49663 12.9572 2.5486 13.0247 2.604C13.0922 2.65941 13.1569 2.71799 13.2186 2.77975C13.2804 2.8415 13.339 2.90614 13.3944 2.97365C13.4498 3.04116 13.5017 3.11123 13.5503 3.18384C13.5988 3.25646 13.6436 3.33128 13.6848 3.40831C13.726 3.48533 13.7633 3.56419 13.7967 3.64488C13.8301 3.72556 13.8595 3.8077 13.8848 3.89127C13.9102 3.97485 13.9314 4.05947 13.9484 4.14512C13.9655 4.23078 13.9783 4.31707 13.9868 4.40399C13.9954 4.4909 13.9997 4.57803 13.9997 4.66536L13.9997 5.9987L12.6663 5.9987L12.6663 4.66536C12.6663 4.6217 12.6642 4.57813 12.6599 4.53467C12.6556 4.49122 12.6492 4.44807 12.6407 4.40524C12.6322 4.36241 12.6216 4.32011 12.6089 4.27832C12.5963 4.23653 12.5816 4.19546 12.5648 4.15512C12.5481 4.11478 12.5295 4.07535 12.5089 4.03684C12.4883 3.99832 12.4659 3.96091 12.4416 3.9246C12.4174 3.88829 12.3914 3.85326 12.3637 3.81951C12.336 3.78575 12.3067 3.75343 12.2758 3.72256C12.2449 3.69168 12.2126 3.66239 12.1789 3.63468C12.1451 3.60698 12.1101 3.581 12.0738 3.55674C12.0375 3.53248 12 3.51005 11.9615 3.48947C11.923 3.46888 11.8836 3.45024 11.8433 3.43352C11.8029 3.41681 11.7618 3.40212 11.7201 3.38944C11.6783 3.37677 11.636 3.36617 11.5931 3.35765C11.5503 3.34913 11.5072 3.34273 11.4637 3.33845C11.4202 3.33417 11.3767 3.33203 11.333 3.33203L9.33301 3.33203L9.33301 1.9987L11.333 1.9987L11.333 1.9987ZM3.99967 3.9987L2.66634 3.9987L2.66634 5.9987L3.99967 5.9987L3.99967 3.9987ZM6.66634 3.9987L5.33301 3.9987L5.33301 5.9987L6.66634 5.9987L6.66634 3.9987Z" fill="rgb(5,95,194)" fill-rule="nonzero" />
</svg>
<template>
<div class="newsBrief-page">
<div v-if="showPage === 'home'">
<div style="justify-content: space-between">
<div class="news-header">新闻速览</div>
<div class="input-box">
<el-input placeholder="请输入关键词" :suffix-icon="searchInput" clearable style="width: 800px; height: 48px">
</el-input>
</div>
<div class="btn-box">
<div
v-for="(item, index) in moduleList"
:key="index"
:class="moduleActiveId !== item.moduleId ? 'header-btn' : 'header-btn-select'"
@click="handleToWorldHot(item)"
@mouseenter="handleActiveModule(true, item)"
@mouseleave="handleActiveModule(false, item)"
>
<div class="btn-box-text">{{ item.moduleName }}</div>
<div class="btn-box-icon">
<img v-if="moduleActiveId === item.moduleId" 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" v-if="moduleList.length">
<img src="@/assets/icons/adjustment.png" />
</div>
</div>
</div>
<div class="main">
<div class="box">
<div class="box-header">
<div class="box-header-img">
<img src="@/assets/icons/Headlines-icon.svg" />
</div>
<div class="box-header-title" @click="changePage('headlines')">今日要闻 ></div>
</div>
<div class="divider"></div>
<div v-for="(item, index) in HeadlinesData" :key="index">
<div class="box1-item">
<div class="box1-item-left">
<div class="box1-item-title">
{{ item.title }}
</div>
<div class="box1-item-content">
<div class="source">新闻来源: {{ item.from }}</div>
<div class="time">发表时间:{{ item.time }}</div>
</div>
<div class="tag-box">
<div v-for="(tag, index) in item.tag" :key="index" class="tag">
{{ tag }}
</div>
</div>
</div>
<div style="margin-left: auto; padding: 10px">
<img :src="item.image" />
</div>
</div>
<div class="divider"></div>
</div>
</div>
<div class="box">
<div class="box-header">
<div class="box-header-img"><img src="@/assets/icons/subject-icon.png" /></div>
<div class="box-header-title">中美博弈专题</div>
</div>
<div class="divider"></div>
<div v-for="(item, index) in subjectData" :key="index">
<div class="subject-line">
<div style="display: flex; align-items: center">
<div
class="subject-line-id"
:class="{
subjectLineId1: index === 0,
subjectLineId2: index === 1,
subjectLineId3: index === 2
}"
>
{{ index <= 2 ? index + 1 : "•" }}
</div>
<div class="text" :class="{ textTop: index < 3 }">
{{ item.newsTitle }}
</div>
</div>
<img v-if="item.hot" :src="`src/assets/icons/arrow-0.png`" />
<img v-else :src="`src/assets/icons/arrow-1.png`" />
</div>
</div>
</div>
</div>
<el-scrollbar class="news-image-background">
<div class="common-page">
<el-space direction="vertical" class="full-width">
<div class="text-title-0-show" style="margin-top: 50px;">新闻速览</div>
<search-box placeholder="请输入关键词" style="margin-top: 19px;margin-bottom: 42px;"></search-box>
<news-main></news-main>
<!-- <Headlines v-if="showPage === 'headlines'" @type="showPage" @back="changePage" />
<Subject v-if="showPage === 'subject'" @back="changePage" /> -->
</el-space>
</div>
<Headlines v-if="showPage === 'headlines'" @type="showPage" @back="changePage" />
<Subject v-if="showPage === 'subject'" @back="changePage" />
</div>
</el-scrollbar>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getMoudleType, getTodayNews, getHotNews } from "@/api/news/newsBrief";
import '@/styles/container.scss';
import { useRoute } from "vue-router";
import Headlines from "./Headlines.vue";
import Subject from "./Subject.vue";
// import style from './style.css'
import { ElInput, ElSpace, ElImage, ElDivider, ElCol, ElRow } from "element-plus";
import AreaTag from '@/components/base/AreaTag/index.vue'
import CommonText from "@/components/base/texts/CommonText.vue";
import NewsMain from "./NewsMain.vue";
import SearchBox from "@/components/base/SearchBox/index.vue";
const route = useRoute();
//顶部数据搜索
const searchInput = ref("");
const moduleList = ref([]);
const moduleActiveId = ref("");
const handleGetModuleType = async () => {
try {
const res = await getMoudleType();
console.log("模块类别", res);
if (res.code === 200 && res.data) {
moduleList.value = res.data;
}
} catch (error) {}
};
// 今日要闻
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"
}
]);
const handleGetTodayNews = async () => {
try {
const res = await getTodayNews();
console.log("今日要闻", res);
if (res.code === 200 && res.data) {
} else {
HeadlinesData.value = [];
}
} catch (error) {
HeadlinesData.value = [];
}
};
//当前页面显示
const showPage = ref("home");
......@@ -178,54 +38,23 @@ const changePage = 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 },
]);
const handleGetHotNews = async () => {
try {
const res = await getHotNews();
console.log("中美博弈专题", res);
if (res.code === 200 && res.data) {
subjectData.value = res.data;
} else {
subjectData.value = [];
}
} catch (error) {
subjectData.value = [];
}
};
const handleActiveModule = (isIn, module) => {
moduleActiveId.value = isIn ? module.moduleId : "";
};
const handleToWorldHot = () => {
showPage.value = "subject";
moduleActiveId.value = "";
};
onMounted(() => {
handleGetModuleType();
handleGetTodayNews();
handleGetHotNews();
});
</script>
<style lang="scss" scoped>
@import url("./style.css");
.newsBrief-page {
height: 100%;
background: url("@/assets/images/background.png") no-repeat;
background-position: center -100px;
background-size: 100% 100%;
padding-top: 50px;
overflow: hidden;
overflow-y: auto;
.search-container {
margin: 0 auto;
}
.search-input {
width: 800px;
height: 48px;
//水平居中
margin: 0 auto;
display: block; // 强制设置为块级元素
}
</style>
.news-image-background {
height: 100%;
background-image: url("./assets/images/概览页顶端背景.png");
background-position: center -100px;
background-size: 100% 100%;
background-repeat: no-repeat;
overflow: hidden;
overflow-y: auto;
}
.news-header {
color: rgba(34, 41, 52, 1);
font-family: YouSheBiaoTiHei;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论