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

update

上级 ce8f4051
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.0", "@vitejs/plugin-vue": "^5.0.0",
"sass": "^1.92.1", "sass": "^1.93.3",
"unplugin-auto-import": "^0.17.0", "unplugin-auto-import": "^0.17.0",
"unplugin-vue-components": "^0.26.0", "unplugin-vue-components": "^0.26.0",
"vite": "^5.0.0" "vite": "^5.0.0"
...@@ -2554,9 +2554,9 @@ ...@@ -2554,9 +2554,9 @@
} }
}, },
"node_modules/sass": { "node_modules/sass": {
"version": "1.92.1", "version": "1.93.3",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.92.1.tgz", "resolved": "https://registry.npmmirror.com/sass/-/sass-1.93.3.tgz",
"integrity": "sha512-ffmsdbwqb3XeyR8jJR6KelIXARM9bFQe8A6Q3W4Klmwy5Ckd5gz7jgUNHo4UOqutU5Sk1DtKLbpDP0nLCg1xqQ==", "integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.0.0", "@vitejs/plugin-vue": "^5.0.0",
"sass": "^1.92.1", "sass": "^1.93.3",
"unplugin-auto-import": "^0.17.0", "unplugin-auto-import": "^0.17.0",
"unplugin-vue-components": "^0.26.0", "unplugin-vue-components": "^0.26.0",
"vite": "^5.0.0" "vite": "^5.0.0"
......
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
</div> </div>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item command="/">智库首页</el-dropdown-item>
<el-dropdown-item command="/billHome">法案首页</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="/exportControl">出口管制</el-dropdown-item>
<el-dropdown-item command="/decree">政令</el-dropdown-item>
<el-dropdown-item command="/marketAccessRestrictions">市场准入限制</el-dropdown-item> <el-dropdown-item command="/marketAccessRestrictions">市场准入限制</el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</el-header> </el-header>
<!-- 面包屑导航 --> <!-- 面包屑导航 -->
<Breadcrumb /> <!-- <Breadcrumb /> -->
<el-main class="main-container"> <el-main class="main-container">
<router-view /> <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 @@ ...@@ -34,7 +34,7 @@
</template> </template>
<script setup> <script setup>
import { ref, defineProps } from 'vue' import { ref } from 'vue'
import { Link } from '@element-plus/icons-vue' import { Link } from '@element-plus/icons-vue'
const props = defineProps({ const props = defineProps({
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, defineProps, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { Search } from '@element-plus/icons-vue'; import { Search } from '@element-plus/icons-vue';
import PolicyList from './PolicyList.vue'; import PolicyList from './PolicyList.vue';
import CardTitle from './CardTitle.vue'; import CardTitle from './CardTitle.vue';
......
import { createRouter, createWebHistory } from "vue-router"; 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 BillHome from '@/views/bill/billHome/index.vue'
import BillLayoutContainer from '@/views/bill/billLayout/index.vue' import BillLayoutContainer from '@/views/bill/billLayout/index.vue'
import BillLayout from '@/views/bill/index.vue' import BillLayout from '@/views/bill/index.vue'
...@@ -42,39 +43,37 @@ import MarketSingleCaseOverview from "@/views/marketAccessRestrictions/singleCas ...@@ -42,39 +43,37 @@ import MarketSingleCaseOverview from "@/views/marketAccessRestrictions/singleCas
import MarketSingleCaseDeepdig from "@/views/marketAccessRestrictions/singleCaseLayout/deepdig/index.vue"; import MarketSingleCaseDeepdig from "@/views/marketAccessRestrictions/singleCaseLayout/deepdig/index.vue";
const routes = [ const routes = [
// 智库系统的主要路由
{ {
path: "/", path: '/',
name: "Home", redirect: '/billHome'
component: Home, },
meta: {
title: "首页" // 智库系统的主要路由
} {
}, path: "/thinkTank",
{ name: "thinkTank",
path: "/about", component: thinkTank,
name: "About", meta: {
component: About, title: "首页"
meta: { }
title: "关于我们" },
} {
}, path: "/think-tank/:id",
{ name: "ThinkTankDetail",
path: "/think-tank/:id", component: ThinkTankDetail,
name: "ThinkTankDetail", meta: {
component: ThinkTankDetail, title: "智库详情"
meta: { }
title: "智库详情" },
} {
}, path: "/report/:id",
{ name: "ReportDetail",
path: "/report/:id", component: ReportDetail,
name: "ReportDetail", meta: {
component: ReportDetail, title: "报告详情"
meta: { }
title: "报告详情" },
}
},
// 法案系统路由 // 法案系统路由
{ {
...@@ -189,15 +188,15 @@ const routes = [ ...@@ -189,15 +188,15 @@ const routes = [
] ]
}, },
// 出口管制首页 // 出口管制首页
{ {
path: "/exportControl", path: "/exportControl",
name: "ExportControl", name: "ExportControl",
component: ExportControl, component: ExportControl,
meta: { meta: {
title: "出口管制" title: "出口管制"
} }
}, },
// 政令首页 // 政令首页
{ {
...@@ -329,68 +328,65 @@ const routes = [ ...@@ -329,68 +328,65 @@ const routes = [
] ]
}, },
// 转移过来的页面 // 出口管制转移过来的页面
{ {
path: "/analysis", path: "/exportControl/analysis",
name: "analysis", name: "analysis",
component: () => import("@/views/analysis/index.vue"), component: () => import("@/views/exportControl/analysis/index.vue"),
meta: { meta: {
title: "分析页" title: "分析页"
} }
}, },
{ {
path: "/infoplatform", path: "/exportControl/infoplatform",
name: "infoplatform", name: "infoplatform",
component: () => import("@/views/infoPlatform/index.vue"), component: () => import("@/views/exportControl/infoPlatform/index.vue"),
meta: { meta: {
title: "信息平台" title: "信息平台"
} }
}, },
{ {
path: "/rulelimit", path: "/exportControl/rulelimit",
name: "rulelimit", name: "rulelimit",
component: () => import("@/views/ruleLimit/index.vue"), component: () => import("@/views/exportControl/ruleLimit/index.vue"),
meta: { meta: {
title: "规则限制" title: "规则限制"
} }
}, },
{ {
path: "/ruledetail", path: "/exportControl/ruledetail",
name: "ruledetail", name: "ruledetail",
component: () => import("@/views/ruleDetail/index.vue"), component: () => import("@/views/exportControl/ruleDetail/index.vue"),
meta: { meta: {
title: "规则详情" title: "规则详情"
} }
}, },
{ {
path: "/researchfunding", path: "/exportControl/researchfunding",
name: "researchfunding", name: "researchfunding",
component: () => import("@/views/researchFunding/index.vue"), component: () => import("@/views/exportControl/researchFunding/index.vue"),
meta: { meta: {
title: "科研资助" title: "科研资助"
} }
}, }
{
path: "/decree", // 门户路由放在这块
name: "decree",
component: () => import("@/views/decree/index.vue"),
meta: {
title: "政令信息"
}
}
]; ];
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes routes
}); });
// 路由守卫 - 设置页面标题 // 路由守卫 - 设置页面标题
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
if (to.meta.title) { if (to.meta.title) {
// document.title = `${to.meta.title} - Think Tank` // document.title = `${to.meta.title} - Think Tank`
} }
next(); next();
}); });
export default router; export default router;
<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
<template> <template>
<div class="home-wrapper"> <div class="home-wrapper">
<div class="home-header"> <div class="home-header">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>> <span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>科技法案 </span> <span>科技法案 </span>
</div> </div>
<div class="home-main"> <div class="home-main">
<div class="home-main-header"> <div class="home-main-header">
<div class="home-main-header-center"> <div class="home-main-header-center">
<el-input <el-input v-model="input" style="width: 800px; height: 100%" placeholder="搜索科技法案" />
v-model="input" <div class="search">
style="width: 800px; height: 100%" <div class="search-icon">
placeholder="搜索科技法案" <img src="./assets/images/search-icon.png" alt="" />
/> </div>
<div class="search"> <div class="search-text">搜索</div>
<div class="search-icon"> </div>
<img src="./assets/images/search-icon.png" alt="" /> </div>
</div> <div class="home-main-header-footer">
<div class="search-text">搜索</div> <div class="home-main-header-footer-item">
</div> <div class="item-top">3.8T</div>
</div> <div class="item-footer">数据量</div>
<div class="home-main-header-footer"> </div>
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">3.8T</div> <div class="item-top">14433</div>
<div class="item-footer">数据量</div> <div class="item-footer">科技动向</div>
</div> </div>
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">14433</div> <div class="item-top">1986</div>
<div class="item-footer">科技动向</div> <div class="item-footer">提出法案</div>
</div> </div>
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">1986</div> <div class="item-top">341</div>
<div class="item-footer">提出法案</div> <div class="item-footer">通过法案</div>
</div> </div>
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">341</div> <div class="item-top">285</div>
<div class="item-footer">通过法案</div> <div class="item-footer">分析报告</div>
</div> </div>
<div class="home-main-header-footer-item"> </div>
<div class="item-top">285</div> <div class="home-main-header-btn-box">
<div class="item-footer">分析报告</div> <div class="btn">
</div> <div class="btn-text">{{ "最新动态" }}</div>
</div> <div class="btn-icon">{{ ">" }}</div>
</div> </div>
<div class="home-main-center"> <div class="btn">
<div class="center-top"> <div class="btn-text">{{ "资讯要闻" }}</div>
<div class="box1"> <div class="btn-icon">{{ ">" }}</div>
<div class="box1-left" @click="handleSwithCurBill('left')"> </div>
<div class="icon"> <div class="btn">
<img src="./assets/images/box1-left.png" alt="" /> <div class="btn-text">{{ "统计概览" }}</div>
</div> <div class="btn-icon">{{ ">" }}</div>
</div> </div>
<div class="box1-right" @click="handleSwithCurBill('right')"> <div class="btn">
<div class="icon"> <div class="btn-text">{{ "资源库" }}</div>
<img src="./assets/images/box1-right.png" alt="" /> <div class="btn-icon">{{ ">" }}</div>
</div> </div>
</div> </div>
<div class="box1-header"> </div>
<div class="box1-header-left"> <DivideHeader class="divide1" :titleText="'最新动态'"></DivideHeader>
<div class="icon"> <div class="home-main-center">
<img src="./assets/images/box1-header-icon.png" alt="" /> <div class="center-top">
</div> <div class="box1">
<div class="title">{{ "热门法案" }}</div> <div class="box1-left" @click="handleSwithCurBill('left')">
</div> <div class="icon">
<div class="box1-header-right" @click="handleClickToDetail()"> <img src="./assets/images/box1-left.png" alt="" />
{{ "查看详情 >" }} </div>
</div> </div>
</div> <div class="box1-right" @click="handleSwithCurBill('right')">
<div class="box1-main"> <div class="icon">
<div class="box1-main-left"> <img src="./assets/images/box1-right.png" alt="" />
<div class="box1-main-left-title"> </div>
<!-- "H.R.1(119th)-大而美法案" --> </div>
{{ curBill.billName }} <div class="box1-header">
</div> <div class="box1-header-left">
<div class="box1-main-left-info"> <div class="icon">
<div <img src="./assets/images/box1-header-icon.png" alt="" />
class="info-box" </div>
:class="{ <div class="title">{{ "热门法案" }}</div>
info1: item.status === 1, </div>
info2: item.status === 2, <div class="box1-header-right" @click="handleClickToDetail()">
info3: item.status === 3, {{ "查看详情 >" }}
info4: item.status === 4, </div>
}" </div>
v-for="(item, index) in curBill.hylyList" <div class="box1-main">
:key="index" <div class="box1-main-left">
> <div class="box1-main-left-title">
{{ item }} <!-- "H.R.1(119th)-大而美法案" -->
</div> {{ curBill.billName }}
</div> </div>
<div class="box1-main-left-info1"> <div class="box1-main-left-info">
<div class="info1-box"> <div
<div class="icon"></div> class="info-box"
<div class="info1-box-left">{{ "提案人:" }}</div> :class="{
<div class="info1-box-right">{{ curBill.tarName }}</div> info1: item.status === 1,
</div> info2: item.status === 2,
<div class="info1-box"> info3: item.status === 3,
<div class="icon"></div> info4: item.status === 4
<div class="info1-box-left">{{ "提出时间:" }}</div> }"
<div class="info1-box-right"> v-for="(item, index) in curBill.hylyList"
{{ curBill.introductionDate }} :key="index"
</div> >
</div> {{ item }}
</div> </div>
<div class="box1-main-left-info2"> </div>
<div <div class="box1-main-left-info1">
class="time-line" <div class="info1-box">
:style="{ height: 38 * 3 + 'px' }" <div class="icon"></div>
></div> <div class="info1-box-left">{{ "提案人:" }}</div>
<div <div class="info1-box-right">{{ curBill.tarName }}</div>
class="info2-item" </div>
v-for="(item, index) in curBill.dyqkList" <div class="info1-box">
:key="index" <div class="icon"></div>
> <div class="info1-box-left">{{ "提出时间:" }}</div>
<div class="item-icon"> <div class="info1-box-right">
<img src="./assets/images/info2-icon.png" alt="" /> {{ curBill.introductionDate }}
</div> </div>
<div </div>
class="item-time" </div>
:class="{ itemTimeActive: item.status === 1 }" <div class="box1-main-left-info2">
> <div class="time-line" :style="{ height: 38 * 3 + 'px' }"></div>
{{ item.dysj }} <div class="info2-item" v-for="(item, index) in curBill.dyqkList" :key="index">
</div> <div class="item-icon">
<div <img src="./assets/images/info2-icon.png" alt="" />
class="item-title" </div>
:class="{ itemTitleActive: item.status === 1 }" <div class="item-time" :class="{ itemTimeActive: item.status === 1 }">
> {{ item.dysj }}
{{ item.dyms }} </div>
</div> <div class="item-title" :class="{ itemTitleActive: item.status === 1 }">
</div> {{ item.dyms }}
<!-- <div class="info2-item"> </div>
<div class="item-icon"> </div>
<img src="./assets/images/info2-icon.png" alt="" /> </div>
</div> </div>
<div class="item-time">{{ "2025-07-04" }}</div> <div class="box1-main-right">
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div> <img src="./assets/images/box1-main-right-img.png" alt="" />
</div> <div class="inner-box">
<div class="info2-item"> <div class="inner-box-header">
<div class="item-icon"> <div class="inner-box-title">
<img src="./assets/images/info2-icon.png" alt="" /> {{ "大而美法案涉险通过参议院表决,众议院将继续..." }}
</div> </div>
<div class="item-time">{{ "2025-07-04" }}</div> <div class="inner-box-time">{{ "1小时前" }}</div>
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div> </div>
</div> <div class="inner-box-content">
<div class="info2-item"> {{
<div class="item-icon"> "三名美国共和党众议员(2025年7月21日)致函几家美国科技巨头公司的负责人,询问他们是否已经采取了充分的安全保障措施以有效解..."
<img src="./assets/images/info2-icon.png" alt="" /> }}
</div> </div>
<div class="item-time">{{ "2025-07-04" }}</div> </div>
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div> </div>
</div> </div>
<div class="info2-item"> </div>
<div class="item-icon"> <div class="box2">
<img src="./assets/images/info2-icon.png" alt="" /> <div class="box2-header">
</div> <div class="icon">
<div class="item-time">{{ "2025-07-04" }}</div> <img src="./assets/images/box2-header-icon.png" alt="" />
<div class="item-title">{{ "成为公法 No: 119-21。" }}</div> </div>
</div> --> <div class="title">
</div> <div class="text">{{ "风险信号" }}</div>
</div> <div class="num">{{ warningList.length }}</div>
<div class="box1-main-right"> </div>
<img src="./assets/images/box1-main-right-img.png" alt="" /> <div class="more">{{ "更多 +" }}</div>
<div class="inner-box"> </div>
<div class="inner-box-header"> <div class="box2-main">
<div class="inner-box-title"> <div class="box2-main-item" v-for="(item, index) in warningList" :key="index">
{{ "大而美法案涉险通过参议院表决,众议院将继续..." }} <div
</div> class="item-left"
<div class="inner-box-time">{{ "1小时前" }}</div> :class="{
</div> itemLeftStatus1: item.status === '一般风险',
<div class="inner-box-content"> itemLeftStatus2: item.status === '重大风险'
{{ }"
"三名美国共和党众议员(2025年7月21日)致函几家美国科技巨头公司的负责人,询问他们是否已经采取了充分的安全保障措施以有效解..." >
}} {{ item.status }}
</div> </div>
</div> <div class="item-right">
</div> <div class="text">
</div> {{ item.title }}
</div> </div>
<div class="box2"> <div class="time">{{ item.time }}</div>
<div class="box2-header"> </div>
<div class="icon"> </div>
<img src="./assets/images/box2-header-icon.png" alt="" /> </div>
</div> <div class="box2-footer">
<div class="title"> <div class="icon">
<div class="text">{{ "风险信号" }}</div> <img src="./assets/images/box2-footer-icon.png" alt="" />
<div class="num">{{ warningList.length }}</div> </div>
</div> <div class="text">{{ "风险处理" }}</div>
<div class="more">{{ "更多 +" }}</div> </div>
</div> </div>
<div class="box2-main"> </div>
<div <DivideHeader class="divide2" :titleText="'资讯要闻'"></DivideHeader>
class="box2-main-item" <div class="center-center">
v-for="(item, index) in warningList" <div class="box3">
:key="index" <div class="box3-header">
> <div class="box3-header-left">
<div <div class="box3-header-icon">
class="item-left" <img src="./assets/images/box3-header-icon.png" alt="" />
:class="{ </div>
itemLeftStatus1: item.status === '一般风险', <div class="box3-header-title">{{ "新闻资讯" }}</div>
itemLeftStatus2: item.status === '重大风险', </div>
}" </div>
> <div class="box3-main">
{{ item.status }} <div class="box3-item" v-for="(news, index) in newsList" :key="index">
</div> <div class="left">
<div class="item-right"> <img :src="news.img" alt="" />
<div class="text"> </div>
{{ item.title }} <div class="right">
</div> <div class="right-top">
<div class="time">{{ item.time }}</div> <div class="title">{{ news.title }}</div>
</div> <div class="time">{{ news.from }}</div>
</div> </div>
</div> <div class="right-footer">{{ news.content }}</div>
<div class="box2-footer"> </div>
<div class="icon"> </div>
<img src="./assets/images/box2-footer-icon.png" alt="" /> </div>
</div> </div>
<div class="text">{{ "风险处理" }}</div> <div class="box4">
</div> <div class="box4-header">
</div> <div class="header-icon">
</div> <img src="./assets/images/box4-header-icon.png" alt="" />
<div class="center-footer"> </div>
<div class="box3"> <div class="header-title">{{ "社交媒体" }}</div>
<div class="box3-header"> </div>
<div class="box3-header-left"> <div class="box4-main">
<div class="box3-header-icon"> <div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<img src="./assets/images/box3-header-icon.png" alt="" /> <div class="left">
</div> <img :src="item.img" alt="" />
<div class="box3-header-title">{{ "涉华法案数量" }}</div> </div>
</div> <div class="right">
<div class="box3-header-right"> <div class="right-top">
<div class="right-box"> <div class="name">{{ item.name }}</div>
<div class="icon1"></div> <div class="time">{{ item.time }}</div>
<div class="text">{{ "提出法案" }}</div> </div>
</div> <div class="content">{{ item.content }}</div>
<div class="right-box"> </div>
<div class="icon2"></div> </div>
<div class="text">{{ "通过法案" }}</div> </div>
</div> </div>
</div> </div>
</div> <DivideHeader class="divide3" :titleText="'统计概览'"></DivideHeader>
<div class="box3-main" id="chart1"></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 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>
</div>
</div>
</div>
<div class="home-main-footer">
<div class="home-main-footer-header">
<div class="btn-wrapper">
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: activeCate === cate.hylymc }"
v-for="(cate, index) in categoryList"
:key="index"
@click="handleClickCate(cate)"
>
{{ cate.hylymc }}
</div>
</div>
</div>
<div class="select-box"> <div class="center-footer">
<el-select <div class="box5">
v-model="releaseTime" <div class="box5-header">
placeholder="选择发布时间" <div class="box5-header-left">
style="width: 120px" <div class="box5-header-icon">
> <img src="./assets/images/box5-header-icon.png" alt="" />
<el-option </div>
v-for="item in releaseTimeList" <div class="box5-header-title">{{ "涉华法案数量" }}</div>
:key="item.value" </div>
:label="item.label" <div class="box5-header-right">
:value="item.value" <div class="right-box">
/> <div class="icon1"></div>
</el-select> <div class="text">{{ "提出法案" }}</div>
<!-- <el-select </div>
<div class="right-box">
<div class="icon2"></div>
<div class="text">{{ "通过法案" }}</div>
</div>
</div>
</div>
<div class="box5-main" id="chart1"></div>
</div>
<div class="box6">
<div class="box6-header">
<div class="header-icon">
<img src="./assets/images/box6-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "关键条款" }}</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">
<div
class="btn"
:class="{ btnActive: activeCate === cate.hylymc }"
v-for="(cate, index) in categoryList"
:key="index"
@click="handleClickCate(cate)"
>
{{ cate.hylymc }}
</div>
</div>
</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>
<!-- <el-select
v-model="releaseTime" v-model="releaseTime"
placeholder="选择发布时间" placeholder="选择发布时间"
style="width: 120px" style="width: 120px"
...@@ -309,26 +305,29 @@ ...@@ -309,26 +305,29 @@
:value="item.value" :value="item.value"
/> />
</el-select> --> </el-select> -->
</div> </div>
</div> </div>
<div class="home-main-footer-main"> <div class="home-main-footer-main">
<div <div class="main-item" v-for="(bill, index) in curBillList" :key="index">
class="main-item" <div class="main-item-box1">
v-for="(bill, index) in curBillList" <img :src="bill.img" alt="" />
:key="index" </div>
> <div class="main-item-box2">
<div class="main-item-box1"> {{ bill.billName }}
<img :src="bill.img" alt="" /> </div>
</div> <div class="main-item-box3">{{ bill.introductionDate }}</div>
<div class="main-item-box2"> </div>
{{ bill.billName }} </div>
</div> <div class="home-main-footer-footer">
<div class="main-item-box3">{{ bill.introductionDate }}</div> <div class="footer-left">
</div> {{ `共${curBillList.length}项调查` }}
</div> </div>
</div> <div class="footer-right">
</div> <el-pagination background layout="prev, pager, next" :total="curBillList.length" />
</div> </div>
</div>
</div>
</div>
</template> </template>
<script setup> <script setup>
...@@ -337,6 +336,7 @@ import * as echarts from "echarts"; ...@@ -337,6 +336,7 @@ import * as echarts from "echarts";
import router from "@/router/index"; import router from "@/router/index";
import { getHotBills, getBillsByType, getHylyList } from "@/api/home"; import { getHotBills, getBillsByType, getHylyList } from "@/api/home";
import DivideHeader from "@/components/DivideHeader.vue";
import headerIcon1 from "./assets/icons/header-icon1.png"; import headerIcon1 from "./assets/icons/header-icon1.png";
import headerIcon2 from "./assets/icons/header-icon2.png"; import headerIcon2 from "./assets/icons/header-icon2.png";
...@@ -345,6 +345,7 @@ import headerIcon4 from "./assets/icons/header-icon4.png"; ...@@ -345,6 +345,7 @@ import headerIcon4 from "./assets/icons/header-icon4.png";
import headerIcon5 from "./assets/icons/header-icon5.png"; import headerIcon5 from "./assets/icons/header-icon5.png";
import getMultiLineChart from "./utils/multiLineChart"; import getMultiLineChart from "./utils/multiLineChart";
import getWordCloudChart from "./utils/worldCloudChart";
import bill1 from "./assets/images/bill1.png"; import bill1 from "./assets/images/bill1.png";
import bill2 from "./assets/images/bill2.png"; import bill2 from "./assets/images/bill2.png";
...@@ -359,263 +360,273 @@ import bill10 from "./assets/images/bill10.png"; ...@@ -359,263 +360,273 @@ import bill10 from "./assets/images/bill10.png";
import bill11 from "./assets/images/bill11.png"; import bill11 from "./assets/images/bill11.png";
import bill12 from "./assets/images/bill12.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 billList = ref([]);
const curBillListIndex = ref(0); const curBillListIndex = ref(0);
const handleSwithCurBill = (name) => { const handleSwithCurBill = name => {
if (name === "left") { if (name === "left") {
if (curBillListIndex.value === 0) { if (curBillListIndex.value === 0) {
curBillListIndex.value = billList.value.length - 1; curBillListIndex.value = billList.value.length - 1;
} else { } else {
curBillListIndex.value--; curBillListIndex.value--;
} }
} else { } else {
if (curBillListIndex.value === billList.value.length - 1) { if (curBillListIndex.value === billList.value.length - 1) {
curBillListIndex.value = 0; curBillListIndex.value = 0;
} else { } else {
curBillListIndex.value++; curBillListIndex.value++;
} }
} }
curBill.value = billList.value[curBillListIndex.value]; curBill.value = billList.value[curBillListIndex.value];
}; };
// 当前法案 // 当前法案
const curBill = ref({ const curBill = ref({
billName: "", billName: "",
billId: 0, billId: 0,
dyqkList: [], dyqkList: [],
hylyList: [], hylyList: [],
tarName: "", tarName: "",
introductionDate: "", introductionDate: ""
}); });
const handleClickToDetail = () => { const handleClickToDetail = () => {
window.sessionStorage.setItem("billId", curBill.value.billId); window.sessionStorage.setItem("billId", curBill.value.billId);
router.push("/billLayout"); router.push("/billLayout");
}; };
const billTrendList = ref([ const billTrendList = ref([
{ {
title: "限制与中国合作", title: "限制与中国合作",
no: "H.R.2670", no: "H.R.2670"
}, },
{ {
title: "限制中国获取技术", title: "限制中国获取技术",
no: "H.R.2471", no: "H.R.2471"
}, },
{ {
title: "禁止在中国建设半导体产能", title: "禁止在中国建设半导体产能",
no: "H.R.5895", no: "H.R.5895"
}, },
{ {
title: "限制中国产燃油进口", title: "限制中国产燃油进口",
no: "S.870", no: "S.870"
}, },
{ {
title: "禁止政府部门采购受控半导体或服务", title: "禁止政府部门采购受控半导体或服务",
no: "H.R.6395", no: "H.R.6395"
}, },
{ {
title: "禁止向部分中国实体提供资金", title: "禁止向部分中国实体提供资金",
no: "H.R.3935", no: "H.R.3935"
}, },
{ {
title: "限制采购中国生产电池", title: "限制采购中国生产电池",
no: "H.R.7776", no: "H.R.7776"
}, },
{ {
title: "重视新兴中国技术公司威胁", title: "重视新兴中国技术公司威胁",
no: "H.R.3935", no: "H.R.3935"
}, },
{ {
title: "禁止卫星出口至中国", title: "禁止卫星出口至中国",
no: "S.870", no: "S.870"
}, },
{ {
title: "禁购华为设备", title: "禁购华为设备",
no: "H.R.5895", no: "H.R.5895"
}, }
]); ]);
const warningList = ref([ const warningList = ref([
{ {
title: "美国大而美法案落地,总统签署通过", title: "美国大而美法案落地,总统签署通过",
time: "一天前", time: "一天前",
status: "特别重大", status: "特别重大"
}, },
{ {
title: "美大而美法案7月1日以51:50的票数通过...", title: "美大而美法案7月1日以51:50的票数通过...",
time: "一天前", time: "一天前",
status: "特别重大", status: "特别重大"
}, },
{ {
title: "首次提出“限制外国敏感实体获取补贴”", title: "首次提出“限制外国敏感实体获取补贴”",
time: "一天前", time: "一天前",
status: "重大风险", status: "重大风险"
}, },
{ {
title: "将中国企业海外子公司、合资公司纳入受...", title: "将中国企业海外子公司、合资公司纳入受...",
time: "一天前", time: "一天前",
status: "重大风险", status: "重大风险"
}, },
{ {
title: "H.R.8333《生物安全法案》将华大基因等...", title: "H.R.8333《生物安全法案》将华大基因等...",
time: "一天前", time: "一天前",
status: "一般风险", status: "一般风险"
}, }
]); ]);
const timelineList = ref([ const timelineList = ref([
{ {
title: "成为公法 No: 119-21。", title: "成为公法 No: 119-21。",
time: "2025-07-04", time: "2025-07-04",
status: 1, status: 1
}, },
{ {
title: "总统签署", title: "总统签署",
time: "2025-07-04", time: "2025-07-04",
status: 0, status: 0
}, },
{ {
title: "提交总统", title: "提交总统",
time: "2025-07-03", time: "2025-07-03",
status: 0, status: 0
}, },
{ {
title: "重新审议动议搁置案无异议通过。", title: "重新审议动议搁置案无异议通过。",
time: "2025-07-03 14:31", time: "2025-07-03 14:31",
status: 0, status: 0
}, },
{ {
title: "关于‘众议院同意参议院修正案’...", title: "关于‘众议院同意参议院修正案’...",
time: "2025-07-02 14:31", time: "2025-07-02 14:31",
status: 0, status: 0
}, }
]); ]);
const areaList = ref([ const areaList = ref([
{ {
name: "跨境电商", name: "跨境电商",
status: 2, status: 2
}, },
{ {
name: "新能源产业", name: "新能源产业",
status: 4, status: 4
}, },
{ {
name: "半导体产业", name: "半导体产业",
status: 1, status: 1
}, },
{ {
name: "关税", name: "关税",
status: 3, status: 3
}, },
{ {
name: "光伏产业", name: "光伏产业",
status: 2, status: 2
}, }
]); ]);
const curBillList = ref([ const curBillList = ref([
{ {
billName: "大而美法案", billName: "大而美法案",
introductionDate: "2025年7月4日", introductionDate: "2025年7月4日",
img: bill1, img: bill1
}, },
{ {
billName: "GENIUS稳定币法案", billName: "GENIUS稳定币法案",
introductionDate: "2025年7月5日", introductionDate: "2025年7月5日",
img: bill2, img: bill2
}, },
{ {
billName: "美越贸易协议", billName: "美越贸易协议",
introductionDate: "2025年7月6日", introductionDate: "2025年7月6日",
img: bill3, img: bill3
}, },
{ {
billName: "美越贸易协议", billName: "美越贸易协议",
introductionDate: "2025年7月7日", introductionDate: "2025年7月7日",
img: bill4, img: bill4
}, },
{ {
billName: "汽车零部件25%关税实施规则", billName: "汽车零部件25%关税实施规则",
introductionDate: "2025年7月10日", introductionDate: "2025年7月10日",
img: bill5, img: bill5
}, },
{ {
billName: "汽车零部件25%关税实施规则", billName: "汽车零部件25%关税实施规则",
introductionDate: "2025年7月12日", introductionDate: "2025年7月12日",
img: bill6, img: bill6
}, },
{ {
billName: "小额豁免包裹政策调整", billName: "小额豁免包裹政策调整",
introductionDate: "2025年7月14日", introductionDate: "2025年7月14日",
img: bill7, img: bill7
}, },
{ {
billName: "NIH预算否决案", billName: "NIH预算否决案",
introductionDate: "2025年7月15日", introductionDate: "2025年7月15日",
img: bill8, img: bill8
}, },
{ {
billName: "得州国会选区重划法案", billName: "得州国会选区重划法案",
introductionDate: "2025年7月17日", introductionDate: "2025年7月17日",
img: bill9, img: bill9
}, },
{ {
billName: "美越贸易协议", billName: "美越贸易协议",
introductionDate: "2025年7月24日", introductionDate: "2025年7月24日",
img: bill10, img: bill10
}, },
{ {
billName: "美越贸易协议", billName: "美越贸易协议",
introductionDate: "2025年8月4日", introductionDate: "2025年8月4日",
img: bill11, img: bill11
}, },
{ {
billName: "美越贸易协议", billName: "美越贸易协议",
introductionDate: "2025年8月8日", introductionDate: "2025年8月8日",
img: bill12, img: bill12
}, }
]); ]);
const releaseTime = ref("近一年发布"); const releaseTime = ref("近一年发布");
const releaseTimeList = ref([ const releaseTimeList = ref([
{ {
label: "近半年发布", label: "近半年发布",
value: "近半年发布", value: "近半年发布"
}, },
{ {
label: "近一年发布", label: "近一年发布",
value: "近一年发布", value: "近一年发布"
}, },
{ {
label: "近两年发布", label: "近两年发布",
value: "近两年发布", value: "近两年发布"
}, },
{ {
label: "近三年发布", label: "近三年发布",
value: "近三年发布", value: "近三年发布"
}, },
{ {
label: "近五年发布", label: "近五年发布",
value: "近五年发布", value: "近五年发布"
}, }
]); ]);
const categoryList = ref([ const categoryList = ref([
// "全部分类", // "全部分类",
// "生物科技", // "生物科技",
// "集成电路", // "集成电路",
// "通信网络", // "通信网络",
// "量子科技", // "量子科技",
// "新能源", // "新能源",
// "新一代信息技术", // "新一代信息技术",
// "海洋", // "海洋",
// "先进制造", // "先进制造",
// "新材料", // "新材料",
// "航空航天", // "航空航天",
]); ]);
const activeCate = ref("全部分类"); const activeCate = ref("全部分类");
...@@ -623,972 +634,1280 @@ const activeHylyId = ref(""); ...@@ -623,972 +634,1280 @@ const activeHylyId = ref("");
// 获取领域分类 // 获取领域分类
const handleGetHylyList = async () => { const handleGetHylyList = async () => {
try { try {
const res = await getHylyList(); const res = await getHylyList();
console.log("行业领域列表"); console.log("行业领域列表");
categoryList.value = res.data; categoryList.value = res.data;
const obj = { const obj = {
id: 0, id: 0,
hylyid: "", hylyid: "",
hylymc: "全部分类", hylymc: "全部分类"
}; };
categoryList.value = [obj, ...categoryList.value]; categoryList.value = [obj, ...categoryList.value];
} catch (error) {} } catch (error) {}
}; };
const handleClickCate = (cate) => { const handleClickCate = cate => {
console.log(cate); console.log(cate);
activeCate.value = cate.hylymc; activeCate.value = cate.hylymc;
activeHylyId.value = cate.hylyid; activeHylyId.value = cate.hylyid;
handleGetBillsByType(); handleGetBillsByType();
}; };
const navList = ref([ const navList = ref([
{ {
icon: headerIcon1, icon: headerIcon1,
activeIcno: headerIcon1, activeIcno: headerIcon1,
name: "首页", name: "首页",
path: "/home", path: "/home"
}, },
{ {
icon: headerIcon2, icon: headerIcon2,
activeIcno: headerIcon2, activeIcno: headerIcon2,
name: "国家", name: "国家",
path: "/country", path: "/country"
}, },
{ {
icon: headerIcon3, icon: headerIcon3,
activeIcno: headerIcon3, activeIcno: headerIcon3,
name: "领域", name: "领域",
path: "/area", path: "/area"
}, },
{ {
icon: headerIcon4, icon: headerIcon4,
activeIcno: headerIcon4, activeIcno: headerIcon4,
name: "要素", name: "要素",
path: "/home", path: "/home"
}, },
{ {
icon: headerIcon5, icon: headerIcon5,
activeIcno: headerIcon5, activeIcno: headerIcon5,
name: "事件", name: "事件",
path: "/home", path: "/home"
}, }
]); ]);
const activeNavIndex = ref(0); const activeNavIndex = ref(0);
const handleClickNav = (index, item) => { const handleClickNav = (index, item) => {
activeNavIndex.value = index; activeNavIndex.value = index;
router.push(item.path); router.push(item.path);
}; };
// 绘制echarts图表 // 绘制echarts图表
const setChart = (option, chartId) => { const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId); let chartDom = document.getElementById(chartId);
chartDom.removeAttribute("_echarts_instance_"); chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom); let chart = echarts.init(chartDom);
chart.setOption(option); chart.setOption(option);
return chart; return chart;
}; };
const chart1Data = ref({ const chart1Data = ref({
title: [ title: [
"2024-09", "2024-09",
"2024-10", "2024-10",
"2024-11", "2024-11",
"2024-12", "2024-12",
"2025-01", "2025-01",
"2025-02", "2025-02",
"2025-03", "2025-03",
"2025-04", "2025-04",
"2025-05", "2025-05",
"2025-06", "2025-06",
"2025-07", "2025-07",
"2025-08", "2025-08"
], ],
data: [ data: [
{ {
name: "提出法案", 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: "通过法案", 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 () => { const handleGetHotBills = async () => {
try { try {
const res = await getHotBills(); const res = await getHotBills();
console.log("热门法案", res); console.log("热门法案", res);
billList.value = res.data; billList.value = res.data;
} catch (error) { } catch (error) {
console.error(error); console.error(error);
} }
}; };
// 根据法案类型获取法案列表 // 根据法案类型获取法案列表
const handleGetBillsByType = async () => { const handleGetBillsByType = async () => {
const params = { const params = {
type: activeHylyId.value, type: activeHylyId.value
}; };
try { try {
const res = await getBillsByType(params); const res = await getBillsByType(params);
console.log("根据法案类型获取法案列表", res); console.log("根据法案类型获取法案列表", res);
curBillList.value = res.data.map((item) => { curBillList.value = res.data.map(item => {
return { return {
billId: item.billId, billId: item.billId,
billName: item.billName, billName: item.billName,
introductionDate: item.introductionDate, introductionDate: item.introductionDate,
img: bill1, img: bill1
}; };
}); });
} catch (error) {} } 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 () => { onMounted(async () => {
handleGetHylyList(); handleGetHylyList();
await handleGetHotBills(); await handleGetHotBills();
curBill.value = billList.value[0]; curBill.value = billList.value[0];
handleGetBillsByType(); // handleGetBillsByType();
let chart1 = getMultiLineChart( let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value, chart1Data.value.data[1].value);
chart1Data.value.title, setChart(chart1, "chart1");
chart1Data.value.data[0].value,
chart1Data.value.data[1].value const wordCloudChart = getWordCloudChart(wordCloudData.value);
); setChart(wordCloudChart, "wordCloudChart");
setChart(chart1, "chart1");
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
:deep(.el-input__wrapper) { :deep(.el-input__wrapper) {
box-shadow: none; box-shadow: none;
} }
.home-wrapper { .home-wrapper {
.home-header { .home-header {
height: 64px; height: 64px;
color: #fff; color: #fff;
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
line-height: 26px; line-height: 26px;
line-height: 64px; line-height: 64px;
background: url("./assets/images/header-bg.png"); background: url("./assets/images/header-bg.png");
box-sizing: border-box; box-sizing: border-box;
padding-left: 160px; padding-left: 160px;
} }
.home-main { .home-main {
width: 1400px; width: 1600px;
margin: 0 auto; margin: 0 auto;
background: url("./assets/images/background.png"); margin-top: 48px;
background-size: 100% 100%; background: url("./assets/images/background.png");
.home-main-header { background-size: 100% 100%;
display: flex; .home-main-header {
flex-direction: column; display: flex;
align-items: center; flex-direction: column;
.home-main-header-center { align-items: center;
margin-top: 13px; .home-main-header-center {
width: 960px; width: 960px;
height: 48px; height: 48px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
box-sizing: border-box; box-sizing: border-box;
padding: 1px; padding: 1px;
position: relative; position: relative;
.search { .search {
position: absolute; position: absolute;
right: 1px; right: 1px;
top: 1px; top: 2px;
width: 120px; width: 120px;
height: 42px; height: 42px;
border-radius: 4px; border-radius: 10px;
background: rgba(22, 119, 255, 1); background: var(--color-main-active);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
.search-icon { .search-icon {
width: 18px; width: 18px;
height: 18px; height: 18px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.search-text { .search-text {
margin-left: 8px; margin-left: 8px;
height: 22px; height: 22px;
color: #fff; color: #fff;
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
} }
} }
} }
.home-main-header-footer { .home-main-header-footer {
margin-top: 38px; margin-top: 38px;
width: 960px; width: 960px;
height: 64px; height: 64px;
box-sizing: border-box; box-sizing: border-box;
padding: 0 108px; padding: 0 108px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
.home-main-header-footer-item { .home-main-header-footer-item {
padding: 0 10px; padding: 0 10px;
text-align: center; text-align: center;
.item-top { .item-top {
height: 22px; height: 22px;
color: rgba(20, 89, 187, 1); color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 36px; font-size: 36px;
font-weight: 700; font-weight: 700;
line-height: 22px; line-height: 22px;
} }
.item-footer { .item-footer {
margin-top: 10px; margin-top: 10px;
height: 30px; height: 30px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 30px; line-height: 30px;
} }
} }
} }
} .home-main-header-btn-box {
.home-main-center { margin-top: 36px;
margin-top: 34px; display: flex;
.center-top { .btn {
height: 450px; display: flex;
display: flex; width: 160px;
gap: 20px; height: 48px;
.box1 { border: 1px solid #aed6ff;
width: 920px; box-sizing: border-box;
height: 450px; border-radius: 24px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); justify-content: center;
background: #fff; margin: 0 16px;
box-sizing: border-box; background: #e7f3ff;
position: relative; cursor: pointer;
.box1-left { &:hover {
position: absolute; background: #cae3fc;
left: 0; }
top: 200px; .btn-text {
width: 24px; color: var(--color-main-active);
height: 48px; font-family: Microsoft YaHei;
background: #e7f1ff; font-size: 20px;
display: flex; font-weight: 400;
justify-content: center; line-height: 44px;
align-items: center; margin-left: 5px;
cursor: pointer; }
.icon { .btn-icon {
width: 11px; margin-left: 20px;
height: 18px; color: var(--color-main-active);
img { font-family: Microsoft YaHei;
width: 100%; font-size: 20px;
height: 100%; font-weight: 400;
} line-height: 44px;
} }
} }
.box1-right { }
position: absolute; }
right: 0; .divide1 {
top: 200px; margin-top: 64px;
width: 24px; margin-bottom: 36px;
height: 48px; }
background: #e7f1ff; .home-main-center {
display: flex; margin-top: 34px;
justify-content: center; .center-top {
align-items: center; height: 450px;
cursor: pointer; display: flex;
.icon { gap: 20px;
width: 11px; .box1 {
height: 18px; width: 1064px;
img { height: 450px;
width: 100%; box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
height: 100%; background: #fff;
} box-sizing: border-box;
} position: relative;
} .box1-left {
.box1-header { position: absolute;
height: 48px; left: 0;
border-bottom: 1px solid rgba(240, 242, 244, 1); top: 200px;
display: flex; width: 24px;
justify-content: space-between; height: 48px;
box-sizing: border-box; background: #e7f1ff;
padding: 0 40px 0 30px; display: flex;
.box1-header-left { justify-content: center;
display: flex; align-items: center;
.icon { cursor: pointer;
width: 18px; .icon {
height: 18px; width: 11px;
margin-top: 19px; height: 18px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.title { }
width: 112px; .box1-right {
height: 48px; position: absolute;
background: var(--color-main-active); right: 0;
margin-left: 18px; top: 200px;
color: #fff; width: 24px;
font-family: Microsoft YaHei; height: 48px;
font-size: 20px; background: #e7f1ff;
font-weight: 700; display: flex;
line-height: 48px; justify-content: center;
text-align: center; align-items: center;
} cursor: pointer;
} .icon {
.box1-header-right { width: 11px;
margin-top: 19px; height: 18px;
height: 16px; img {
color: rgba(20, 89, 187, 1); width: 100%;
font-family: Microsoft YaHei; height: 100%;
font-size: 16px; }
font-weight: 400; }
line-height: 16px; }
cursor: pointer; .box1-header {
} height: 48px;
} border-bottom: 1px solid rgba(240, 242, 244, 1);
.box1-main { display: flex;
display: flex; justify-content: space-between;
height: 354px; box-sizing: border-box;
margin-top: 22px; padding: 0 40px 0 30px;
box-sizing: border-box; .box1-header-left {
padding-left: 31px; display: flex;
.box1-main-left { .icon {
margin-left: 37px; width: 18px;
// flex: 1; height: 18px;
width: 410px; margin-top: 19px;
.box1-main-left-title { img {
height: 22px; width: 100%;
color: rgba(20, 89, 187, 1); height: 100%;
font-family: Microsoft YaHei; }
font-size: 20px; }
font-weight: 700; .title {
line-height: 22px; width: 112px;
} height: 48px;
.box1-main-left-info { background: var(--color-main-active);
margin-top: 17px; margin-left: 18px;
display: flex; color: #fff;
.info-box { font-family: Microsoft YaHei;
height: 30px; font-size: 20px;
width: 80px; font-weight: 700;
text-align: center; line-height: 48px;
overflow: hidden; text-align: center;
padding: 0 8px; }
box-sizing: border-box; }
border: 1px solid rgba(186, 224, 255, 1); .box1-header-right {
border-radius: 4px; margin-top: 19px;
background: rgba(230, 244, 255, 1); height: 16px;
color: rgba(22, 119, 255, 1); color: rgba(20, 89, 187, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 14px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 30px; line-height: 16px;
margin-right: 8px; cursor: pointer;
} }
.info1 { }
border: 1px solid rgba(135, 232, 222, 1); .box1-main {
background: rgba(230, 255, 251, 1); display: flex;
color: rgba(19, 168, 168, 1); height: 354px;
} margin-top: 22px;
.info2 { box-sizing: border-box;
border: 1px solid rgba(186, 224, 255, 1); padding-left: 31px;
background: rgba(230, 244, 255, 1); .box1-main-left {
color: rgba(22, 119, 255, 1); margin-left: 39px;
} // flex: 1;
.info3 { width: 484px;
border: 1px solid rgba(255, 229, 143, 1); .box1-main-left-title {
background: rgba(255, 251, 230, 1); height: 22px;
color: rgba(250, 173, 20, 1); color: rgba(20, 89, 187, 1);
} font-family: Microsoft YaHei;
.info4 { font-size: 20px;
border: 1px solid rgba(255, 163, 158, 1); font-weight: 700;
background: rgba(255, 241, 240, 1); line-height: 22px;
color: rgba(245, 34, 45, 1); }
} .box1-main-left-info {
} margin-top: 17px;
.box1-main-left-info1 { display: flex;
margin-top: 25px; .info-box {
margin-left: 4px; height: 30px;
.info1-box { width: 80px;
display: flex; text-align: center;
.icon { overflow: hidden;
margin-top: 15px; padding: 0 8px;
width: 4px; box-sizing: border-box;
height: 4px; border: 1px solid rgba(186, 224, 255, 1);
border-radius: 2px; border-radius: 4px;
background: rgba(132, 136, 142, 1); background: rgba(230, 244, 255, 1);
} color: rgba(22, 119, 255, 1);
.info1-box-left { font-family: Microsoft YaHei;
margin-left: 18px; font-size: 14px;
width: 100px; font-weight: 400;
height: 30px; line-height: 30px;
color: rgba(95, 101, 108, 1); margin-right: 8px;
font-family: Microsoft YaHei; }
font-size: 16px; .info1 {
font-weight: 400; border: 1px solid rgba(135, 232, 222, 1);
line-height: 30px; background: rgba(230, 255, 251, 1);
} color: rgba(19, 168, 168, 1);
.info1-box-right { }
margin-left: 64px; .info2 {
height: 30px; border: 1px solid rgba(186, 224, 255, 1);
color: rgba(95, 101, 108, 1); background: rgba(230, 244, 255, 1);
font-family: Microsoft YaHei; color: rgba(22, 119, 255, 1);
font-size: 16px; }
font-weight: 400; .info3 {
line-height: 30px; border: 1px solid rgba(255, 229, 143, 1);
} background: rgba(255, 251, 230, 1);
} color: rgba(250, 173, 20, 1);
} }
.box1-main-left-info2 { .info4 {
margin-top: 21px; border: 1px solid rgba(255, 163, 158, 1);
height: 200px; background: rgba(255, 241, 240, 1);
width: 400px; color: rgba(245, 34, 45, 1);
position: relative; }
.time-line { }
position: absolute; .box1-main-left-info1 {
z-index: 0; margin-top: 25px;
top: 15px; margin-left: 4px;
left: 4px; .info1-box {
width: 2px; display: flex;
background: #e6e7e8; .icon {
} margin-top: 15px;
.info2-item { width: 4px;
margin-left: 1px; height: 4px;
margin-bottom: 8px; border-radius: 2px;
height: 30px; background: rgba(132, 136, 142, 1);
display: flex; }
// background: orange; .info1-box-left {
.item-icon { margin-left: 18px;
margin-top: 2px; width: 100px;
width: 10px; height: 30px;
height: 10px; color: rgba(95, 101, 108, 1);
position: relative; font-family: Microsoft YaHei;
z-index: 1; font-size: 16px;
img { font-weight: 400;
width: 10px; line-height: 30px;
height: 10px; }
} .info1-box-right {
} margin-left: 64px;
.itemTimeActive { height: 30px;
color: rgba(20, 89, 187, 1) !important; color: rgba(95, 101, 108, 1);
} font-family: Microsoft YaHei;
.itemTitleActive { font-size: 16px;
font-weight: 700 !important; font-weight: 400;
color: rgba(20, 89, 187, 1) !important; line-height: 30px;
} }
.item-time { }
margin-left: 15px; }
width: 147px; .box1-main-left-info2 {
height: 30px; margin-top: 21px;
color: rgba(95, 101, 108, 1); height: 200px;
font-family: Microsoft YaHei; width: 400px;
font-size: 16px; position: relative;
font-weight: 700; .time-line {
line-height: 30px; position: absolute;
} z-index: 0;
.item-title { top: 15px;
margin-left: 10px; left: 4px;
width: 295px; width: 2px;
height: 30px; background: #e6e7e8;
color: rgba(132, 136, 142, 1); }
font-family: Microsoft YaHei; .info2-item {
font-size: 16px; margin-left: 1px;
font-weight: 400; margin-bottom: 8px;
line-height: 30px; height: 30px;
} display: flex;
} // background: orange;
} .item-icon {
} margin-top: 2px;
.box1-main-right { width: 10px;
margin-top: 50px; height: 10px;
height: 270px; position: relative;
width: 350px; z-index: 1;
border-radius: 4px; img {
overflow: hidden; width: 10px;
position: relative; height: 10px;
img { }
width: 100%; }
height: 100%; .itemTimeActive {
} color: rgba(20, 89, 187, 1) !important;
.inner-box { }
width: 330px; .itemTitleActive {
height: 93px; font-weight: 700 !important;
background: rgba(10, 18, 30, 0.75); color: rgba(20, 89, 187, 1) !important;
position: absolute; }
left: 0; .item-time {
bottom: 0; margin-left: 15px;
box-sizing: border-box; width: 147px;
padding: 9px 10px 12px 10px; height: 30px;
.inner-box-header { color: rgba(95, 101, 108, 1);
height: 30px; font-family: Microsoft YaHei;
display: flex; font-size: 16px;
.inner-box-title { font-weight: 700;
width: 270px; line-height: 30px;
color: rgba(255, 255, 255, 1); }
font-family: Microsoft YaHei; .item-title {
font-size: 16px; margin-left: 10px;
font-weight: 700; width: 295px;
line-height: 30px; height: 30px;
overflow: hidden; color: rgba(132, 136, 142, 1);
text-overflow: ellipsis; font-family: Microsoft YaHei;
white-space: nowrap; font-size: 16px;
} font-weight: 400;
.inner-box-time { line-height: 30px;
width: 60px; }
height: 30px; }
color: rgba(255, 255, 255, 0.65); }
font-family: Microsoft YaHei; }
font-size: 14px; .box1-main-right {
font-weight: 400; height: 354px;
line-height: 30px; width: 458px;
overflow: hidden; border-radius: 4px;
text-overflow: ellipsis; overflow: hidden;
white-space: nowrap; position: relative;
} img {
} width: 100%;
.inner-box-content { height: 100%;
width: 330px; }
height: 40px; .inner-box {
overflow: hidden; width: 330px;
color: rgba(255, 255, 255, 0.8); height: 93px;
font-family: Microsoft YaHei; background: rgba(10, 18, 30, 0.75);
font-size: 14px; position: absolute;
font-weight: 400; left: 0;
line-height: 20px; bottom: 0;
} box-sizing: border-box;
} padding: 9px 10px 12px 10px;
} .inner-box-header {
} height: 30px;
} display: flex;
.box2 { .inner-box-title {
flex: 1; width: 270px;
height: 450px; color: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); font-family: Microsoft YaHei;
background: rgba(255, 255, 255, 1); font-size: 16px;
position: relative; font-weight: 700;
.box2-header { line-height: 30px;
height: 48px; overflow: hidden;
display: flex; text-overflow: ellipsis;
box-sizing: border-box; white-space: nowrap;
padding-right: 20px; }
border-bottom: 1px solid rgba(234, 236, 238, 1); .inner-box-time {
.icon { width: 60px;
width: 24px; height: 30px;
height: 22px; color: rgba(255, 255, 255, 0.65);
margin-left: 18px; font-family: Microsoft YaHei;
margin-top: 18px; font-size: 14px;
img { font-weight: 400;
width: 100%; line-height: 30px;
height: 100%; overflow: hidden;
} text-overflow: ellipsis;
} white-space: nowrap;
.title { }
margin-left: 18px; }
width: 148px; .inner-box-content {
height: 48px; width: 330px;
background: rgba(206, 79, 81, 1); height: 40px;
display: flex; overflow: hidden;
.text { color: rgba(255, 255, 255, 0.8);
margin-left: 16px; font-family: Microsoft YaHei;
height: 22px; font-size: 14px;
color: #fff; font-weight: 400;
font-family: Microsoft YaHei; line-height: 20px;
font-size: 20px; }
font-weight: 700; }
line-height: 48px; }
} }
.num { }
width: 24px; .box2 {
height: 20px; flex: 1;
text-align: center; height: 450px;
color: rgba(255, 255, 255, 1); box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
font-family: Microsoft YaHei; background: rgba(255, 255, 255, 1);
font-size: 12px; position: relative;
margin-left: 10px; .box2-header {
margin-top: 15px; height: 48px;
// border: 1px solid rgba(255, 255, 255, 1); display: flex;
border-radius: 100px; box-sizing: border-box;
background: rgba(255, 255, 255, 0.3); padding-right: 20px;
} border-bottom: 1px solid rgba(234, 236, 238, 1);
} .icon {
.more { width: 24px;
margin-top: 19px; height: 22px;
margin-left: 224px; margin-left: 18px;
color: rgba(20, 89, 187, 1); margin-top: 18px;
font-family: Microsoft YaHei; img {
font-size: 16px; width: 100%;
font-weight: 400; height: 100%;
line-height: 16px; }
} }
} .title {
.box2-main { margin-left: 18px;
height: 330px; width: 148px;
overflow-y: auto; height: 48px;
box-sizing: border-box; background: rgba(206, 79, 81, 1);
padding-right: 20px; display: flex;
.box2-main-item { .text {
margin-left: 23px; margin-left: 16px;
height: 47px; height: 22px;
width: 464px; color: #fff;
display: flex; font-family: Microsoft YaHei;
.itemLeftStatus1 { font-size: 20px;
color: rgba(82, 196, 26, 1) !important; font-weight: 700;
background: rgba(246, 255, 237, 1) !important; line-height: 48px;
} }
.itemLeftStatus2 { .num {
color: rgba(250, 140, 22, 1) !important; width: 24px;
background: rgba(255, 247, 230, 1) !important; height: 20px;
} text-align: center;
.item-left { color: rgba(255, 255, 255, 1);
margin-top: 4px; font-family: Microsoft YaHei;
margin-left: 2px; font-size: 12px;
width: 40px; margin-left: 10px;
height: 40px; margin-top: 15px;
border-radius: 20px; // border: 1px solid rgba(255, 255, 255, 1);
background: rgba(255, 241, 240); border-radius: 100px;
color: rgba(245, 34, 45, 1); background: rgba(255, 255, 255, 0.3);
font-family: Microsoft YaHei; }
font-size: 12px; }
font-weight: 400; .more {
line-height: 14px; margin-top: 19px;
box-sizing: border-box; margin-left: 224px;
padding: 6px 4px; color: rgba(20, 89, 187, 1);
text-align: center; font-family: Microsoft YaHei;
} font-size: 16px;
.item-right { font-weight: 400;
margin-left: 13px; line-height: 16px;
width: 408px; }
height: 47px; }
border-bottom: 1px solid rgba(240, 242, 244, 1); .box2-main {
display: flex; height: 330px;
.text { overflow-y: auto;
width: 348px; box-sizing: border-box;
color: rgba(59, 65, 75, 1); padding-right: 20px;
font-family: Microsoft YaHei; .box2-main-item {
font-size: 16px; margin-left: 23px;
font-weight: 400; height: 47px;
line-height: 47px; width: 464px;
} display: flex;
.time { .itemLeftStatus1 {
margin-left: 10px; color: rgba(82, 196, 26, 1) !important;
line-height: 47px; background: rgba(246, 255, 237, 1) !important;
color: rgba(132, 136, 142, 1); }
font-family: Microsoft YaHei; .itemLeftStatus2 {
font-size: 14px; color: rgba(250, 140, 22, 1) !important;
font-weight: 400; background: rgba(255, 247, 230, 1) !important;
} }
} .item-left {
} margin-top: 4px;
} margin-left: 2px;
.box2-footer { width: 40px;
position: absolute; height: 40px;
left: 40px; border-radius: 20px;
bottom: 20px; background: rgba(255, 241, 240);
width: 430px; color: rgba(245, 34, 45, 1);
height: 42px; font-family: Microsoft YaHei;
display: flex; font-size: 12px;
flex-direction: row; font-weight: 400;
justify-content: center; line-height: 14px;
align-items: center; box-sizing: border-box;
border-radius: 6px; padding: 6px 4px;
background: rgba(22, 119, 255, 1); text-align: center;
cursor: pointer; }
.icon { .item-right {
width: 16px; margin-left: 13px;
height: 16px; width: 408px;
img { height: 47px;
width: 100%; border-bottom: 1px solid rgba(240, 242, 244, 1);
height: 100%; display: flex;
} .text {
} width: 348px;
.text { color: rgba(59, 65, 75, 1);
margin-left: 8px; font-family: Microsoft YaHei;
color: rgba(255, 255, 255, 1); font-size: 16px;
font-family: Microsoft YaHei; font-weight: 400;
font-size: 14px; line-height: 47px;
font-weight: 400; }
line-height: 22px; .time {
} margin-left: 10px;
} line-height: 47px;
} color: rgba(132, 136, 142, 1);
} font-family: Microsoft YaHei;
.center-footer { font-size: 14px;
margin-top: 21px; font-weight: 400;
height: 450px; }
display: flex; }
.box3 { }
width: 900px; }
height: 450px; .box2-footer {
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); position: absolute;
background: rgba(255, 255, 255, 1); left: 40px;
.box3-header { bottom: 20px;
height: 53px; width: 430px;
border-bottom: 1px solid rgba(240, 242, 244, 1); height: 42px;
margin: 0 auto; display: flex;
display: flex; flex-direction: row;
justify-content: space-between; justify-content: center;
padding: 0 20px; align-items: center;
.box3-header-left { border-radius: 6px;
display: flex; background: rgba(22, 119, 255, 1);
.box3-header-icon { cursor: pointer;
margin-top: 16px; .icon {
width: 19px; width: 16px;
height: 19px; height: 16px;
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.box3-header-title { .text {
margin-top: 16px; margin-left: 8px;
margin-left: 19px; color: rgba(255, 255, 255, 1);
height: 22px; font-family: Microsoft YaHei;
color: rgba(20, 89, 187, 1); font-size: 14px;
font-family: Microsoft YaHei; font-weight: 400;
font-size: 20px; line-height: 22px;
font-weight: 700; }
line-height: 22px; }
} }
} }
.box3-header-right { .divide2 {
display: flex; margin-top: 68px;
justify-content: flex-end; margin-bottom: 36px;
width: 178px; }
height: 22px; .center-center {
.right-box { margin-top: 21px;
display: flex; height: 450px;
margin-top: 16px; display: flex;
width: 89px; .box3 {
height: 22px; width: 792px;
justify-content: flex-end; height: 450px;
.icon1 { box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
margin-top: 5px; background: rgba(255, 255, 255, 1);
width: 12px; .box3-header {
height: 12px; height: 48px;
border-radius: 6px; border-bottom: 1px solid rgba(240, 242, 244, 1);
background: rgba(20, 89, 187, 1); margin: 0 auto;
} display: flex;
.icon2 { justify-content: space-between;
margin-top: 5px; padding: 0 20px;
width: 12px; .box3-header-left {
height: 12px; display: flex;
border-radius: 6px; .box3-header-icon {
background: rgba(250, 140, 22, 1); margin-top: 16px;
} width: 19px;
.text { height: 19px;
margin-left: 5px; img {
color: rgba(95, 101, 108, 1); width: 100%;
font-family: Microsoft YaHei; height: 100%;
font-size: 14px; }
font-weight: 400; }
line-height: 22px; .box3-header-title {
} margin-top: 16px;
} margin-left: 19px;
} height: 22px;
} color: rgba(20, 89, 187, 1);
.box3-main { font-family: Microsoft YaHei;
height: 397px; font-size: 20px;
} font-weight: 700;
} line-height: 22px;
.box4 { }
margin-left: 20px; }
width: 521px; }
height: 450px; .box3-main {
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); height: 402px;
background: rgba(255, 255, 255, 1); overflow-y: auto;
.box4-header { overflow-x: hidden;
width: 521px; padding-top: 6px;
height: 53px; .box3-item {
border-bottom: 1px solid rgba(240, 242, 244, 1); display: flex;
display: flex; height: 77px;
box-sizing: border-box; width: 749px;
padding-left: 22px; margin-left: 21px;
.header-icon { border-bottom: 1px solid rgba(240, 242, 244, 1);
margin-top: 15px; .left {
width: 20px; width: 72px;
height: 20px; height: 48px;
img { margin-top: 15px;
width: 100%; img {
height: 100%; width: 100%;
} height: 100%;
} }
.header-title { }
margin-top: 16px; .right {
margin-left: 18px; width: 657px;
height: 22px; margin-left: 20px;
color: var(--color-main-active); .right-top {
font-family: Microsoft YaHei; width: 657px;
font-size: 20px; display: flex;
font-weight: 700; justify-content: space-between;
line-height: 22px; .title {
} margin-top: 13px;
} width: 520px;
.box4-main { height: 24px;
width: 452px; color: rgba(59, 65, 75, 1);
margin: 0 auto; font-family: Microsoft YaHei;
margin-top: 8px; font-size: 16px;
height: 360px; font-weight: 700;
overflow-y: auto; line-height: 24px;
.box4-main-item { overflow: hidden;
margin-top: 6px; text-overflow: ellipsis;
height: 30px; white-space: nowrap;
display: flex; }
.leftStatus3 { .time {
color: rgba(255, 197, 61, 1) !important; flex: 1;
} text-align: right;
.leftStatus2 { height: 22px;
color: rgba(255, 169, 64, 1) !important; margin-top: 19px;
} color: rgba(95, 101, 108, 1);
.left { font-family: Microsoft YaHei;
width: 44px; font-size: 14px;
text-align: left; font-weight: 400;
font-family: Microsoft YaHei; line-height: 22px;
font-size: 18px; }
font-weight: 700; }
line-height: 30px; .right-footer {
color: rgba(206, 79, 81, 1); width: 657px;
} height: 24px;
.center { color: rgba(59, 65, 75, 1);
width: 300px; font-family: Microsoft YaHei;
color: rgba(95, 101, 108, 1); font-size: 16px;
font-family: Microsoft YaHei; font-weight: 400;
font-size: 16px; line-height: 24px;
font-weight: 400; overflow: hidden;
line-height: 30px; text-overflow: ellipsis;
} white-space: nowrap;
.right { }
width: 108px; }
color: rgba(132, 136, 142, 1); }
font-family: Microsoft YaHei; }
font-size: 14px; }
font-weight: 400; .box4 {
line-height: 30px; margin-left: 20px;
text-align: right; 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;
.home-main-footer { border-bottom: 1px solid rgba(240, 242, 244, 1);
// width: 100%; display: flex;
height: 911px; box-sizing: border-box;
background: rgba(248, 249, 250, 1); padding-left: 22px;
margin-bottom: 20px; .header-icon {
.home-main-footer-header { margin-top: 15px;
margin-top: 37px; width: 20px;
margin-bottom: 36px; height: 20px;
// width: 1600px; img {
height: 62px; width: 100%;
// background: orange; height: 100%;
display: flex; }
justify-content: space-between; }
.btn-wrapper { .header-title {
width: 1300px; margin-top: 16px;
overflow-x: auto; margin-left: 18px;
.btn-box { height: 22px;
display: flex; color: var(--color-main-active);
// justify-content: space-between; font-family: Microsoft YaHei;
max-width: 2000px; font-size: 20px;
.btn { font-weight: 700;
max-width: 100px; line-height: 22px;
min-width: 80px; }
height: 42px; }
margin: 0 5px; .box4-main {
overflow: hidden; height: 402px;
color: rgba(95, 101, 108, 1); overflow-y: auto;
font-family: Microsoft YaHei; box-sizing: border-box;
font-size: 16px; padding-top: 8px;
font-weight: 400; .box4-main-item {
line-height: 42px; margin-top: 16px;
text-align: center; display: flex;
border-radius: 21px; margin-left: 21px;
background: rgba(20, 89, 187, 0); .left {
padding: 0 16px; margin-top: 5px;
cursor: pointer; width: 36px;
&:hover { height: 36px;
background: rgba(20, 89, 187, 0.1); img {
} width: 100%;
} height: 100%;
.btnActive { }
border-radius: 21px; }
background: rgba(20, 89, 187, 1); .right {
color: #fff; margin-left: 10px;
font-weight: 700; width: 690px;
&:hover { box-sizing: border-box;
color: #fff; border: 1px solid rgba(231, 243, 255, 1);
background: rgba(20, 89, 187, 1); background: rgba(246, 250, 255, 1);
} padding: 10px 15px;
} .right-top {
} display: flex;
} justify-content: space-between;
.select-box { .name {
height: 42px; height: 24px;
box-sizing: border-box; color: rgba(59, 65, 75, 1);
padding: 5px 0; font-family: Microsoft YaHei;
} font-size: 16px;
} font-weight: 700;
.home-main-footer-main { line-height: 24px;
width: 100%; }
// background: orange; .time {
display: flex; height: 30px;
flex-wrap: wrap; color: rgba(95, 101, 108, 1);
padding: 5px 10px; font-family: Microsoft YaHei;
// justify-content: space-between; font-size: 16px;
// justify-content: center; font-weight: 400;
overflow-y: auto; line-height: 30px;
height: 820px; }
.main-item { }
width: 240px; .content {
height: 320px; color: rgba(59, 65, 75, 1);
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); font-family: Microsoft YaHei;
background: #fff; font-size: 16px;
margin-bottom: 24px; font-weight: 400;
margin-right: 25px; line-height: 24px;
.main-item-box1 { }
margin-top: 20px; }
margin-left: 45px; }
width: 150px; }
height: 200px; }
box-sizing: border-box; }
border: 1px solid rgba(240, 242, 244, 1); .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;
height: 22px;
.right-box {
display: flex;
margin-top: 16px;
width: 89px;
height: 22px;
justify-content: flex-end;
.icon1 {
margin-top: 5px;
width: 12px;
height: 12px;
border-radius: 6px;
background: rgba(20, 89, 187, 1);
}
.icon2 {
margin-top: 5px;
width: 12px;
height: 12px;
border-radius: 6px;
background: rgba(250, 140, 22, 1);
}
.text {
margin-left: 5px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
}
}
}
.box5-main {
height: 397px;
}
}
.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);
.box6-header {
width: 521px;
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;
}
}
.box6-main {
width: 452px;
height: 402px;
}
}
}
}
}
.home-main-footer {
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;
height: 62px;
// background: orange;
display: flex;
justify-content: space-between;
.btn-wrapper {
width: 1300px;
overflow-x: auto;
.btn-box {
display: flex;
// justify-content: space-between;
max-width: 2000px;
.btn {
max-width: 100px;
min-width: 80px;
height: 42px;
margin: 0 5px;
overflow: hidden;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 42px;
text-align: center;
border-radius: 21px;
background: rgba(20, 89, 187, 0);
padding: 0 16px;
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
}
}
.btnActive {
border-radius: 21px;
background: rgba(20, 89, 187, 1);
color: #fff;
font-weight: 700;
&:hover {
color: #fff;
background: rgba(20, 89, 187, 1);
}
}
}
}
.select-box {
height: 42px;
box-sizing: border-box;
padding: 5px 0;
}
}
.home-main-footer-main {
width: 1600px;
margin: 0 auto;
// background: orange;
display: flex;
flex-wrap: wrap;
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;
margin-right: 25px;
.main-item-box1 {
margin-top: 20px;
margin-left: 45px;
width: 150px;
height: 200px;
box-sizing: border-box;
border: 1px solid rgba(240, 242, 244, 1);
img { img {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
} }
.main-item-box2 { .main-item-box2 {
margin-top: 26px; margin-top: 26px;
text-align: center; text-align: center;
height: 30px; height: 30px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
line-height: 30px; line-height: 30px;
} }
.main-item-box3 { .main-item-box3 {
text-align: center; text-align: center;
height: 30px; height: 30px;
color: rgba(132, 136, 142, 1); color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 30px; line-height: 30px;
} }
} }
} }
} .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;
}
}
}
} }
</style> </style>
\ No newline at end of file
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
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -74,22 +74,36 @@ const setActiveTab = tabName => { ...@@ -74,22 +74,36 @@ const setActiveTab = tabName => {
} }
.tab-item { .tab-item {
padding: 12px 24px; width: 120px;
font-size: 14px; height: 40px;
text-align: center;
line-height: 30px;
// padding: 12px 24px;
font-size: 18px;
color: #606266; color: #606266;
cursor: pointer; cursor: pointer;
border-bottom: 2px solid transparent; border-bottom: 3px solid transparent;
transition: all 0.3s; 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 { .tab-item.active {
color: #409eff; color: var(--color-main-active);
border-bottom-color: #409eff; font-family: Microsoft YaHei;
background-color: rgba(64, 158, 255, 0.1); font-size: 18px;
font-weight: 700;
line-height: 30px;
border-bottom: 3px solid var(--color-main-active);
} }
.tab-item:hover { .tab-item:hover {
color: #409eff; color: var(--color-main-active);
} }
.action-buttons { .action-buttons {
...@@ -99,8 +113,6 @@ const setActiveTab = tabName => { ...@@ -99,8 +113,6 @@ const setActiveTab = tabName => {
.content-section { .content-section {
padding: 24px; padding: 24px;
/* padding-left: 2%;
padding-right: 2%; */
min-height: 400px; min-height: 400px;
} }
...@@ -167,4 +179,5 @@ const setActiveTab = tabName => { ...@@ -167,4 +179,5 @@ const setActiveTab = tabName => {
height: 18px; height: 18px;
} }
} }
</style> </style>
<template> <template>
<div class="home-wrapper"> <div class="home-wrapper">
<div class="home-header">
<span>国家科技安全 </span>> <span>中美博弈概览 </span>>
<span>出口管制 </span>
</div>
<div class="home-main"> <div class="home-main">
<div class="home-main-header"> <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"> <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 <el-input
v-model="searchKey" v-model="searchKey"
style="width: 100%; height: 48px" style="width: 100%; height: 48px"
...@@ -26,19 +18,15 @@ ...@@ -26,19 +18,15 @@
<div class="home-main-header-footer"> <div class="home-main-header-footer">
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">142</div> <div class="item-top">142</div>
<div class="item-footer">总调查案件数</div> <div class="item-footer">实体清单</div>
</div> </div>
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">28</div> <div class="item-top">28</div>
<div class="item-footer">调查中案件数</div> <div class="item-footer">商业管制清单</div>
</div> </div>
<div class="home-main-header-footer-item"> <div class="home-main-header-footer-item">
<div class="item-top">326</div> <div class="item-top">326</div>
<div class="item-footer">涉及中企</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> </div>
</div> </div>
</div> </div>
...@@ -46,7 +34,7 @@ ...@@ -46,7 +34,7 @@
<el-col :span="16"> <el-col :span="16">
<custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px"> <custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px">
<template #header-right> <template #header-right>
<el-button type="primary" link> <el-button type="primary" @click="handleToDetail" link>
{{ "查看详情 >" }} {{ "查看详情 >" }}
</el-button> </el-button>
</template> </template>
...@@ -567,6 +555,12 @@ import shoushiIcon from "./assets/images/shoushi.png"; ...@@ -567,6 +555,12 @@ import shoushiIcon from "./assets/images/shoushi.png";
import tianyiIcon from "./assets/images/tianyi.png"; import tianyiIcon from "./assets/images/tianyi.png";
import aircasIcon from "./assets/images/aircas.png"; import aircasIcon from "./assets/images/aircas.png";
const handleToDetail = () => {
router.push({
path: '/exportControl/analysis'
})
}
const billList = ref([]); const billList = ref([]);
const curBillListIndex = ref(0); const curBillListIndex = ref(0);
...@@ -1408,6 +1402,19 @@ onMounted(async () => { ...@@ -1408,6 +1402,19 @@ onMounted(async () => {
box-shadow: none; 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 { .box1 {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -1832,7 +1839,7 @@ onMounted(async () => { ...@@ -1832,7 +1839,7 @@ onMounted(async () => {
} }
.home-main-header-footer { .home-main-header-footer {
margin-top: 38px; margin-top: 38px;
width: 960px; width: 700px;
height: 64px; height: 64px;
box-sizing: border-box; box-sizing: border-box;
padding: 0 108px; 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({ ...@@ -23,7 +23,10 @@ export default defineConfig({
css: { css: {
preprocessorOptions: { preprocessorOptions: {
scss: { scss: {
additionalData: `@import "@/styles/var.scss";` api: 'modern',
additionalData: `
@use "@/styles/var.scss" as *;
`
} }
} }
}, },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论