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

update

上级 ce8f4051
......@@ -19,7 +19,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"sass": "^1.92.1",
"sass": "^1.93.3",
"unplugin-auto-import": "^0.17.0",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.0.0"
......@@ -2554,9 +2554,9 @@
}
},
"node_modules/sass": {
"version": "1.92.1",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.92.1.tgz",
"integrity": "sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ==",
"version": "1.93.3",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.93.3.tgz",
"integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==",
"dev": true,
"license": "MIT",
"dependencies": {
......
......@@ -28,7 +28,7 @@
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"sass": "^1.92.1",
"sass": "^1.93.3",
"unplugin-auto-import": "^0.17.0",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.0.0"
......
......@@ -16,10 +16,10 @@
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="/">智库首页</el-dropdown-item>
<el-dropdown-item command="/billHome">法案首页</el-dropdown-item>
<el-dropdown-item command="/decree">政令首页</el-dropdown-item>
<el-dropdown-item command="/thinkTank">智库首页</el-dropdown-item>
<el-dropdown-item command="/exportControl">出口管制</el-dropdown-item>
<el-dropdown-item command="/decree">政令</el-dropdown-item>
<el-dropdown-item command="/marketAccessRestrictions">市场准入限制</el-dropdown-item>
</el-dropdown-menu>
</template>
......@@ -50,7 +50,7 @@
</el-header>
<!-- 面包屑导航 -->
<Breadcrumb />
<!-- <Breadcrumb /> -->
<el-main class="main-container">
<router-view />
......
<template>
<div class="wrapper">
<div class="box1"></div>
<div class="box2"></div>
<div class="title">{{ titleText }}</div>
<div class="box3"></div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
const props = defineProps(["titleText"]);
</script>
<style lang="scss" scoped>
.wrapper {
display: flex;
width: 1600px;
height: 42px;
align-items: center;
.box1 {
width: 24px;
height: 30px;
background: rgba(174, 214, 255, 1);
margin-top: 6px;
}
.box2 {
width: 8px;
height: 30px;
margin-left: 8px;
margin-top: 6px;
background: rgba(174, 214, 255, 1);
}
.title {
margin-left: 20px;
height: 42px;
color: rgba(10, 18, 30, 1);
font-family: Microsoft YaHei;
font-size: 32px;
font-weight: 700;
line-height: 42px;
}
.box3 {
flex: 1;
height: 1px;
margin-left: 20px;
background: rgba(174, 214, 255, 1);
}
}
</style>
\ No newline at end of file
......@@ -34,7 +34,7 @@
</template>
<script setup>
import { ref, defineProps } from 'vue'
import { ref } from 'vue'
import { Link } from '@element-plus/icons-vue'
const props = defineProps({
......
......@@ -75,7 +75,7 @@
</template>
<script setup lang="ts">
import { ref, defineProps, onMounted } from 'vue';
import { ref, onMounted } from 'vue';
import { Search } from '@element-plus/icons-vue';
import PolicyList from './PolicyList.vue';
import CardTitle from './CardTitle.vue';
......
import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
import About from "../views/About.vue";
import ThinkTankDetail from "@/views/ThinkTankDetail/index.vue";
import ReportDetail from "@/views/ReportDetail/index.vue";
// 法案相关组件
// 智库相关
import thinkTank from "../views/thinkTank/index.vue";
import ThinkTankDetail from "@/views/thinkTank/ThinkTankDetail/index.vue";
import ReportDetail from "@/views/thinkTank/ReportDetail/index.vue";
// 法案相关
import BillHome from '@/views/bill/billHome/index.vue'
import BillLayoutContainer from '@/views/bill/billLayout/index.vue'
import BillLayout from '@/views/bill/index.vue'
......@@ -42,21 +43,19 @@ import MarketSingleCaseOverview from "@/views/marketAccessRestrictions/singleCas
import MarketSingleCaseDeepdig from "@/views/marketAccessRestrictions/singleCaseLayout/deepdig/index.vue";
const routes = [
// 智库系统的主要路由
{
path: "/",
name: "Home",
component: Home,
meta: {
title: "首页"
}
path: '/',
redirect: '/billHome'
},
// 智库系统的主要路由
{
path: "/about",
name: "About",
component: About,
path: "/thinkTank",
name: "thinkTank",
component: thinkTank,
meta: {
title: "关于我们"
title: "首页"
}
},
{
......@@ -329,55 +328,52 @@ const routes = [
]
},
// 转移过来的页面
// 出口管制转移过来的页面
{
path: "/analysis",
path: "/exportControl/analysis",
name: "analysis",
component: () => import("@/views/analysis/index.vue"),
component: () => import("@/views/exportControl/analysis/index.vue"),
meta: {
title: "分析页"
}
},
{
path: "/infoplatform",
path: "/exportControl/infoplatform",
name: "infoplatform",
component: () => import("@/views/infoPlatform/index.vue"),
component: () => import("@/views/exportControl/infoPlatform/index.vue"),
meta: {
title: "信息平台"
}
},
{
path: "/rulelimit",
path: "/exportControl/rulelimit",
name: "rulelimit",
component: () => import("@/views/ruleLimit/index.vue"),
component: () => import("@/views/exportControl/ruleLimit/index.vue"),
meta: {
title: "规则限制"
}
},
{
path: "/ruledetail",
path: "/exportControl/ruledetail",
name: "ruledetail",
component: () => import("@/views/ruleDetail/index.vue"),
component: () => import("@/views/exportControl/ruleDetail/index.vue"),
meta: {
title: "规则详情"
}
},
{
path: "/researchfunding",
path: "/exportControl/researchfunding",
name: "researchfunding",
component: () => import("@/views/researchFunding/index.vue"),
component: () => import("@/views/exportControl/researchFunding/index.vue"),
meta: {
title: "科研资助"
}
},
{
path: "/decree",
name: "decree",
component: () => import("@/views/decree/index.vue"),
meta: {
title: "政令信息"
}
}
// 门户路由放在这块
];
const router = createRouter({
......
<template>
<div class="about">
<el-row :gutter="20">
<el-col :span="24">
<el-card>
<template #header>
<div class="card-header">
<el-icon><InfoFilled /></el-icon>
<span>关于 Think Tank</span>
</div>
</template>
<div class="about-content">
<el-row :gutter="20">
<el-col :span="12">
<h3>项目介绍</h3>
<p>Think Tank 是一个基于 Vue 3 + Element Plus + Vue Router 构建的现代化前端项目模板。</p>
<p>该项目采用了最新的前端技术栈,提供了完整的开发环境配置和项目结构,帮助开发者快速启动新项目。</p>
<h3>技术特性</h3>
<el-timeline>
<el-timeline-item timestamp="Vue 3" placement="top">
<el-card>
<h4>Vue 3 Composition API</h4>
<p>使用最新的 Composition API,提供更好的逻辑复用和类型推导</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="Element Plus" placement="top">
<el-card>
<h4>Element Plus UI 组件库</h4>
<p>基于 Vue 3 的企业级 UI 组件库,提供丰富的组件和主题定制</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="Vue Router" placement="top">
<el-card>
<h4>Vue Router 4</h4>
<p>Vue.js 官方路由管理器,支持动态路由和路由守卫</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="Vite" placement="top">
<el-card>
<h4>Vite 构建工具</h4>
<p>下一代前端构建工具,提供极速的开发体验</p>
</el-card>
</el-timeline-item>
</el-timeline>
</el-col>
<el-col :span="12">
<h3>项目结构</h3>
<el-tree
:data="projectStructure"
:props="treeProps"
default-expand-all
:expand-on-click-node="false"
>
<template #default="{ node, data }">
<span class="tree-node">
<el-icon v-if="data.type === 'folder'"><Folder /></el-icon>
<el-icon v-else><Document /></el-icon>
<span>{{ node.label }}</span>
</span>
</template>
</el-tree>
<h3 style="margin-top: 30px;">开发指南</h3>
<el-steps :active="3" finish-status="success">
<el-step title="安装依赖" description="npm install"></el-step>
<el-step title="启动开发" description="npm run dev"></el-step>
<el-step title="构建项目" description="npm run build"></el-step>
<el-step title="部署上线" description="部署到服务器"></el-step>
</el-steps>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20" style="margin-top: 20px;">
<el-col :span="8">
<el-card>
<template #header>
<div class="card-header">
<el-icon><Star /></el-icon>
<span>版本信息</span>
</div>
</template>
<el-descriptions :column="1" border>
<el-descriptions-item label="项目版本">1.0.0</el-descriptions-item>
<el-descriptions-item label="Vue">^3.4.0</el-descriptions-item>
<el-descriptions-item label="Element Plus">^2.4.4</el-descriptions-item>
<el-descriptions-item label="Vue Router">^4.2.5</el-descriptions-item>
<el-descriptions-item label="Vite">^5.0.0</el-descriptions-item>
</el-descriptions>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<template #header>
<div class="card-header">
<el-icon><Link /></el-icon>
<span>相关链接</span>
</div>
</template>
<div class="links">
<el-button type="primary" link @click="openLink('https://vuejs.org/')">
<el-icon><Link /></el-icon>
Vue.js 官网
</el-button>
<el-button type="primary" link @click="openLink('https://element-plus.org/')">
<el-icon><Link /></el-icon>
Element Plus 官网
</el-button>
<el-button type="primary" link @click="openLink('https://router.vuejs.org/')">
<el-icon><Link /></el-icon>
Vue Router 官网
</el-button>
<el-button type="primary" link @click="openLink('https://vitejs.dev/')">
<el-icon><Link /></el-icon>
Vite 官网
</el-button>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card>
<template #header>
<div class="card-header">
<el-icon><ChatDotRound /></el-icon>
<span>联系我们</span>
</div>
</template>
<div class="contact">
<p><el-icon><Message /></el-icon> 邮箱:contact@thinktank.com</p>
<p><el-icon><Phone /></el-icon> 电话:+86 123-4567-8900</p>
<p><el-icon><Location /></el-icon> 地址:北京市朝阳区</p>
<el-button type="success" style="width: 100%; margin-top: 10px;">
<el-icon><ChatDotRound /></el-icon>
在线咨询
</el-button>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import {
InfoFilled,
Folder,
Document,
Star,
Link,
ChatDotRound,
Message,
Phone,
Location
} from '@element-plus/icons-vue'
// 项目结构数据
const projectStructure = ref([
{
label: 'think-tank',
type: 'folder',
children: [
{
label: 'src',
type: 'folder',
children: [
{ label: 'views', type: 'folder' },
{ label: 'router', type: 'folder' },
{ label: 'components', type: 'folder' },
{ label: 'App.vue', type: 'file' },
{ label: 'main.js', type: 'file' }
]
},
{ label: 'package.json', type: 'file' },
{ label: 'vite.config.js', type: 'file' },
{ label: 'index.html', type: 'file' }
]
}
])
const treeProps = {
children: 'children',
label: 'label'
}
// 打开链接
const openLink = (url) => {
window.open(url, '_blank')
ElMessage.success('正在打开链接...')
}
</script>
<style scoped>
.about {
max-width: 1200px;
margin: 0 auto;
}
.about-content h3 {
color: #409eff;
margin-bottom: 16px;
border-bottom: 2px solid #409eff;
padding-bottom: 8px;
}
.about-content p {
color: #606266;
line-height: 1.6;
margin-bottom: 16px;
}
.card-header {
display: flex;
align-items: center;
gap: 8px;
font-weight: bold;
}
.tree-node {
display: flex;
align-items: center;
gap: 8px;
}
.links {
display: flex;
flex-direction: column;
gap: 12px;
}
.contact p {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 12px;
}
</style>
\ No newline at end of file
<template>
<div class="tech-think-tank">
<!-- 面包屑导航 -->
<el-breadcrumb separator=">" class="breadcrumb">
<el-breadcrumb-item>国家科技安全</el-breadcrumb-item>
<el-breadcrumb-item>中美博弈概览</el-breadcrumb-item>
<el-breadcrumb-item class="current">科技智库</el-breadcrumb-item>
</el-breadcrumb>
<!-- 搜索区域 -->
<div class="search-section">
<el-input
v-model="searchText"
placeholder="搜索智库、报告或政策建议"
class="search-input"
size="large"
>
<template #append>
<el-button
type="primary"
style="background: #1677FF; color: #fff;"
:icon="Search">搜索</el-button>
</template>
</el-input>
</div>
<!-- 统计数据 -->
<div class="stats-section">
<div class="stat-item">
<div class="stat-number">128</div>
<div class="stat-label">追踪智库数量</div>
</div>
<div class="stat-item">
<div class="stat-number">42</div>
<div class="stat-label">本月新增报告</div>
</div>
<div class="stat-item">
<div class="stat-number">18</div>
<div class="stat-label">重点政策建议</div>
</div>
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">热点科技领域</div>
</div>
</div>
<!-- 主要内容区域 -->
<div class="main-content">
<!-- 左侧数据分布 -->
<div class="left-section">
<div class="section-header">
<el-icon class="location-icon"><Location /></el-icon>
<span class="section-title">数据分布</span>
<div class="time-filters">
<span :class="{ active: activeTime === '今天' }" @click="activeTime = '今天'">今天</span>
<span :class="{ active: activeTime === '本周' }" @click="activeTime = '本周'">本周</span>
<span :class="{ active: activeTime === '本月' }" @click="activeTime = '本月'">本月</span>
<span :class="{ active: activeTime === '今年' }" @click="activeTime = '今年'">今年</span>
</div>
</div>
<!-- 地图区域 -->
<div class="map-container">
<div ref="worldMapRef" class="world-map" style="width: 100%; height: 400px;"></div>
</div>
</div>
<!-- 右侧网络信号 -->
<div class="right-section">
<div class="signal-header">
<el-icon class="signal-icon"><Warning /></el-icon>
<span class="signal-title">风险信号</span>
<el-badge :value="5" class="signal-badge" />
<span class="more-link">更多 ></span>
</div>
<div class="signal-list">
<div v-for="signal in signals" :key="signal.id" class="signal-item">
<div class="signal-content">
<div class="signal-left">
<el-tag :type="signal.type" size="small" class="signal-tag">{{ signal.tag }}</el-tag>
<div class="signal-text">{{ signal.content }}</div>
</div>
<div class="signal-time">{{ signal.time }}</div>
</div>
</div>
</div>
<el-button type="primary" class="process-btn" block>
<el-icon><Setting /></el-icon>
风险处理
</el-button>
</div>
</div>
<!-- 智库展示区域 -->
<div class="think-tanks-section">
<div
v-for="tank in thinkTanks" :key="tank.id" class="think-tank-card"
@click="handleClick(tank)">
<div class="tank-header">
<div class="tank-logo">
<el-image :src="$withFallbackImage(tank.logo, tank.id)" :alt="tank.name" />
</div>
<div class="tank-country">{{ tank.country }}</div>
</div>
<div class="tank-name">{{ tank.name }}</div>
<div class="tank-description" :title="tank.describe">{{ tank.describe }}</div>
<div class="tank-tags">
<el-tag v-for="tag in tank.tags" :key="tag" type="primary" size="small">
{{ tag }}
</el-tag>
</div>
</div>
<div class="view-all">
<span class="view-all-link">查看全部智库 ></span>
</div>
</div>
<ReportList />
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { Search, Location, Warning, Setting } from '@element-plus/icons-vue'
import * as echarts from 'echarts'
import ReportList from '@/components/ReportList.vue'
import { useRouter } from 'vue-router'
import rand from '@/assets/images/rand.png'
import brookings from '@/assets/images/brookings.png'
import mit from '@/assets/images/mit.png'
import itif from '@/assets/images/itif.png'
import mckinsley from '@/assets/images/mckinsey.png'
import { getThinkTankList } from '@/api'
const router = useRouter()
const searchText = ref('')
const activeTime = ref('本月')
const worldMapRef = ref(null)
// 世界地图数据 - 各国智库数量统计
const mapData = ref([
{ name: 'United States', value: 6, itemStyle: { color: '#ff4757' } },
{ name: 'China', value: 3, itemStyle: { color: '#ffa726' } },
{ name: 'United Kingdom', value: 2, itemStyle: { color: '#42a5f5' } },
{ name: 'Germany', value: 1, itemStyle: { color: '#66bb6a' } },
{ name: 'Japan', value: 1, itemStyle: { color: '#66bb6a' } },
{ name: 'France', value: 1, itemStyle: { color: '#66bb6a' } }
])
// 初始化世界地图
const initWorldMap = async () => {
if (!worldMapRef.value) return
const chart = echarts.init(worldMapRef.value)
// 使用可靠的世界地图数据源
try {
const response = await fetch('https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson')
const geoJson = await response.json()
// 注册世界地图
echarts.registerMap('world', geoJson)
const option = {
title: {
text: '全球智库分布',
left: 'center',
top: 20,
textStyle: {
color: '#333',
fontSize: 18,
fontWeight: 'bold'
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
if (params.seriesType === 'map') {
const data = mapData.value.find(item => item.name === params.name)
if (data) {
return `${params.name}<br/>智库数量: ${data.value}个`
}
return `${params.name}<br/>暂无数据`
}
return params.name
}
},
visualMap: {
min: 0,
max: 6,
left: 'left',
top: 'bottom',
text: ['高', '低'],
calculable: true,
inRange: {
color: ['#e3f2fd', '#1976d2']
},
textStyle: {
color: '#333'
}
},
series: [
{
name: '智库数量',
type: 'map',
map: 'world',
roam: true,
emphasis: {
label: {
show: true
}
},
data: [
{ name: 'United States of America', value: 6, itemStyle: { color: '#ff4757' } },
{ name: 'China', value: 3, itemStyle: { color: '#ffa726' } },
{ name: 'United Kingdom', value: 2, itemStyle: { color: '#42a5f5' } },
{ name: 'Germany', value: 1, itemStyle: { color: '#66bb6a' } },
{ name: 'Japan', value: 1, itemStyle: { color: '#66bb6a' } },
{ name: 'France', value: 1, itemStyle: { color: '#66bb6a' } }
],
itemStyle: {
borderColor: '#fff',
borderWidth: 1
}
}
]
}
chart.setOption(option)
} catch (error) {
console.log('使用备用地图方案')
// 如果外部数据源失败,使用内置的简化世界地图
const option = {
title: {
text: '全球智库分布',
left: 'center',
top: 20,
textStyle: {
color: '#333',
fontSize: 18,
fontWeight: 'bold'
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
return `${params.name}<br/>智库数量: ${params.value}个`
}
},
geo: {
type: 'map',
map: 'world',
roam: true,
itemStyle: {
color: '#f0f0f0',
borderColor: '#999',
borderWidth: 0.5
},
emphasis: {
itemStyle: {
color: '#e0e0e0'
}
},
regions: [
{
name: 'United States',
itemStyle: {
color: '#ff4757'
}
},
{
name: 'China',
itemStyle: {
color: '#ffa726'
}
},
{
name: 'United Kingdom',
itemStyle: {
color: '#42a5f5'
}
}
]
},
series: [
{
name: '智库分布',
type: 'scatter',
coordinateSystem: 'geo',
data: [
{ name: '美国', value: [-95, 37, 6], itemStyle: { color: '#ff4757' } },
{ name: '中国', value: [104, 35, 3], itemStyle: { color: '#ffa726' } },
{ name: '英国', value: [-3, 55, 2], itemStyle: { color: '#42a5f5' } },
{ name: '德国', value: [10, 51, 1], itemStyle: { color: '#66bb6a' } },
{ name: '日本', value: [138, 36, 1], itemStyle: { color: '#66bb6a' } },
{ name: '法国', value: [2, 46, 1], itemStyle: { color: '#66bb6a' } }
],
symbolSize: function (val) {
return Math.max(val[2] * 15, 25)
},
label: {
show: true,
formatter: function(params) {
return params.data.name + '\n' + params.data.value[2] + '个'
},
position: 'top',
textStyle: {
color: '#333',
fontSize: 12,
fontWeight: 'bold'
}
},
emphasis: {
scale: true,
scaleSize: 10
}
}
]
}
chart.setOption(option)
}
// 响应式处理
window.addEventListener('resize', () => {
chart.resize()
})
}
const signals = ref([
{
id: 1,
type: 'danger',
tag: '特别重大',
content: '兰德科技智库发布2025中美年度科技报告',
time: '一天前'
},
{
id: 2,
type: 'danger',
tag: '特别重大',
content: '信息技术与创新基金会发布《中国正在迅速成...',
time: '一天前'
},
{
id: 3,
type: 'warning',
tag: '重大',
content: '战略与国际研究中心发布《DeepSeek、华为、...',
time: '一天前'
},
{
id: 4,
type: 'warning',
tag: '重大',
content: '兰德科技智库发布《中国对AI的转型产业政策》',
time: '一天前'
},
{
id: 5,
type: 'success',
tag: '一般',
content: '兰德科技智库发布《中美对抗、竞争和合作...',
time: '一天前'
}
])
const thinkTanks = ref([])
const getThinkTanks= async () => {
const { data } = await getThinkTankList()
thinkTanks.value = data
}
const handleClick = (tank) => {
router.push({ name: 'ThinkTankDetail', params: { id: tank.id } })
}
// 组件挂载后初始化地图
onMounted(() => {
getThinkTanks()
nextTick(() => {
initWorldMap()
})
})
</script>
<style scoped lang="scss">
.tech-think-tank {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
background: url('@/assets/images/background.png') no-repeat;
background-position: center -100px;
background-size: 100% 100%;
min-height: 100vh;
}
.breadcrumb {
margin-bottom: 20px;
.current {
font-weight: 600;
}
}
.search-section {
margin-bottom: 30px;
display: flex;
justify-content: center;
}
.search-input {
max-width: 800px;
}
.stats-section {
display: flex;
justify-content: center;
gap: 80px;
margin-bottom: 40px;
}
.stat-item {
text-align: center;
}
.stat-number {
font-size: 48px;
font-weight: bold;
color: #1459BB;
line-height: 1;
margin-bottom: 8px;
}
.stat-label {
font-size: 14px;
color: #666;
}
.main-content {
display: flex;
gap: 10px;
margin-bottom: 40px;
height: 490px;
}
.left-section {
flex: 2;
background: white;
border-radius: 2px;
padding: 20px;
}
.section-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.location-icon {
color: #409eff;
margin-right: 8px;
}
.section-title {
font-weight: 500;
margin-right: auto;
}
.time-filters {
display: flex;
gap: 15px;
}
.time-filters span {
cursor: pointer;
padding: 4px 8px;
border-radius: 4px;
font-size: 14px;
color: #666;
}
.time-filters span.active {
background-color: #409eff;
color: white;
}
.map-container {
// height: 300px;
background: #f0f2f5;
border-radius: 8px;
position: relative;
overflow: hidden;
}
.map-placeholder {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
position: relative;
}
.data-point {
position: absolute;
}
.point-circle {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 12px;
font-weight: bold;
}
.point-circle.yellow {
background-color: #f39c12;
}
.point-circle.red {
background-color: #e74c3c;
}
.point-circle.blue {
background-color: #3498db;
}
.right-section {
flex: 1;
background: white;
border-radius: 2px;
padding: 20px;
}
.signal-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.signal-icon {
color: #f56c6c;
margin-right: 2px;
}
.signal-title {
font-weight: 500;
margin-right: 8px;
}
.signal-badge {
margin-right: auto;
}
.more-link {
color: #409eff;
font-size: 14px;
cursor: pointer;
}
.signal-list {
margin-bottom: 40px;
height: 330px;
overflow-y: auto;
}
.signal-item {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #f0f0f0;
}
.signal-item:last-child {
border-bottom: none;
}
.signal-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 12px;
}
.signal-left {
flex: 1;
display: flex;
gap: 6px;
}
.signal-tag {
align-self: flex-start;
}
.signal-text {
font-size: 14px;
color: #333;
line-height: 1.4;
word-break: break-word;
}
.signal-time {
font-size: 12px;
color: #999;
white-space: nowrap;
flex-shrink: 0;
}
.process-btn {
width: 100%;
}
.think-tanks-section {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: flex-start;
}
.think-tank-card {
background: white;
border-radius: 8px;
padding: 12px;
border: 1px solid #e4e7ed;
width: 220px;
// height: 180px;
flex-shrink: 0;
display: flex;
flex-direction: column;
cursor: pointer;
}
.tank-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
}
.tank-logo {
width: 60px;
height: 60px;
background: #f0f0f0;
border-radius: 8px;
margin-right: 15px;
display: flex;
align-items: center;
justify-content: center;
.el-image {
width: 100%;
height: 100%;
border-radius: 8px;
object-fit: contain;
}
}
.tank-logo img {
width: 100%;
height: 100%;
object-fit: contain;
}
.tank-country {
background: #f0f0f0;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
color: #666;
}
.tank-name {
font-size: 16px;
font-weight: 500;
margin-bottom: 10px;
color: #333;
}
.tank-description {
font-size: 12px;
color: #666;
flex: 1;
overflow: hidden;
display: -webkit-box;
text-overflow: ellipsis;
margin-bottom: 5px;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.tank-tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: auto;
}
.view-all {
text-align: center;
width: 180px;
padding: 0 5px;
background: #fff;
display: flex;
align-items: center;
cursor: pointer;
}
.view-all-link {
color:#1459BB;
font-size: 16px;
font-weight: 600;
text-align: center;
margin: 0 auto;
}
.view-all-link:hover {
text-decoration: underline;
}
</style>
\ No newline at end of file
......@@ -7,11 +7,7 @@
<div class="home-main">
<div class="home-main-header">
<div class="home-main-header-center">
<el-input
v-model="input"
style="width: 800px; height: 100%"
placeholder="搜索科技法案"
/>
<el-input v-model="input" style="width: 800px; height: 100%" placeholder="搜索科技法案" />
<div class="search">
<div class="search-icon">
<img src="./assets/images/search-icon.png" alt="" />
......@@ -41,7 +37,26 @@
<div class="item-footer">分析报告</div>
</div>
</div>
<div class="home-main-header-btn-box">
<div class="btn">
<div class="btn-text">{{ "最新动态" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "资讯要闻" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "统计概览" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "资源库" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
</div>
</div>
<DivideHeader class="divide1" :titleText="'最新动态'"></DivideHeader>
<div class="home-main-center">
<div class="center-top">
<div class="box1">
......@@ -79,7 +94,7 @@
info1: item.status === 1,
info2: item.status === 2,
info3: item.status === 3,
info4: item.status === 4,
info4: item.status === 4
}"
v-for="(item, index) in curBill.hylyList"
:key="index"
......@@ -102,59 +117,18 @@
</div>
</div>
<div class="box1-main-left-info2">
<div
class="time-line"
:style="{ height: 38 * 3 + 'px' }"
></div>
<div
class="info2-item"
v-for="(item, index) in curBill.dyqkList"
:key="index"
>
<div class="time-line" :style="{ height: 38 * 3 + 'px' }"></div>
<div class="info2-item" v-for="(item, index) in curBill.dyqkList" :key="index">
<div class="item-icon">
<img src="./assets/images/info2-icon.png" alt="" />
</div>
<div
class="item-time"
:class="{ itemTimeActive: item.status === 1 }"
>
<div class="item-time" :class="{ itemTimeActive: item.status === 1 }">
{{ item.dysj }}
</div>
<div
class="item-title"
:class="{ itemTitleActive: item.status === 1 }"
>
<div class="item-title" :class="{ itemTitleActive: item.status === 1 }">
{{ item.dyms }}
</div>
</div>
<!-- <div class="info2-item">
<div class="item-icon">
<img src="./assets/images/info2-icon.png" alt="" />
</div>
<div class="item-time">{{ "2025-07-04" }}</div>
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div>
</div>
<div class="info2-item">
<div class="item-icon">
<img src="./assets/images/info2-icon.png" alt="" />
</div>
<div class="item-time">{{ "2025-07-04" }}</div>
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div>
</div>
<div class="info2-item">
<div class="item-icon">
<img src="./assets/images/info2-icon.png" alt="" />
</div>
<div class="item-time">{{ "2025-07-04" }}</div>
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div>
</div>
<div class="info2-item">
<div class="item-icon">
<img src="./assets/images/info2-icon.png" alt="" />
</div>
<div class="item-time">{{ "2025-07-04" }}</div>
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div>
</div> -->
</div>
</div>
<div class="box1-main-right">
......@@ -187,16 +161,12 @@
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box2-main">
<div
class="box2-main-item"
v-for="(item, index) in warningList"
:key="index"
>
<div class="box2-main-item" v-for="(item, index) in warningList" :key="index">
<div
class="item-left"
:class="{
itemLeftStatus1: item.status === '一般风险',
itemLeftStatus2: item.status === '重大风险',
itemLeftStatus2: item.status === '重大风险'
}"
>
{{ item.status }}
......@@ -217,16 +187,67 @@
</div>
</div>
</div>
<div class="center-footer">
<DivideHeader class="divide2" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center">
<div class="box3">
<div class="box3-header">
<div class="box3-header-left">
<div class="box3-header-icon">
<img src="./assets/images/box3-header-icon.png" alt="" />
</div>
<div class="box3-header-title">{{ "涉华法案数量" }}</div>
<div class="box3-header-title">{{ "新闻资讯" }}</div>
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(news, index) in newsList" :key="index">
<div class="left">
<img :src="news.img" alt="" />
</div>
<div class="right">
<div class="right-top">
<div class="title">{{ news.title }}</div>
<div class="time">{{ news.from }}</div>
</div>
<div class="right-footer">{{ news.content }}</div>
</div>
</div>
</div>
</div>
<div class="box4">
<div class="box4-header">
<div class="header-icon">
<img src="./assets/images/box4-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "社交媒体" }}</div>
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left">
<img :src="item.img" alt="" />
</div>
<div class="box3-header-right">
<div class="right">
<div class="right-top">
<div class="name">{{ item.name }}</div>
<div class="time">{{ item.time }}</div>
</div>
<div class="content">{{ item.content }}</div>
</div>
</div>
</div>
</div>
</div>
<DivideHeader class="divide3" :titleText="'统计概览'"></DivideHeader>
<div class="center-footer">
<div class="box5">
<div class="box5-header">
<div class="box5-header-left">
<div class="box5-header-icon">
<img src="./assets/images/box5-header-icon.png" alt="" />
</div>
<div class="box5-header-title">{{ "涉华法案数量" }}</div>
</div>
<div class="box5-header-right">
<div class="right-box">
<div class="icon1"></div>
<div class="text">{{ "提出法案" }}</div>
......@@ -237,38 +258,22 @@
</div>
</div>
</div>
<div class="box3-main" id="chart1"></div>
<div class="box5-main" id="chart1"></div>
</div>
<div class="box4">
<div class="box4-header">
<div class="box6">
<div class="box6-header">
<div class="header-icon">
<img src="./assets/images/box4-header-icon.png" alt="" />
<img src="./assets/images/box6-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "关键条款" }}</div>
</div>
<div class="box4-main">
<div
class="box4-main-item"
v-for="(item, index) in billTrendList"
:key="index"
>
<div
class="left"
:class="{
leftStatus2: index === 1,
leftStatus3: index === 2,
}"
>
{{ index < 3 ? index + 1 : "" }}
</div>
<div class="center">{{ item.title }}</div>
<div class="right">{{ item.no }}</div>
</div>
<div class="box6-main" id="wordCloudChart"></div>
</div>
</div>
</div>
</div>
<div class="home-main-footer">
<DivideHeader class="divide4" :titleText="'资源库'"></DivideHeader>
<div class="home-main-footer-header">
<div class="btn-wrapper">
<div class="btn-box">
......@@ -285,17 +290,8 @@
</div>
<div class="select-box">
<el-select
v-model="releaseTime"
placeholder="选择发布时间"
style="width: 120px"
>
<el-option
v-for="item in releaseTimeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="releaseTime" placeholder="选择发布时间" style="width: 120px">
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<!-- <el-select
v-model="releaseTime"
......@@ -312,11 +308,7 @@
</div>
</div>
<div class="home-main-footer-main">
<div
class="main-item"
v-for="(bill, index) in curBillList"
:key="index"
>
<div class="main-item" v-for="(bill, index) in curBillList" :key="index">
<div class="main-item-box1">
<img :src="bill.img" alt="" />
</div>
......@@ -326,6 +318,13 @@
<div class="main-item-box3">{{ bill.introductionDate }}</div>
</div>
</div>
<div class="home-main-footer-footer">
<div class="footer-left">
{{ `共${curBillList.length}项调查` }}
</div>
<div class="footer-right">
<el-pagination background layout="prev, pager, next" :total="curBillList.length" />
</div>
</div>
</div>
</div>
......@@ -337,6 +336,7 @@ import * as echarts from "echarts";
import router from "@/router/index";
import { getHotBills, getBillsByType, getHylyList } from "@/api/home";
import DivideHeader from "@/components/DivideHeader.vue";
import headerIcon1 from "./assets/icons/header-icon1.png";
import headerIcon2 from "./assets/icons/header-icon2.png";
......@@ -345,6 +345,7 @@ import headerIcon4 from "./assets/icons/header-icon4.png";
import headerIcon5 from "./assets/icons/header-icon5.png";
import getMultiLineChart from "./utils/multiLineChart";
import getWordCloudChart from "./utils/worldCloudChart";
import bill1 from "./assets/images/bill1.png";
import bill2 from "./assets/images/bill2.png";
......@@ -359,10 +360,20 @@ import bill10 from "./assets/images/bill10.png";
import bill11 from "./assets/images/bill11.png";
import bill12 from "./assets/images/bill12.png";
import News1 from "./assets/images/news1.png";
import News2 from "./assets/images/news2.png";
import News3 from "./assets/images/news3.png";
import News4 from "./assets/images/news4.png";
import News5 from "./assets/images/news5.png";
import Message1 from "./assets/images/message-icon1.png";
import Message2 from "./assets/images/message-icon2.png";
import Message3 from "./assets/images/message-icon3.png";
const billList = ref([]);
const curBillListIndex = ref(0);
const handleSwithCurBill = (name) => {
const handleSwithCurBill = name => {
if (name === "left") {
if (curBillListIndex.value === 0) {
curBillListIndex.value = billList.value.length - 1;
......@@ -386,7 +397,7 @@ const curBill = ref({
dyqkList: [],
hylyList: [],
tarName: "",
introductionDate: "",
introductionDate: ""
});
const handleClickToDetail = () => {
......@@ -397,186 +408,186 @@ const handleClickToDetail = () => {
const billTrendList = ref([
{
title: "限制与中国合作",
no: "H.R.2670",
no: "H.R.2670"
},
{
title: "限制中国获取技术",
no: "H.R.2471",
no: "H.R.2471"
},
{
title: "禁止在中国建设半导体产能",
no: "H.R.5895",
no: "H.R.5895"
},
{
title: "限制中国产燃油进口",
no: "S.870",
no: "S.870"
},
{
title: "禁止政府部门采购受控半导体或服务",
no: "H.R.6395",
no: "H.R.6395"
},
{
title: "禁止向部分中国实体提供资金",
no: "H.R.3935",
no: "H.R.3935"
},
{
title: "限制采购中国生产电池",
no: "H.R.7776",
no: "H.R.7776"
},
{
title: "重视新兴中国技术公司威胁",
no: "H.R.3935",
no: "H.R.3935"
},
{
title: "禁止卫星出口至中国",
no: "S.870",
no: "S.870"
},
{
title: "禁购华为设备",
no: "H.R.5895",
},
no: "H.R.5895"
}
]);
const warningList = ref([
{
title: "美国大而美法案落地,总统签署通过",
time: "一天前",
status: "特别重大",
status: "特别重大"
},
{
title: "美大而美法案7月1日以51:50的票数通过...",
time: "一天前",
status: "特别重大",
status: "特别重大"
},
{
title: "首次提出“限制外国敏感实体获取补贴”",
time: "一天前",
status: "重大风险",
status: "重大风险"
},
{
title: "将中国企业海外子公司、合资公司纳入受...",
time: "一天前",
status: "重大风险",
status: "重大风险"
},
{
title: "H.R.8333《生物安全法案》将华大基因等...",
time: "一天前",
status: "一般风险",
},
status: "一般风险"
}
]);
const timelineList = ref([
{
title: "成为公法 No: 119-21。",
time: "2025-07-04",
status: 1,
status: 1
},
{
title: "总统签署",
time: "2025-07-04",
status: 0,
status: 0
},
{
title: "提交总统",
time: "2025-07-03",
status: 0,
status: 0
},
{
title: "重新审议动议搁置案无异议通过。",
time: "2025-07-03 14:31",
status: 0,
status: 0
},
{
title: "关于‘众议院同意参议院修正案’...",
time: "2025-07-02 14:31",
status: 0,
},
status: 0
}
]);
const areaList = ref([
{
name: "跨境电商",
status: 2,
status: 2
},
{
name: "新能源产业",
status: 4,
status: 4
},
{
name: "半导体产业",
status: 1,
status: 1
},
{
name: "关税",
status: 3,
status: 3
},
{
name: "光伏产业",
status: 2,
},
status: 2
}
]);
const curBillList = ref([
{
billName: "大而美法案",
introductionDate: "2025年7月4日",
img: bill1,
img: bill1
},
{
billName: "GENIUS稳定币法案",
introductionDate: "2025年7月5日",
img: bill2,
img: bill2
},
{
billName: "美越贸易协议",
introductionDate: "2025年7月6日",
img: bill3,
img: bill3
},
{
billName: "美越贸易协议",
introductionDate: "2025年7月7日",
img: bill4,
img: bill4
},
{
billName: "汽车零部件25%关税实施规则",
introductionDate: "2025年7月10日",
img: bill5,
img: bill5
},
{
billName: "汽车零部件25%关税实施规则",
introductionDate: "2025年7月12日",
img: bill6,
img: bill6
},
{
billName: "小额豁免包裹政策调整",
introductionDate: "2025年7月14日",
img: bill7,
img: bill7
},
{
billName: "NIH预算否决案",
introductionDate: "2025年7月15日",
img: bill8,
img: bill8
},
{
billName: "得州国会选区重划法案",
introductionDate: "2025年7月17日",
img: bill9,
img: bill9
},
{
billName: "美越贸易协议",
introductionDate: "2025年7月24日",
img: bill10,
img: bill10
},
{
billName: "美越贸易协议",
introductionDate: "2025年8月4日",
img: bill11,
img: bill11
},
{
billName: "美越贸易协议",
introductionDate: "2025年8月8日",
img: bill12,
},
img: bill12
}
]);
const releaseTime = ref("近一年发布");
......@@ -584,24 +595,24 @@ const releaseTime = ref("近一年发布");
const releaseTimeList = ref([
{
label: "近半年发布",
value: "近半年发布",
value: "近半年发布"
},
{
label: "近一年发布",
value: "近一年发布",
value: "近一年发布"
},
{
label: "近两年发布",
value: "近两年发布",
value: "近两年发布"
},
{
label: "近三年发布",
value: "近三年发布",
value: "近三年发布"
},
{
label: "近五年发布",
value: "近五年发布",
},
value: "近五年发布"
}
]);
const categoryList = ref([
......@@ -630,13 +641,13 @@ const handleGetHylyList = async () => {
const obj = {
id: 0,
hylyid: "",
hylymc: "全部分类",
hylymc: "全部分类"
};
categoryList.value = [obj, ...categoryList.value];
} catch (error) {}
};
const handleClickCate = (cate) => {
const handleClickCate = cate => {
console.log(cate);
activeCate.value = cate.hylymc;
......@@ -649,32 +660,32 @@ const navList = ref([
icon: headerIcon1,
activeIcno: headerIcon1,
name: "首页",
path: "/home",
path: "/home"
},
{
icon: headerIcon2,
activeIcno: headerIcon2,
name: "国家",
path: "/country",
path: "/country"
},
{
icon: headerIcon3,
activeIcno: headerIcon3,
name: "领域",
path: "/area",
path: "/area"
},
{
icon: headerIcon4,
activeIcno: headerIcon4,
name: "要素",
path: "/home",
path: "/home"
},
{
icon: headerIcon5,
activeIcno: headerIcon5,
name: "事件",
path: "/home",
},
path: "/home"
}
]);
const activeNavIndex = ref(0);
......@@ -706,20 +717,76 @@ const chart1Data = ref({
"2025-05",
"2025-06",
"2025-07",
"2025-08",
"2025-08"
],
data: [
{
name: "提出法案",
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172],
value: [145, 52, 84, 99, 71, 96, 128, 144, 140, 168, 188, 172]
},
{
name: "通过法案",
value: [6, 3, 4, 6, 11, 5, 2, 14, 16, 27, 28, 44],
},
],
value: [6, 3, 4, 6, 11, 5, 2, 14, 16, 27, 28, 44]
}
]
});
// 新闻资讯
const newsList = ref([
{
img: News1,
title: "美政府停摆仍持续,拨款法案存缺陷,但两党磋商露曙光",
content: `美国政府停摆已持续34天,距离历史上最长的停摆纪录仅差一天,参议院已先后13次尝试...`,
from: "11-4 · 华盛顿邮报"
},
{
img: News2,
title: "美参议院通过决议,要求终止特朗普全球关税政策",
content: `参议院以51票赞成、47票反对通过一项决议,旨在终止特朗普实施的全面关税政策,四名......`,
from: "11-4 · 纽约时报"
},
{
img: News3,
title: "美众院通过950亿美元对外援助法案,包含对台军援",
content: `国会众议院在4月通过了大规模对外援助法案,其中包括为“印太安全”提供资金的条款,......`,
from: "11-3 · 洛杉矶时报"
},
{
img: News4,
title: "“大而美”法案在激烈争议中通过",
content: `特朗普力推的大规模税收与支出法案在国会以微弱优势通过。该法案因大幅削减医疗补助和......`,
from: "11-3 · 今日美国"
},
{
img: News5,
title: "美政府“停摆”追平历史最长纪录,民生多领域受重创",
content: `联邦政府“停摆”进入第35天,追平历史纪录。食品救济项目资金中断,数百万低收入民......`,
from: "11-2 · ​福克斯新闻网"
}
]);
// 社交媒体
const messageList = ref([
{
img: Message1,
name: "唐纳德·特朗普",
time: "15:23 · 发布于真实社交",
content: `埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。`
},
{
img: Message2,
name: "埃隆·马斯克",
time: "14:49 · 发布于X",
content: `如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。`
},
{
img: Message3,
name: "塞巴斯蒂安·马拉比",
time: "11:05 · 发布于X",
content: `提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。`
}
]);
// 获取热门法案
const handleGetHotBills = async () => {
try {
......@@ -734,33 +801,55 @@ const handleGetHotBills = async () => {
// 根据法案类型获取法案列表
const handleGetBillsByType = async () => {
const params = {
type: activeHylyId.value,
type: activeHylyId.value
};
try {
const res = await getBillsByType(params);
console.log("根据法案类型获取法案列表", res);
curBillList.value = res.data.map((item) => {
curBillList.value = res.data.map(item => {
return {
billId: item.billId,
billName: item.billName,
introductionDate: item.introductionDate,
img: bill1,
img: bill1
};
});
} catch (error) {}
};
const wordCloudData = ref([
{ name: "限制中国获取能源技术", value: 100 },
{ name: "未实现赤字控制目标", value: 66 },
{ name: "关注核聚变能源研究", value: 77 },
{ name: "抵制外国人才争夺", value: 35 },
{ name: "进行可再生能源税收减免", value: 88 },
{ name: "评估中美现代化技术", value: 57 },
{ name: "应对中国制造2025战略", value: 72 },
{ name: "实施能源税收延期", value: 18 },
{ name: "限制采购中国产电池", value: 34 },
{ name: "加强美国在核能领域得到领导力", value: 16 },
{ name: "发展替代燃料", value: 72 },
{ name: "发展风能", value: 58 },
{ name: "发展太阳能", value: 24 },
{ name: "施加额外能源出口限制", value: 33 },
{ name: "评估中美能源技术", value: 47 },
{ name: "禁止资助中国能源项目", value: 32 },
{ name: "不得向中国机构提供援助", value: 62 },
{ name: "开展先进生物能源计划", value: 51 },
{ name: "减少燃料对外依赖", value: 81 },
{ name: "加强供应链风险管理", value: 73 }
]);
onMounted(async () => {
handleGetHylyList();
await handleGetHotBills();
curBill.value = billList.value[0];
handleGetBillsByType();
let chart1 = getMultiLineChart(
chart1Data.value.title,
chart1Data.value.data[0].value,
chart1Data.value.data[1].value
);
// handleGetBillsByType();
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value, chart1Data.value.data[1].value);
setChart(chart1, "chart1");
const wordCloudChart = getWordCloudChart(wordCloudData.value);
setChart(wordCloudChart, "wordCloudChart");
});
</script>
......@@ -782,8 +871,9 @@ onMounted(async () => {
padding-left: 160px;
}
.home-main {
width: 1400px;
width: 1600px;
margin: 0 auto;
margin-top: 48px;
background: url("./assets/images/background.png");
background-size: 100% 100%;
.home-main-header {
......@@ -791,10 +881,9 @@ onMounted(async () => {
flex-direction: column;
align-items: center;
.home-main-header-center {
margin-top: 13px;
width: 960px;
height: 48px;
border-radius: 4px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
......@@ -803,11 +892,11 @@ onMounted(async () => {
.search {
position: absolute;
right: 1px;
top: 1px;
top: 2px;
width: 120px;
height: 42px;
border-radius: 4px;
background: rgba(22, 119, 255, 1);
border-radius: 10px;
background: var(--color-main-active);
display: flex;
justify-content: center;
align-items: center;
......@@ -860,6 +949,45 @@ onMounted(async () => {
}
}
}
.home-main-header-btn-box {
margin-top: 36px;
display: flex;
.btn {
display: flex;
width: 160px;
height: 48px;
border: 1px solid #aed6ff;
box-sizing: border-box;
border-radius: 24px;
justify-content: center;
margin: 0 16px;
background: #e7f3ff;
cursor: pointer;
&:hover {
background: #cae3fc;
}
.btn-text {
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 44px;
margin-left: 5px;
}
.btn-icon {
margin-left: 20px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 44px;
}
}
}
}
.divide1 {
margin-top: 64px;
margin-bottom: 36px;
}
.home-main-center {
margin-top: 34px;
......@@ -868,7 +996,7 @@ onMounted(async () => {
display: flex;
gap: 20px;
.box1 {
width: 920px;
width: 1064px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: #fff;
......@@ -963,9 +1091,9 @@ onMounted(async () => {
box-sizing: border-box;
padding-left: 31px;
.box1-main-left {
margin-left: 37px;
margin-left: 39px;
// flex: 1;
width: 410px;
width: 484px;
.box1-main-left-title {
height: 22px;
color: rgba(20, 89, 187, 1);
......@@ -1109,9 +1237,8 @@ onMounted(async () => {
}
}
.box1-main-right {
margin-top: 50px;
height: 270px;
width: 350px;
height: 354px;
width: 458px;
border-radius: 4px;
overflow: hidden;
position: relative;
......@@ -1321,17 +1448,21 @@ onMounted(async () => {
}
}
}
.center-footer {
.divide2 {
margin-top: 68px;
margin-bottom: 36px;
}
.center-center {
margin-top: 21px;
height: 450px;
display: flex;
.box3 {
width: 900px;
width: 792px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box3-header {
height: 53px;
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
......@@ -1359,7 +1490,208 @@ onMounted(async () => {
line-height: 22px;
}
}
.box3-header-right {
}
.box3-main {
height: 402px;
overflow-y: auto;
overflow-x: hidden;
padding-top: 6px;
.box3-item {
display: flex;
height: 77px;
width: 749px;
margin-left: 21px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
.left {
width: 72px;
height: 48px;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.right {
width: 657px;
margin-left: 20px;
.right-top {
width: 657px;
display: flex;
justify-content: space-between;
.title {
margin-top: 13px;
width: 520px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
flex: 1;
text-align: right;
height: 22px;
margin-top: 19px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
.right-footer {
width: 657px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
.box4 {
margin-left: 20px;
width: 792px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box4-header {
width: 792px;
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
box-sizing: border-box;
padding-left: 22px;
.header-icon {
margin-top: 15px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.header-title {
margin-top: 16px;
margin-left: 18px;
height: 22px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
}
.box4-main {
height: 402px;
overflow-y: auto;
box-sizing: border-box;
padding-top: 8px;
.box4-main-item {
margin-top: 16px;
display: flex;
margin-left: 21px;
.left {
margin-top: 5px;
width: 36px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
.right {
margin-left: 10px;
width: 690px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
background: rgba(246, 250, 255, 1);
padding: 10px 15px;
.right-top {
display: flex;
justify-content: space-between;
.name {
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
}
.time {
height: 30px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
}
}
.content {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
}
}
}
}
}
.divide3 {
margin-top: 64px;
margin-bottom: 36px;
}
.center-footer {
margin-top: 21px;
height: 450px;
display: flex;
.box5 {
width: 1059px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.box5-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
padding: 0 20px;
.box5-header-left {
display: flex;
.box5-header-icon {
margin-top: 16px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box5-header-title {
margin-top: 16px;
margin-left: 19px;
height: 22px;
color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 22px;
}
}
.box5-header-right {
display: flex;
justify-content: flex-end;
width: 178px;
......@@ -1395,19 +1727,19 @@ onMounted(async () => {
}
}
}
.box3-main {
.box5-main {
height: 397px;
}
}
.box4 {
.box6 {
margin-left: 20px;
width: 521px;
height: 450px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
.box4-header {
.box6-header {
width: 521px;
height: 53px;
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
box-sizing: border-box;
......@@ -1432,59 +1764,30 @@ onMounted(async () => {
line-height: 22px;
}
}
.box4-main {
.box6-main {
width: 452px;
margin: 0 auto;
margin-top: 8px;
height: 360px;
overflow-y: auto;
.box4-main-item {
margin-top: 6px;
height: 30px;
display: flex;
.leftStatus3 {
color: rgba(255, 197, 61, 1) !important;
}
.leftStatus2 {
color: rgba(255, 169, 64, 1) !important;
}
.left {
width: 44px;
text-align: left;
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 30px;
color: rgba(206, 79, 81, 1);
}
.center {
width: 300px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 30px;
}
.right {
width: 108px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 30px;
text-align: right;
}
height: 402px;
}
}
}
}
}
.home-main-footer {
// width: 100%;
height: 911px;
width: 100%;
height: 1000px;
background: rgba(248, 249, 250, 1);
margin-bottom: 20px;
overflow: hidden;
margin-top: 36px;
.divide4 {
margin: 0 auto;
margin-top: 52px;
margin-bottom: 36px;
}
.home-main-footer-header {
width: 1600px;
margin: 0 auto;
margin-top: 37px;
margin-bottom: 36px;
// width: 1600px;
......@@ -1538,18 +1841,20 @@ onMounted(async () => {
}
}
.home-main-footer-main {
width: 100%;
width: 1600px;
margin: 0 auto;
// background: orange;
display: flex;
flex-wrap: wrap;
padding: 5px 10px;
// justify-content: space-between;
// justify-content: center;
overflow-y: auto;
height: 820px;
padding: 5px 0px;
padding-left: 5px;
overflow: hidden;
height: 700px;
.main-item {
width: 240px;
height: 320px;
border-radius: 4px;
background: linear-gradient(0deg, rgba(255, 255, 255, 1) 44%, rgba(255, 255, 255, 0) 100%);
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: #fff;
margin-bottom: 24px;
......@@ -1588,6 +1893,20 @@ onMounted(async () => {
}
}
}
.home-main-footer-footer {
width: 1600px;
margin: 0 auto;
height: 32px;
margin-top: 30px;
display: flex;
justify-content: space-between;
.footer-left {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 32px;
}
}
}
}
......
const getWordCloudChart = (data) => {
const option = {
grid: {
left: 0,
top: 0,
right: 0,
bottom: 0,
},
series: [
{
type: "wordCloud",
shape: "rect", //
// 其他形状你可以使用形状路径
// 或者自定义路径
// shape: 'circle' // 圆形(默认)
// shape: 'rect' // 矩形
// shape: 'roundRect' // 圆角矩形
// shape: 'triangle' // 三角形
// shape: 'diamond' // 菱形
// shape: 'pentagon' // 五边形
// shape: 'star' // 星形
// shape: 'cardioid' // 心形
gridSize: 5, // 网格大小,影响词间距。
sizeRange: [10, 30], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 10,
drawOutOfBound: false, // 是否超出画布
// 字体
textStyle: {
// normal: {
// color: function () {
// return 'rgb(' + [
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160)
// ].join(',') + ')';
// }
// },
color: function () {
let colors = [
"rgba(189, 33, 33, 1)",
"rgba(232, 151, 21, 1)",
"rgba(220, 190, 68, 1)",
"rgba(96, 58, 186, 1)",
"rgba(32, 121, 69, 1)",
"rgba(22, 119, 255, 1)",
];
return colors[parseInt(Math.random() * colors.length)];
},
emphasis: {
shadowBlur: 5,
shadowColor: "#333",
},
},
// 设置词云数据
data: data,
},
],
}
return option
}
export default getWordCloudChart
\ No newline at end of file
......@@ -7,11 +7,7 @@
<span>科技政令</span>
</div>
<div class="home-main-header-center">
<el-input
v-model="input"
style="width: 838px; height: 100%"
placeholder="搜索科技政令"
/>
<el-input v-model="input" style="width: 838px; height: 100%" placeholder="搜索科技政令" />
<div class="search">
<div class="search-icon">
<img src="./assets/images/search-icon.png" alt="" />
......@@ -41,7 +37,34 @@
<div class="item-footer">分析报告</div>
</div>
</div>
<div class="home-main-header-btn-box">
<div class="btn">
<div class="btn-text">{{ "最新动态" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "资讯要闻" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "统计概览" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
<div class="btn">
<div class="btn-text">{{ "资源库" }}</div>
<div class="btn-icon">{{ ">" }}</div>
</div>
</div>
<div class="home-main-header-item-box">
<div class="item" v-for="(item, index) in govInsList" :key="index">
<div class="item-left">
<img :src="item.img" alt="" />
</div>
<div class="item-right">{{ item.name }}</div>
</div>
</div>
</div>
<DivideHeader class="divide" :titleText="'最新动态'"></DivideHeader>
<div class="home-main-center">
<div class="center-top">
<div class="box1">
......@@ -81,7 +104,7 @@
tag1: tag.status == 1,
tag2: tag.status == 2,
tag3: tag.status == 3,
tag4: tag.status == 4,
tag4: tag.status == 4
}"
v-for="(tag, index) in tagList"
:key="index"
......@@ -121,16 +144,12 @@
<div class="more">{{ "更多 +" }}</div>
</div>
<div class="box2-main">
<div
class="box2-main-item"
v-for="(item, index) in warningList"
:key="index"
>
<div class="box2-main-item" v-for="(item, index) in warningList" :key="index">
<div
class="item-left"
:class="{
itemLeftStatus1: item.status === '一般风险',
itemLeftStatus2: item.status === '重大风险',
itemLeftStatus2: item.status === '重大风险'
}"
>
{{ item.status }}
......@@ -161,16 +180,10 @@
<img src="./assets/images/p1.png" alt="" />
</div>
<div class="right">
<div
class="name"
:class="{ nameActive: center1ActiveIndex === 0 }"
>
<div class="name" :class="{ nameActive: center1ActiveIndex === 0 }">
{{ "唐纳德·特朗普任期" }}
</div>
<div
class="time"
:class="{ timeActive: center1ActiveIndex === 0 }"
>
<div class="time" :class="{ timeActive: center1ActiveIndex === 0 }">
{{ "2025.1.20-至今" }}
</div>
</div>
......@@ -184,16 +197,10 @@
<img src="./assets/images/p2.png" alt="" />
</div>
<div class="right">
<div
class="name"
:class="{ nameActive: center1ActiveIndex === 1 }"
>
<div class="name" :class="{ nameActive: center1ActiveIndex === 1 }">
{{ "乔·拜登任期" }}
</div>
<div
class="time"
:class="{ timeActive: center1ActiveIndex === 1 }"
>
<div class="time" :class="{ timeActive: center1ActiveIndex === 1 }">
{{ "2021.1.20-2025.1.20" }}
</div>
</div>
......@@ -207,16 +214,10 @@
<img src="./assets/images/p1.png" alt="" />
</div>
<div class="right">
<div
class="name"
:class="{ nameActive: center1ActiveIndex === 2 }"
>
<div class="name" :class="{ nameActive: center1ActiveIndex === 2 }">
{{ "唐纳德·特朗普任期" }}
</div>
<div
class="time"
:class="{ timeActive: center1ActiveIndex === 2 }"
>
<div class="time" :class="{ timeActive: center1ActiveIndex === 2 }">
{{ "2017.1.20-2021.1.20" }}
</div>
</div>
......@@ -230,16 +231,10 @@
<img src="./assets/images/p3.png" alt="" />
</div>
<div class="right">
<div
class="name"
:class="{ nameActive: center1ActiveIndex === 3 }"
>
<div class="name" :class="{ nameActive: center1ActiveIndex === 3 }">
{{ "贝拉克·奥巴马任期" }}
</div>
<div
class="time"
:class="{ timeActive: center1ActiveIndex === 3 }"
>
<div class="time" :class="{ timeActive: center1ActiveIndex === 3 }">
{{ "2013.1.20-2017.1.20" }}
</div>
</div>
......@@ -310,11 +305,7 @@
<div class="text">{{ "主要内阁成员" }}</div>
</div>
<div class="main">
<div
class="item"
v-for="(item, index) in personList"
:key="index"
>
<div class="item" v-for="(item, index) in personList" :key="index">
<div class="item-left">
<img :src="item.avator" alt="" />
</div>
......@@ -350,11 +341,7 @@
</div>
</div>
<div class="main">
<div
class="main-item"
v-for="(val, idx) in list[tabActiveIndex].data"
:key="idx"
>
<div class="main-item" v-for="(val, idx) in list[tabActiveIndex].data" :key="idx">
<div class="id">{{ idx + 1 }}</div>
<div class="info">
<div class="info-header">
......@@ -407,11 +394,7 @@
<div class="header-title">{{ "关键政令及举措" }}</div>
</div>
<div class="box5-main">
<div
class="box5-item"
v-for="(item, index) in keyDecreeList"
:key="index"
>
<div class="box5-item" v-for="(item, index) in keyDecreeList" :key="index">
<div class="icon">
<img src="./assets/images/warning.png" alt="" />
</div>
......@@ -452,11 +435,7 @@
</div>
</div>
<div class="select-box">
<el-select
v-model="releaseTime"
placeholder="选择发布时间"
style="width: 120px"
>
<el-select v-model="releaseTime" placeholder="选择发布时间" style="width: 120px">
<el-option
v-for="item in releaseTimeList"
:key="item.value"
......@@ -479,18 +458,14 @@
</div>
</div>
<div class="home-main-footer-main">
<div
class="main-item"
v-for="(decree, index) in curDecreeList"
:key="index"
>
<div class="main-item" v-for="(decree, index) in curDecreeList" :key="index">
<div class="main-item-left">
<div
class="left-box"
:class="{
type1: decree.status === 1,
type2: decree.status === 2,
type3: decree.status === 3,
type3: decree.status === 3
}"
>
{{ decree.type }}
......@@ -518,6 +493,7 @@ import { onMounted, ref } from "vue";
import * as echarts from "echarts";
import router from "@/router";
import WordCloudMap from "./WordCloudMap.vue";
import DivideHeader from "@/components/DivideHeader.vue";
import getMultiLineChart from "./utils/multiLineChart";
import getBarChart from "./utils/barChart";
......@@ -535,63 +511,117 @@ import p8 from "./assets/images/iconp8.png";
import p9 from "./assets/images/iconp9.png";
import p10 from "./assets/images/iconp10.png";
import Gov1 from "./assets/images/gov1.png";
import Gov2 from "./assets/images/gov2.png";
import Gov3 from "./assets/images/gov3.png";
import Gov4 from "./assets/images/gov4.png";
import Gov5 from "./assets/images/gov5.png";
import Gov6 from "./assets/images/gov6.png";
import Gov7 from "./assets/images/gov7.png";
import Gov8 from "./assets/images/gov8.png";
import Gov9 from "./assets/images/gov9.png";
import Gov10 from "./assets/images/gov10.png";
const center1ActiveIndex = ref(0);
const handleClickCenter1Item = (index) => {
const handleClickCenter1Item = index => {
center1ActiveIndex.value = index;
};
const govInsList = ref([
{
img: Gov1,
name: "美国白宫"
},
{
img: Gov2,
name: "美国财政部"
},
{
img: Gov3,
name: "美国能源部"
},
{
img: Gov4,
name: "美国商务部"
},
{
img: Gov5,
name: "美国战争部"
},
{
img: Gov6,
name: "联邦通信委员会 "
},
{
img: Gov7,
name: "食品药品监督管理局 (FDA)"
},
{
img: Gov8,
name: "美国航空航天局 (NASA)"
},
{
img: Gov9,
name: "美国国家卫生基金会 (NSF)"
},
{
img: Gov10,
name: "美国国立卫生研究院 (NIH)"
}
]);
const personList = ref([
{
name: "詹姆斯·JD·万斯",
posi: "副总统",
avator: p1,
avator: p1
},
{
name: "马尔科·卢比奥",
posi: "国务卿",
avator: p2,
avator: p2
},
{
name: "斯科特·贝森特",
posi: "财政部长",
avator: p3,
avator: p3
},
{
name: "皮特·赫格塞斯",
posi: "国防部长",
avator: p4,
avator: p4
},
{
name: "帕姆·邦迪",
posi: "司法部长",
avator: p5,
avator: p5
},
{
name: "霍华德·卢特尼克",
posi: "商务部长",
avator: p6,
avator: p6
},
{
name: "苏西·威尔斯",
posi: "白宫办公厅主任",
avator: p7,
avator: p7
},
{
name: "克里斯蒂·诺姆",
posi: "国土安全部长",
avator: p8,
avator: p8
},
{
name: "道格·伯古姆",
posi: "内政部长",
avator: p9,
avator: p9
},
{
name: "克里斯·赖特",
posi: "能源部长",
avator: p10,
},
avator: p10
}
]);
const tabActiveIndex = ref(0);
......@@ -603,29 +633,29 @@ const list = [
{
title: "司法与法律政策",
tag: "司法改革",
content: `继续任命保守派法官至联邦各级范元、可能利用司法部调查政治对手,破坏司法部独立性传统。`,
content: `继续任命保守派法官至联邦各级范元、可能利用司法部调查政治对手,破坏司法部独立性传统。`
},
{
title: "移民政策",
tag: "边境安全",
content: `重启并扩大美墨边境墙建设,启动大规模非法移民驱逐行动。恢复并加强"留在墨西哥"政策,限制庇护申请。`,
content: `重启并扩大美墨边境墙建设,启动大规模非法移民驱逐行动。恢复并加强"留在墨西哥"政策,限制庇护申请。`
},
{
title: "能源政策",
tag: "能源独立",
content: `推行"钻探、钻探、钻探"政策,全力扩大化石燃料(石油、天然气、煤炭)的生产,撤销清洁能源补贴和环保法规。`,
content: `推行"钻探、钻探、钻探"政策,全力扩大化石燃料(石油、天然气、煤炭)的生产,撤销清洁能源补贴和环保法规。`
},
{
title: "关税政策",
tag: "能征关税",
content: `全面加征关税,推行“对等关税”,将关税收入作为弥补减税造成的财政收入缺口的手段之一。`,
content: `全面加征关税,推行“对等关税”,将关税收入作为弥补减税造成的财政收入缺口的手段之一。`
},
{
title: "外交政策",
tag: "能华强硬",
content: `采取单边主义和交易性做法,对国际多边体系构成挑战,要求盟友承担更多成本,对华政策更趋强硬。`,
},
],
content: `采取单边主义和交易性做法,对国际多边体系构成挑战,要求盟友承担更多成本,对华政策更趋强硬。`
}
]
},
{
title: "外交情况",
......@@ -633,29 +663,29 @@ const list = [
{
title: "司法与法律政策1",
tag: "司法改革",
content: `继续任命保守派法官至联邦各级范元、可能利用司法部调查政治对手,破坏司法部独立性传统。`,
content: `继续任命保守派法官至联邦各级范元、可能利用司法部调查政治对手,破坏司法部独立性传统。`
},
{
title: "移民政策",
tag: "边境安全",
content: `重启并扩大美墨边境墙建设,启动大规模非法移民驱逐行动。恢复并加强"留在墨西哥"政策,限制庇护申请。`,
content: `重启并扩大美墨边境墙建设,启动大规模非法移民驱逐行动。恢复并加强"留在墨西哥"政策,限制庇护申请。`
},
{
title: "能源政策",
tag: "能源独立",
content: `推行"钻探、钻探、钻探"政策,全力扩大化石燃料(石油、天然气、煤炭)的生产,撤销清洁能源补贴和环保法规。`,
content: `推行"钻探、钻探、钻探"政策,全力扩大化石燃料(石油、天然气、煤炭)的生产,撤销清洁能源补贴和环保法规。`
},
{
title: "关税政策",
tag: "能征关税",
content: `全面加征关税,推行“对等关税”,将关税收入作为弥补减税造成的财政收入缺口的手段之一。`,
content: `全面加征关税,推行“对等关税”,将关税收入作为弥补减税造成的财政收入缺口的手段之一。`
},
{
title: "外交政策",
tag: "能华强硬",
content: `采取单边主义和交易性做法,对国际多边体系构成挑战,要求盟友承担更多成本,对华政策更趋强硬。`,
},
],
content: `采取单边主义和交易性做法,对国际多边体系构成挑战,要求盟友承担更多成本,对华政策更趋强硬。`
}
]
},
{
title: "经济情况",
......@@ -663,41 +693,41 @@ const list = [
{
title: "司法与法律政策2",
tag: "司法改革",
content: `继续任命保守派法官至联邦各级范元、可能利用司法部调查政治对手,破坏司法部独立性传统。`,
content: `继续任命保守派法官至联邦各级范元、可能利用司法部调查政治对手,破坏司法部独立性传统。`
},
{
title: "移民政策",
tag: "边境安全",
content: `重启并扩大美墨边境墙建设,启动大规模非法移民驱逐行动。恢复并加强"留在墨西哥"政策,限制庇护申请。`,
content: `重启并扩大美墨边境墙建设,启动大规模非法移民驱逐行动。恢复并加强"留在墨西哥"政策,限制庇护申请。`
},
{
title: "能源政策",
tag: "能源独立",
content: `推行"钻探、钻探、钻探"政策,全力扩大化石燃料(石油、天然气、煤炭)的生产,撤销清洁能源补贴和环保法规。`,
content: `推行"钻探、钻探、钻探"政策,全力扩大化石燃料(石油、天然气、煤炭)的生产,撤销清洁能源补贴和环保法规。`
},
{
title: "关税政策",
tag: "能征关税",
content: `全面加征关税,推行“对等关税”,将关税收入作为弥补减税造成的财政收入缺口的手段之一。`,
content: `全面加征关税,推行“对等关税”,将关税收入作为弥补减税造成的财政收入缺口的手段之一。`
},
{
title: "外交政策",
tag: "能华强硬",
content: `采取单边主义和交易性做法,对国际多边体系构成挑战,要求盟友承担更多成本,对华政策更趋强硬。`,
},
],
},
content: `采取单边主义和交易性做法,对国际多边体系构成挑战,要求盟友承担更多成本,对华政策更趋强硬。`
}
]
}
];
const tagList = ref([
{
name: "互联网",
status: 2,
status: 2
},
{
name: "人工智能",
status: 4,
},
status: 4
}
]);
const wordCloudData = [
......@@ -718,7 +748,7 @@ const wordCloudData = [
{ name: "抗议医疗补助条款", value: 47 },
{ name: "深红州", value: 32 },
{ name: "温和派选区", value: 62 },
{ name: "高压游说", value: 51 },
{ name: "高压游说", value: 51 }
];
const handleClickToDetail = () => {
......@@ -729,79 +759,79 @@ const warningList = ref([
{
title: "关于对中华人民共和国合成阿片类药物供应链...",
time: "一天前",
status: "特别重大",
status: "特别重大"
},
{
title: "关于调整汽车及汽车零部件进口的公告",
time: "一天前",
status: "特别重大",
status: "特别重大"
},
{
title: "关于调整钢铁进口的公告",
time: "一天前",
status: "重大风险",
status: "重大风险"
},
{
title: "关于使用互惠关税规范进口以纠正导致大规模...",
time: "一天前",
status: "重大风险",
status: "重大风险"
},
{
title: "关于修订对中华人民共和国低价值进口商品适...",
time: "一天前",
status: "一般风险",
},
status: "一般风险"
}
]);
const timelineList = ref([
{
title: "成为公法 No: 119-21。",
time: "2025-07-04",
status: 1,
status: 1
},
{
title: "总统签署",
time: "2025-07-04",
status: 0,
status: 0
},
{
title: "提交总统",
time: "2025-07-03",
status: 0,
status: 0
},
{
title: "重新审议动议搁置案无异议通过。",
time: "2025-07-03 14:31",
status: 0,
status: 0
},
{
title: "关于‘众议院同意参议院修正案’...",
time: "2025-07-02 14:31",
status: 0,
},
status: 0
}
]);
const areaList = ref([
{
name: "跨境电商",
status: 2,
status: 2
},
{
name: "新能源产业",
status: 4,
status: 4
},
{
name: "半导体产业",
status: 1,
status: 1
},
{
name: "关税",
status: 3,
status: 3
},
{
name: "光伏产业",
status: 2,
},
status: 2
}
]);
const curDecreeList = ref([
......@@ -809,49 +839,49 @@ const curDecreeList = ref([
type: "总统政令",
status: 1,
title: "关于进一步延长TikTok执法宽限期的行政令",
time: "2025年9月16日",
time: "2025年9月16日"
},
{
type: "总统政令",
status: 1,
title: "为国家安全部署先进核反应堆技术",
time: "2025年9月16日",
time: "2025年9月16日"
},
{
type: "总统政令",
status: 1,
title: "修改对等关税税率以反映与中华人民共和国会谈情况的行政令",
time: "2025年9月15日",
time: "2025年9月15日"
},
{
type: "总统政令",
status: 1,
title: "调整互惠关税范围,并制定实施贸易和安全协议的程序",
time: "2025年9月15日",
time: "2025年9月15日"
},
{
type: "总统政令",
status: 1,
title: "持续努力加强国家网络安全,并修订第13694号行政命令和第14144号行政命令",
time: "2025年9月14日",
time: "2025年9月14日"
},
{
type: "总统备忘录",
status: 3,
title: "通过第232条款行动确保加工关键矿物及衍生产品的国家安全与经济韧性",
time: "2025年9月14日",
time: "2025年9月14日"
},
{
type: "提名与任命",
status: 2,
title: "终止对不可靠、非受控能源的市场扭曲补贴",
time: "2025年9月11日",
time: "2025年9月11日"
},
{
type: "总统政令",
status: 1,
title: "对所有国家暂停免关税待遇",
time: "2025年9月6日",
time: "2025年9月6日"
}
]);
......@@ -860,33 +890,27 @@ const releaseTime = ref("近一年发布");
const releaseTimeList = ref([
{
label: "近半年发布",
value: "近半年发布",
value: "近半年发布"
},
{
label: "近一年发布",
value: "近一年发布",
value: "近一年发布"
},
{
label: "近两年发布",
value: "近两年发布",
value: "近两年发布"
},
{
label: "近三年发布",
value: "近三年发布",
value: "近三年发布"
},
{
label: "近五年发布",
value: "近五年发布",
},
value: "近五年发布"
}
]);
const categoryList = ref([
"全部分类",
"总统政令",
"提名与任命",
"总统备忘录",
"声明",
]);
const categoryList = ref(["全部分类", "总统政令", "提名与任命", "总统备忘录", "声明"]);
const activeCate = ref("全部分类");
const activeHylyId = ref("");
......@@ -906,7 +930,7 @@ const activeHylyId = ref("");
// } catch (error) {}
// };
const handleClickCate = (cate) => {
const handleClickCate = cate => {
activeCate.value = cate;
};
......@@ -928,49 +952,41 @@ const setChart = (option, chartId) => {
const chart1Data = ref({
dataX: ["2019", "2020", "2021", "2022", "2023", "2024", "2025"],
dataY: [219, 228, 129, 159, 152, 157, 78],
dataY: [219, 228, 129, 159, 152, 157, 78]
});
const chart2Data = ref([
{
name: "集成电路",
value: 50,
value: 50
},
{
name: "人工智能",
value: 46,
value: 46
},
{
name: "通信网络",
value: 40,
value: 40
},
{
name: "量子科技",
value: 32,
value: 32
},
{
name: "能源",
value: 31,
value: 31
},
{
name: "生物科技",
value: 30,
value: 30
},
{
name: "航空航天",
value: 24,
},
value: 24
}
]);
const colorList = [
"#69B1FF",
"#FFC069",
"#87E8DE",
"#85A5FF",
"#FF7875",
"#B37FEB",
"#4096FF",
];
const colorList = ["#69B1FF", "#FFC069", "#87E8DE", "#85A5FF", "#FF7875", "#B37FEB", "#4096FF"];
// 根据法案类型获取法案列表
// const handleGetBillsByType = async () => {
......@@ -995,23 +1011,23 @@ const keyDecreeList = ref([
{
title: "关于“对等关税”的行政令",
time: "2025年4月",
content: `对所有贸易伙伴设立10%的“最低基准关税”,并对中国商品加征高达34%​​ 的额外关税,使针对中国的总关税水平大幅提升。`,
content: `对所有贸易伙伴设立10%的“最低基准关税”,并对中国商品加征高达34%​​ 的额外关税,使针对中国的总关税水平大幅提升。`
},
{
title: "《美国优先投资政策》备忘录",
time: "2025年2月",
content: `将中国列为“外国对手”,系统性收紧中美在半导体、人工智能、量子技术等前沿科技领域的双向投资,构建对华科技封锁体系。`,
content: `将中国列为“外国对手”,系统性收紧中美在半导体、人工智能、量子技术等前沿科技领域的双向投资,构建对华科技封锁体系。`
},
{
title: "针对TikTok的行政令",
time: "2025年2月",
content: `以所谓“信息安全”为由,要求字节跳动剥离TikTok在美业务,并禁止通过微信、支付宝等中国应用程序进行交易。`,
content: `以所谓“信息安全”为由,要求字节跳动剥离TikTok在美业务,并禁止通过微信、支付宝等中国应用程序进行交易。`
},
{
title: "签署《外国投资风险审查现代化法》",
time: "2025年2月",
content: `极大加强了美国外国投资委员会(CFIUS)的权限,重点关注来自中国的投资。`,
},
content: `极大加强了美国外国投资委员会(CFIUS)的权限,重点关注来自中国的投资。`
}
]);
const calendarData = ref([
......@@ -1053,7 +1069,7 @@ const calendarData = ref([
["2025-09-18", 312],
["2025-10-15", 60],
["2025-10-19", 80],
["2025-10-21", 190],
["2025-10-21", 190]
]);
onMounted(async () => {
......@@ -1100,7 +1116,7 @@ onMounted(async () => {
padding-left: 160px;
}
.home-main-header-center {
margin-top: 13px;
margin-top: 48px;
width: 960px;
height: 48px;
border-radius: 4px;
......@@ -1169,6 +1185,79 @@ onMounted(async () => {
}
}
}
.home-main-header-btn-box {
margin-top: 36px;
display: flex;
.btn {
display: flex;
width: 160px;
height: 48px;
border: 1px solid #aed6ff;
box-sizing: border-box;
border-radius: 24px;
justify-content: center;
margin: 0 16px;
background: #e7f3ff;
cursor: pointer;
&:hover {
background: #cae3fc;
}
.btn-text {
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 44px;
margin-left: 5px;
}
.btn-icon {
margin-left: 20px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 44px;
}
}
}
.home-main-header-item-box {
margin-top: 48px;
margin-bottom: 64px;
width: 1600px;
display: flex;
flex-wrap: wrap;
.item {
width: 254px;
height: 72px;
display: flex;
box-sizing: border-box;
border: 1px solid rgba(255, 255, 255, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 0.65);
align-items: center;
margin:0 6px 16px 6px;
.item-left {
width: 48px;
height: 48px;
margin-left: 24px;
margin-top: 12px;
img {
width: 100%;
height: 100%;
}
}
.item-right {
margin-left: 17px;
width: 140px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 24px;
}
}
}
}
.home-main-center {
margin-top: 34px;
......@@ -2321,4 +2410,8 @@ onMounted(async () => {
}
}
}
.divide{
margin: 0 auto;
}
</style>
\ No newline at end of file
......@@ -74,22 +74,36 @@ const setActiveTab = tabName => {
}
.tab-item {
padding: 12px 24px;
font-size: 14px;
width: 120px;
height: 40px;
text-align: center;
line-height: 30px;
// padding: 12px 24px;
font-size: 18px;
color: #606266;
cursor: pointer;
border-bottom: 2px solid transparent;
border-bottom: 3px solid transparent;
transition: all 0.3s;
box-sizing: border-box;
}
// .tab-item.active {
// color: #409eff;
// border-bottom-color: #409eff;
// background-color: rgba(64, 158, 255, 0.1);
// }
.tab-item.active {
color: #409eff;
border-bottom-color: #409eff;
background-color: rgba(64, 158, 255, 0.1);
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 30px;
border-bottom: 3px solid var(--color-main-active);
}
.tab-item:hover {
color: #409eff;
color: var(--color-main-active);
}
.action-buttons {
......@@ -99,8 +113,6 @@ const setActiveTab = tabName => {
.content-section {
padding: 24px;
/* padding-left: 2%;
padding-right: 2%; */
min-height: 400px;
}
......@@ -167,4 +179,5 @@ const setActiveTab = tabName => {
height: 18px;
}
}
</style>
<template>
<div class="home-wrapper">
<div class="home-header">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>出口管制 </span>
</div>
<div class="home-main">
<div class="home-main-header">
<!-- <div class="home-main-header-top">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span style="color: #1459bb; font-weight: bold">出口管制 </span>
</div> -->
<div class="home-main-header-center">
<!-- <el-input v-model="input" style="width: 800px; height: 100%" placeholder="搜索出口管制调查" />
<div class="search">
<div class="search-icon">
<img src="./assets/images/search-icon.png" alt="" />
</div>
<div class="search-text">搜索</div>
</div> -->
<el-input
v-model="searchKey"
style="width: 100%; height: 48px"
......@@ -26,19 +18,15 @@
<div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">142</div>
<div class="item-footer">总调查案件数</div>
<div class="item-footer">实体清单</div>
</div>
<div class="home-main-header-footer-item">
<div class="item-top">28</div>
<div class="item-footer">调查中案件数</div>
<div class="item-footer">商业管制清单</div>
</div>
<div class="home-main-header-footer-item">
<div class="item-top">326</div>
<div class="item-footer">涉及中企</div>
</div>
<div class="home-main-header-footer-item">
<div class="item-top">38%</div>
<div class="item-footer">胜诉/和解率</div>
<div class="item-footer">关键和新型技术清单</div>
</div>
</div>
</div>
......@@ -46,7 +34,7 @@
<el-col :span="16">
<custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px">
<template #header-right>
<el-button type="primary" link>
<el-button type="primary" @click="handleToDetail" link>
{{ "查看详情 >" }}
</el-button>
</template>
......@@ -567,6 +555,12 @@ import shoushiIcon from "./assets/images/shoushi.png";
import tianyiIcon from "./assets/images/tianyi.png";
import aircasIcon from "./assets/images/aircas.png";
const handleToDetail = () => {
router.push({
path: '/exportControl/analysis'
})
}
const billList = ref([]);
const curBillListIndex = ref(0);
......@@ -1408,6 +1402,19 @@ onMounted(async () => {
box-shadow: none;
}
.home-header {
height: 64px;
color: #fff;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
line-height: 64px;
background: url("@/assets/images/nav-bg.png");
box-sizing: border-box;
padding-left: 160px;
}
.box1 {
display: flex;
flex-direction: column;
......@@ -1832,7 +1839,7 @@ onMounted(async () => {
}
.home-main-header-footer {
margin-top: 38px;
width: 960px;
width: 700px;
height: 64px;
box-sizing: border-box;
padding: 0 108px;
......
<template>
<div class="page-container">
<div style="height: 30px; width: 960px; display: flex; justify-content: flex-start">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item>国家科技安全</el-breadcrumb-item>
<el-breadcrumb-item>中美博弈概览</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/' }"
><span style="font-weight: 700; color: rgba(6, 110, 217, 1)"
>美对华科技合作限制信息平台</span
></el-breadcrumb-item
>
</el-breadcrumb>
</div>
<el-input v-model="searchKey" style="max-width: 960px" placeholder="搜索政策关键词" class="input-with-select">
<template #append>
<el-button :icon="Search" size="large" type="primary">搜索</el-button>
</template>
</el-input>
<div class="page-data">
<div class="page-data-item" v-for="item in pageData" :key="item.desc">
<div class="page-data-item-num">
{{ item.num }}
</div>
<div class="page-data-item-desc">
{{ item.desc }}
</div>
</div>
</div>
<!-- 内容 -->
<div class="page-content">
<el-row :gutter="20">
<el-col :span="16">
<custom-container title="本次制裁共新增83个实体,其中53个中国大陆实体、1个中国台湾实体。" height="866px">
<template #header-left>
<div class="custom-container-header-left">
<img class="custom-container-icon" src="@/assets/images/icon-law.png" alt="" />
<span class="custom-container-title">最新限制动态</span>
</div>
</template>
<!-- 顶部右侧自定义内容 -->
<template #header-right>
<div style="display: flex; gap: 12px">
<el-button type="primary" link>查看详情 ></el-button>
</div>
</template>
<!-- 中间内容自定义 -->
<template #default>
<div class="content-card" v-for="item in limitData" :key="item.title">
<div class="content-card-date">{{ `${item.date} · ${item.importance}` }}</div>
<div class="content-card-title">
<div class="content-card-title-text">{{ item.title }}</div>
<!-- <div class="content-card-title-tag" v-for="tag in item.tag" :key="tag">{{ tag }}</div> -->
<el-tag :type="tagType[Math.floor(Math.random() * 5)]" v-for="tag in item.tag" :key="tag">{{
tag
}}</el-tag>
</div>
<div class="content-card-desc">{{ item.desc }}</div>
</div>
</template>
<!-- 底部自定义内容 -->
<!-- <template #footer>
<el-button>取消</el-button>
<el-button type="primary">保存更改</el-button>
</template> -->
</custom-container>
</el-col>
<el-col :span="8">
<custom-container title="风险信号" height="450px">
<template #header-left>
<div class="custom-container-header-left">
<img class="custom-container-icon" src="@/assets/images/icon-warning.png" alt="" />
<span class="custom-container-title">风险信号</span>
<span class="custom-container-count">5</span>
</div>
</template>
<!-- 顶部右侧自定义内容 -->
<template #header-right>
<div style="display: flex; gap: 12px">
<el-button type="primary" link>更多 ></el-button>
</div>
</template>
<!-- 中间内容自定义 -->
<template #default>
<div class="content-list-card" v-for="item in riskData" :key="item.title">
<el-tag :type="item.danger" size="small">{{ item.importance }}</el-tag>
<div class="content-list">
<div class="content-list-title">{{ item.title }}</div>
<div class="content-list-time">{{ item.date }}</div>
</div>
</div>
<div class="content-list-footer">
<el-button type="primary" size="default" style="width: 100%">
<img class="icon-mark" src="@/assets/images/icon-mark.png" alt="" />
风险处理
</el-button>
</div>
</template>
</custom-container>
<custom-container title="学术交流限制" height="400px">
<template #header-left>
<div class="custom-container-header-left">
<img class="custom-container-icon" src="@/assets/images/icon-hot.png" alt="" />
<span class="custom-container-title">学术交流限制</span>
</div>
</template>
<!-- 中间内容自定义 -->
<template #default>
<div class="content-list-card" v-for="item in academicData" :key="item.title">
<!-- <el-tag :type="item.danger" size="small">{{ item.importance }}</el-tag> -->
<div class="content-list-row">
<div class="content-card-title-text">{{ item.title }}</div>
<div class="content-card-desc">{{ item.desc }}</div>
</div>
</div>
</template>
</custom-container>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<custom-container title="政策禁令限制">
<template #header-left>
<div class="custom-container-header-left1">
<div class="icon"></div>
<div class="title">学术交流限制</div>
</div>
</template>
<template #default>
<div
class="content-list-item content-card-title-text-2"
v-for="item in policyBanData"
:key="item.title"
>
<!-- <el-tag :type="item.danger" size="small">{{ item.importance }}</el-tag> -->
<div class="content-card-title-text">{{ item.title }}</div>
<div class="content-card-desc">{{ item.desc }}</div>
<div class="content-card-tag-box">
<div class="content-card-tag-box-item">
<el-tag
:type="tagType[Math.floor(Math.random() * 5)]"
v-for="tag in item.tag"
:key="tag"
>{{ tag }}</el-tag
>
</div>
<el-button class="content-card-tag-btn" type="primary" link>查看全文 ></el-button>
</div>
</div>
<div class="content-card-footer">
<el-button type="primary" link>
查看详情 <img class="icon-mark" src="@/assets/images/icon-double-down.png" alt="" />
</el-button>
</div>
</template>
</custom-container>
</el-col>
<el-col :span="12">
<custom-container title="近期时间线">
<template #header-left>
<div class="custom-container-header-left1">
<div class="icon"></div>
<div class="title">近期时间线</div>
</div>
</template>
<template #default>
<div style="text-align: center; width: 100%; margin-bottom: 20px">
<el-space>
<el-button plain type="primary">全部</el-button>
<el-button>半导体</el-button>
<el-button>人工智能</el-button>
<el-button>出口管制</el-button>
<el-button>学术交流</el-button>
<el-button>投资审查</el-button>
</el-space>
</div>
<div class="time-line" v-for="item in recentTimeline" :key="item.title">
<img class="time-line-dot" src="@/assets/images/dot.png" alt="" />
<div class="time-line-title">
<span class="time-line-title-text">{{ item.date }}</span>
<div class="time-line-desc">
<div class="time-line-desc-title">{{ item.title }}</div>
<div class="content-card-tag-box-item">
<el-tag
:type="tagType[Math.floor(Math.random() * 5)]"
v-for="tag in item.tag"
:key="tag"
>{{ tag }}</el-tag
>
</div>
</div>
</div>
</div>
<div class="content-card-footer">
<el-button type="primary" link>
查看详情 <img class="icon-mark" src="@/assets/images/icon-double-down.png" alt="" />
</el-button>
</div>
</template>
</custom-container>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<custom-container title="科研项目合作情况">
<template #header-left>
<div class="custom-container-header-left1">
<div class="icon"></div>
<div class="title">科研项目合作情况</div>
</div>
</template>
<template #default>
<div
class="content-list-item content-card-title-text-2"
v-for="item in researchData"
:key="item.title"
>
<!-- <el-tag :type="item.danger" size="small">{{ item.importance }}</el-tag> -->
<div class="content-card-title-text">{{ item.title }}</div>
<div class="content-card-desc">{{ item.desc }}</div>
</div>
<div class="content-card-footer">
<el-button type="primary" link>
查看更多 <img class="icon-mark" src="@/assets/images/icon-double-down.png" alt="" />
</el-button>
</div>
</template>
</custom-container>
</el-col>
<el-col :span="12">
<custom-container title="人才流动限制情况">
<template #header-left>
<div class="custom-container-header-left1">
<div class="icon"></div>
<div class="title">人才流动限制情况</div>
</div>
</template>
<template #default>
<div class="content-list-item content-card-title-text-2" v-for="item in talentData" :key="item.title">
<div class="content-card-title-text">{{ item.title }}</div>
<div class="content-card-desc">{{ item.desc }}</div>
</div>
<div class="content-card-footer">
<el-button type="primary" link>
查看更多 <img class="icon-mark" src="@/assets/images/icon-double-down.png" alt="" />
</el-button>
</div>
</template>
</custom-container>
</el-col>
</el-row>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { Search } from "@element-plus/icons-vue";
import { ArrowRight } from "@element-plus/icons-vue";
import CustomContainer from "@/components/Container/index.vue";
const searchKey = ref("");
const pageData = ref([
{
num: 42,
desc: "生效政策禁令"
},
{
num: 128,
desc: "受限制实体"
},
{
num: 16,
desc: "受限制领域"
},
{
num: 7,
desc: "本月更新"
}
]);
// tag类型
const tagType = ["primary", "success", "info", "warning", "danger"];
// 限制动态数据
const limitData = ref([
{
date: "2025年9月2日",
importance: "紧急",
tag: ["半导体", "出口管制"],
title: "美国撤销多家芯片企业在华VEU授权",
desc: `美国最终用户审查委员会(ERC)宣布撤销英特尔、SK海力士和三星在中国工厂的"经验证最终用户"(VEU)授权,影响其在华芯片生产。新规定计划于10月2日《联邦公报》出版120天后正式生效:cite[3]:cite[4]。`
},
{
date: "2025年9月2日",
importance: "紧急",
tag: [" 半导体", "晶圆制造"],
title: "台积电南京厂VEU资格被撤销",
desc: `台积电已收到美国政府通知,其南京工厂的"经验证最终用户"(VEU)资格将于2025年12月31日被撤销。此后,每一批运往南京工厂的受管制设备均需经过美国商务部逐案审批。`
},
{
date: "2025年9月2日",
importance: "紧急",
tag: [" 半导体", "晶圆制造"],
title: "台积电南京厂VEU资格被撤销",
desc: `台积电已收到美国政府通知,其南京工厂的"经验证最终用户"(VEU)资格将于2025年12月31日被撤销。此后,每一批运往南京工厂的受管制设备均需经过美国商务部逐案审批。`
},
{
date: "2025年9月2日",
importance: "紧急",
tag: [" 报道题", "晶圆制造"],
title: "台积电南京厂VEU资格被撤销",
desc: `台积电已收到美国政府通知,其南京工厂的"经验证最终用户"(VEU)资格将于2025年12月31日被撤销。此后,每一批运往南京工厂的受管制设备均需经过美国商务部逐案审批。`
},
{
date: "2025年9月2日",
importance: "紧急",
tag: [" 报道题", "晶圆制造"],
title: "台积电南京厂VEU资格被撤销",
desc: `台积电已收到美国政府通知,其南京工厂的"经验证最终用户"(VEU)资格将于2025年12月31日被撤销。此后,每一批运往南京工厂的受管制设备均需经过美国商务部逐案审批。`
},
{
date: "2025年9月2日",
importance: "紧急",
tag: [" 报道题", "晶圆制造"],
title: "台积电南京厂VEU资格被撤销",
desc: `台积电已收到美国政府通知,其南京工厂的"经验证最终用户"(VEU)资格将于2025年12月31日被撤销。此后,每一批运往南京工厂的受管制设备均需经过美国商务部逐案审批。`
}
]);
// 风险
const riskType = ref(["特别重大", "重大风险", "一般风险"]);
const riskData = ref([
{
date: "一天前",
importance: "特别重大",
danger: "danger",
title: "美国大而美法案落地,总统签署通过"
},
{
date: "两天前",
importance: "重大风险",
danger: "warning",
title: "美大而美法案7月1日以51:50的票数通过..."
},
{
date: "三天前",
importance: "特别重大",
danger: "danger",
title: "首次提出“限制外国敏感实体获取补贴”"
},
{
date: "四天前",
importance: "一般风险",
danger: "success",
title: "将中国企业海外子公司、合资公司纳入受..."
},
{
date: "五天前",
importance: "一般风险",
danger: "success",
title: "H.R.8333《生物安全法案》将华大基因等..."
}
]);
// 学术交流限制
const academicData = ref([
{
title: "签证限制",
desc: "美国国务院已开始取消部分中国留学生的签证,针对STEM领域学生和研究人员加强审查。"
},
{
title: "合作项目终止",
desc: "密歇根大学终止了与上海交通大学的长期合作,佐治亚理工停止深圳学院运营。"
},
{
title: "数据访问限制",
desc: "美国国立卫生研究院(NIH)禁止中国、俄罗斯、伊朗等国的机构访问其受控数据。"
}
]);
// 政策禁令限制
const policyBanData = ref([
{
title: "《美国优先投资政策》总统备忘录",
desc: `2025年2月签署,限制美国资本投资中国"军民融合"战略相关产业,并审查甚至阻止中国对美关键领域的投资。备忘录扩大CFIUS的审查范围,要求将限制领域扩展到"医疗、农业、能源、原材料等战略行业"。`,
tag: ["投资审查", "国家暗安全"]
},
{
title: "《外国公司问责法》",
desc: `2025年2月签署,限制美国资本投资中国"军民融合"战略相关产业,并审查甚至阻止中国对美关键领域的投资。备忘录扩大CFIUS的审查范围,要求将限制领域扩展到"医疗、农业、能源、原材料等战略行业"。`,
tag: ["金融", "上市公司"]
}
]);
// 近期时间线
const recentTimeline = ref([
{
date: "2025-9-2",
tag: ["半导体", "出口管制"],
title: "撤销芯片企业VEU授权"
},
{
date: "2025-07-29",
tag: ["人工智能", "出口管制"],
title: "强化AI芯片出口限制"
},
{
date: "2025-05-08",
tag: ["半导体", "出口管制"],
title: "TikTok剥离期限再次延期"
}
// {
// date: "2025-04-02",
// tag: ["半导体", "出口管制"],
// title: "14117规则生效"
// }
]);
// 科研项目合作
const researchData = ref([
{
title: "合作范围缩小",
desc: "中美科技合作协定虽得以续签,但范围有所收窄,更强调透明性、互惠性和研究人员保护。"
},
{
title: "敏感领域合作遇冷",
desc: `在人工智能、量子计算等敏感技术领域,合作项目面临严格的"国家安全审查"。`
}
]);
// 人才流动限制
const talentData = ref([
{
title: "华人科学家离美趋势",
desc: "2010年至2021年间,有近1.25万名华裔科学家离开美国回到中国。"
},
{
title: "审查措施加强",
desc: `美国政府以"国家安全"为由,调查并限制华人科学家参与美国科研项目。`
}
]);
</script>
<style lang="scss" scoped>
.page-container {
display: flex;
flex-direction: column;
align-items: center;
/* height: 100vh; */
margin: 0px auto;
padding: 0px 120px;
padding-top: 40px;
/* background-color: rgba(234, 236, 238, 1); */
background: url("/assets/images/background.png");
}
.page-data {
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
width: 960px;
gap: 80px;
}
.page-data-item {
display: flex;
flex-direction: column;
align-items: center;
}
.page-data-item-num {
font-size: 24px;
font-weight: 600;
color: var(--color-main-active);
}
.page-data-item-desc {
font-size: 12px;
color: rgba(95, 101, 108, 1);
}
.page-content {
margin-top: 20px;
width: 100%;
/* padding: 0px 20px; */
}
.custom-container-header-left1 {
display: flex;
margin-left: -15px;
height: 24px;
.icon {
width: 8px;
height: 16px;
background: var(--color-main-active);
margin-top: 4px;
border-radius: 0 2px 2px 0;
}
.title {
margin-left: 14px;
height: 24px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
}
}
.custom-container-header-left {
display: flex;
align-items: center;
gap: 8px;
padding-left: 20px;
padding-bottom: 5px;
/* border-bottom: 1px solid rgba(234, 236, 238, 1); */
}
.custom-container-title {
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
}
.custom-container-count {
text-align: center;
width: 24px;
height: 16px;
border-radius: 100px;
font-size: 12px;
background-color: rgba(255, 77, 79, 1);
color: #fff;
}
.custom-container-icon {
height: 18px;
width: 18px;
}
.content-card {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 8px;
padding: 12px 20px;
background-color: rgba(247, 248, 249, 1);
border-radius: 8px;
margin-bottom: 14px;
}
.content-card-date {
font-size: 14px;
font-weight: 400;
color: rgba(10, 87, 166, 1);
}
.content-card-title {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
}
.content-card-title-text {
font-size: 16px;
font-weight: 700;
color: rgba(10, 18, 30, 1);
margin-right: auto;
}
.content-card-title-text-2 {
display: flex;
flex-direction: column;
gap: 11px;
padding: 10px;
margin-bottom: 10px;
border-radius: 4px;
/* box-shadow: 0 2px 8px rgba(60, 87, 126, 0.2); */
box-shadow: 0 0 15px 0 rgba(60, 87, 126, 0.2);
}
.content-card-tag-box {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
}
.content-card-tag-box-item {
display: flex;
align-items: center;
gap: 6px;
}
.content-card-tag-btn {
margin-left: autp;
}
.content-card-title-tag {
font-size: 12px;
color: rgba(95, 101, 108, 1);
}
.content-card-desc {
font-size: 12px;
color: rgba(95, 101, 108, 1);
}
.content-list-card {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
}
.content-list {
height: 40px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
}
.content-list-row {
height: 60px;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
}
.content-list-title {
width: 80%;
font-size: 16px;
font-weight: 400;
color: rgba(59, 65, 75, 1);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.content-list-time {
font-size: 14px;
color: rgba(132, 136, 142, 1);
}
.content-list-footer {
width: 100%;
margin-top: 115px;
}
.icon-mark {
height: 12px;
width: 12px;
margin-right: 5px;
margin-left: 8px;
}
.content-card-footer {
display: flex;
width: 100%;
justify-content: center;
margin-top: 30px;
}
.time-line {
display: flex;
gap: 15px;
align-items: flex-start;
padding-left: 10px;
margin-bottom: 20px;
}
.time-line-title {
display: flex;
align-items: flex-start;
flex-direction: column;
gap: 8px;
width: 100%;
}
.time-line-dot {
width: 10px;
height: 10px;
margin-top: 5px;
}
.time-line-title-text {
font-size: 14px;
font-weight: 700;
color: rgba(95, 101, 108, 1);
color: var(--base-color);
}
.time-line-desc {
width: 100%;
display: flex;
justify-content: space-between;
}
.time-line-desc-title {
font-size: 16px;
font-weight: 400;
color: rgba(95, 101, 108, 1);
margin-bottom: 5px;
}
.time-line-desc-text {
font-size: 14px;
font-weight: 400;
color: rgba(95, 101, 108, 1);
}
.time-line-dot {
width: 8px;
height: 8px;
background-color: rgba(10, 87, 166, 1);
border-radius: 50%;
}
</style>
<template>
<!-- 面包屑导航 -->
<div class="breadcrumb">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>科技智库 </span>
</div>
<div class="tech-think-tank">
<!-- 搜索区域 -->
<div class="search-section">
<el-input v-model="searchText" placeholder="搜索智库、报告或政策建议" class="search-input" size="large">
<template #append>
<el-button type="primary" style="background: #1677ff; color: #fff" :icon="Search">搜索</el-button>
</template>
</el-input>
</div>
<!-- 统计数据 -->
<div class="stats-section">
<div class="stat-item">
<div class="stat-number">128</div>
<div class="stat-label">追踪智库数量</div>
</div>
<div class="stat-item">
<div class="stat-number">42</div>
<div class="stat-label">本月新增报告</div>
</div>
<div class="stat-item">
<div class="stat-number">18</div>
<div class="stat-label">重点政策建议</div>
</div>
<div class="stat-item">
<div class="stat-number">12</div>
<div class="stat-label">热点科技领域</div>
</div>
</div>
<!-- 主要内容区域 -->
<div class="main-content">
<!-- 左侧数据分布 -->
<div class="left-section">
<div class="section-header">
<el-icon class="location-icon"><Location /></el-icon>
<span class="section-title">数据分布</span>
<div class="time-filters">
<span :class="{ active: activeTime === '今天' }" @click="activeTime = '今天'">今天</span>
<span :class="{ active: activeTime === '本周' }" @click="activeTime = '本周'">本周</span>
<span :class="{ active: activeTime === '本月' }" @click="activeTime = '本月'">本月</span>
<span :class="{ active: activeTime === '今年' }" @click="activeTime = '今年'">今年</span>
</div>
</div>
<!-- 地图区域 -->
<div class="map-container">
<div ref="worldMapRef" class="world-map" style="width: 100%; height: 400px"></div>
</div>
</div>
<!-- 右侧网络信号 -->
<div class="right-section">
<div class="signal-header">
<el-icon class="signal-icon"><Warning /></el-icon>
<span class="signal-title">风险信号</span>
<el-badge :value="5" class="signal-badge" />
<span class="more-link">更多 ></span>
</div>
<div class="signal-list">
<div v-for="signal in signals" :key="signal.id" class="signal-item">
<div class="signal-content">
<div class="signal-left">
<el-tag :type="signal.type" size="small" class="signal-tag">{{ signal.tag }}</el-tag>
<div class="signal-text">{{ signal.content }}</div>
</div>
<div class="signal-time">{{ signal.time }}</div>
</div>
</div>
</div>
<el-button type="primary" class="process-btn" block>
<el-icon><Setting /></el-icon>
风险处理
</el-button>
</div>
</div>
<!-- 智库展示区域 -->
<div class="think-tanks-section">
<div v-for="tank in thinkTanks" :key="tank.id" class="think-tank-card" @click="handleClick(tank)">
<div class="tank-header">
<div class="tank-logo">
<el-image :src="$withFallbackImage(tank.logo, tank.id)" :alt="tank.name" />
</div>
<div class="tank-country">{{ tank.country }}</div>
</div>
<div class="tank-name">{{ tank.name }}</div>
<div class="tank-description" :title="tank.describe">{{ tank.describe }}</div>
<div class="tank-tags">
<el-tag v-for="tag in tank.tags" :key="tag" type="primary" size="small">
{{ tag }}
</el-tag>
</div>
</div>
<div class="view-all">
<span class="view-all-link">查看全部智库 ></span>
</div>
</div>
<ReportList />
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from "vue";
import { Search, Location, Warning, Setting } from "@element-plus/icons-vue";
import * as echarts from "echarts";
import ReportList from "@/components/ReportList.vue";
import { useRouter } from "vue-router";
import rand from "@/assets/images/rand.png";
import brookings from "@/assets/images/brookings.png";
import mit from "@/assets/images/mit.png";
import itif from "@/assets/images/itif.png";
import mckinsley from "@/assets/images/mckinsey.png";
import { getThinkTankList } from "@/api";
const router = useRouter();
const searchText = ref("");
const activeTime = ref("本月");
const worldMapRef = ref(null);
// 世界地图数据 - 各国智库数量统计
const mapData = ref([
{ name: "United States", value: 6, itemStyle: { color: "#ff4757" } },
{ name: "China", value: 3, itemStyle: { color: "#ffa726" } },
{ name: "United Kingdom", value: 2, itemStyle: { color: "#42a5f5" } },
{ name: "Germany", value: 1, itemStyle: { color: "#66bb6a" } },
{ name: "Japan", value: 1, itemStyle: { color: "#66bb6a" } },
{ name: "France", value: 1, itemStyle: { color: "#66bb6a" } }
]);
// 初始化世界地图
const initWorldMap = async () => {
if (!worldMapRef.value) return;
const chart = echarts.init(worldMapRef.value);
// 使用可靠的世界地图数据源
try {
const response = await fetch("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson");
const geoJson = await response.json();
// 注册世界地图
echarts.registerMap("world", geoJson);
const option = {
title: {
text: "全球智库分布",
left: "center",
top: 20,
textStyle: {
color: "#333",
fontSize: 18,
fontWeight: "bold"
}
},
tooltip: {
trigger: "item",
formatter: function (params) {
if (params.seriesType === "map") {
const data = mapData.value.find(item => item.name === params.name);
if (data) {
return `${params.name}<br/>智库数量: ${data.value}个`;
}
return `${params.name}<br/>暂无数据`;
}
return params.name;
}
},
visualMap: {
min: 0,
max: 6,
left: "left",
top: "bottom",
text: ["高", "低"],
calculable: true,
inRange: {
color: ["#e3f2fd", "#1976d2"]
},
textStyle: {
color: "#333"
}
},
series: [
{
name: "智库数量",
type: "map",
map: "world",
roam: true,
emphasis: {
label: {
show: true
}
},
data: [
{ name: "United States of America", value: 6, itemStyle: { color: "#ff4757" } },
{ name: "China", value: 3, itemStyle: { color: "#ffa726" } },
{ name: "United Kingdom", value: 2, itemStyle: { color: "#42a5f5" } },
{ name: "Germany", value: 1, itemStyle: { color: "#66bb6a" } },
{ name: "Japan", value: 1, itemStyle: { color: "#66bb6a" } },
{ name: "France", value: 1, itemStyle: { color: "#66bb6a" } }
],
itemStyle: {
borderColor: "#fff",
borderWidth: 1
}
}
]
};
chart.setOption(option);
} catch (error) {
console.log("使用备用地图方案");
// 如果外部数据源失败,使用内置的简化世界地图
const option = {
title: {
text: "全球智库分布",
left: "center",
top: 20,
textStyle: {
color: "#333",
fontSize: 18,
fontWeight: "bold"
}
},
tooltip: {
trigger: "item",
formatter: function (params) {
return `${params.name}<br/>智库数量: ${params.value}个`;
}
},
geo: {
type: "map",
map: "world",
roam: true,
itemStyle: {
color: "#f0f0f0",
borderColor: "#999",
borderWidth: 0.5
},
emphasis: {
itemStyle: {
color: "#e0e0e0"
}
},
regions: [
{
name: "United States",
itemStyle: {
color: "#ff4757"
}
},
{
name: "China",
itemStyle: {
color: "#ffa726"
}
},
{
name: "United Kingdom",
itemStyle: {
color: "#42a5f5"
}
}
]
},
series: [
{
name: "智库分布",
type: "scatter",
coordinateSystem: "geo",
data: [
{ name: "美国", value: [-95, 37, 6], itemStyle: { color: "#ff4757" } },
{ name: "中国", value: [104, 35, 3], itemStyle: { color: "#ffa726" } },
{ name: "英国", value: [-3, 55, 2], itemStyle: { color: "#42a5f5" } },
{ name: "德国", value: [10, 51, 1], itemStyle: { color: "#66bb6a" } },
{ name: "日本", value: [138, 36, 1], itemStyle: { color: "#66bb6a" } },
{ name: "法国", value: [2, 46, 1], itemStyle: { color: "#66bb6a" } }
],
symbolSize: function (val) {
return Math.max(val[2] * 15, 25);
},
label: {
show: true,
formatter: function (params) {
return params.data.name + "\n" + params.data.value[2] + "个";
},
position: "top",
textStyle: {
color: "#333",
fontSize: 12,
fontWeight: "bold"
}
},
emphasis: {
scale: true,
scaleSize: 10
}
}
]
};
chart.setOption(option);
}
// 响应式处理
window.addEventListener("resize", () => {
chart.resize();
});
};
const signals = ref([
{
id: 1,
type: "danger",
tag: "特别重大",
content: "兰德科技智库发布2025中美年度科技报告",
time: "一天前"
},
{
id: 2,
type: "danger",
tag: "特别重大",
content: "信息技术与创新基金会发布《中国正在迅速成...",
time: "一天前"
},
{
id: 3,
type: "warning",
tag: "重大",
content: "战略与国际研究中心发布《DeepSeek、华为、...",
time: "一天前"
},
{
id: 4,
type: "warning",
tag: "重大",
content: "兰德科技智库发布《中国对AI的转型产业政策》",
time: "一天前"
},
{
id: 5,
type: "success",
tag: "一般",
content: "兰德科技智库发布《中美对抗、竞争和合作...",
time: "一天前"
}
]);
const thinkTanks = ref([]);
const getThinkTanks = async () => {
const { data } = await getThinkTankList();
thinkTanks.value = data;
};
const handleClick = tank => {
router.push({ name: "ThinkTankDetail", params: { id: tank.id } });
};
// 组件挂载后初始化地图
onMounted(() => {
getThinkTanks();
nextTick(() => {
initWorldMap();
});
});
</script>
<style scoped lang="scss">
.breadcrumb {
width: 100%;
height: 64px;
background: url("@/assets/images/nav-bg.png") no-repeat;
color: #fff;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
line-height: 64px;
box-sizing: border-box;
padding-left: 160px;
}
.tech-think-tank {
max-width: 1400px;
margin: 0 auto;
margin-top: 31px;
padding: 20px;
background: url("@/assets/images/background.png") no-repeat;
background-position: center -100px;
background-size: 100% 100%;
min-height: 100vh;
}
.search-section {
margin-bottom: 30px;
display: flex;
justify-content: center;
}
.search-input {
max-width: 800px;
}
.stats-section {
display: flex;
justify-content: center;
gap: 80px;
margin-bottom: 40px;
}
.stat-item {
text-align: center;
}
.stat-number {
font-size: 48px;
font-weight: bold;
color: #1459bb;
line-height: 1;
margin-bottom: 8px;
}
.stat-label {
font-size: 14px;
color: #666;
}
.main-content {
display: flex;
gap: 10px;
margin-bottom: 40px;
height: 490px;
}
.left-section {
flex: 2;
background: white;
border-radius: 2px;
padding: 20px;
}
.section-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.location-icon {
color: #409eff;
margin-right: 8px;
}
.section-title {
font-weight: 500;
margin-right: auto;
}
.time-filters {
display: flex;
gap: 15px;
}
.time-filters span {
cursor: pointer;
padding: 4px 8px;
border-radius: 4px;
font-size: 14px;
color: #666;
}
.time-filters span.active {
background-color: #409eff;
color: white;
}
.map-container {
// height: 300px;
background: #f0f2f5;
border-radius: 8px;
position: relative;
overflow: hidden;
}
.map-placeholder {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #e3f2fd 0%, #f3e5f5 100%);
position: relative;
}
.data-point {
position: absolute;
}
.point-circle {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 12px;
font-weight: bold;
}
.point-circle.yellow {
background-color: #f39c12;
}
.point-circle.red {
background-color: #e74c3c;
}
.point-circle.blue {
background-color: #3498db;
}
.right-section {
flex: 1;
background: white;
border-radius: 2px;
padding: 20px;
}
.signal-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.signal-icon {
color: #f56c6c;
margin-right: 2px;
}
.signal-title {
font-weight: 500;
margin-right: 8px;
}
.signal-badge {
margin-right: auto;
}
.more-link {
color: #409eff;
font-size: 14px;
cursor: pointer;
}
.signal-list {
margin-bottom: 40px;
height: 330px;
overflow-y: auto;
}
.signal-item {
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #f0f0f0;
}
.signal-item:last-child {
border-bottom: none;
}
.signal-content {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 12px;
}
.signal-left {
flex: 1;
display: flex;
gap: 6px;
}
.signal-tag {
align-self: flex-start;
}
.signal-text {
font-size: 14px;
color: #333;
line-height: 1.4;
word-break: break-word;
}
.signal-time {
font-size: 12px;
color: #999;
white-space: nowrap;
flex-shrink: 0;
}
.process-btn {
width: 100%;
}
.think-tanks-section {
display: flex;
flex-wrap: wrap;
gap: 20px;
justify-content: flex-start;
}
.think-tank-card {
background: white;
border-radius: 8px;
padding: 12px;
border: 1px solid #e4e7ed;
width: 220px;
// height: 180px;
flex-shrink: 0;
display: flex;
flex-direction: column;
cursor: pointer;
}
.tank-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15px;
}
.tank-logo {
width: 60px;
height: 60px;
background: #f0f0f0;
border-radius: 8px;
margin-right: 15px;
display: flex;
align-items: center;
justify-content: center;
.el-image {
width: 100%;
height: 100%;
border-radius: 8px;
object-fit: contain;
}
}
.tank-logo img {
width: 100%;
height: 100%;
object-fit: contain;
}
.tank-country {
background: #f0f0f0;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
color: #666;
}
.tank-name {
font-size: 16px;
font-weight: 500;
margin-bottom: 10px;
color: #333;
}
.tank-description {
font-size: 12px;
color: #666;
flex: 1;
overflow: hidden;
display: -webkit-box;
text-overflow: ellipsis;
margin-bottom: 5px;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
.tank-tags {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: auto;
}
.view-all {
text-align: center;
width: 180px;
padding: 0 5px;
background: #fff;
display: flex;
align-items: center;
cursor: pointer;
}
.view-all-link {
color: #1459bb;
font-size: 16px;
font-weight: 600;
text-align: center;
margin: 0 auto;
}
.view-all-link:hover {
text-decoration: underline;
}
</style>
\ No newline at end of file
......@@ -23,7 +23,10 @@ export default defineConfig({
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/var.scss";`
api: 'modern',
additionalData: `
@use "@/styles/var.scss" as *;
`
}
}
},
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论