提交 a9b8232b authored 作者: 张烨's avatar 张烨

Merge branch 'master' into zy-dev

...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div id="app"> <div id="app">
<div class="pro-wrapper"> <div class="pro-wrapper">
<div class="home-page"> <div class="home-page">
<ModuleHeader/> <ModuleHeader />
<div class="main-container"> <div class="main-container">
<router-view /> <router-view />
</div> </div>
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
</div> </div>
</div> </div>
<div class="tool-box" @click="handleClickToolBox"> <div class="tool-box">
<div class="tool-item"> <!-- <div class="tool-item">
<img src="@/assets/icons/tool-item-icon1.png" alt="" /> <img src="@/assets/icons/tool-item-icon1.png" alt="" />
</div> </div>
<div class="tool-item"> <div class="tool-item">
...@@ -34,7 +34,26 @@ ...@@ -34,7 +34,26 @@
</div> </div>
<div class="tool-item"> <div class="tool-item">
<img src="@/assets/icons/tool-item-icon4.png" alt="" /> <img src="@/assets/icons/tool-item-icon4.png" alt="" />
</div> -->
<el-tooltip content="智能写报" placement="left" :offset="10">
<div class="tool-item" @click="handleOpenPage('znxb')">
<img src="@/assets/icons/tool-item-icon1.png" alt="" />
</div>
</el-tooltip>
<el-tooltip content="智能翻译" placement="left" :offset="10">
<div class="tool-item" @click="handleClickToolBox">
<img src="@/assets/icons/tool-item-icon2.png" alt="" />
</div>
</el-tooltip>
<!-- <div class="tool-item">
<img src="@/assets/icons/tool-item-icon3.png" alt="" />
</div> -->
<el-tooltip content="智能问答" placement="left" :offset="10">
<div class="tool-item" @click="handleOpenPage('znwd')">
<img src="@/assets/icons/tool-item-icon4.png" alt="" />
</div> </div>
</el-tooltip>
</div> </div>
<!-- <div class="ai-btn" @click="openAiBox"> <!-- <div class="ai-btn" @click="openAiBox">
...@@ -121,7 +140,7 @@ const handleGetPersonType = async () => { ...@@ -121,7 +140,7 @@ const handleGetPersonType = async () => {
personTypeList.value = []; personTypeList.value = [];
} }
window.sessionStorage.setItem("personTypeList", JSON.stringify(personTypeList.value)); window.sessionStorage.setItem("personTypeList", JSON.stringify(personTypeList.value));
} catch (error) { } } catch (error) {}
}; };
const isCurrentOverview = computed(() => { const isCurrentOverview = computed(() => {
...@@ -252,6 +271,14 @@ const handleClickTitle = item => { ...@@ -252,6 +271,14 @@ const handleClickTitle = item => {
} }
}; };
const handleOpenPage = page => {
const pageObj = {
znwd: "/chat",
znxb: "/writtingAsstaint"
};
window.open(pageObj[page], "_blank");
};
const handleClickToolBox = () => { const handleClickToolBox = () => {
ElMessage.warning("当前功能正在开发中,敬请期待!"); ElMessage.warning("当前功能正在开发中,敬请期待!");
}; };
...@@ -291,7 +318,7 @@ body { ...@@ -291,7 +318,7 @@ body {
text-align: justify; text-align: justify;
} }
.el-popper[data-popper-placement^="top"]>.el-popper__arrow:before { .el-popper[data-popper-placement^="top"] > .el-popper__arrow:before {
display: none; display: none;
} }
......
...@@ -129,3 +129,42 @@ export function getSupplyList(params) { ...@@ -129,3 +129,42 @@ export function getSupplyList(params) {
params, params,
}) })
} }
// 企业市值:市值变化
export function getMarketCapList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/marketCap/${params}`,
})
}
// 企业发展:营收折线图
export function getRevenueList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/revenue/${params}`,
})
}
// 企业发展:净利润折线图
export function getNetProfitList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/netProfit/${params}`,
})
}
// 企业发展:人员情况折线图
export function getPersonnelList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/personnel/${params}`,
})
}
// 企业发展: 市场占比折线图
export function getMarketShareList(params) {
return request({
method: 'GET',
url: `/api/enterprisePage/marketShare/${params}`,
})
}
\ No newline at end of file
...@@ -222,9 +222,14 @@ export function getThinkTankReportAbstract(params) { ...@@ -222,9 +222,14 @@ export function getThinkTankReportAbstract(params) {
//获取报告主要观点 //获取报告主要观点
export function getThinkTankReportContent(params) { export function getThinkTankReportContent(params) {
const { id, currentPage, pageSize } = params
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/thinkTankReport/content/${params}`, url: `/api/thinkTankReport/content/${id}`,
params: {
currentPage,
pageSize,
}
}) })
} }
......
...@@ -10,23 +10,20 @@ ...@@ -10,23 +10,20 @@
</div> </div>
</div> </div>
<div class="box3-main"> <div class="box3-main">
<div class="box3-item" v-for="(news, index) in list" :key="index" @click="handleClickToNewsDetail(news)"> <div class="box3-item" v-for="(news, index) in normalizedList" :key="index"
@click="handleClickToNewsDetail(news)">
<div class="left"> <div class="left">
<img <img :src="getProxyUrl(news.newsImage) || defaultImg" alt="" referrerpolicy="no-referrer"
:src="getProxyUrl(news.newsImage) || defaultImg" @error="e => (e.target.src = errImg || News1)" />
alt=""
referrerpolicy="no-referrer"
@error="e => (e.target.src = errImg||News1)"
/>
</div> </div>
<div class="right"> <div class="right">
<div class="right-top"> <div class="right-top">
<div class="title">{{ news.newsTitle||news.title }}</div> <div class="title">{{ news.newsTitle || news.title }}</div>
<div class="time"> <div class="time">
{{ news.newsDate ? news.newsDate.slice(5) : "" }} {{ news.newsOrg ? "-" + news.newsOrg : "" }} {{ news.newsDate ? news.newsDate.slice(5) : "" }} {{ news.newsOrg ? "-" + news.newsOrg : "" }}
</div> </div>
</div> </div>
<div class="right-footer">{{ news.newsContent||news.description }}</div> <div class="right-footer">{{ news.newsContent || news.description }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -34,15 +31,21 @@ ...@@ -34,15 +31,21 @@
</template> </template>
<script setup> <script setup>
import { computed } from "vue";
import router from "@/router/index"; import router from "@/router/index";
import News1 from "@/assets/images/news1.png"; // 错误图片 import News1 from "@/assets/images/news1.png"; // 错误图片
import defaultNew from "@/assets/images/default-icon-news.png"; // 默认图片 import defaultNew from "@/assets/images/default-icon-news.png"; // 默认图片
let { list,errImg,defaultImg } = defineProps({ let { list, newsList, errImg, defaultImg } = defineProps({
list: { list: {
type: Array, type: Array,
default: () => [] default: () => []
}, },
// 兼容历史用法:部分页面使用 newsList 作为入参
newsList: {
type: Array,
default: undefined
},
defaultImg: { defaultImg: {
type: String, type: String,
default: defaultNew default: defaultNew
...@@ -53,6 +56,11 @@ let { list,errImg,defaultImg } = defineProps({ ...@@ -53,6 +56,11 @@ let { list,errImg,defaultImg } = defineProps({
} }
}); });
// 统一对外渲染数据源:优先使用 list,其次兼容 newsList
const normalizedList = computed(() => {
return (Array.isArray(list) && list.length ? list : newsList) || [];
});
// 处理图片代理 // 处理图片代理
const getProxyUrl = url => { const getProxyUrl = url => {
if (!url) return ""; if (!url) return "";
...@@ -74,7 +82,7 @@ const handleClickToNewsDetail = news => { ...@@ -74,7 +82,7 @@ const handleClickToNewsDetail = news => {
const route = router.resolve({ const route = router.resolve({
path: "/newsAnalysis", path: "/newsAnalysis",
query: { query: {
newsId: news.newsId newsId: news.newsId ?? news.id
} }
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
...@@ -183,9 +191,11 @@ const handleToMoreNews = () => { ...@@ -183,9 +191,11 @@ const handleToMoreNews = () => {
width: 657px; width: 657px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
color: var(--color-main-active); color: var(--color-main-active);
.title { .title {
color: var(--color-main-active); color: var(--color-main-active);
} }
......
...@@ -70,7 +70,7 @@ const handleCollect = () => { ...@@ -70,7 +70,7 @@ const handleCollect = () => {
} }
const emit = defineEmits(['save','download','collect']) const emit = defineEmits(['save', 'download', 'collect'])
</script> </script>
......
<template> <template>
<div class="box4"> <div class="msg-bubble">
<div class="box4-header"> <div class="msg-bubble-header">
<div class="header-icon"> <div class="header-icon">
<!-- <img src="./image1.png" alt="" /> --> <!-- <img src="./image1.png" alt="" /> -->
<img src="./message-icon.svg" alt="" /> <img src="./message-icon.svg" alt="" />
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
</div> </div>
<div class="more" @click="handleToMoreNews">{{ "更多 +" }}</div> <div class="more" @click="handleToMoreNews">{{ "更多 +" }}</div>
</div> </div>
<div class="box4-main"> <div class="msg-bubble-main">
<div class="message-bubble" v-for="(item, index) in messageList" :key="index" @click="handleClickPerson(item)"> <div class="message-bubble" v-for="(item, index) in messageList" :key="index" @click="handleClickPerson(item)">
<div class="avatar-container"> <div class="avatar-container">
<img :src="item[props.imageUrl] || avatarUser" :alt="item[props.name]" class="avatar" /> <img :src="item[props.imageUrl] || avatarUser" :alt="item[props.name]" class="avatar" />
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
<!-- <MessageBubble v-for="(item, index) in messageList" @click="handleClickPsserson(item)" <!-- <MessageBubble v-for="(item, index) in messageList" @click="handleClickPsserson(item)"
@info-click="handleMediaClick(item)" :key="index" :avatar="item.img ? item.img : DefaultIcon1" :name="item.name" @info-click="handleMediaClick(item)" :key="index" :avatar="item.img ? item.img : DefaultIcon1" :name="item.name"
:time="item.time" :source="item.source" :content="item.content" /> --> :time="item.time" :source="item.source" :content="item.content" /> -->
<!-- <div class="box4-main-item" v-for="(item, index) in messageList" :key="index"> <!-- <div class="msg-bubble-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left" @click="handleClickPerson(item)"> <div class="left" @click="handleClickPerson(item)">
<img :src="item.img ? item.img : DefaultIcon1" alt="" /> <img :src="item.img ? item.img : DefaultIcon1" alt="" />
</div> </div>
...@@ -121,7 +121,7 @@ const handleToMoreNews = item => { ...@@ -121,7 +121,7 @@ const handleToMoreNews = item => {
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.box4 { .msg-bubble {
width: 792px; width: 792px;
height: 450px; height: 450px;
border-radius: 10px; border-radius: 10px;
...@@ -129,7 +129,7 @@ const handleToMoreNews = item => { ...@@ -129,7 +129,7 @@ const handleToMoreNews = item => {
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
border: 1px solid rgb(234, 236, 238); border: 1px solid rgb(234, 236, 238);
.box4-header { .msg-bubble-header {
width: 792px; width: 792px;
height: 48px; height: 48px;
border-bottom: 1px solid rgb(234, 236, 238); border-bottom: 1px solid rgb(234, 236, 238);
...@@ -178,7 +178,7 @@ const handleToMoreNews = item => { ...@@ -178,7 +178,7 @@ const handleToMoreNews = item => {
} }
} }
.box4-main { .msg-bubble-main {
height: 402px; height: 402px;
overflow-y: auto; overflow-y: auto;
box-sizing: border-box; box-sizing: border-box;
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
<div class="name">{{ "管理员" }}</div> <div class="name">{{ "管理员" }}</div>
</div> </div>
</div> </div>
<div class="menu-box" v-if="isShowMenu" @mouseenter="handleHoverMenu(true)" @mouseleave="handleHoverMenu(false)"> <div class="menu-box" v-show="isShowMenu" @mouseenter="handleHoverMenu(true)" @mouseleave="handleHoverMenu(false)">
<div class="menu-content"> <div class="menu-content">
<div class="menu-item" v-for="(item, index) in menuList" :key="index" @click="handleToModule(item)"> <div class="menu-item" v-for="(item, index) in menuList" :key="index" @click="handleToModule(item)">
<div class="icon"> <div class="icon">
...@@ -372,11 +372,16 @@ onMounted(() => { ...@@ -372,11 +372,16 @@ onMounted(() => {
top: 52px; top: 52px;
left: 0; left: 0;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px; border-radius: 10px;
backdrop-filter: blur(30px); backdrop-filter: blur(10px);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); -webkit-backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.8); box-shadow: 0px 8px 32px 0px rgba(31, 38, 135, 0.15);
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.2) 100%);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
.menu-content { .menu-content {
width: 562px; width: 562px;
......
...@@ -112,7 +112,7 @@ const handleToNewsAnalysis = (item, index) => { ...@@ -112,7 +112,7 @@ const handleToNewsAnalysis = (item, index) => {
} }
.more { .more {
width: 45px; width: 54px;
height: 24px; height: 24px;
position: absolute; position: absolute;
top: 12px; top: 12px;
...@@ -134,7 +134,7 @@ const handleToNewsAnalysis = (item, index) => { ...@@ -134,7 +134,7 @@ const handleToNewsAnalysis = (item, index) => {
.news-item { .news-item {
display: flex; display: flex;
height: 78px; height: 76px;
width: 749px; width: 749px;
margin-left: 21px; margin-left: 21px;
border-bottom: 1px solid rgba(240, 242, 244, 1); border-bottom: 1px solid rgba(240, 242, 244, 1);
......
//样式主页 //样式主页
const StylePages = () => import("@/components/devStyle/components/index.vue"); const StylePages = () => import("@/styles/components/index.vue");
const stylePagesRoutes = [ const stylePagesRoutes = [
// 智库系统的主要路由 // 智库系统的主要路由
......
<script setup lang="ts">
import { ElRow, ElCol } from 'element-plus';
import '@/styles/common.scss'
const span = 12
</script>
<template>
<el-row class="wrapper">
<el-col :span="span">
<pre>
{{ `import '@/styles/common.scss';
<template>
<div class="background-as-card"></div>
</template>
`}}
</pre>
<div class="background-as-card">
<div v-for="item in [1, 2, 3, 4]" :key="item">
{{ item }}
</div>
</div>
</el-col>
</el-row>
</template>
<style lang="scss" scoped>
.wrapper {
background-color: rgba(0, 0, 0, 0.068);
padding: 10px;
}
</style>
\ No newline at end of file
<script setup lang="ts">
import { ElRadioGroup, ElRadioButton, ElRow, ElCol } from 'element-plus';
import { ref } from 'vue';
import '@/styles/radio.scss';
const radio = ref(1)
const span = 12
</script>
<template>
<el-row>
<el-col :span="span">
<pre>
{{ `import '@/styles/radio.scss';
<template>
<el-radio-group class="radio-group-as-gap-btn">
</el-radio-group>
</template>
`}}
</pre>
<el-radio-group v-model="radio" class="radio-group-as-gap-btn">
<el-radio-button :value="1">选项1</el-radio-button>
<el-radio-button :value="2">选项2</el-radio-button>
<el-radio-button :value="3">选项3</el-radio-button>
</el-radio-group>
</el-col>
</el-row>
</template>
<style lang="scss" scoped></style>
\ No newline at end of file
<script setup lang="ts">
import { ElTabs, ElTabPane, ElSpace, ElRow, ElCol } from 'element-plus';
import { ref } from 'vue';
import '@/styles/tabs.scss'
const span = 12
</script>
<template>
<el-row>
<el-col :span="span">
<pre>
{{ `import '@/styles/tabs.scss';
<template>
<el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn">
</el-tabs>
</template>
`}}
</pre>
<el-tabs stretch class="tabs-header-as-card tabs-nav-no-wrap tabs-bar-as-btn">
<el-tab-pane label="tab1">tab1</el-tab-pane>
<el-tab-pane label="tab2">tab2</el-tab-pane>
<el-tab-pane label="tab3">tab3</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</template>
<style lang="scss" scoped></style>
\ No newline at end of file
<template> <template>
<el-scrollbar> <el-scrollbar>
<div class="common-page"> <div class="common-page">
<el-space direction="vertical" :size="20" alignment="flex-start"> <el-space direction="vertical" :size="20" alignment="flex-start" fill>
<div class="text-title-0-show">开发样式</div> <div class="text-title-0-show">开发样式</div>
<div class="text-title-1-show">样式变量</div> <div class="text-title-1-show">样式变量</div>
<ConstStyle /> <ConstStyle />
<div class="text-title-1-show">文字样式</div> <div class="text-title-1-show">文字样式</div>
<TextStyle /> <TextStyle />
<div class="text-title-1-show">通用样式/组件</div>
<el-tabs tabPosition="left">
<el-tab-pane label="通用" lazy>
<common-page />
</el-tab-pane>
<el-tab-pane label="单选框" lazy>
<radio-page />
</el-tab-pane>
<el-tab-pane label="选项卡" lazy>
<tabs-page />
</el-tab-pane>
</el-tabs>
</el-space> </el-space>
</div> </div>
</el-scrollbar> </el-scrollbar>
...@@ -16,5 +28,10 @@ ...@@ -16,5 +28,10 @@
import "@/styles/container.scss" import "@/styles/container.scss"
import TextStyle from './textStyle.vue'; import TextStyle from './textStyle.vue';
import ConstStyle from './constStyle.vue'; import ConstStyle from './constStyle.vue';
import { ElTabs, ElTabPane, ElSpace } from "element-plus";
import RadioPage from './RadioPage/index.vue';
import TabsPage from './TabsPage/index.vue';
import CommonPage from './CommonPage/index.vue';
</script> </script>
<style lang="scss" scoped></style>
\ No newline at end of file
@use '@/styles/common.scss';
.radio-group-as-gap-btn {
@extend .text-tip-1;
.el-radio-button {
--el-radio-button-checked-bg-color: var(--bg-white-100);
--el-radio-button-checked-border-color: var(--bg-black-10);
border-radius: 4px;
}
.el-radio-button.is-active {
--el-radio-button-checked-text-color: var(--color-primary-100);
--el-radio-button-checked-bg-color: var(--color-primary-10);
--el-radio-button-checked-border-color: var(--color-primary-5);
border-radius: 4px;
}
}
\ No newline at end of file
...@@ -3,14 +3,23 @@ ...@@ -3,14 +3,23 @@
<div class="content-wrapper"> <div class="content-wrapper">
<div class="policy-monitoring"> <div class="policy-monitoring">
<div class="header"> <div class="header">
<div class="section" v-for="(section, index) in sectionTab" :key="index" <div
:style="sections[index].waveBall.length === 2 ? 'width: 350px' : 'width:503px'"> class="section"
v-for="(section, index) in sectionTab"
:key="index"
:style="sections[index].waveBall.length === 2 ? 'width: 350px' : 'width:503px'"
>
<img class="section-title" :src="`/public/icon/riskToday/btn-` + index + `.png`" /> <img class="section-title" :src="`/public/icon/riskToday/btn-` + index + `.png`" />
<div class="stats"> <div class="stats">
<div v-for="value in sections[index].waveBall" @click="highLight(value)"> <div v-for="value in sections[index].waveBall" @click="highLight(value)">
<div @click="highLight(value.title)" style="cursor: pointer;"> <div @click="highLight(value.title)" style="cursor: pointer">
<WaveBall :percent="value.percent" :data="value" :color="section.waterColor" :size="128" <WaveBall
@click="highLight(value)" /> :percent="value.percent"
:data="value"
:color="section.waterColor"
:size="128"
@click="highLight(value)"
/>
<div class="waveBall-text">{{ value.title }}</div> <div class="waveBall-text">{{ value.title }}</div>
</div> </div>
</div> </div>
...@@ -35,12 +44,20 @@ ...@@ -35,12 +44,20 @@
</div> </div>
<div style="display: flex"> <div style="display: flex">
<div class="risk-signals"> <div class="risk-signals">
<div class="risk-signals-item" v-for="(item, index) in warningList" :key="index" <div
@click="handleClickToDetailO(item)" :class="{ 'highlighted': item.eventType === highlightedEventType }"> class="risk-signals-item"
<div class="item-left" :class="{ v-for="(item, index) in warningList"
:key="index"
@click="handleClickToDetailO(item)"
:class="{ highlighted: item.eventType === highlightedEventType }"
>
<div
class="item-left"
:class="{
itemLeftStatus1: item.signalLevel === '特别重大', itemLeftStatus1: item.signalLevel === '特别重大',
itemLeftStatus2: item.signalLevel === '重大风险' itemLeftStatus2: item.signalLevel === '重大风险'
}"> }"
>
{{ item.signalLevel ? item.signalLevel : "一般风险" }} {{ item.signalLevel ? item.signalLevel : "一般风险" }}
</div> </div>
<div class="item-right"> <div class="item-right">
...@@ -62,8 +79,15 @@ ...@@ -62,8 +79,15 @@
<img src="./icon/box1-right.png" alt="" /> <img src="./icon/box1-right.png" alt="" />
</div> </div>
</div> </div>
<el-carousel ref="carouselRef" style="height: 412px; width: 736px" :autoplay="true" :interval="3000" <el-carousel
arrow="never" indicator-position="none" @change="handleCarouselChange"> ref="carouselRef"
style="height: 412px; width: 736px"
:autoplay="true"
:interval="3000"
arrow="never"
indicator-position="none"
@change="handleCarouselChange"
>
<el-carousel-item v-for="(News, NewsIndex) in hotNewsList" :key="NewsIndex"> <el-carousel-item v-for="(News, NewsIndex) in hotNewsList" :key="NewsIndex">
<div class="carousel-item"> <div class="carousel-item">
<div class="carousel-title"> <div class="carousel-title">
...@@ -74,9 +98,13 @@ ...@@ -74,9 +98,13 @@
{{ News.category }} {{ News.category }}
</div> </div>
</div> </div>
<div style="/* 矩形 351 */ width: 664px; height: 1px; background: rgba(234, 236, 238, 1)"></div> <div
style="/* 矩形 351 */ width: 664px; height: 1px; background: rgba(234, 236, 238, 1)"
></div>
<div class="carousel-content">{{ News.content }}</div> <div class="carousel-content">{{ News.content }}</div>
<div style="/* 矩形 351 */ width: 664px; height: 1px; background: rgba(234, 236, 238, 1)"></div> <div
style="/* 矩形 351 */ width: 664px; height: 1px; background: rgba(234, 236, 238, 1)"
></div>
<div class="carousel-bottom"> <div class="carousel-bottom">
<div class="carousel-bottom">{{ News.date + News.source }}</div> <div class="carousel-bottom">{{ News.date + News.source }}</div>
</div> </div>
...@@ -198,7 +226,7 @@ const sections = ref([ ...@@ -198,7 +226,7 @@ const sections = ref([
count: 14, count: 14,
change: "无新增", change: "无新增",
unit: "次", unit: "次",
title: "230调查" title: "232调查"
}, },
{ {
percent: 3, // 估算的百分比 percent: 3, // 估算的百分比
...@@ -223,7 +251,7 @@ const handlegetBillRiskSignal = async () => { ...@@ -223,7 +251,7 @@ const handlegetBillRiskSignal = async () => {
if (res.code === 200) { if (res.code === 200) {
warningList.value = res.data; warningList.value = res.data;
} }
} catch (error) { } } catch (error) {}
}; };
const hotNewsList = ref([ const hotNewsList = ref([
{ {
...@@ -269,9 +297,9 @@ const handleClickToDetailO = item => { ...@@ -269,9 +297,9 @@ const handleClickToDetailO = item => {
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
const highlightedEventType = ref('') const highlightedEventType = ref("");
const highLight = (title) => { const highLight = title => {
console.log(title) console.log(title);
// 如果再次点击同一个,取消高亮 // 如果再次点击同一个,取消高亮
if (highlightedEventType.value === title) { if (highlightedEventType.value === title) {
highlightedEventType.value = null; highlightedEventType.value = null;
......
...@@ -187,7 +187,7 @@ ...@@ -187,7 +187,7 @@
<div class="col-domain" style="color: rgb(59, 65, 75); font-weight: 700">所属领域</div> <div class="col-domain" style="color: rgb(59, 65, 75); font-weight: 700">所属领域</div>
<div class="col-date" style="color: rgb(59, 65, 75); font-weight: 700">制裁时间</div> <div class="col-date" style="color: rgb(59, 65, 75); font-weight: 700">制裁时间</div>
<div class="col-member" v-if="rankType !== 'school'" style="color: rgb(59, 65, 75); font-weight: 700"> <div class="col-member" v-if="rankType !== 'school'" style="color: rgb(59, 65, 75); font-weight: 700">
关键人物 省份
</div> </div>
</div> </div>
<div class="table-list"> <div class="table-list">
...@@ -210,7 +210,8 @@ ...@@ -210,7 +210,8 @@
</div> </div>
</div> </div>
<div class="col-date">{{ item.date }}</div> <div class="col-date">{{ item.date }}</div>
<div class="col-member" v-if="rankType !== 'school'">{{ item.member }}</div> <!-- <div class="col-member" v-if="rankType !== 'school'">{{ item.member }}</div> -->
<div class="col-member" v-if="rankType !== 'school'">{{ item.province }}</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -1108,6 +1109,7 @@ const handleGetDomainContainmentRanking = async () => { ...@@ -1108,6 +1109,7 @@ const handleGetDomainContainmentRanking = async () => {
// 处理返回的数据结构 // 处理返回的数据结构
const processedData = processRankingData(res.data); const processedData = processRankingData(res.data);
rankList.value = processedData; rankList.value = processedData;
console.log("排行数据 =>", rankList.value);
} }
} catch (error) { } catch (error) {
console.error("获取美对华领域打压遏制排行失败:", error); console.error("获取美对华领域打压遏制排行失败:", error);
......
...@@ -89,7 +89,7 @@ ...@@ -89,7 +89,7 @@
<el-empty <el-empty
v-if="box2DataList.length === 0" v-if="box2DataList.length === 0"
style="padding-top: 80px" style="padding-top: 80px"
description="暂无数据1" description="暂无数据"
:image-size="100" :image-size="100"
/> />
<div <div
...@@ -712,7 +712,7 @@ onUnmounted(() => { ...@@ -712,7 +712,7 @@ onUnmounted(() => {
.main { .main {
width: 1598px; width: 1598px;
height: 884px; // height: 884px;
margin: 0 auto; margin: 0 auto;
margin-top: 14px; margin-top: 14px;
display: flex; display: flex;
...@@ -726,9 +726,9 @@ onUnmounted(() => { ...@@ -726,9 +726,9 @@ onUnmounted(() => {
background: rgba(255, 255, 255, 0.65); background: rgba(255, 255, 255, 0.65);
} }
.left { & > .left {
width: 472px; width: 472px;
display: none;
.box1 { .box1 {
width: 472px; width: 472px;
height: 884px; height: 884px;
...@@ -915,11 +915,12 @@ onUnmounted(() => { ...@@ -915,11 +915,12 @@ onUnmounted(() => {
} }
.right { .right {
width: 1110px; width: 100%;
.box2 { .box2 {
width: 1110px; width: 100%;
height: 434px; // height: 434px;
height: 700px;
.box2-header { .box2-header {
height: 48px; height: 48px;
...@@ -957,30 +958,34 @@ onUnmounted(() => { ...@@ -957,30 +958,34 @@ onUnmounted(() => {
} }
.box2-main { .box2-main {
height: 386px; // height: 386px;
height: 646px;
background: rgba(255, 255, 255, 0.65); background: rgba(255, 255, 255, 0.65);
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 16px; gap: 16px;
.inner-box1 { .inner-box1 {
width: 640px; width: 50%;
height: 368px; // height: 368px;
height: 100%;
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1); // border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px; // border-radius: 10px;
display: flex; display: flex;
.left { .left {
width: 320px; // width: 320px;
border-right: 1px solid rgba(234, 236, 238, 1); width: 100%;
// border-right: 1px solid rgba(234, 236, 238, 1);
.left-main { .left-main {
margin-top: 9px; // margin-top: 9px;
height: 270px; height: 600px;
.left-item { .left-item {
width: 100%;
height: 54px; height: 54px;
border: 1px solid transparent; border: 1px solid transparent;
display: flex; display: flex;
...@@ -1009,7 +1014,7 @@ onUnmounted(() => { ...@@ -1009,7 +1014,7 @@ onUnmounted(() => {
} }
.text { .text {
width: 260px; width: 95%;
height: 30px; height: 30px;
margin-left: 12px; margin-left: 12px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
...@@ -1035,7 +1040,7 @@ onUnmounted(() => { ...@@ -1035,7 +1040,7 @@ onUnmounted(() => {
} }
.left-footer { .left-footer {
margin-top: 30px; // margin-top: 30px;
height: 60px; height: 60px;
display: flex; display: flex;
justify-content: center; justify-content: center;
...@@ -1049,7 +1054,7 @@ onUnmounted(() => { ...@@ -1049,7 +1054,7 @@ onUnmounted(() => {
overflow: hidden; overflow: hidden;
overflow-y: auto; overflow-y: auto;
cursor: pointer; cursor: pointer;
display: none;
.title { .title {
width: 283px; width: 283px;
min-height: 24px; min-height: 24px;
...@@ -1157,8 +1162,10 @@ onUnmounted(() => { ...@@ -1157,8 +1162,10 @@ onUnmounted(() => {
} }
.inner-box2 { .inner-box2 {
width: 412px; // width: 412px;
height: 368px; width: 760px;
// height: 368px;
height: 617px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1); border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px; border-radius: 10px;
...@@ -1185,8 +1192,8 @@ onUnmounted(() => { ...@@ -1185,8 +1192,8 @@ onUnmounted(() => {
} }
.box2Chart { .box2Chart {
width: 412px; width: 760px;
height: 368px; height: 617px;
} }
} }
} }
...@@ -1194,8 +1201,9 @@ onUnmounted(() => { ...@@ -1194,8 +1201,9 @@ onUnmounted(() => {
.box3 { .box3 {
margin-top: 16px; margin-top: 16px;
width: 1110px; width: 100%;
height: 434px; // height: 434px;
height: 700px;
.box3-header { .box3-header {
height: 48px; height: 48px;
...@@ -1233,30 +1241,32 @@ onUnmounted(() => { ...@@ -1233,30 +1241,32 @@ onUnmounted(() => {
} }
.box3-main { .box3-main {
height: 386px; height: 646px;
background: rgba(255, 255, 255, 0.65); background: rgba(255, 255, 255, 0.65);
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 16px; gap: 16px;
.inner-box1 { .inner-box1 {
width: 640px; width: 50%;
height: 368px; // height: 368px;
height: 100%;
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1); // border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px; // border-radius: 10px;
display: flex; display: flex;
.left { .left {
width: 320px; width: 100%;
border-right: 1px solid rgba(234, 236, 238, 1); // border-right: 1px solid rgba(234, 236, 238, 1);
.left-main { .left-main {
margin-top: 9px; // margin-top: 9px;
height: 270px; height: 600px;
.left-item { .left-item {
width: 100%;
height: 54px; height: 54px;
border: 1px solid transparent; border: 1px solid transparent;
display: flex; display: flex;
...@@ -1285,7 +1295,7 @@ onUnmounted(() => { ...@@ -1285,7 +1295,7 @@ onUnmounted(() => {
} }
.text { .text {
width: 260px; width: 95%;
height: 30px; height: 30px;
margin-left: 12px; margin-left: 12px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
...@@ -1311,7 +1321,7 @@ onUnmounted(() => { ...@@ -1311,7 +1321,7 @@ onUnmounted(() => {
} }
.left-footer { .left-footer {
margin-top: 30px; // margin-top: 30px;
height: 60px; height: 60px;
display: flex; display: flex;
justify-content: center; justify-content: center;
...@@ -1325,7 +1335,7 @@ onUnmounted(() => { ...@@ -1325,7 +1335,7 @@ onUnmounted(() => {
overflow: hidden; overflow: hidden;
overflow-y: auto; overflow-y: auto;
cursor: pointer; cursor: pointer;
display: none;
.title { .title {
width: 283px; width: 283px;
min-height: 24px; min-height: 24px;
...@@ -1433,8 +1443,8 @@ onUnmounted(() => { ...@@ -1433,8 +1443,8 @@ onUnmounted(() => {
} }
.inner-box2 { .inner-box2 {
width: 412px; width: 760px;
height: 368px; height: 617px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1); border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px; border-radius: 10px;
...@@ -1461,8 +1471,8 @@ onUnmounted(() => { ...@@ -1461,8 +1471,8 @@ onUnmounted(() => {
} }
.box3Chart { .box3Chart {
width: 412px; width: 760px;
height: 368px; height: 617px;
} }
} }
} }
......
...@@ -45,28 +45,32 @@ ...@@ -45,28 +45,32 @@
</div> </div>
<div class="tooltip-main"> <div class="tooltip-main">
<div class="tooltip-main-item" v-for="item, index in currentDetailList" :key="index"> <div class="tooltip-main-item" v-for="item, index in currentDetailList" :key="index">
<div class="item-footer color-bg-active flex-display" @click="handleToDetail(item)">
<div class="footer-text text-tip-2 main-color">{{ item.name }}</div>
<div class="footer-arrow">
<img src="./right-arrow.svg" alt="">
</div>
</div>
<div class="item-list" v-for="val, idx in item.list" :key="idx">
<div class="item-header flex-display"> <div class="item-header flex-display">
<div class="item-header-left flex-display"> <div class="item-header-left flex-display">
<div class="logo"> <div class="logo">
<img style="width:100%; height: 100%" :src="item.orgLogoUrl" alt="logo"> <img style="width:100%; height: 100%" :src="val.orgLogoUrl" alt="logo">
</div> </div>
<div class="name text-bold">{{ item.orgName }}</div> <div class="name text-primary-80-clor text-bold">{{ val.orgName }}</div>
<div class="status"> <div class="status">
<div class="status-on text-tip-2" v-if="item.stauts === 2">{{ '已落实' }}</div> <div class="status-on text-tip-2" v-if="val.stauts === 2">{{ '已落实' }}</div>
<div class="status-off text-tip-2" v-else>{{ '未落实' }}</div> <div class="status-off text-tip-2" v-else>{{ '未落实' }}</div>
</div> </div>
</div> </div>
<div class="item-header-right flex-display"> <div class="item-header-right flex-display">
<AreaTag v-for="tag, idx in item.techDomainList.slice(0, 3)" :key="idx" :tagName="tag"></AreaTag> <AreaTag v-for="tag, idxx in val.techDomainList.slice(0, 3)" :key="idxx" :tagName="tag"></AreaTag>
</div>
</div> </div>
<div class="item-content text-compact">{{ item.name }}</div>
<div class="item-footer color-bg-active flex-display" @click="handleToDetail(item)">
<div class="footer-text text-tip-2 main-color">{{ item.administrativeOrderInfoTitle }}</div>
<div class="footer-arrow">
<img src="./right-arrow.svg" alt="">
</div> </div>
<div class="item-content text-compact">{{ val.name }}</div>
</div> </div>
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
...@@ -282,7 +286,7 @@ function getOption() { ...@@ -282,7 +286,7 @@ function getOption() {
const titles = months.map((month, index) => ({ const titles = months.map((month, index) => ({
// text: `{month|${month.format('M月')}} {stats| ${monthStats[index].total} , 已落实 ${monthStats[index].resolved} 项}`, // text: `{month|${month.format('M月')}} {stats| ${monthStats[index].total} , 已落实 ${monthStats[index].resolved} 项}`,
text: index ===0 ?`{month|${month.format('M月')}} {stats| ${monthStats[index].total} , 已落实 0 项}`:` {month|${month.format('M月')}} {stats| ${monthStats[index].total} , 已落实 0 项}`, text: index === 0 ? `{month|${month.format('M月')}} {stats| ${monthStats[index].total} , 已落实 0 项}` : ` {month|${month.format('M月')}} {stats| ${monthStats[index].total} , 已落实 0 项}`,
left: `${gapPercent + index * (calendarWidthPercent + gapPercent)}%`, left: `${gapPercent + index * (calendarWidthPercent + gapPercent)}%`,
top: 10, top: 10,
textStyle: { textStyle: {
...@@ -447,7 +451,20 @@ onMounted(() => { ...@@ -447,7 +451,20 @@ onMounted(() => {
const list = params.data[1].raw const list = params.data[1].raw
if (list.length > 0) { if (list.length > 0) {
currentDate.value = date currentDate.value = date
currentDetailList.value = list // 按 administrativeOrderInfoTitle 分类
const grouped = [];
const map = new Map();
list.forEach(item => {
const key = item.administrativeOrderInfoTitle;
if (!map.has(key)) {
map.set(key, { name: key, list: [] });
grouped.push(map.get(key));
}
map.get(key).list.push(item);
});
currentDetailList.value = grouped;
console.log('currentDetailList', currentDetailList.value);
// 统计不同 orgName 的个数 // 统计不同 orgName 的个数
const orgNames = new Set(list.map(item => item.orgName)); const orgNames = new Set(list.map(item => item.orgName));
currentOrgNum.value = orgNames.size currentOrgNum.value = orgNames.size
...@@ -505,8 +522,9 @@ onBeforeUnmount(() => { ...@@ -505,8 +522,9 @@ onBeforeUnmount(() => {
} }
.tooltip-main-item { .tooltip-main-item {
padding: 10px 0;
width: 622px; width: 622px;
height: 144px; /* height: 144px; */
border-bottom: 1px solid rgb(234, 236, 238); border-bottom: 1px solid rgb(234, 236, 238);
} }
...@@ -559,7 +577,7 @@ onBeforeUnmount(() => { ...@@ -559,7 +577,7 @@ onBeforeUnmount(() => {
.item-footer { .item-footer {
width: 622px; width: 622px;
height: 30px; height: 40px;
padding: 0 8px; padding: 0 8px;
margin-top: 4px; margin-top: 4px;
border-radius: 4px; border-radius: 4px;
......
...@@ -195,7 +195,7 @@ ...@@ -195,7 +195,7 @@
<div class="bottom-item"> <div class="bottom-item">
<div class="bottom-item-title"> <div class="bottom-item-title">
<img :src="icon4" alt="" /> <img :src="icon4" alt="" />
<span>美政府部门对华打压遏制历程</span> <span>美政府部门对华工作日程表</span>
</div> </div>
<div class="bottom-item-select"> <div class="bottom-item-select">
<!-- <div class="select-btn" :class="{ active: measureType === 'history' }" @click="measureType = 'history'"> <!-- <div class="select-btn" :class="{ active: measureType === 'history' }" @click="measureType = 'history'">
......
...@@ -49,7 +49,21 @@ ...@@ -49,7 +49,21 @@
</div> </div>
</div> </div>
<div style="width: 100%; height: 620px; padding-top: 24px" id="char"></div> <div v-if="activeButtonId == 2" style="width: 100%; height: 520px; padding-top: 24px" id="char"></div>
<!-- <Echarts v-if="activeButtonId == 2" :option="lineOption" height="520px" /> -->
<div v-else>
<div class="content-line-chart-header">
<el-radio-group v-model="selectedIndicator" @change="handleIndicatorChange" size="default">
<el-radio
v-for="option in indicatorOptions"
:key="option.value"
:label="option.label"
:value="option.value"
/>
</el-radio-group>
</div>
<Echarts :option="lineOption" height="520px" />
</div>
</div> </div>
<div style="width: 778px; height: 620px; overflow: auto"> <div style="width: 778px; height: 620px; overflow: auto">
<el-table <el-table
...@@ -128,7 +142,8 @@ ...@@ -128,7 +142,8 @@
<div class="card-box" style="margin-top: 16px" @mouseenter="stopAutoPlay" @mouseleave="startAutoPlay(true)"> <div class="card-box" style="margin-top: 16px" @mouseenter="stopAutoPlay" @mouseleave="startAutoPlay(true)">
<div class="card-title"> <div class="card-title">
<img class="icon" src="../../assets/icons/title-icon2.png" /> <img class="icon" src="../../assets/icons/title-icon2.png" />
<img class="text" src="../../assets/icons/title-text2.svg" /> <!-- <img class="text" src="../../assets/icons/title-text2.svg" /> -->
<span class="text-new">中美科技博弈历程</span>
</div> </div>
<div class="card-main"> <div class="card-main">
<!-- <Timeline :data="course" text-key="title" id-key="seq" /> --> <!-- <Timeline :data="course" text-key="title" id-key="seq" /> -->
...@@ -218,6 +233,8 @@ import { ArrowRight, CaretBottom } from "@element-plus/icons-vue"; ...@@ -218,6 +233,8 @@ import { ArrowRight, CaretBottom } from "@element-plus/icons-vue";
import Timeline from "./Timeline.vue"; import Timeline from "./Timeline.vue";
import tableShow from "./tableShow.vue"; import tableShow from "./tableShow.vue";
import ButtonList from "@/components/buttonList/buttonList.vue"; import ButtonList from "@/components/buttonList/buttonList.vue";
import Echarts from "@/components/Chart/index.vue";
import mockData from "./mock.json";
import radarChart from "./radarChart3.js"; import radarChart from "./radarChart3.js";
import { getCompare, getChartDict, getTechnologyGameAnalysis } from "@/api/zmOverview/risk/index.js"; import { getCompare, getChartDict, getTechnologyGameAnalysis } from "@/api/zmOverview/risk/index.js";
...@@ -242,8 +259,8 @@ import { ElMessage } from "element-plus"; ...@@ -242,8 +259,8 @@ import { ElMessage } from "element-plus";
const buttonList = ref([ const buttonList = ref([
{ {
id: 1, id: 1,
text: "趋势变化", text: "趋势变化"
disabled: true // disabled: true
}, },
{ {
id: 2, id: 2,
...@@ -253,6 +270,9 @@ const buttonList = ref([ ...@@ -253,6 +270,9 @@ const buttonList = ref([
const activeButtonId = ref(buttonList.value[1]?.id || 1); const activeButtonId = ref(buttonList.value[1]?.id || 1);
const setActiveButtonId = id => { const setActiveButtonId = id => {
activeButtonId.value = id; activeButtonId.value = id;
if (id == 2) {
handleGetCompare();
}
}; };
const course = ref([ const course = ref([
...@@ -390,6 +410,197 @@ onMounted(async () => { ...@@ -390,6 +410,197 @@ onMounted(async () => {
// // setChart(option, "char7"); // // setChart(option, "char7");
startAutoPlay(); startAutoPlay();
processIndicatorOptions();
});
const chartColors = [
"rgba(8, 151, 156, 1)",
"#FF4D4F",
"#FF9900",
"#00CC99",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc"
];
// const series = {
// name: key,
// type: "line",
// symbolSize: 15,
// // stack: "Total",
// itemStyle: {
// color: chartColors[Math.floor(Math.random() * chartColors.length)]
// },
// data: []
// };
const indicatorOptions = ref([]);
const selectedIndicator = ref("");
// 整理指标选项
const processIndicatorOptions = () => {
const chinaData = mockData["中国"];
if (!chinaData) return;
indicatorOptions.value = Object.keys(chinaData).map(key => ({
label: key,
value: key
}));
if (indicatorOptions.value.length > 0) {
selectedIndicator.value = indicatorOptions.value[0].value;
handleIndicatorChange(selectedIndicator.value);
}
};
// 处理指标变化
const handleIndicatorChange = indicator => {
const chinaData = mockData["中国"]?.[indicator] || [];
const usaData = mockData["美国"]?.[indicator] || [];
const years = chinaData.map(item => item.year.toString());
const chinaValues = chinaData.map(item => item.value);
const usaValues = usaData.map(item => item.value);
lineOption.value.xAxis.data = years;
lineOption.value.series = [
{
name: "中国",
type: "line",
symbolSize: 10,
itemStyle: {
color: "#CE4F51"
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgb(206, 79, 81, .8)"
},
{
offset: 1,
color: "rgb(206, 79, 81, .3)"
}
])
},
data: chinaValues
},
{
name: "美国",
type: "line",
symbolSize: 10,
itemStyle: {
color: "#055FC2"
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgb(5, 95, 194,.8)"
},
{
offset: 1,
color: "rgb(5, 95, 194, .3)"
}
])
},
data: usaValues
}
];
};
const lineOption = ref({
title: {
text: ""
},
tooltip: {
trigger: "axis",
confine: true,
backgroundColor: "rgba(50, 50, 50, 0.7)",
borderColor: "#333",
borderWidth: 0,
padding: [5, 10],
textStyle: {
color: "#fff",
fontSize: 16
}
},
legend: {
show: false
},
grid: {
top: "5%",
left: "3%",
right: "4%",
bottom: "2%",
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
axisLine: {
lineStyle: {
color: "#ccc",
width: 1
}
},
axisTick: {
show: true,
lineStyle: {
color: "#ccc"
}
},
axisLabel: {
color: "#ccc",
fontSize: 16,
fontWeight: 400
},
data: ["2021", "2022", "2023", "2024", "2025"]
},
yAxis: {
type: "value",
// name: "指数",
nameLocation: "top",
nameGap: 35,
nameTextStyle: {
color: "#666",
fontSize: 13,
fontWeight: 600,
padding: [0, 0, 10, 0]
},
axisLine: {
show: false,
lineStyle: {
color: "#ccc",
width: 1
}
},
axisTick: {
show: false,
lineStyle: {
color: "#ccc"
}
},
axisLabel: {
color: "#ccc",
fontSize: 14,
fontWeight: 400,
formatter: value => {
return value.toFixed(0);
}
},
splitLine: {
lineStyle: {
width: 1,
type: "dashed",
color: "rgba(12, 78, 125, .3)"
}
},
splitNumber: 8
},
series: []
}); });
const tableData = ref([ const tableData = ref([
...@@ -562,7 +773,7 @@ const handleClickBottomBtn = () => { ...@@ -562,7 +773,7 @@ const handleClickBottomBtn = () => {
<style lang="scss" scoped> <style lang="scss" scoped>
.content-wrapper { .content-wrapper {
width: 1600px; width: 1600px;
height: 1600px; height: 1450px;
margin: 0 auto; margin: 0 auto;
.card-box { .card-box {
...@@ -585,6 +796,7 @@ const handleClickBottomBtn = () => { ...@@ -585,6 +796,7 @@ const handleClickBottomBtn = () => {
// width: 100%; // width: 100%;
height: 48px; height: 48px;
display: flex; display: flex;
align-items: center;
.icon { .icon {
/* 合并 */ /* 合并 */
...@@ -599,6 +811,13 @@ const handleClickBottomBtn = () => { ...@@ -599,6 +811,13 @@ const handleClickBottomBtn = () => {
height: 31px; height: 31px;
margin: 8px 0px; margin: 8px 0px;
} }
.text-new {
font-family: YouSheBiaoTiHei;
font-size: 24px;
font-weight: 400;
line-height: 24px;
color: rgb(5, 95, 194);
}
} }
.content-chart-header { .content-chart-header {
...@@ -608,6 +827,10 @@ const handleClickBottomBtn = () => { ...@@ -608,6 +827,10 @@ const handleClickBottomBtn = () => {
// line-height: 32px; // line-height: 32px;
align-items: center; align-items: center;
} }
.content-line-chart-header {
margin-top: 15px;
margin-left: 48px;
}
.card-main { .card-main {
height: 650px; height: 650px;
...@@ -1022,7 +1245,8 @@ const handleClickBottomBtn = () => { ...@@ -1022,7 +1245,8 @@ const handleClickBottomBtn = () => {
width: 100%; width: 100%;
height: auto; height: auto;
/* 高度自适应内容 */ /* 高度自适应内容 */
display: flex; // display: flex;
display: none;
flex-direction: row; flex-direction: row;
/* 行方向布局 */ /* 行方向布局 */
flex-wrap: wrap; flex-wrap: wrap;
......
{
"中国": {
"企业研发人才占比": [
{
"year": 2021,
"value": 79.8
},
{
"year": 2022,
"value": 80.1
},
{
"year": 2023,
"value": 82.7
},
{
"year": 2024,
"value": 81.3
},
{
"year": 2025,
"value": 82.1
}
],
"公共研发支出占比": [
{
"year": 2021,
"value": 72.6
},
{
"year": 2022,
"value": 72.6
},
{
"year": 2023,
"value": 73.7
},
{
"year": 2024,
"value": 72.7
},
{
"year": 2025,
"value": 73.5
}
],
"创新关联": [
{
"year": 2021,
"value": 78.2
},
{
"year": 2022,
"value": 78.1
},
{
"year": 2023,
"value": 77.0
},
{
"year": 2024,
"value": 78.5
},
{
"year": 2025,
"value": 77.0
}
],
"国内产业分布": [
{
"year": 2021,
"value": 99.4
},
{
"year": 2022,
"value": 99.9
},
{
"year": 2023,
"value": 100.4
},
{
"year": 2024,
"value": 100.9
},
{
"year": 2025,
"value": 101.4
}
],
"知识与技术产出": [
{
"year": 2021,
"value": 63.6
},
{
"year": 2022,
"value": 64.3
},
{
"year": 2023,
"value": 64.5
},
{
"year": 2024,
"value": 63.4
},
{
"year": 2025,
"value": 62.9
}
],
"知识工作者": [
{
"year": 2021,
"value": 79.5
},
{
"year": 2022,
"value": 79.7
},
{
"year": 2023,
"value": 78.1
},
{
"year": 2024,
"value": 78.9
},
{
"year": 2025,
"value": 79.4
}
]
},
"美国": {
"企业研发人才占比": [
{
"year": 2021,
"value": 81.1
},
{
"year": 2022,
"value": 81.8
},
{
"year": 2023,
"value": 82.8
},
{
"year": 2024,
"value": 81.3
},
{
"year": 2025,
"value": 82.5
}
],
"公共研发支出占比": [
{
"year": 2021,
"value": 73.8
},
{
"year": 2022,
"value": 71.6
},
{
"year": 2023,
"value": 72.1
},
{
"year": 2024,
"value": 72.6
},
{
"year": 2025,
"value": 71.9
}
],
"创新关联": [
{
"year": 2021,
"value": 77.4
},
{
"year": 2022,
"value": 77.3
},
{
"year": 2023,
"value": 77.2
},
{
"year": 2024,
"value": 77.1
},
{
"year": 2025,
"value": 77.0
}
],
"国内产业分布": [
{
"year": 2021,
"value": 98.5
},
{
"year": 2022,
"value": 101.1
},
{
"year": 2023,
"value": 98.4
},
{
"year": 2024,
"value": 99.8
},
{
"year": 2025,
"value": 98.2
}
],
"知识与技术产出": [
{
"year": 2021,
"value": 64.5
},
{
"year": 2022,
"value": 63.4
},
{
"year": 2023,
"value": 63.7
},
{
"year": 2024,
"value": 63.4
},
{
"year": 2025,
"value": 62.7
}
],
"知识工作者": [
{
"year": 2021,
"value": 66.8
},
{
"year": 2022,
"value": 71.8
},
{
"year": 2023,
"value": 76.8
},
{
"year": 2024,
"value": 81.8
},
{
"year": 2025,
"value": 86.8
}
]
}
}
\ No newline at end of file
...@@ -142,11 +142,11 @@ ...@@ -142,11 +142,11 @@
</div> </div>
<div class="carousel-footer"> <div class="carousel-footer">
<div class="footer-left"> <div class="footer-left">
<div class="type">{{ News.hotspotType +'——' }}</div> <div class="type">{{ News.hotspotType + "——" }}</div>
<div class="text">{{ News.eventTitle }}</div> <div class="text">{{ News.eventTitle }}</div>
</div> </div>
<div class="footer-right"> <div class="footer-right">
<img src="@/assets/icons/arrow-right.png" alt=""> <img src="@/assets/icons/arrow-right.png" alt="" />
</div> </div>
</div> </div>
</div> </div>
...@@ -290,8 +290,8 @@ const sections = ref([ ...@@ -290,8 +290,8 @@ const sections = ref([
count: 0, count: 0,
change: "无新增", change: "无新增",
unit: "次", unit: "次",
title: "230调查", title: "232调查",
type: "230调查" type: "232调查"
}, },
{ {
percent: 0, // 估算的百分比 percent: 0, // 估算的百分比
...@@ -436,8 +436,8 @@ const handleGetLatestRiskUpdates = async () => { ...@@ -436,8 +436,8 @@ const handleGetLatestRiskUpdates = async () => {
count: res.data["232Survey"].total, count: res.data["232Survey"].total,
change: res.data["232Survey"].dailyIncrement, change: res.data["232Survey"].dailyIncrement,
unit: "次", unit: "次",
title: "230调查", title: "232调查",
type: "230调查" type: "232调查"
}, },
{ {
percent: 3, // 估算的百分比 percent: 3, // 估算的百分比
...@@ -1222,7 +1222,6 @@ onUnmounted(() => { ...@@ -1222,7 +1222,6 @@ onUnmounted(() => {
// color:var(--color-main-active); // color:var(--color-main-active);
// } // }
// } // }
// } // }
......
...@@ -148,11 +148,12 @@ ...@@ -148,11 +148,12 @@
</div> </div>
</div> --> </div> -->
<AnalysisBox title="政治献金流向"> <AnalysisBox title="政治献金流向">
<div class="box2-main"> <div class="box2-main" :class="{ 'box2-main-no-footer': !showHardcodedTips }">
<el-empty v-if="!fullSourceList.length" description="暂无数据" :image-size="100" /> <el-empty v-if="!fullSourceList.length" description="暂无数据" :image-size="100" />
<div v-else class="chart-box2" id="chart1"></div> <div v-else class="chart-box2" id="chart1"></div>
</div> </div>
<div class="box-footer"> <!-- 该提示文案后续改为接口返回,当前按需求先隐藏展示 -->
<div v-if="showHardcodedTips" class="box-footer">
<div class="box-footer-left"> <div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" /> <img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div> </div>
...@@ -210,7 +211,7 @@ ...@@ -210,7 +211,7 @@
</div> </div>
</div> --> </div> -->
<AnalysisBox title="政治献金领域分布"> <AnalysisBox title="政治献金领域分布">
<div class="box3-main"> <div class="box3-main" :class="{ 'box3-main-no-footer': !showHardcodedTips }">
<div class="box3-main-left" id="chart2"></div> <div class="box3-main-left" id="chart2"></div>
<div class="box3-main-right"> <div class="box3-main-right">
<el-empty v-if="!areaList.length" description="暂无数据" :image-size="100" /> <el-empty v-if="!areaList.length" description="暂无数据" :image-size="100" />
...@@ -225,7 +226,8 @@ ...@@ -225,7 +226,8 @@
</div> </div>
</div> </div>
</div> </div>
<div class="box-footer"> <!-- 该提示文案后续改为接口返回,当前按需求先隐藏展示 -->
<div v-if="showHardcodedTips" class="box-footer">
<div class="box-footer-left"> <div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" /> <img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div> </div>
...@@ -271,6 +273,9 @@ import Mzd from "@/assets/icons/mzd.png"; ...@@ -271,6 +273,9 @@ import Mzd from "@/assets/icons/mzd.png";
const activeBtnIndex = ref(0); const activeBtnIndex = ref(0);
const itemActiveIndex = ref(0); const itemActiveIndex = ref(0);
// 写死提示文案先保留逻辑,默认不展示;后续接口完成后改为 true 或替换为接口控制
const showHardcodedTips = ref(false);
const currentPersonName = computed(() => { const currentPersonName = computed(() => {
if (mainPoliContribution.value && mainPoliContribution.value[itemActiveIndex.value]) { if (mainPoliContribution.value && mainPoliContribution.value[itemActiveIndex.value]) {
return mainPoliContribution.value[itemActiveIndex.value].name; return mainPoliContribution.value[itemActiveIndex.value].name;
...@@ -631,7 +636,7 @@ const renderSankeyChart = () => { ...@@ -631,7 +636,7 @@ const renderSankeyChart = () => {
} }
}, },
...sourceList.map((item, index) => ({ ...sourceList.map((item, index) => ({
name: item.orgName, name: item.orgNameZh,
value: item.amount, value: item.amount,
itemStyle: { itemStyle: {
color: sankeyColors[index % sankeyColors.length] color: sankeyColors[index % sankeyColors.length]
...@@ -640,7 +645,7 @@ const renderSankeyChart = () => { ...@@ -640,7 +645,7 @@ const renderSankeyChart = () => {
]; ];
const links = sourceList.map(item => ({ const links = sourceList.map(item => ({
source: item.orgName, source: item.orgNameZhZh,
target: personName, target: personName,
value: item.amount value: item.amount
})); }));
...@@ -1104,6 +1109,14 @@ onMounted(() => { ...@@ -1104,6 +1109,14 @@ onMounted(() => {
margin: 0 auto; margin: 0 auto;
margin-bottom: 9px; margin-bottom: 9px;
&.box2-main-no-footer {
height: 351px;
.chart-box2 {
height: 351px;
}
}
.chart-box2 { .chart-box2 {
width: 1020px; width: 1020px;
height: 302px; height: 302px;
...@@ -1128,6 +1141,10 @@ onMounted(() => { ...@@ -1128,6 +1141,10 @@ onMounted(() => {
margin-bottom: 9px; margin-bottom: 9px;
display: flex; display: flex;
&.box3-main-no-footer {
height: 349px;
}
.box3-main-left { .box3-main-left {
width: 492px; width: 492px;
} }
......
...@@ -32,14 +32,14 @@ ...@@ -32,14 +32,14 @@
</div> </div>
</div> --> </div> -->
<AnalysisBox title="典型阶段耗时"> <AnalysisBox title="典型阶段耗时">
<div class="box1-main"> <div class="box1-main" :class="{ 'box1-main--full': !timeFooterText }">
<div class="box1-main-center" id="chart1"></div> <div class="box1-main-center" id="chart1"></div>
<div class="box1-main-footer"> <div v-if="timeFooterText" class="box1-main-footer">
<div class="box-footer-left"> <div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" /> <img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div> </div>
<div class="box-footer-center"> <div class="box-footer-center">
从立法耗时角度分析,大而美法案从提交到签署仅39天,远快于历史同类法案(通常需6个月以上),立法速度极快。 {{ timeFooterText }}
</div> </div>
<div class="box-footer-right"> <div class="box-footer-right">
<img src="../assets/icons/arrow-right.png" alt="" /> <img src="../assets/icons/arrow-right.png" alt="" />
...@@ -80,15 +80,14 @@ ...@@ -80,15 +80,14 @@
</div> </div>
</div> --> </div> -->
<AnalysisBox title="修正案次数分析"> <AnalysisBox title="修正案次数分析">
<div class="box2-main"> <div class="box2-main" :class="{ 'box2-main--full': !amendFooterText }">
<div class="box2-main-center" id="chart2"></div> <div class="box2-main-center" id="chart2"></div>
<div class="box2-main-footer"> <div v-if="amendFooterText" class="box2-main-footer">
<div class="box-footer-left"> <div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" /> <img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div> </div>
<div class="box-footer-center"> <div class="box-footer-center">
法案本质是共和党与资本集团的深度联盟,共和党获超 {{ amendFooterText }}
​80%利益集团献金,以减税、松监管、军工扩张为核心回报。
</div> </div>
<div class="box-footer-right"> <div class="box-footer-right">
<img src="../assets/icons/arrow-right.png" alt="" /> <img src="../assets/icons/arrow-right.png" alt="" />
...@@ -367,7 +366,17 @@ ...@@ -367,7 +366,17 @@
</div> </div>
</div> --> </div> -->
<AnalysisBox title="投票分析"> <AnalysisBox title="投票分析">
<div class="box3-main"> <div class="vote-legend">
<div class="vote-legend-item">
<span class="vote-legend-dot agree"></span>
<span>赞成票</span>
</div>
<div class="vote-legend-item">
<span class="vote-legend-dot against"></span>
<span>反对票</span>
</div>
</div>
<div class="box3-main" :class="{ 'box3-main--full': !voteFooterText }">
<div class="box3-main-center"> <div class="box3-main-center">
<div class="box3-main-center-header"> <div class="box3-main-center-header">
<div class="box3-main-center-header-box1">立法阶段</div> <div class="box3-main-center-header-box1">立法阶段</div>
...@@ -658,12 +667,12 @@ ...@@ -658,12 +667,12 @@
</div> --> </div> -->
</div> </div>
</div> </div>
<div class="box3-main-footer"> <div v-if="voteFooterText" class="box3-main-footer">
<div class="box-footer-left"> <div class="box-footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" /> <img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div> </div>
<div class="box-footer-center"> <div class="box-footer-center">
法案以218:214​(众议院)和51:50​(副总统决胜票)微弱优势强行通过,暴露两党极端对立、党内倒戈频发的特点。 {{ voteFooterText }}
</div> </div>
<div class="box-footer-right"> <div class="box-footer-right">
<img src="../assets/icons/arrow-right.png" alt="" /> <img src="../assets/icons/arrow-right.png" alt="" />
...@@ -881,6 +890,11 @@ const voteAnalysisList4 = ref([ ...@@ -881,6 +890,11 @@ const voteAnalysisList4 = ref([
} }
]); ]);
// 底部说明文案(接口预留,默认不展示)
const timeFooterText = ref("");
const amendFooterText = ref("");
const voteFooterText = ref("");
// 绘制echarts图表 // 绘制echarts图表
const setChart = (option, chartId) => { const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId); let chartDom = document.getElementById(chartId);
...@@ -1091,6 +1105,12 @@ onMounted(async () => { ...@@ -1091,6 +1105,12 @@ onMounted(async () => {
.box1-main { .box1-main {
height: 368px; height: 368px;
&.box1-main--full {
.box1-main-center {
height: 340px;
}
}
.box1-main-center { .box1-main-center {
width: 792px; width: 792px;
height: 300px; height: 300px;
...@@ -1230,6 +1250,12 @@ onMounted(async () => { ...@@ -1230,6 +1250,12 @@ onMounted(async () => {
.box2-main { .box2-main {
height: 359px; height: 359px;
&.box2-main--full {
.box2-main-center {
height: 340px;
}
}
.box2-main-center { .box2-main-center {
height: 300px; height: 300px;
margin: 0 5px; margin: 0 5px;
...@@ -1345,7 +1371,7 @@ onMounted(async () => { ...@@ -1345,7 +1371,7 @@ onMounted(async () => {
#chart2 { #chart2 {
position: relative; position: relative;
width: 330px; width: 330px;
height: 300px; height: 340px;
z-index: 0; z-index: 0;
} }
...@@ -1471,9 +1497,52 @@ onMounted(async () => { ...@@ -1471,9 +1497,52 @@ onMounted(async () => {
.box3 { .box3 {
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative;
.vote-legend {
position: absolute;
top: 15px;
left: 50%;
transform: translateX(-50%);
display: inline-flex;
align-items: center;
gap: 20px;
z-index: 2;
.vote-legend-item {
display: inline-flex;
align-items: center;
gap: 8px;
font-size: 14px;
color: rgba(95, 101, 108, 1);
line-height: 22px;
}
.vote-legend-dot {
display: inline-block;
width: 12px;
height: 12px;
border-radius: 50%;
&.agree {
background: rgb(33, 129, 57);
}
&.against {
background: rgb(206, 79, 81);
}
}
}
.box3-main { .box3-main {
height: 791px; height: 791px;
&.box3-main--full {
.box3-main-center {
height: 772px;
}
}
.box3-main-center { .box3-main-center {
height: 732px; height: 732px;
margin: 0 20px; margin: 0 20px;
...@@ -1529,7 +1598,7 @@ onMounted(async () => { ...@@ -1529,7 +1598,7 @@ onMounted(async () => {
} }
.box3-main-center-content { .box3-main-center-content {
height: 682px; height: 722px;
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
......
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
> >
<div class="item-title">{{ item.actionTitle }}</div> <div class="item-title">{{ item.actionTitle }}</div>
</el-tooltip> </el-tooltip>
<!-- <div class="right"> <div class="right">
<div class="risk-tag" :class="item.riskClass">{{ item.riskText }}</div> <div v-if="item.riskText" class="risk-tag" :class="item.riskClass">{{ item.riskText }}</div>
<div class="arrow">></div> <div class="arrow">></div>
</div> --> </div>
</div> </div>
</div> </div>
...@@ -41,6 +41,27 @@ const RISK_CLASS_MAP = { ...@@ -41,6 +41,27 @@ const RISK_CLASS_MAP = {
"低风险": "risk-low" "低风险": "risk-low"
}; };
const normalizeRiskSignal = riskSignal => {
if (riskSignal === null || riskSignal === undefined) return "";
if (typeof riskSignal === "number" && Number.isFinite(riskSignal)) {
const idx = Math.max(0, Math.min(RISK_LEVELS.length - 1, Math.floor(riskSignal)));
return RISK_LEVELS[idx];
}
const text = String(riskSignal).trim();
if (!text) return "";
if (RISK_CLASS_MAP[text]) return text;
const numeric = Number(text);
if (Number.isFinite(numeric)) {
const idx = Math.max(0, Math.min(RISK_LEVELS.length - 1, Math.floor(numeric)));
return RISK_LEVELS[idx];
}
return text;
};
export default { export default {
name: "SBillProgressList", name: "SBillProgressList",
data() { data() {
...@@ -81,7 +102,7 @@ export default { ...@@ -81,7 +102,7 @@ export default {
formattedDate = `${dateObj.getMonth() + 1}${dateObj.getDate()}日`; formattedDate = `${dateObj.getMonth() + 1}${dateObj.getDate()}日`;
} }
const riskText = RISK_LEVELS[Math.min(index, RISK_LEVELS.length - 1)]; const riskText = normalizeRiskSignal(item?.level);
const riskClass = RISK_CLASS_MAP[riskText] || "risk-low"; const riskClass = RISK_CLASS_MAP[riskText] || "risk-low";
return { return {
......
<template> <template>
<div class="temp-wrap"> <div class="temp-wrap">
<div class="left"> <div class="side">
<div class="side-box side-box-domain">
<AnalysisBox title="涉及领域" width="520px" height="415px">
<div :class="['right-box2-main', { 'right-box-main--full': !domainFooterText }]" id="chart2"></div>
<div v-if="domainFooterText" class="right-box2-footer">
<div class="right-box2-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box2-footer-center">
{{ domainFooterText }}
</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
<div class="side-box side-box-limit">
<AnalysisBox title="限制手段" width="520px" height="415px">
<div :class="['right-box1-main', { 'right-box-main--full': !limitFooterText }]" id="chart1"></div>
<div v-if="limitFooterText" class="right-box1-footer">
<div class="right-box1-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box1-footer-center">
{{ limitFooterText }}
</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
</div>
<div class="terms">
<!-- <div class="box-header"> <!-- <div class="box-header">
<div class="box-header-left"></div> <div class="box-header-left"></div>
<div class="box-header-title">主要条款</div> <div class="box-header-title">主要条款</div>
...@@ -91,7 +125,7 @@ ...@@ -91,7 +125,7 @@
</div> </div>
</div> </div>
<div class="left-main"> <div class="left-main">
<div class="left-main-item" v-for="(term, index) in mainTermsList" :key="index"> <div class="left-main-item" v-for="(term, index) in mainTermsList" :key="getTermKey(term, index)">
<div class="id">{{ (currentPage - 1) * pageSize + index + 1 }}</div> <div class="id">{{ (currentPage - 1) * pageSize + index + 1 }}</div>
<div class="info"> <div class="info">
<div class="title"> <div class="title">
...@@ -104,7 +138,7 @@ ...@@ -104,7 +138,7 @@
</div> </div>
</div> </div>
<div class="tags-box"> <div class="tags-box">
<div class="tag" v-for="(val, idx) in (term.hylyList || []).slice(0, 2)" :key="idx" :class="{ <div class="tag" v-for="(val, idx) in (term.hylyList || []).slice(0, 2)" :key="getTagKey(val, idx)" :class="{
tag1: val === '人工智能', tag1: val === '人工智能',
tag2: val === '新一代信息技术' || !['人工智能', '政治', '经济', '军事', '科技'].includes(val), tag2: val === '新一代信息技术' || !['人工智能', '政治', '经济', '军事', '科技'].includes(val),
tag3: val === '政治', tag3: val === '政治',
...@@ -131,86 +165,6 @@ ...@@ -131,86 +165,6 @@
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
<div class="right">
<div class="right-box1">
<!-- <div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">限制手段</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="right-box1-main" id="chart1"></div>
<div class="right-box1-footer">
<div class="right-box1-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box1-footer-center">通过关税壁垒、技术脱钩、新能源打压、地缘捆绑遏制中国产业链发展</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div> -->
<AnalysisBox title="限制手段">
<div class="right-box1-main" id="chart1"></div>
<div class="right-box1-footer">
<div class="right-box1-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box1-footer-center">通过关税壁垒、技术脱钩、新能源打压、地缘捆绑遏制中国产业链发展</div>
<div class="right-box1-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
<div class="right-box2">
<!-- <div class="box-header">
<div class="box-header-left"></div>
<div class="box-header-title">涉及领域</div>
<div class="header-right">
<div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
</div>
<div class="icon">
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="right-box2-main" id="chart2"></div>
<div class="right-box2-footer">
<div class="right-box2-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box2-footer-center">系统性挤压中国新能源、跨境电商及高端制造的在美生存空间。</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div> -->
<AnalysisBox title="涉及领域">
<div class="right-box2-main" id="chart2"></div>
<div class="right-box2-footer">
<div class="right-box2-footer-left">
<img src="./assets/icons/right-icon1.png" alt="" />
</div>
<div class="right-box2-footer-center">系统性挤压中国新能源、跨境电商及高端制造的在美生存空间。</div>
<div class="right-box2-footer-right">
<img src="./assets/icons/arrow-right.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
</div>
</div> </div>
</template> </template>
...@@ -234,11 +188,21 @@ const pageSize = ref(10); ...@@ -234,11 +188,21 @@ const pageSize = ref(10);
const total = ref(0); const total = ref(0);
const mainTermsList = ref([]); const mainTermsList = ref([]);
const domainFooterText = ref("");
const limitFooterText = ref("");
const btnActiveIndex = ref(1); const btnActiveIndex = ref(1);
const handleSelectBtn = index => { const handleSelectBtn = index => {
btnActiveIndex.value = index; btnActiveIndex.value = index;
}; };
const getTermKey = (term, index) => {
return term?.ywid ?? term?.id ?? term?.tkxh ?? index;
};
const getTagKey = (val, idx) => {
return `${val}-${idx}`;
};
const chart1Data = ref([]); const chart1Data = ref([]);
const chart1ColorList = ref(["#4096ff", "#b37feb", "#ff7875", "#85a5ff", "#69b1ff", "#ffc069", "#87e8de"]); const chart1ColorList = ref(["#4096ff", "#b37feb", "#ff7875", "#85a5ff", "#69b1ff", "#ffc069", "#87e8de"]);
...@@ -478,8 +442,9 @@ onMounted(async () => { ...@@ -478,8 +442,9 @@ onMounted(async () => {
} }
} }
.left { .terms {
margin-top: 16px; margin-top: 16px;
margin-left: 16px;
width: 1064px; width: 1064px;
height: 845px; height: 845px;
.left-top { .left-top {
...@@ -668,12 +633,16 @@ onMounted(async () => { ...@@ -668,12 +633,16 @@ onMounted(async () => {
} }
} }
.right { .side {
width: 520px; width: 520px;
margin-top: 16px; margin-top: 16px;
margin-left: 16px;
.right-box1 { .side-box {
width: 520px;
}
.side-box-limit {
margin-top: 15px;
width: 520px; width: 520px;
height: 415px; height: 415px;
.right-box1-main { .right-box1-main {
...@@ -682,6 +651,10 @@ onMounted(async () => { ...@@ -682,6 +651,10 @@ onMounted(async () => {
padding: 16px; padding: 16px;
} }
.right-box-main--full {
height: 375px;
}
.right-box1-footer { .right-box1-footer {
width: 493px; width: 493px;
height: 40px; height: 40px;
...@@ -735,8 +708,7 @@ onMounted(async () => { ...@@ -735,8 +708,7 @@ onMounted(async () => {
} }
} }
.right-box2 { .side-box-domain {
margin-top: 15px;
width: 520px; width: 520px;
height: 415px; height: 415px;
.right-box2-main { .right-box2-main {
...@@ -745,6 +717,10 @@ onMounted(async () => { ...@@ -745,6 +717,10 @@ onMounted(async () => {
padding: 16px; padding: 16px;
} }
.right-box-main--full {
height: 375px;
}
.right-box2-footer { .right-box2-footer {
width: 493px; width: 493px;
height: 40px; height: 40px;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue'; import AnalysisBox from '@/components/base/boxBackground/analysisBox.vue';
import { ref, watch } from 'vue'; import { ref, watch } from 'vue';
import { getEnterpriseBranch, getEnterpriseKeyPerson } from '@/api/companyPages'; import { getEnterpriseBranch, getEnterpriseKeyPerson } from '@/api/companyPages';
import PersonAvatar from '@/components/base/people/personAvatar.vue'; import PersonAvatar from '@/components/base/people/PersonAvatar.vue';
import { ElDescriptions, ElDescriptionsItem, ElDivider, ElImage, ElSpace } from 'element-plus'; import { ElDescriptions, ElDescriptionsItem, ElDivider, ElImage, ElSpace } from 'element-plus';
import '@/styles/descriptions.scss' import '@/styles/descriptions.scss'
......
<template>
<sanctions-situation :enterprise-info="enterpriseInfo" :line-data="lineData"></sanctions-situation>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { getNetProfitList, getPersonnelList, getRevenueList } from '@/api/companyPages';
import SanctionsSituation, { LineDataItem } from './SanctionsSituation.vue';
// 定义组件属性
const props = defineProps({
enterpriseInfo: {
type: Object,
default: {}
}
});
const lineData = ref<LineDataItem[]>([])
onMounted(async () => {
await intData()
})
async function intData() {
let { data: revenue } = await getRevenueList(props.enterpriseInfo.id)
revenue = revenue?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '营收',
unit: item.unit ?? '亿元'
})) ?? []
let { data: netProfit } = await getNetProfitList(props.enterpriseInfo.id)
netProfit = netProfit?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '净利润',
unit: item.unit ?? '亿元'
})) ?? []
let { data: personnel } = await getPersonnelList(props.enterpriseInfo.id)
personnel = personnel?.map(item => ({
time: new Date(item.year, 1, 1),
value: item.value,
type: '人员',
unit: item.unit ?? '亿元'
})) ?? []
lineData.value = [...revenue, ...netProfit, ...personnel]
}
</script>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论