提交 cb755878 authored 作者: huhuiqing's avatar huhuiqing

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

...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
...@@ -4139,7 +4140,7 @@ ...@@ -4139,7 +4140,7 @@
}, },
"node_modules/lodash": { "node_modules/lodash": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"license": "MIT" "license": "MIT"
}, },
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1", "highlight.js": "^11.11.1",
"json5": "^2.2.3", "json5": "^2.2.3",
"lodash": "^4.17.21",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"vue": "^3.4.0", "vue": "^3.4.0",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
......
import request from "@/api/request.js";
import {
ElMessage
} from 'element-plus'
const request200 = (requestP) => {
return requestP.then((data) => {
if (data.code === 200) {
return data.data
}
ElMessage({
message: data.message,
type: 'error',
duration: 3 * 1000
})
return null
})
}
// 实体清单总条数统计
/**
* @returns {Promise<number>}
*/
export function getEntitiesDataCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countData',
}))
}
// 最新实体清单信息查询
/**
* @returns {Promise<{
* chNum: number
* entities:{
* entityNameZh: string
* entityName: string
* }[]
* organization:{
* orgName: string
* }
* domains: string[]
* startTime: string
*}>}
*/
export function getEntitiesDataInfo() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/latestInfoSelect',
}))
}
/**
* 每年最多领域及该领域发布次数
* @returns {Promise<{
* year?: number
* maxDomain: string
* maxCount: number
* }[]>}
*/
export function getIndustryCountByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/industryCountByYear',
}))
}
/**
* 不同领域每年数量
* @returns {Promise<{
* data:{
* year?: number
* domainNum: {
* [ key: string]: number;
* }
* }[]
* domains: string[]
* }>}
*/
export function getCountDomainByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countDomainByYear',
}))
}
/**
* 历次制裁过程(月份统计)
* @returns {Promise<{
* tittle: string
* entitiesChNum: string
* sanReason: string
* }[]>}
*/
export function getSanctionsInfoCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/sanctionsInfoCount',
}))
}
/**
* 查询发布机构
* @returns {Promise<{
* orgName: string //机构名称
* orgIntroduction: string //相关措施
* orgIntroduction: string //机构职责
* }>}
*/
export function getOrganizationInfo() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/getOrganizationInfo',
}))
}
/**
* 查询重点人物
* @returns {Promise<{
* name: string
* ename: string
* avatarUrl: string
* positionTitle: string
* }[]>}
*/
export function getPersonList() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/getPersonList',
}))
}
/**
* 不同领域实体统计
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* domain: string
* count: number
* }[]>}
*/
export function getCountByDomain(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countByDomain',
params: {
startTime
}
}))
}
/**
* 不同类型实体统计
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* type: string
* count: number
* }[]>}
*/
export function getCountByType(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countByType',
params: {
startTime
}
}))
}
/**
* 查询制裁原因
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<string[]>}
*/
export function getSanReasonSelect(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/sanReasonSelect',
params: {
startTime
}
}))
}
/**
* 查询实体清单列表
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* entityNameZh: string
* techDomainList: string[]
* startTime: staring
* }[]>}
*/
export function getSelectEntitiesList(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataInfo/selectEntitiesList',
params: {
startTime
}
}))
}
/**
* 数量比对分析
* @param {string} startTime - 统计开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* countDomainLast: number
* countDomainNow: number
* countSanLast: number
* countSanNow: number
* countTypeLast: number
* countTypeNow: number
* }>}
*/
export function getCompareCountSan(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/compareCountSan',
params: {
startTime
}
}))
}
/**
* 实体清单变化统计
* @param {number} domain
* @param {number} type
* @returns {Promise<{
* year:number
* count:number
* }[]>}
*/
export function getEntitiesChangeCount(domain, type) {
return request200(request({
method: 'GET',
// url: '/api/entitiesDataCount/entitiesChangeCount',
url: '/api/entitiesDataCount/sanCountByYear',
params: {
domain,
type
}
}))
}
/**
* 新增实体数量增长趋势
* @returns {Promise<{
* year: string
* percent: string //百分比'20%'
* }>}
*/
export function getEntitiesGrowthTrend() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesGrowthTrend',
}))
}
/**
* 实体清单更新频率
* @returns {Promise<{
* series: number[]
* xAxis: string[]
* }>}
*/
export function getEntitiesUpdateCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesUpdateCount',
}))
}
/**
* 新增实体领域分布情况
* @param {string} sanTime - 开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* value: number
* name: string
* }[]>}
*/
export function getEntitiesAreaCountByYear(sanTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesAreaCountByYear',
params: {
sanTime
}
}))
}
/**
* 历次制裁涉及领域数
* @returns {Promise<{
* series: number[]
* xAxis: string[]
* }>}
*/
export function getEntitiesDomainCount() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/entitiesDomainCount'
}))
}
/**
* 指定领域每年实体数量查询
* @param {string} param
* @returns {Promise<{
* year: string
* count: number
* }[]>}
*/
export function getCountThisDomain(param) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countThisDomain',
params: {
param
}
}))
}
/**
* 历次制裁涉及类别数量
* @returns {Promise<{
* year: string
* count: number
* }[]>}
*/
export function getCountTypeByYear() {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countTypeByYear',
}))
}
/**
* 新增实体类别统计
* @param {string} startTime - 开始时间,格式为 'YYYY-MM-DD'
* @returns {Promise<{
* type: string
* count: number
* }[]>}
*/
export function getCountSanTypeByTime(startTime) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countSanTypeByTime',
params: {
startTime
}
}))
}
/**
* 指定类别每年实体数量查询
* @param {string} param
* @returns {Promise<{
* year: number
* count: number
* }[]>}
*/
export function getCountThisType(param) {
return request200(request({
method: 'GET',
url: '/api/entitiesDataCount/countThisType',
params: {
param
}
}))
}
import { ref } from 'vue';
export function useRequest(apiFunction, immediate = true) {
const data = ref(null);
const loading = ref(false);
const error = ref(null);
const execute = async (...args) => {
loading.value = true;
error.value = null;
try {
data.value = await apiFunction(...args);
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
};
if (immediate) {
execute(); // 可选:是否立即执行
}
return {
data,
loading,
error,
execute, // 手动触发函数
};
}
\ No newline at end of file
...@@ -13,6 +13,7 @@ const routes = [ ...@@ -13,6 +13,7 @@ const routes = [
...fileRoutes, ...fileRoutes,
]; ];
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
routes routes
......
...@@ -14,7 +14,7 @@ const cooperationRestrictionsRoutes = [ ...@@ -14,7 +14,7 @@ const cooperationRestrictionsRoutes = [
}, },
// 合作限制详情 // 合作限制详情
{ {
path: "/coopRestriction/detail", path: "/cooperationRestrictions/detail",
name: "CooperationRestrictionsDetail", name: "CooperationRestrictionsDetail",
component: CooperationRestrictionsDetail, component: CooperationRestrictionsDetail,
meta: { meta: {
......
// 规则限制
import RuleRestriction from "@/views/ruleRestriction/index.vue";
import RuleRestrictionDetail from "@/views/ruleRestriction/detail/index.vue";
const ruleRestrictionsRoutes = [
// 规则限制
{
path: "/ruleRestrictions",
name: "RuleRestrictions",
component: RuleRestriction,
meta: {
title: "规则限制"
}
},
// 规则限制详情
{
path: "/ruleRestrictions/detail",
name: "RuleRestrictionsDetail",
component: RuleRestrictionDetail,
meta: {
title: "规则限制详情"
}
},
]
export default ruleRestrictionsRoutes
// 科研资助体系
import ScientificFunding from "@/views/scientificFunding/index.vue";
const scientificFundingRoutes = [
// 科研资助体系
{
path: "/scientificFunding",
name: "ScientificFunding",
component: ScientificFunding,
meta: {
title: "科研资助体系"
}
}
]
export default scientificFundingRoutes
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="left-title"> <div class="left-title">
<img src="./assets/icon01.png" alt=""> <img src="./assets/icon01.png" alt="">
<div class="tit">新闻资讯</div> <div class="tit">新闻资讯</div>
<div class="more">更多 +</div> <div class="more" @click="handleToMoreNews">更多 +</div>
</div> </div>
<div class="left-main"> <div class="left-main">
<div v-for="item in leftList" :key="item.id" class="main-item"> <div v-for="item in leftList" :key="item.id" class="main-item">
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import router from '@/router'
import image01 from './assets/image01.png' import image01 from './assets/image01.png'
import image02 from './assets/image02.png' import image02 from './assets/image02.png'
import image03 from './assets/image03.png' import image03 from './assets/image03.png'
...@@ -128,6 +129,12 @@ const rightList = ref([ ...@@ -128,6 +129,12 @@ const rightList = ref([
} }
]) ])
// 查看更多新闻资讯
const handleToMoreNews = () => {
const route = router.resolve("/newsBrief");
window.open(route.href, "_blank");
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
......
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
</div> </div>
</div> </div>
<div style="margin: 6px 34px 0 23px"> <div style="margin: 6px 34px 0 23px">
<div v-for="item in list" :key="item.id" class="right-main"> <div v-for="item in list" :key="item.id" class="right-main" @click="handleClickToDetail()">
<div class="main-left" :class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险' }"> <div class="main-left" :class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险' }">
{{ item.title }} {{ item.title }}
</div> </div>
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
<div class="main-right">{{ item.time }}</div> <div class="main-right">{{ item.time }}</div>
</div> </div>
</div> </div>
<div class="right-mainbtn"> <div class="right-mainbtn" @click="handleToMoreRiskSignal">
<img src="./assets/btn.png" alt="" /> <img src="./assets/btn.png" alt="" />
查看更多 查看更多
</div> </div>
...@@ -76,6 +76,7 @@ ...@@ -76,6 +76,7 @@
<script setup> <script setup>
import { ref } from "vue"; import { ref } from "vue";
import router from "@/router";
const list = ref([ const list = ref([
{ {
...@@ -103,6 +104,20 @@ const list = ref([ ...@@ -103,6 +104,20 @@ const list = ref([
time: "一天前" time: "一天前"
} }
]); ]);
// 点击查看详情
const handleClickToDetail = () => {
// router.push("/decreeLayout");
const curRoute = router.resolve("/cooperationRestrictions/detail");
window.open(curRoute.href, "_blank");
};
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
window.open(route.href, "_blank");
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
...@@ -340,11 +355,16 @@ const list = ref([ ...@@ -340,11 +355,16 @@ const list = ref([
} }
} }
.right-main { .right-main {
width: 463px; width: 468px;
padding-right: 5px;
height: 47px; height: 47px;
border-radius: 2px; border-radius: 2px;
display: flex; display: flex;
align-items: center; align-items: center;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.main-left { .main-left {
width: 40px; width: 40px;
height: 40px; height: 40px;
......
...@@ -36,47 +36,47 @@ ...@@ -36,47 +36,47 @@
</div> </div>
</div> </div>
<div class="search-bottom"> <div class="search-bottom">
<div class="btn"> <div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div> <div class="btn-text">最新动态</div>
<div class="btn-icon">></div> <div class="btn-icon">></div>
</div> </div>
<div class="btn"> <div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">咨询要闻</div> <div class="btn-text">咨询要闻</div>
<div class="btn-icon">></div> <div class="btn-icon">></div>
</div> </div>
<div class="btn"> <div class="btn" @click="scrollToTop('position3')">
<div class="btn-text">数据总览</div> <div class="btn-text">数据总览</div>
<div class="btn-icon">></div> <div class="btn-icon">></div>
</div> </div>
<div class="btn"> <div class="btn" @click="scrollToTop('position4')">
<div class="btn-text">资源库</div> <div class="btn-text">资源库</div>
<div class="btn-icon">></div> <div class="btn-icon">></div>
</div> </div>
</div> </div>
</div> </div>
<!-- 最新动态 --> <!-- 最新动态 -->
<div class="newdata"> <div class="newdata" id="position1">
<com-title title="最新动态" /> <com-title title="最新动态" />
<div class="newdata-main"> <div class="newdata-main">
<newData /> <newData />
</div> </div>
</div> </div>
<!-- 资讯要问 --> <!-- 资讯要问 -->
<div class="ask"> <div class="ask" id="position2">
<com-title title="咨询要闻" /> <com-title title="咨询要闻" />
<div class="ask-main"> <div class="ask-main">
<askPage /> <askPage />
</div> </div>
</div> </div>
<!-- 数据总览 --> <!-- 数据总览 -->
<div class="datasub"> <div class="datasub" id="position3">
<com-title title="数据总览" /> <com-title title="数据总览" />
<div class="datasub-main"> <div class="datasub-main">
<dataSub /> <dataSub />
</div> </div>
</div> </div>
<!-- 资源库 --> <!-- 资源库 -->
<div class="reslib"> <div class="reslib" id="position4">
<com-title title="资源库" /> <com-title title="资源库" />
<div class="reslib-main"> <div class="reslib-main">
<resLib /> <resLib />
...@@ -94,6 +94,7 @@ import newData from "./components/dataNew/index.vue"; ...@@ -94,6 +94,7 @@ import newData from "./components/dataNew/index.vue";
import askPage from "./components/askPage/index.vue"; import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue"; import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue"; import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
...@@ -153,6 +154,7 @@ const handleBackHome = () => { ...@@ -153,6 +154,7 @@ const handleBackHome = () => {
width: 960px; width: 960px;
height: 225px; height: 225px;
margin: 0 auto 68px auto; margin: 0 auto 68px auto;
.search-main { .search-main {
display: flex; display: flex;
padding-right: 3px; padding-right: 3px;
...@@ -163,11 +165,14 @@ const handleBackHome = () => { ...@@ -163,11 +165,14 @@ const handleBackHome = () => {
height: 48px; height: 48px;
background-color: rgba(255, 255, 255, 0.65); background-color: rgba(255, 255, 255, 0.65);
border-radius: 10px; border-radius: 10px;
border: 1px solid #fff; border: 1px solid transparent;
&:hover {
border: 1px solid var(--color-main-active);
}
.search-input { .search-input {
border: none; border: none;
outline: none; outline: none;
width: 800px; width: 838px;
height: 48px; height: 48px;
background-color: transparent; background-color: transparent;
font-size: 16px; font-size: 16px;
...@@ -178,12 +183,13 @@ const handleBackHome = () => { ...@@ -178,12 +183,13 @@ const handleBackHome = () => {
color: rgb(132, 136, 142); color: rgb(132, 136, 142);
} }
.search-btn { .search-btn {
margin-right: -3px;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 120px; width: 120px;
height: 42px; height: 46px;
border-radius: 8px; border-radius: 8px;
background-color: rgb(5, 95, 194); background-color: rgb(5, 95, 194);
font-size: 18px; font-size: 18px;
......
...@@ -6,18 +6,20 @@ ...@@ -6,18 +6,20 @@
<el-select <el-select
:style="{ width: '120px', marginRight: '8px' }" :style="{ width: '120px', marginRight: '8px' }"
size="mini" size="mini"
v-model="value1" v-model="domainValue"
placeholder="领域选择" placeholder="领域选择"
> >
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> <el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select> </el-select>
<el-select <el-select
:style="{ width: '120px', marginRight: '18px' }" :style="{ width: '120px', marginRight: '18px' }"
size="mini" size="mini"
v-model="value2" v-model="typeValue"
placeholder="类型选择" placeholder="类型选择"
> >
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option> <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select> </el-select>
</template> </template>
<div class="subPanel1"> <div class="subPanel1">
...@@ -82,28 +84,169 @@ ...@@ -82,28 +84,169 @@
</template> </template>
<script setup> <script setup>
import { ref, shallowRef, onMounted } from "vue"; import { ref, shallowRef, onMounted, watch } from "vue";
import CardCustom from "../../components/CardCustom.vue"; import CardCustom from "../../components/CardCustom.vue";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart } from "../../utils/charts"; import { getBarChart, getLineChart } from "../../utils/charts";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
const options = [ import { getEntitiesChangeCount, getEntitiesGrowthTrend, getEntitiesUpdateCount } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const line1Option = shallowRef({});
const bar2Option = shallowRef({});
onMounted(async () => {
try {
const [entitiesGrowthTrendData, entitiesUpdateCountData] = await Promise.all([
getEntitiesGrowthTrend(),
getEntitiesUpdateCount()
]);
const list = _.reverse(entitiesGrowthTrendData);
const xAxisData = _.map(list, "year");
const seriesData = _.map(list, item => {
return parseInt(item.percent);
});
line1Option.value = getLineChart({ xAxisData, seriesData, name: "增长趋势", color: "rgba(146, 84, 222, 1)" }, true);
bar2Option.value = getBarChart(
_.reverse(entitiesUpdateCountData.xAxis),
_.reverse(entitiesUpdateCountData.series),
["rgba(22, 119, 255, 1)", "rgba(22, 119, 255, 0)"],
"更新频率"
);
} catch (err) {
console.log(err);
}
});
const domainOptions = [
{ {
value: "1", value: "1",
label: "人工智能" label: "人工智能"
}, },
{ {
value: "2", value: "2",
label: "生物科技"
},
{
value: "3",
label: "新一代信息技术"
},
{
value: "4",
label: "量子科技"
},
{
value: "5",
label: "新能源"
},
{
value: "6",
label: "集成电路"
},
{
value: "7",
label: "海洋"
},
{
value: "8",
label: "先进制造"
},
{
value: "9",
label: "新材料"
},
{
value: "10",
label: "航空航天" label: "航空航天"
},
{
value: "11",
label: "深海"
},
{
value: "12",
label: "极地"
},
{
value: "13",
label: "太空"
},
{
value: "14",
label: "核"
},
{
value: "20",
label: "政治"
},
{
value: "21",
label: "外交"
},
{
value: "22",
label: "经济"
},
{
value: "23",
label: "军事"
},
{
value: "24",
label: "科技"
},
{
value: "25",
label: "安全"
},
{
value: "99",
label: "其他"
} }
]; ];
const value1 = ref(""); const typeOptions = [
const value2 = ref(""); {
const value3 = ref(""); value: "1",
label: "人物"
},
{
value: "2",
label: "机构"
},
{
value: "7",
label: "地址"
}
];
const domainValue = ref(domainOptions[0].value);
const typeValue = ref(typeOptions[0].value);
const bar1Option = shallowRef({}); const bar1Option = shallowRef({});
const bar2Option = shallowRef({}); watch(
const line1Option = shallowRef({}); [domainValue, typeValue],
async ([domain, type]) => {
let EntitiesChangeCount = await getEntitiesChangeCount(domain, type);
EntitiesChangeCount = _.reverse(EntitiesChangeCount);
bar1Option.value = getBarChart(
_.map(EntitiesChangeCount, "year"),
_.map(EntitiesChangeCount, "count"),
["rgba(255, 159, 22, 1)", "rgba(255, 159, 22, 0)"],
"制裁强度"
);
},
{ immediate: true }
);
// const options = [
// {
// value: "1",
// label: "人工智能"
// },
// {
// value: "2",
// label: "航空航天"
// }
// ];
const subPanel4 = ref([ const subPanel4 = ref([
{ {
name: "中国科学技术大学", name: "中国科学技术大学",
...@@ -141,21 +284,7 @@ const subPanel4 = ref([ ...@@ -141,21 +284,7 @@ const subPanel4 = ref([
] ]
} }
]); ]);
onMounted(() => { const value3 = ref("");
bar1Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[219, 228, 129, 159, 152, 157, 78, 34, 56, 78],
["rgba(255, 159, 22, 1)", "rgba(255, 159, 22, 0)"],
"制裁强度"
);
bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
["rgba(22, 119, 255, 1)", "rgba(22, 119, 255, 0)"],
"更新频率"
);
line1Option.value = getLineChart();
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
......
...@@ -121,9 +121,14 @@ onMounted(() => { ...@@ -121,9 +121,14 @@ onMounted(() => {
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"], ["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28], [39, 28, 49, 19, 22, 25, 78, 34, 56, 28],
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"], ["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率" "市值变化"
); );
line1Option.value = getLineChart(); line1Option.value = getLineChart({
xAxisData: [2013, 2023, 2024, 2015],
seriesData: [434, 24, 453, 322],
name: "融资变化",
color: "rgba(146, 84, 222, 1)"
});
}); });
</script> </script>
......
...@@ -46,30 +46,51 @@ import { Search } from "@element-plus/icons-vue"; ...@@ -46,30 +46,51 @@ import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts"; import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
import { getEntitiesAreaCountByYear, getEntitiesDomainCount, getCountThisDomain } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({}); const pie1Option = shallowRef({});
const bar2Option = shallowRef({}); const bar2Option = shallowRef({});
const line1Option = shallowRef({}); const line1Option = shallowRef({});
const line2Option = shallowRef({}); const line2Option = shallowRef({});
onMounted(() => {
pie1Option.value = getPieOption1( onMounted(async () => {
[ try {
{ name: "半导体与集成电路领域", value: 50 }, const [entitiesAreaCountByYearData, countThisDomainData4, entitiesDomainCountData, countThisDomainData10] =
{ name: "生物技术与生命科学领域", value: 46 }, await Promise.all([
{ name: "航天遥感与量子技术领域", value: 12 }, getEntitiesAreaCountByYear(route.query.startTime),
{ name: "航空航天领域", value: 32 }, getCountThisDomain("4"),
{ name: "人工智能领域", value: 31 }, getEntitiesDomainCount(),
{ name: "供应链与物流服务领域", value: 30 }, getCountThisDomain("10")
{ name: "工业软件领域", value: 24 } ]);
]
); pie1Option.value = getPieOption1(entitiesAreaCountByYearData ?? []);
const list4 = _.reverse(countThisDomainData4 ?? []);
line1Option.value = getLineChart({
xAxisData: _.map(list4, "year"),
seriesData: _.map(list4, "count"),
name: "量子科技领域",
color: "rgba(255, 149, 77, 1)"
});
bar2Option.value = getBarChart( bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"], _.reverse(entitiesDomainCountData?.xAxis ?? []),
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28], _.reverse(entitiesDomainCountData?.series ?? []),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"], ["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率" "领域数"
); );
line1Option.value = getLineChart("rgba(255, 149, 77, 1)");
line2Option.value = getLineChart("rgba(146, 84, 222, 1)"); const list10 = _.reverse(countThisDomainData10 ?? []);
line2Option.value = getLineChart({
xAxisData: _.map(list10, "year"),
seriesData: _.map(list10, "count"),
name: "航空航天领域",
color: "rgba(146, 84, 222, 1)"
});
} catch (err) {
console.log(err);
}
}); });
</script> </script>
......
...@@ -46,28 +46,58 @@ import { Search } from "@element-plus/icons-vue"; ...@@ -46,28 +46,58 @@ import { Search } from "@element-plus/icons-vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts"; import { getBarChart, getLineChart, getPieOption1 } from "../../utils/charts";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
import { getCountSanTypeByTime, getCountTypeByYear, getCountThisType } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({}); const pie1Option = shallowRef({});
const bar2Option = shallowRef({}); const bar2Option = shallowRef({});
const line1Option = shallowRef({}); const line1Option = shallowRef({});
const line2Option = shallowRef({}); const line2Option = shallowRef({});
onMounted(() => { onMounted(async () => {
try {
const [countSanTypeByTimeData, countThisTypeData1, countTypeByYearData, countThisTypeData2] = await Promise.all([
getCountSanTypeByTime(route.query.startTime),
getCountThisType("1"),
getCountTypeByYear(),
getCountThisType("2")
]);
pie1Option.value = getPieOption1( pie1Option.value = getPieOption1(
[ _.map(countSanTypeByTimeData ?? [], item => {
{ name: "企业", value: 50 }, return {
{ name: "科研院所", value: 40 }, name: item?.type,
{ name: "高校", value: 32 }, value: item?.count
{ name: "政府官员", value: 30 }, };
{ name: "个人", value: 24}, })
]
); );
const list1 = _.reverse(countThisTypeData1 ?? []);
line1Option.value = getLineChart({
xAxisData: _.map(list1, "year"),
seriesData: _.map(list1, "count"),
name: "科研院所类",
color: "rgba(255, 149, 77, 1)"
});
const list = _.reverse(countTypeByYearData ?? []);
bar2Option.value = getBarChart( bar2Option.value = getBarChart(
["2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"], _.map(list, "year"),
[39, 28, 49, 19, 22, 25, 78, 34, 56, 28], _.map(list, "count"),
["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"], ["rgba(19, 188, 196, 1)", "rgba(19, 188, 196, 0)"],
"更新频率" "实体数"
); );
line1Option.value = getLineChart("rgba(255, 149, 77, 1)");
line2Option.value = getLineChart("rgba(146, 84, 222, 1)"); const list2 = _.reverse(countThisTypeData2 ?? []);
line2Option.value = getLineChart({
xAxisData: _.map(list2, "year"),
seriesData: _.map(list2, "count"),
name: "企业类",
color: "rgba(117, 29, 219, 1)"
});
} catch (err) {
console.log(err);
}
}); });
</script> </script>
......
...@@ -13,31 +13,70 @@ ...@@ -13,31 +13,70 @@
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import { getPieOption } from "../../utils/charts"; import { getPieOption } from "../../utils/charts";
import { ref, onMounted, shallowRef } from "vue"; import { ref, onMounted, shallowRef } from "vue";
import { getCountByDomain, getCountByType } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
const route = useRoute();
const pie1Option = shallowRef({}); const pie1Option = shallowRef({});
const pie2Option = shallowRef({}); const pie2Option = shallowRef({});
onMounted(() => { onMounted(async () => {
try {
const [countByDomainData, countByTypeData] = await Promise.all([
getCountByDomain(route.query.startTime),
getCountByType(route.query.startTime)
]);
pie1Option.value = getPieOption( pie1Option.value = getPieOption(
[ _.chain(countByDomainData)
{ name: "能源领域", value: 30 }, .filter(item => item.count > 0)
{ name: "集成电路领域", value: 20 }, .map(item => {
{ name: "人工智能领域", value: 12 }, return {
{ name: "通信网络领域", value: 18 }, name: item?.domain,
{ name: "量子科技领域", value: 10 }, value: item?.count
{ name: "生物科技领域", value: 10 } };
], })
.value(),
"领域分布" "领域分布"
); );
pie2Option.value = getPieOption( pie2Option.value = getPieOption(
[ _.chain(countByTypeData)
{ name: "能源领域", value: 30 }, .filter(item => item.count > 0)
{ name: "集成电路领域", value: 20 }, .map(item => {
{ name: "人工智能领域", value: 12 }, return {
{ name: "通信网络领域", value: 18 }, name: item?.type,
{ name: "量子科技领域", value: 10 }, value: item?.count
{ name: "生物科技领域", value: 10 } };
], })
"类别分布" .value(),
"类型分布"
); );
} catch (err) {
console.log(err);
}
});
onMounted(() => {
// pie1Option.value = getPieOption(
// [
// { name: "能源领域", value: 30 },
// { name: "集成电路领域", value: 20 },
// { name: "人工智能领域", value: 12 },
// { name: "通信网络领域", value: 18 },
// { name: "量子科技领域", value: 10 },
// { name: "生物科技领域", value: 10 }
// ],
// "领域分布"
// );
// pie2Option.value = getPieOption(
// [
// { name: "能源领域", value: 30 },
// { name: "集成电路领域", value: 20 },
// { name: "人工智能领域", value: 12 },
// { name: "通信网络领域", value: 18 },
// { name: "量子科技领域", value: 10 },
// { name: "生物科技领域", value: 10 }
// ],
// "类别分布"
// );
}); });
</script> </script>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<div <div
class="item" class="item"
:class="{ activeItem: activePanelId === item.id }" :class="{ activeItem: activePanelId === item.id }"
v-for="item in panelListData" v-for="item in compareCountSan"
:key="item.id" :key="item.id"
@click="setActivePanelId(item.id)" @click="setActivePanelId(item.id)"
> >
...@@ -44,51 +44,67 @@ ...@@ -44,51 +44,67 @@
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<panel1 v-if="activePanelId === panelListData[0].id"></panel1> <panel1 v-if="activePanelId === compareCountSan[0]?.id"></panel1>
<panel2 v-if="activePanelId === panelListData[1].id"></panel2> <panel2 v-if="activePanelId === compareCountSan[1]?.id"></panel2>
<panel3 v-if="activePanelId === panelListData[2].id"></panel3> <panel3 v-if="activePanelId === compareCountSan[2]?.id"></panel3>
<panel4 v-if="activePanelId === panelListData[3].id"></panel4> <panel4 v-if="activePanelId === compareCountSan[3]?.id"></panel4>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onMounted, shallowRef } from "vue";
import Panel1 from "../components/panel1.vue"; import Panel1 from "../components/panel1.vue";
import Panel2 from "../components/panel2.vue"; import Panel2 from "../components/panel2.vue";
import Panel3 from "../components/panel3.vue"; import Panel3 from "../components/panel3.vue";
import Panel4 from "../components/panel4.vue"; import Panel4 from "../components/panel4.vue";
const panelListData = [ import { getCompareCountSan } from "@/api/exportControl";
import { useRoute } from "vue-router";
const route = useRoute();
const compareCountSan = shallowRef([]);
const activePanelId = ref(null);
onMounted(async () => {
try {
const [compareCountSanData] = await Promise.all([getCompareCountSan(route.query.startTime)]);
const { countSanNow, countSanLast, countDomainNow, countDomainLast, countTypeNow, countTypeLast } =
compareCountSanData ?? {};
compareCountSan.value = [
{ {
id: 1, id: 1,
name: "新增实体数量", name: "新增实体数量",
number: "37", number: countSanNow,
isUp: true, isUp: countSanNow - countSanLast >= 0,
ComparisonNumber: "31" ComparisonNumber: Math.abs(countSanNow - countSanLast)
}, },
{ {
id: 2, id: 2,
name: "上市企业数量", name: "上市企业数量",
number: "6", number: "--",
isUp: true, isUp: true,
ComparisonNumber: "2" ComparisonNumber: "--"
}, },
{ {
id: 3, id: 3,
name: "涉及领域数量", name: "涉及领域数量",
number: "2", number: countDomainNow,
isUp: false, isUp: countDomainNow - countDomainLast >= 0,
ComparisonNumber: "1" ComparisonNumber: Math.abs(countDomainNow - countDomainLast)
}, },
{ {
id: 4, id: 4,
name: "实体类别数量", name: "实体类别数量",
number: "4", number: countTypeNow,
isUp: true, isUp: countTypeNow - countTypeLast >= 0,
ComparisonNumber: "1" ComparisonNumber: Math.abs(countTypeNow - countTypeLast)
} }
]; ];
const activePanelId = ref(panelListData[0].id); activePanelId.value = compareCountSan.value[0].id;
} catch (err) {
console.log(err);
}
});
const setActivePanelId = id => { const setActivePanelId = id => {
activePanelId.value = id; activePanelId.value = id;
}; };
......
...@@ -3,26 +3,26 @@ ...@@ -3,26 +3,26 @@
<div class="row"> <div class="row">
<CardCustom title="实体清单发布机构" :style="{ width: '984px', height: '284px' }"> <CardCustom title="实体清单发布机构" :style="{ width: '984px', height: '284px' }">
<div class="panel1"> <div class="panel1">
<img :src="panel1.img" alt="" class="img" /> <img :src="organizationInfo.img" alt="" class="img" />
<div class="infoWrap"> <div class="infoWrap">
<div class="item"> <div class="item">
<div class="name">机构名称:</div> <div class="name">机构名称:</div>
<div class="doc">{{ panel1.mingcheng }}</div> <div class="doc">{{ organizationInfo.mingcheng }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="name">相关措施:</div> <div class="name">相关措施:</div>
<div class="doc">{{ panel1.cuoshi }}</div> <div class="doc">{{ organizationInfo.cuoshi }}</div>
</div> </div>
<div class="item"> <div class="item">
<div class="name">机构职责:</div> <div class="name">机构职责:</div>
<div class="doc zhize">{{ panel1.zhize }}</div> <div class="doc zhize">{{ organizationInfo.zhize }}</div>
</div> </div>
</div> </div>
</div> </div>
</CardCustom> </CardCustom>
<CardCustom title="重点人物" :style="{ width: '600px', height: '284px' }"> <CardCustom title="重点人物" :style="{ width: '600px', height: '284px' }">
<div class="panel2"> <div class="panel2">
<div class="item" v-for="(item, index) in panel2" :key="index"> <div class="item" v-for="(item, index) in personLis" :key="index">
<img :src="item.img" alt="" class="img" /> <img :src="item.img" alt="" class="img" />
<div class="infoWrap"> <div class="infoWrap">
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
</CardCustom> </CardCustom>
<CardCustom title="制裁原因" :style="{ width: '600px', height: '520px' }"> <CardCustom title="制裁原因" :style="{ width: '600px', height: '520px' }">
<div class="panel4"> <div class="panel4">
<div class="item" v-for="(item, index) in panel4" :key="index"> <div class="item" v-for="(item, index) in sanReasonSelect" :key="index">
<div class="icon1">{{ index + 1 }}</div> <div class="icon1">{{ index + 1 }}</div>
<div class="text">{{ item.text }}</div> <div class="text">{{ item.text }}</div>
<div class="icon2"></div> <div class="icon2"></div>
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
</div> </div>
<div class="tableWrap"> <div class="tableWrap">
<el-table <el-table
:data="panel5MockData" :data="selectEntitiesList"
class="sanction-table" class="sanction-table"
stripe stripe
empty-text="暂无数据" empty-text="暂无数据"
...@@ -106,7 +106,10 @@ ...@@ -106,7 +106,10 @@
<el-table-column prop="name" label="实体清单" min-width="180"> <el-table-column prop="name" label="实体清单" min-width="180">
<template #default="{ row }"> <template #default="{ row }">
<div style="font-weight: 500" class="name"> <div style="font-weight: 500" class="name">
<img :src="row.img" alt="" class="img" /> <img v-if="row.img" :src="row.img" alt="" class="img" />
<div v-else class="imgUndefined">
{{ row.name?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
{{ row.name }} {{ row.name }}
</div> </div>
</template> </template>
...@@ -122,7 +125,7 @@ ...@@ -122,7 +125,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="address" label="上市地点" width="100" align="center"> <el-table-column prop="address" label="上市地点" width="90" align="center">
<template #default="{ row }"> <template #default="{ row }">
{{ row.address }} {{ row.address }}
</template> </template>
...@@ -180,8 +183,7 @@ import PieCharts from "../components/pieCharts.vue"; ...@@ -180,8 +183,7 @@ import PieCharts from "../components/pieCharts.vue";
import MapCharts from "../components/mapCharts.vue"; import MapCharts from "../components/mapCharts.vue";
import ButtonList from "@/components/buttonList/buttonList.vue"; import ButtonList from "@/components/buttonList/buttonList.vue";
import Hint from "../components/hint.vue"; import Hint from "../components/hint.vue";
import { onMounted, reactive, ref, shallowRef } from "vue";
import { onMounted, reactive, ref } from "vue";
import panel1_1 from "../../assets/images/panel1_1.png"; import panel1_1 from "../../assets/images/panel1_1.png";
import panel2_1 from "../../assets/images/panel2_1.png"; import panel2_1 from "../../assets/images/panel2_1.png";
import panel2_2 from "../../assets/images/panel2_2.png"; import panel2_2 from "../../assets/images/panel2_2.png";
...@@ -195,43 +197,39 @@ import panel5_5 from "../../assets/images/panel5_5.png"; ...@@ -195,43 +197,39 @@ import panel5_5 from "../../assets/images/panel5_5.png";
import panel5_6 from "../../assets/images/panel5_6.png"; import panel5_6 from "../../assets/images/panel5_6.png";
import panel5_7 from "../../assets/images/panel5_7.png"; import panel5_7 from "../../assets/images/panel5_7.png";
import panel5_8 from "../../assets/images/panel5_8.png"; import panel5_8 from "../../assets/images/panel5_8.png";
const panel1 = ref({ import { getOrganizationInfo, getPersonList, getSanReasonSelect, getSelectEntitiesList } from "@/api/exportControl";
img: panel1_1, import _ from "lodash";
mingcheng: "美国商务部工业与安全局", import { useRoute } from "vue-router";
cuoshi: "出口管制条例(EAR)、实体清单、商业管制清单(CCL)、232调查等", import { formatAnyDateToChinese } from "../../utils";
zhize: "美国商务部工业与安全局(BIS)是美国商务部下属机构,核心职责围绕国家安全与战略技术管控展开,具体包括:以维护商业管制清单(CCL)和出口管制分类号(ECCN)的方式,对敏感货物及两用技术实施出口管制并确定许可要求;通过出口执行局(OEE)执行出口管制、反抵制等相关法律,对违规行为采取行政、刑事等处罚措施;在出口管制和战略贸易问题上与其他国家合作,参与并领导国际出口管制制度。" const route = useRoute();
}); const organizationInfo = shallowRef({});
const panel2 = ref([ const personLis = shallowRef([
{ // {
name: "吉娜·雷蒙多", // name: "吉娜·雷蒙多",
enName: "Gina Raimondo", // enName: "Gina Raimondo",
party: "美国民主党", // party: "美国民主党",
img: panel2_1 // img: panel2_1
}, // },
{ // {
name: "迈克・约翰逊", // name: "迈克・约翰逊",
enName: "Mike Johnson", // enName: "Mike Johnson",
party: "美国共和党", // party: "美国共和党",
img: panel2_2 // img: panel2_2
}, // },
{ // {
name: "艾伦·埃斯特韦斯", // name: "艾伦·埃斯特韦斯",
enName: "Alan Estevez", // enName: "Alan Estevez",
party: "美国民主党", // party: "美国民主党",
img: panel2_3 // img: panel2_3
}, // },
{ // {
name: "凯・格兰杰", // name: "凯・格兰杰",
enName: "Kay Granger", // enName: "Kay Granger",
party: "美国共和党", // party: "美国共和党",
img: panel2_4 // img: panel2_4
} // }
]); ]);
const panel3ActiveIndex = ref(1); const sanReasonSelect = shallowRef([
const setPanel3ActiveIndex = index => {
panel3ActiveIndex.value = index;
};
const panel4 = ref([
{ {
text: "获取美国产物项,以支持中国量子技术;" text: "获取美国产物项,以支持中国量子技术;"
}, },
...@@ -248,6 +246,54 @@ const panel4 = ref([ ...@@ -248,6 +246,54 @@ const panel4 = ref([
text: "将中国定位为“通过强制技术转让获取先进制程的威胁”" text: "将中国定位为“通过强制技术转让获取先进制程的威胁”"
} }
]); ]);
const selectEntitiesList = shallowRef([]);
onMounted(async () => {
try {
const [organizationInfoData, personListData, sanReasonSelectData, selectEntitiesListData] = await Promise.all([
getOrganizationInfo(),
getPersonList(),
getSanReasonSelect(route.query.startTime),
getSelectEntitiesList(route.query.startTime)
]);
organizationInfo.value = {
img: panel1_1,
mingcheng: organizationInfoData?.orgName,
cuoshi: organizationInfoData?.cuoshi || "美国商务部工业与安全局",
zhize: organizationInfoData?.orgIntroduction || "--"
};
personLis.value = _.map(personListData, item => {
return {
name: item.name,
enName: item.enName,
party: item.positionTitle,
img: item.avatarUrl
};
});
sanReasonSelect.value = _.map(sanReasonSelectData, item => {
return { text: item };
});
selectEntitiesList.value = _.map(selectEntitiesListData, item => {
return {
name: item?.entityNameZh,
domains: item.techDomainList,
address: "--",
time: formatAnyDateToChinese(item?.startTime),
isUp: true,
revenue: "--",
subCompany: "--",
img: ""
};
});
} catch (err) {
console.log(err);
}
});
const panel3ActiveIndex = ref(1);
const setPanel3ActiveIndex = index => {
panel3ActiveIndex.value = index;
};
const panel5ButtonList = [ const panel5ButtonList = [
{ id: 1, text: "新增实体" }, { id: 1, text: "新增实体" },
...@@ -379,7 +425,7 @@ const panel6 = ref([ ...@@ -379,7 +425,7 @@ const panel6 = ref([
} }
.panel1 { .panel1 {
height: 100%; height: 100%;
padding: 2px 24px 0 24px; padding: 2px 35px 0 24px;
display: flex; display: flex;
.img { .img {
width: 90px; width: 90px;
...@@ -414,6 +460,11 @@ const panel6 = ref([ ...@@ -414,6 +460,11 @@ const panel6 = ref([
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 5; /* 控制行数 */
overflow: hidden;
text-overflow: ellipsis;
} }
} }
} }
...@@ -551,6 +602,10 @@ const panel6 = ref([ ...@@ -551,6 +602,10 @@ const panel6 = ref([
font-weight: 400; font-weight: 400;
line-height: 30px; line-height: 30px;
flex: 1; flex: 1;
overflow: hidden;
white-space: noWrap;
text-overflow: ellipsis;
min-width: 0;
} }
.icon2 { .icon2 {
width: 16px; width: 16px;
...@@ -605,6 +660,7 @@ const panel6 = ref([ ...@@ -605,6 +660,7 @@ const panel6 = ref([
flex: 1; flex: 1;
margin-top: 14px; margin-top: 14px;
min-height: 0; min-height: 0;
overflow: auto;
} }
.name { .name {
display: flex; display: flex;
...@@ -614,6 +670,20 @@ const panel6 = ref([ ...@@ -614,6 +670,20 @@ const panel6 = ref([
height: 40px; height: 40px;
margin-right: 6px; margin-right: 6px;
margin-left: 6px; margin-left: 6px;
flex-shrink: 0;
}
.imgUndefined {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
color: rgba(5, 95, 194, 1);
background-color: rgb(236, 245, 255);
border-radius: 20px;
margin-right: 6px;
margin-left: 6px;
} }
} }
.subCompany { .subCompany {
......
...@@ -125,7 +125,8 @@ import icon2 from "../assets/icons/icon2.png"; ...@@ -125,7 +125,8 @@ import icon2 from "../assets/icons/icon2.png";
import icon2Active from "../assets/icons/icon2_active.png"; import icon2Active from "../assets/icons/icon2_active.png";
import icon3 from "../assets/icons/icon3.png"; import icon3 from "../assets/icons/icon3.png";
import icon3Active from "../assets/icons/icon3_active.png"; import icon3Active from "../assets/icons/icon3_active.png";
import { useRoute } from "vue-router";
const route = useRoute();
const activeName = ref("分析报告"); const activeName = ref("分析报告");
const handleSwitchActiveName = name => { const handleSwitchActiveName = name => {
...@@ -171,7 +172,12 @@ const activeTitle = ref("制裁概况"); ...@@ -171,7 +172,12 @@ const activeTitle = ref("制裁概况");
const handleClickMainHeaderBtn = item => { const handleClickMainHeaderBtn = item => {
activeTitle.value = item.name; activeTitle.value = item.name;
// window.sessionStorage.setItem('activeTitle', activeTitle.value) // window.sessionStorage.setItem('activeTitle', activeTitle.value)
router.push(item.path); router.push({
path: item.path,
query: {
...route.query
}
});
}; };
const activeNavIndex = ref(0); const activeNavIndex = ref(0);
......
...@@ -98,21 +98,27 @@ ...@@ -98,21 +98,27 @@
</div> --> </div> -->
<div class="box1-top"> <div class="box1-top">
<div class="box1-top-title">2025年9月12日——BIS《实体清单增列与修订条目》</div> <div class="box1-top-title">
{{ entitiesDataInfoReactive.startTime }}——BIS《实体清单增列与修订条目》
</div>
<div class="box1-top-content"> <div class="box1-top-content">
<div class="box1-top-content-item"> <div class="box1-top-content-item">
<span class="box1-top-content-item-title">· 发布机构:</span> <span class="box1-top-content-item-title">· 发布机构:</span>
<span class="box1-top-content-item-content">美国商务部工业与安全局</span> <span class="box1-top-content-item-content">{{
entitiesDataInfoReactive.orgName
}}</span>
</div> </div>
<div class="box1-top-content-item"> <div class="box1-top-content-item">
<span class="box1-top-content-item-title">· 生效日期:</span> <span class="box1-top-content-item-title">· 生效日期:</span>
<span class="box1-top-content-item-content">2025年9月12日</span> <span class="box1-top-content-item-content">{{
entitiesDataInfoReactive.startTime
}}</span>
</div> </div>
<div class="box1-top-content-item"> <div class="box1-top-content-item">
<span class="box1-top-content-item-title">· 涉及领域:</span> <span class="box1-top-content-item-title">· 涉及领域:</span>
<div <div
class="box1-top-content-item-tags" class="box1-top-content-item-tags"
v-for="item in ['航空航天', '人工智能', '集成电路']" v-for="item in entitiesDataInfoReactive.domains"
:key="item" :key="item"
> >
<el-tag <el-tag
...@@ -128,9 +134,21 @@ ...@@ -128,9 +134,21 @@
<div class="box1-bottom"> <div class="box1-bottom">
<div class="box1-bottom-title">· 涉及主要实体:</div> <div class="box1-bottom-title">· 涉及主要实体:</div>
<div class="box1-bottom-content"> <div class="box1-bottom-content">
<div class="box1-bottom-content-item" v-for="(item, index) in entityList" :key="index"> <div
<el-image class="box1-bottom-content-item-img" :src="item.img" alt=""></el-image> class="box1-bottom-content-item"
<div class="box1-bottom-content-item-txt">{{ item.name }}</div> v-for="(item, index) in entitiesDataInfoReactive.entityList"
:key="index"
>
<el-image
v-if="item.img"
class="box1-bottom-content-item-img"
:src="item.img"
alt=""
></el-image>
<div v-else class="box1-bottom-content-item-imgUndefined">
{{ (item.name || item.enName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
<div class="box1-bottom-content-item-txt">{{ item.name || item.enName }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -139,7 +157,7 @@ ...@@ -139,7 +157,7 @@
<el-icon><Warning color="rgba(206, 79, 81, 1)" /></el-icon> <el-icon><Warning color="rgba(206, 79, 81, 1)" /></el-icon>
<span>新增中国实体</span> <span>新增中国实体</span>
</div> </div>
<div class="box1-absolute-num">23</div> <div class="box1-absolute-num">{{ entitiesDataInfoReactive.chNum }}</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -404,7 +422,7 @@ ...@@ -404,7 +422,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="box4-footer"> <div class="box4-footer" :style="{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }">
<el-button type="primary" link :icon="DownRight" <el-button type="primary" link :icon="DownRight"
>查看更多 >查看更多
<el-icon><DArrowRight /></el-icon> <el-icon><DArrowRight /></el-icon>
...@@ -514,7 +532,7 @@ ...@@ -514,7 +532,7 @@
</template> </template>
<script setup> <script setup>
import { onMounted, ref, computed } from "vue"; import { onMounted, ref, computed, reactive, shallowRef } from "vue";
import scrollToTop from "@/utils/scrollToTop"; import scrollToTop from "@/utils/scrollToTop";
import * as echarts from "echarts"; import * as echarts from "echarts";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
...@@ -581,7 +599,78 @@ import shenggongIcon from "./assets/images/shenggong.png"; ...@@ -581,7 +599,78 @@ import shenggongIcon from "./assets/images/shenggong.png";
import shoushiIcon from "./assets/images/shoushi.png"; 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";
import {
getEntitiesDataCount,
getEntitiesDataInfo,
getIndustryCountByYear,
getCountDomainByYear,
getSanctionsInfoCount
} from "@/api/exportControl";
import { getMultipleBarChart_m } from "./utils/charts";
import { formatAnyDateToChinese } from "./utils";
import _ from "lodash";
//数据定义
const entitiesDataInfoReactive = shallowRef({
chNum: undefined,
entityList: [],
domains: [],
startTime: "",
rawStartTime: "",
orgName: ""
});
// 趋势图
const trendOption = ref({});
// 发布频度
const tableData1 = ref([]);
// 历次制裁过程
const sanctionProcessList = ref([]);
onMounted(async () => {
try {
const [dataCount, entitiesDataInfo, industryCountByYear, countDomainByYear, sanctionsInfoCount = []] = await Promise.all([
getEntitiesDataCount(),
getEntitiesDataInfo(),
getIndustryCountByYear(),
getCountDomainByYear(),
getSanctionsInfoCount()
]);
infoList.value[0].num = dataCount;
const entityList = _.map(entitiesDataInfo?.entities ?? [], ({ entityNameZh, entityName }) => {
return { name: entityNameZh, enName: entityName };
});
entitiesDataInfoReactive.value = {
entityList,
chNum: entitiesDataInfo?.chNum,
domains: entitiesDataInfo?.domains ?? [],
startTime: formatAnyDateToChinese(entitiesDataInfo?.startTime ?? ""),
rawStartTime: entitiesDataInfo?.startTime ?? "",
orgName: entitiesDataInfo?.organization?.orgName
};
const list = _.chain(industryCountByYear).filter("year").orderBy("year", "desc").value();
const total = _.sumBy(list, "maxCount");
tableData1.value = _.map(list, item => {
return {
year: item.year,
num: item.maxCount,
percent: item.maxCount / total,
tags: item.maxDomain.split(",")
};
});
trendOption.value = getMultipleBarChart_m(countDomainByYear);
sanctionProcessList.value = _.map(_.slice(sanctionsInfoCount, 0, 5), item => {
return {
title: item.tittle,
desc: `${item.entitiesChNum} 家中国实体`,
content:
item.sanReason ||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
};
});
} catch (err) {
console.log(err);
}
});
// 返回首页 // 返回首页
const handleBackHome = () => { const handleBackHome = () => {
router.push({ router.push({
...@@ -597,7 +686,12 @@ const handleToDetail = () => { ...@@ -597,7 +686,12 @@ const handleToDetail = () => {
// path: "/exportControl/analysis" // path: "/exportControl/analysis"
// }); // });
const route = router.resolve("/exportControlAnalysis"); const route = router.resolve({
path: "/exportControlAnalysis",
query: {
startTime: entitiesDataInfoReactive.value.rawStartTime
}
});
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
...@@ -611,7 +705,7 @@ const infoList = ref([ ...@@ -611,7 +705,7 @@ const infoList = ref([
title: "实体清单", title: "实体清单",
subTitle: "Entity List", subTitle: "Entity List",
des: "美国商务部工业与安全局依据《出口管理条例》建立的出口管制机制", des: "美国商务部工业与安全局依据《出口管理条例》建立的出口管制机制",
num: 956, num: null,
color: "rgba(206, 79, 81, 1)" color: "rgba(206, 79, 81, 1)"
}, },
{ {
...@@ -712,40 +806,6 @@ const customNewsData = ref([ ...@@ -712,40 +806,6 @@ const customNewsData = ref([
} }
]); ]);
// 发布频度
const tableData1 = ref([
{
year: "2025",
num: 5,
percent: 0.4,
tags: ["通信网络"]
},
{
year: "2024",
num: 12,
percent: 0.9,
tags: ["通信网络", "人工智能"]
},
{
year: "2023",
num: 2,
percent: 0.4,
tags: ["通信网络"]
},
{
year: "2022",
num: 6,
percent: 0.7,
tags: ["通信网络", "集成电路"]
},
{
year: "2021",
num: 7,
percent: 0.8,
tags: ["生物科技", "集成电路"]
}
]);
// 雷达图 // 雷达图
const radarOption = ref({ const radarOption = ref({
title: { title: {
...@@ -807,151 +867,6 @@ const radarOption = ref({ ...@@ -807,151 +867,6 @@ const radarOption = ref({
] ]
}); });
// 趋势图
const trendOption = ref({
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
top: 50
},
legend: {
// type: "scroll",
// show: true,
// orient: "horizontal",
icon: "circle",
data: ["量子科技", "人工智能", "通信网络", "集成电路", "生物科技", "能源领域"]
},
xAxis: {
type: "category",
data: ["2021", "2022", "2023", "2024", "2025"]
},
yAxis: {
type: "value"
},
series: [
{
name: "量子科技",
data: [120, 200, 150, 80, 70, 110, 130],
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(22, 119, 255, 1)" },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: "rgba(22, 119, 255, 0)" }
]),
borderRadius: [6, 6, 0, 0]
}
},
{
name: "人工智能",
data: [20, 230, 100, 100, 30, 210, 180],
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(206, 79, 81, 1)" },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: "rgba(206, 79, 81, 0)" }
]),
borderRadius: [6, 6, 0, 0]
}
},
{
name: "通信网络",
data: [150, 100, 200, 130, 50, 190, 330],
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(255, 197, 61, 1)" },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: "rgba(255, 197, 61, 0)" }
]),
borderRadius: [6, 6, 0, 0]
}
},
{
name: "集成电路",
data: [220, 100, 250, 180, 170, 100, 80],
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(255, 204, 199, 1)" },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: "rgba(255, 204, 199, 0)" }
]),
borderRadius: [6, 6, 0, 0]
}
},
{
name: "生物科技",
data: [220, 300, 50, 180, 170, 210, 400],
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(179, 127, 235, 1)" },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: "rgba(179, 127, 235, 0)" }
]),
borderRadius: [6, 6, 0, 0]
}
},
{
name: "能源领域",
data: [120, 200, 150, 80, 70, 110, 130],
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(127, 218, 235, 1)" },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: "rgba(127, 214, 235, 0)" }
]),
borderRadius: [6, 6, 0, 0]
}
}
]
});
// 历次制裁过程
const sanctionProcessList = ref([
{
title: "2025年3月—实体清单(BIS)",
desc: "54家中国实体",
content:
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
},
{
title: "2025年1月—实体清单(BIS)",
desc: "25家中国实体",
content:
"2025年1月15日,美国商务部工业和安全局宣布更新《出口管理条例》(EAR),并发布两项最终规则,将25家中国企业及其相关实体列入实体清单。"
},
{
title: "2024年12月—商业管制清单(BIS)",
desc: "12家中国实体",
content:
"2024年12月20日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的12家实体新增至“商业管制清单”。"
},
{
title: "2024年10月—商业管制清单(BIS)",
desc: "6家中国实体",
content: "2024年10月21日,美国商务部将6个中国实体加入其“实体清单”,同时将 1 个中国实体移出该清单。"
},
{
title: "2024年8月—商业管制清单(BIS)",
desc: "39家中国实体",
content: "2024年8月23日,美国商务部工业安全局发布公告,将多个外国实体加入其“实体清单”,其中包括39个中国实体。"
}
]);
// 进度条状态 // 进度条状态
const getStatus = _percent => { const getStatus = _percent => {
const percent = _percent * 100; const percent = _percent * 100;
...@@ -1299,6 +1214,7 @@ const handleGetHylyList = async () => { ...@@ -1299,6 +1214,7 @@ 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,
...@@ -1489,6 +1405,8 @@ onMounted(async () => { ...@@ -1489,6 +1405,8 @@ onMounted(async () => {
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
padding-left: 10px; padding-left: 10px;
height: 156px;
overflow: auto;
&-item { &-item {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -1500,6 +1418,19 @@ onMounted(async () => { ...@@ -1500,6 +1418,19 @@ onMounted(async () => {
&-img { &-img {
width: 24px; width: 24px;
height: 24px; height: 24px;
flex-shrink: 0;
}
&-imgUndefined {
width: 24px;
height: 24px;
font-size: 14px;
font-weight: 700;
flex-shrink: 0;
color: rgba(5, 95, 194, 1);
background-color: rgb(236, 245, 255);
line-height: 24px;
text-align: center;
border-radius: 12px;
} }
&-txt { &-txt {
font-size: 16px; font-size: 16px;
...@@ -1670,39 +1601,43 @@ onMounted(async () => { ...@@ -1670,39 +1601,43 @@ onMounted(async () => {
} }
.box4 { .box4 {
height: 786px;
overflow: auto;
display: flex;
flex-direction: column;
padding-top: 16px;
.box4-item { .box4-item {
display: flex; display: flex;
gap: 10px; gap: 10px;
align-items: flex-start; align-items: flex-start;
padding-bottom: 30px; padding-bottom: 35px;
position: relative;
.box4-item-left { .box4-item-left {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding-top: 8px;
position: relative;
.box4-item-left-icon { .box4-item-left-icon {
width: 10px; width: 10px;
height: 10px; height: 10px;
} }
.box4-item-left-line { .box4-item-left-line {
width: 1px; width: 1px;
height: 145px; height: 100%;
position: absolute; position: absolute;
top: 15px;
border-left: 1px solid rgba(10, 87, 166, 0.3); border-left: 1px solid rgba(10, 87, 166, 0.3);
} }
} }
.box4-item-right { .box4-item-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px;
.box4-item-right-header { .box4-item-right-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding-bottom: 12px;
border-bottom: 1px solid rgba(234, 236, 238, 1); border-bottom: 1px solid rgba(234, 236, 238, 1);
position: relative;
top: -7.5px;
padding-bottom: 8px;
&-title { &-title {
font-size: 18px; font-size: 18px;
color: $base-color; color: $base-color;
...@@ -1715,7 +1650,6 @@ onMounted(async () => { ...@@ -1715,7 +1650,6 @@ onMounted(async () => {
} }
} }
.box4-item-right-content { .box4-item-right-content {
margin-top: 10px;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
...@@ -1724,20 +1658,19 @@ onMounted(async () => { ...@@ -1724,20 +1658,19 @@ onMounted(async () => {
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
text-overflow: ellipsis; text-overflow: ellipsis;
height: 70px;
line-height: 25px; line-height: 25px;
} }
} }
} }
.box4-footer { .box4-footer {
margin-top: 50px; margin-top: auto;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
position: absolute;
bottom: 30px; bottom: 30px;
left: 50%; left: 50%;
margin-left: -20px; margin-left: -20px;
margin-bottom: 30px;
} }
} }
......
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import chinaJson from './China.json' import chinaJson from './China.json'
import _ from 'lodash';
//饼图 //饼图
export function getPieOption(data, title) { export function getPieOption(data, title) {
let option = { let option = {
...@@ -85,7 +86,7 @@ export function getPieOption1(data, title) { ...@@ -85,7 +86,7 @@ export function getPieOption1(data, title) {
}, },
label: { label: {
alignTo: 'edge', alignTo: 'edge',
formatter: '{b}\n{two|{c}家 {d}%}', formatter: `{b}${data.length < 10 ? '\n' : ''} {two|{c}家 {d}%}`,
fontSize: 17.6, fontSize: 17.6,
fontWeight: 700, fontWeight: 700,
minMargin: 5, minMargin: 5,
...@@ -104,12 +105,13 @@ export function getPieOption1(data, title) { ...@@ -104,12 +105,13 @@ export function getPieOption1(data, title) {
maxSurfaceAngle: 80 maxSurfaceAngle: 80
}, },
labelLayout: function (params) { labelLayout: function (params) {
console.log('labelLayoutparams', params)
const isLeft = params.labelRect.x < 556 / 2; const isLeft = params.labelRect.x < 556 / 2;
const points = params.labelLinePoints; const points = params.labelLinePoints;
// Update the end point. // Update the end point.
points[2][0] = isLeft points[2][0] = isLeft
? params.labelRect.x ? data.length < 10 ? params.labelRect.x : (params.labelRect.x + params.labelRect.width)
: params.labelRect.x + params.labelRect.width; : data.length < 10 ? (params.labelRect.x + params.labelRect.width) : params.labelRect.x;
return { return {
labelLinePoints: points labelLinePoints: points
}; };
...@@ -600,7 +602,7 @@ export const getBarChart = (nameList, valueList, color = ['rgba(255, 159, 22, 1) ...@@ -600,7 +602,7 @@ export const getBarChart = (nameList, valueList, color = ['rgba(255, 159, 22, 1)
} }
return option return option
} }
export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { export const getLineChart = (object, isPercent) => {
const option = { const option = {
title: { title: {
text: "" text: ""
...@@ -611,11 +613,11 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -611,11 +613,11 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
let result = params[0].name + '<br/>'; let result = params[0].name + '<br/>';
params.forEach(function (item, index) { params.forEach(function (item, index) {
// 自定义颜色数组 // 自定义颜色数组
const customColors = [color]; const customColors = [object.color];
const dotColor = customColors[index % customColors.length]; // 循环取色 const dotColor = customColors[index % customColors.length]; // 循环取色
// 创建彩色圆点图标 // 创建彩色圆点图标
const dot = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${dotColor};"></span>`; const dot = `<span style="display:inline-block;margin-right:5px;border-radius:50%;width:10px;height:10px;background-color:${dotColor};"></span>`;
result += dot + `${item.seriesName}: ${item.value}<br/>`; result += dot + `${item.seriesName}: ${item.value}${isPercent ? '%' : ''}<br/>`;
}); });
return result; return result;
} }
...@@ -648,7 +650,7 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -648,7 +650,7 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
// fontSize: 22, // fontSize: 22,
// fontWeight: 400 // fontWeight: 400
}, },
data: ["2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023"] data: object.xAxisData
}, },
yAxis: { yAxis: {
type: "value", type: "value",
...@@ -662,7 +664,9 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -662,7 +664,9 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
color: "rgba(95, 101, 108, 1)", color: "rgba(95, 101, 108, 1)",
// fontSize: 22, // fontSize: 22,
// fontWeight: 400 // fontWeight: 400
formatter: `{value} ${isPercent ? '%' : ''}`
}, },
splitNumber: 8, splitNumber: 8,
splitLine: { splitLine: {
lineStyle: { lineStyle: {
...@@ -675,19 +679,19 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => { ...@@ -675,19 +679,19 @@ export const getLineChart = (color = 'rgba(146, 84, 222, 1)') => {
}, },
series: [ series: [
{ {
name: "增长趋势", name: object.name,
type: "line", type: "line",
symbolSize: 8, symbolSize: 8,
symbol: 'circle', symbol: 'circle',
itemStyle: { itemStyle: {
color: "#ffffff", color: "#ffffff",
borderColor: color, borderColor: object.color,
borderWidth: 3 borderWidth: 3
}, },
lineStyle: { lineStyle: {
color: color, color: object.color,
}, },
data: [3, 6, 4, 7, 9, 6, 5, 6, 6] data: object.seriesData
} }
] ]
}; };
...@@ -970,3 +974,61 @@ export const getMultipleLineChart = (obj) => { ...@@ -970,3 +974,61 @@ export const getMultipleLineChart = (obj) => {
}; };
return option; return option;
} }
//出口管制主页接口
export const getMultipleBarChart_m = (object) => {
const list = _.chain(object.data).filter('year').orderBy('year', 'asc').value();
const colors = [
['rgba(22, 119, 255, 1)', 'rgba(22, 119, 255, 0)'],
['rgba(206, 79, 81, 1)', 'rgba(206, 79, 81, 0)'],
['rgba(255, 197, 61, 1)', 'rgba(255, 197, 61, 0)'],
['rgba(255, 204, 199, 1)', 'rgba(255, 204, 199, 0)'],
['rgba(179, 127, 235, 1)', 'rgba(179, 127, 235, 0)'],
['rgba(127, 218, 235, 1)', 'rgba(127, 214, 235, 0)'],
];
const names = _.map(list, 'year');
const datas = _.chain(object.domains).splice(0, 6).map((name, index) => {
console.log(_.map(list, name))
return {
name,
data: _.map(list, `domainNum.${name}`),
type: "bar",
barWidth: 12,
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[index % colors.length][0] },
// { offset: 0.5, color: '#188df0' },
{ offset: 1, color: colors[index % colors.length][1] }
]),
borderRadius: [6, 6, 0, 0]
}
}
}).value();
console.log('names', names)
const option = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
grid: {
top: 50
},
legend: {
// type: "scroll",
// show: true,
// orient: "horizontal",
icon: "circle",
},
xAxis: {
type: "category",
data: names
},
yAxis: {
type: "value"
},
series: datas
}
return option;
}
export function formatAnyDateToChinese(dateStr) {
// 支持多种分隔符
const date = new Date(dateStr.replace(/\//g, '-'));
if (isNaN(date.getTime())) {
return ''
}
// 手动获取各部分,避免Intl可能存在的兼容性考虑
const year = date.getFullYear();
const month = date.getMonth() + 1; // 月份从0开始,需+1
const day = date.getDate();
return `${year}${month}${day}日`;
}
\ No newline at end of file
...@@ -315,9 +315,9 @@ ...@@ -315,9 +315,9 @@
</div> </div>
<div class="box6-main"> <div class="box6-main">
<div class="box6-main-select-box"> <div class="box6-main-select-box">
<el-select v-model="curAreaYear" placeholder="选择发布时间" style="width: 120px"> <el-select v-model="box6SelectedYear" placeholder="选择时间" style="width: 120px">
<el-option <el-option
v-for="item in areaYearList" v-for="item in box6YearList"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
...@@ -348,9 +348,9 @@ ...@@ -348,9 +348,9 @@
<div class="box7-main-left" id="box7Chart1"></div> <div class="box7-main-left" id="box7Chart1"></div>
<div class="box7-main-right"> <div class="box7-main-right">
<div class="box7-main-right-top"> <div class="box7-main-right-top">
<el-select v-model="curAreaYear" placeholder="选择发布时间" style="width: 120px"> <el-select v-model="box7SelectedYear" placeholder="选择时间" style="width: 120px">
<el-option <el-option
v-for="item in areaYearList" v-for="item in box7YearList"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
...@@ -661,7 +661,7 @@ const chart1Data = ref({ ...@@ -661,7 +661,7 @@ const chart1Data = ref({
] ]
}); });
const areaYearList = ref([ const box7YearList = ref([
{ {
label: "2025", label: "2025",
value: "2025" value: "2025"
...@@ -688,7 +688,7 @@ const areaYearList = ref([ ...@@ -688,7 +688,7 @@ const areaYearList = ref([
} }
]); ]);
const curAreaYear = ref("2025"); const box7SelectedYear = ref("2025");
const surveyYearList = ref([ const surveyYearList = ref([
{ {
...@@ -894,6 +894,36 @@ const handleToMoreNews = () => { ...@@ -894,6 +894,36 @@ const handleToMoreNews = () => {
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
// 制裁领域分布
const box6SelectedYear = ref("2025");
const box6YearList = ref([
{
label: "2025",
value: "2025"
},
{
label: "2024",
value: "2024"
},
{
label: "2023",
value: "2023"
},
{
label: "2022",
value: "2022"
},
{
label: "2021",
value: "2021"
},
{
label: "2020",
value: "2020"
}
]);
const box7Chart1Data = ref([ const box7Chart1Data = ref([
{ {
name: "337调查", name: "337调查",
...@@ -2154,11 +2184,14 @@ onMounted(async () => { ...@@ -2154,11 +2184,14 @@ onMounted(async () => {
position: relative; position: relative;
.box6-main-select-box { .box6-main-select-box {
position: absolute; position: absolute;
z-index: 100;
top: 10px; top: 10px;
right: 20px; right: 20px;
} }
.box6-mian-chart { .box6-mian-chart {
height: 360px; height: 360px;
position: relative;
z-index: 99;
} }
} }
} }
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
<div class="item-header-text">打压遏制手段分布</div> <div class="item-header-text">打压遏制手段分布</div>
</div> </div>
<div class="item-header-divider"></div> <div class="item-header-divider"></div>
<div style="display: flex; justify-content: space-between; width: 100%; height: calc(100% - 60px);"> <div style="display: flex; justify-content: space-between; width: 100%; height: calc(100% - 60px);" @mouseenter="handleChangeSwiper(false)" @mouseleave="handleChangeSwiper(true)">
<div class="thematic-btn-left" @click="changeBtn('left')"> <div class="thematic-btn-left" @click="handleSwitch('left')">
<img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-left.png"></img> <img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-left.png"></img>
</div> </div>
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
</div> </div>
</div> </div>
</div> </div>
<div class="thematic-btn-right" @click="changeBtn('right')"> <div class="thematic-btn-right" @click="handleSwitch('right')">
<img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-right.png"></img> <img class="thematic-btn-icon" src="@/assets/images/icon/card-btn-right.png"></img>
</div> </div>
</div> </div>
...@@ -169,7 +169,7 @@ ...@@ -169,7 +169,7 @@
</template> </template>
<script setup> <script setup>
import { onMounted, ref, computed } from "vue"; import { onMounted, ref, computed, onUnmounted } from "vue";
import router from "@/router/index"; import router from "@/router/index";
import * as echarts from "echarts"; import * as echarts from "echarts";
import DivideHeader from "@/components/DivideHeader.vue"; import DivideHeader from "@/components/DivideHeader.vue";
...@@ -232,8 +232,7 @@ const course = ref([ ...@@ -232,8 +232,7 @@ const course = ref([
} }
]); ]);
//打压遏制手段分布 const totalDistribution = ref([
const distribution = ref([
{ {
titlle: "法案", titlle: "法案",
value: 80, value: 80,
...@@ -287,9 +286,126 @@ const distribution = ref([ ...@@ -287,9 +286,126 @@ const distribution = ref([
change: "较上个月+1", change: "较上个月+1",
path: "/marketAccessRestrictions", path: "/marketAccessRestrictions",
color: ["#FFE3B9", "#FFEDCE", "#FFF7E6", "#D46B08"] color: ["#FFE3B9", "#FFEDCE", "#FFF7E6", "#D46B08"]
} },
{
titlle: "合作限制",
value: 41,
text: "127",
unit: "次",
change: "较上个月+3",
path: "/cooperationRestrictions",
color: ["rgba(139,69,19,0.4)", "rgba(139,69,19,0.5)", "rgba(139,69,19,0.3)", "rgba(139,69,19,1)"]
},
{
titlle: "规则限制",
value: 24,
text: "724",
unit: "个",
change: "较上月+5",
path: "/ruleRestrictions",
color: ["#9AC8FF", "#BCDCFF", "#E7F4FF", "#0F5EDB"]
},
{
titlle: "科研资助体系",
value: 64,
text: "128",
unit: "个",
change: "较上月+8",
path: "/scientificFunding",
color: ["#FDE19A", "#FEECBD", "#FFFBE6", "#D68E16"]
},
]); ]);
const startIndex = ref(0);
const handleSwitch = flag => {
if (flag == "left") {
if (startIndex.value === 0) {
startIndex.value = totalDistribution.value.length - 6;
} else {
startIndex.value--;
}
} else {
if (startIndex.value === totalDistribution.value.length - 6) {
startIndex.value = 0;
} else {
startIndex.value++;
}
}
};
//打压遏制手段分布
const distribution = computed(() => {
return totalDistribution.value.slice(startIndex.value, startIndex.value + 6);
});
//打压遏制手段分布
// const distribution = ref([
// {
// titlle: "法案",
// value: 80,
// text: "1626",
// unit: "个",
// change: "较上月+3",
// path: "/billHome",
// color: ["#9AC8FF", "#BCDCFF", "#E7F4FF", "#0F5EDB"]
// },
// {
// titlle: "行政令",
// value: 20,
// text: "1626",
// unit: "个",
// change: "较上月+1",
// path: "/decree",
// color: ["#FDE19A", "#FEECBD", "#FFFBE6", "#D68E16"]
// },
// {
// titlle: "科技智库",
// value: 10,
// text: "66",
// unit: "次",
// change: "较上月+2",
// path: "/thinkTank",
// color: ["#C9AAF0", "#DFCAF6", "#FAF1FF", "#531DAC"]
// },
// {
// titlle: "出口管制",
// value: 33,
// text: "66",
// unit: "次",
// change: "较上月+1",
// path: "/exportControl",
// color: ["#96DFDD", "#BCEFEC", "#E7FFFB", "#006E75"]
// },
// {
// titlle: "投融资限制",
// value: 80,
// text: "119",
// unit: "次",
// change: "较上月+1",
// path: "/finance",
// color: ["#F5BEBC", "#F7D3D0", "#FEF1F0", "#C64C4E"]
// },
// {
// titlle: "市场准入",
// value: 50,
// text: "223",
// unit: "次",
// change: "较上个月+1",
// path: "/marketAccessRestrictions",
// color: ["#FFE3B9", "#FFEDCE", "#FFF7E6", "#D46B08"]
// },
// {
// titlle: "合作限制",
// value: 41,
// text: "127",
// unit: "次",
// change: "较上个月+3",
// path: "/cooperationRestrictions",
// color: ["rgba(139,69,19,0.4)", "rgba(139,69,19,0.5)", "rgba(139,69,19,0.3)", "rgba(139,69,19,1)"]
// }
// ]);
//随机生成颜色 //随机生成颜色
const makeColors = () => { const makeColors = () => {
let A = Math.floor(Math.random() * 360); // 随机色相 let A = Math.floor(Math.random() * 360); // 随机色相
...@@ -380,7 +496,20 @@ const handleClickItem = item => { ...@@ -380,7 +496,20 @@ const handleClickItem = item => {
}); });
}; };
const swiper = ref(null);
const isOnSwiper = ref(true)
const handleChangeSwiper = (val) => {
isOnSwiper.value = val
}
onMounted(() => { onMounted(() => {
swiper.value = setInterval(() => {
if (isOnSwiper.value) {
handleSwitch("right");
}
}, 3600);
let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true); let char1 = getBarChart(chart1Data.value.name, chart1Data.value.value, true);
setChart(char1, "chart1"); setChart(char1, "chart1");
...@@ -388,12 +517,15 @@ onMounted(() => { ...@@ -388,12 +517,15 @@ onMounted(() => {
let char2 = radarChart(); let char2 = radarChart();
setChart(char2, "char2"); setChart(char2, "char2");
}); });
onUnmounted(() => {
clearInterval(swiper.value);
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.cup-box { .cup-box {
overflow-x: auto; overflow-x: auto;
.cup-item-box { .cup-item-box {
width: 240px; width: 240px;
text-align: center; text-align: center;
...@@ -534,12 +666,14 @@ onMounted(() => { ...@@ -534,12 +666,14 @@ onMounted(() => {
height: 100%; height: 100%;
width: 24px; width: 24px;
padding-top: 130px; padding-top: 130px;
cursor: pointer;
} }
.thematic-btn-right { .thematic-btn-right {
height: 100%; height: 100%;
width: 24px; width: 24px;
padding-top: 130px; padding-top: 130px;
cursor: pointer;
} }
.thematic-btn-icon { .thematic-btn-icon {
......
<template>
<div class="com-title">
<div class="cl1"></div>
<div class="cl2"></div>
<div class="title">{{ title }}</div>
<div class="cl3"></div>
</div>
</template>
<script setup>
import { ref } from "vue";
// 传入的title数据
const props = defineProps({
title: {
type: String,
default: ""
}
});
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.com-title {
width: 1575px;
height: 42px;
display: flex;
align-items: center;
.cl1 {
width: 24px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.cl2 {
width: 8px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.title {
width: 152px;
height: 42px;
text-align: center;
font-size: 32px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 42px;
margin-right: 8px;
}
.cl3 {
width: 1367px;
height: 1px;
background-color: rgba(174, 214, 255, 1);
box-sizing: border-box;
}
}
</style>
<template>
<div class="ask-page">
<div class="left">
<div class="left-title">
<img src="./assets/icon01.png" alt="">
<div class="tit">新闻资讯</div>
<div class="more" @click="handleToMoreNews">更多 +</div>
</div>
<div class="left-main">
<div v-for="item in leftList" :key="item.id" class="main-item">
<img :src="item.image" alt="">
<div class="item-content">
<div class="title">{{item.title}}</div>
<div class="content">{{item.content}}</div>
<div class="time">{{item.time}}</div>
</div>
</div>
</div>
</div>
<div class="right">
<div class="right-title">
<img src="./assets/icon02.png" alt="">
<div class="tit">社交媒体</div>
<div class="more">更多 +</div>
</div>
<div class="right-main">
<div class="trump">
<img src="./assets/title01.png" alt="">
<div class="trump-main">
<div class="cl1">{{ rightList[0].name }}</div>
<div class="cl2">{{ rightList[0].content }}</div>
<div class="cl3">{{ rightList[0].time }}</div>
</div>
</div>
<div class="mask">
<img src="./assets/title02.png" alt="">
<div class="mask-main">
<div class="cl1">{{ rightList[1].name }}</div>
<div class="cl2">{{ rightList[1].content }}</div>
<div class="cl3">{{ rightList[1].time }}</div>
</div>
</div>
<div class="malaby">
<img src="./assets/title03.png" alt="">
<div class="malaby-main">
<div class="cl1">{{ rightList[2].name }}</div>
<div class="cl2">{{ rightList[2].content }}</div>
<div class="cl3">{{ rightList[2].time }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import router from "@/router"
import image01 from './assets/image01.png'
import image02 from './assets/image02.png'
import image03 from './assets/image03.png'
import image04 from './assets/image04.png'
import image05 from './assets/image05.png'
import title01 from './assets/title01.png'
import title02 from './assets/title02.png'
import title03 from './assets/title03.png'
const leftList = ref([
{
id:1,
title:'美国智库激辩人工智能监管路径',
content:'各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析...',
time:'11-4 · 华盛顿邮报',
image:image01
},
{
id:2,
title:'布鲁金斯学会称美国低估中国在“印太”战略',
content:'分析认为,当美国注意力被其他地区分散时,中国通过外交、发展和防务多管齐下,系统性...',
time:'11-4 · 纽约时报',
image:image02
},
{
id:3,
title:'五角大楼指令引发智库与国防部“脱钩”震荡',
content:'美国国防部长下令全面暂停部内人员参与所有智库活动,标志着传统的“旋转门”关系发生...',
time:'11-3 · 洛杉矶时报',
image:image03
},
{
id:4,
title:'卡内基基金会警告冲突中AI宣传战的风险',
content:'分析指出,在伊朗与以色列的冲突中,人工智能生成的虚假信息泛滥,深度破坏了信息生态...',
time:'11-3 · 今日美国',
image:image04
},
{
id:5,
title:'CSIS建议美国建立跨机构AI基准测试体系',
content:'指出美国《人工智能行动计划》忽视了基准测试这一关键环节,建议由国家标准与技术研究...',
time:'11-2 · ​福克斯新闻网',
image:image05
}
])
const rightList = ref([
{
id:1,
name:'唐纳德·特朗普',
content:'埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。',
time:'15:23 · 发布于真实社交',
title:title01
},
{
id:2,
name:'埃隆·马斯克',
content:'如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。',
time:'14:49 · 发布于X',
title:title02
},
{
id:3,
name:'塞巴斯蒂安·马拉比',
content:'提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。',
time:'11:05 · 发布于X',
title:title03
}
])
// 查看更多新闻资讯
const handleToMoreNews = () => {
const route = router.resolve("/newsBrief");
window.open(route.href, "_blank");
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.ask-page {
width: 1600px;
height: 450px;
display: flex;
justify-content: space-between;
.left {
width: 792px;
height: 450px;
margin-right: 16px;
border-radius: 10px;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.left-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
width: 80px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 26px;
color: rgb(5, 95, 194);
}
.more {
width: 49px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
top: 12px;
right: 27px;
cursor: pointer;
}
}
.left-main {
width: 792px;
height: 402px;
padding: 20px 22px 21px 21px;
.main-item {
width: 749px;
height: 64px;
display: flex;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin-bottom: 14px;
img {
width: 72px;
height: 48px;
margin-right: 20px;
cursor: pointer;
}
.item-content {
width: 657px;
height: 50px;
position: relative;
.title {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
cursor: pointer;
}
.content {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
cursor: pointer;
}
.time {
position: absolute;
top: 0px;
right: 0px;
font-size: 14px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 22px;
color: rgb(95, 101, 108);
cursor: pointer;
}
}
}
}
}
.right {
width: 792px;
height: 450px;
border-radius: 10px;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.right-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
width: 80px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 26px;
color: rgb(5, 95, 194);
}
.more {
width: 49px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
top: 12px;
right: 27px;
cursor: pointer;
}
}
.right-main {
width: 792px;
height: 402px;
padding: 23px 30px 25px 21px;
.trump {
width: 740px;
height: 148px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.trump-main {
width: 695.6px;
height: 148px;
background-image: url('./assets/title01bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
.mask {
width: 740px;
height: 76px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.mask-main {
width: 695.6px;
height: 76px;
background-image: url('./assets/title02bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
.malaby {
width: 740px;
height: 98px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.malaby-main {
width: 695.6px;
height: 98px;
background-image: url('./assets/title03bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="data-new">
<div class="left">
<img src="./assets/leftbtn.png" alt="" class="left-btn" />
<img src="./assets/rightbtn.png" alt="" class="right-btn" />
<div class="left-top">
<img src="./assets/icon01.png" alt="" />
<div class="left-top-title">规则限制动态</div>
<span>查看详情 ></span>
</div>
<div class="left-center">
<img src="./assets/usImg.png" alt="" />
<div class="left-center-main">
<div class="left-center-main-title">
美国联邦通信委员会(FCC)启动撤销重庆信息通信研究院作为认可测试实验室资格的程序
</div>
<div class="left-center-main-ul">
<ul>
<li>
<span class="ul-title">发布机构:</span>
<span class="ul-content">美国联邦通信委员会(FCC)工程技术与媒体关系部</span>
</li>
<li>
<span class="ul-title">发布日期:</span>
<span class="ul-content">2025年10月24日</span>
</li>
<li>
<span class="ul-title">涉及领域:</span>
<span class="ul-pie cl1">能源</span>
<span class="ul-pie cl2">集成电路</span>
<span class="ul-pie cl3">新材料</span>
<span class="ul-pie cl4">生物科技</span>
</li>
<li>
<span class="ul-title">限制实体:</span>
<span class="ul-content">重庆信息通信研究院</span>
</li>
</ul>
</div>
</div>
<!-- <div class="left-center-title">国会法案</div> -->
</div>
<div class="left-bottom">
<ul>
<li class="left-bottom-li">内容摘要:</li>
</ul>
<div class="left-bottom-content">
工程和技术办公室着手撤销对德国莱茵 TÜV 集团/中国检验认证集团(宁波)有限公司作为认可测试实验室的资格。
</div>
</div>
</div>
<div class="right">
<div class="right-top">
<img src="./assets/icon02.png" alt="" />
<div class="right-top-title">
风险信号
<span>4</span>
</div>
</div>
<div style="margin: 6px 34px 0 23px">
<div v-for="item in list" :key="item.id" class="right-main" @click="handleClickToDetail">
<div class="main-left" :class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险' }">
{{ item.title }}
</div>
<div class="main-center">{{ item.content }}</div>
<div class="main-right">{{ item.time }}</div>
</div>
</div>
<div class="right-mainbtn" @click="handleToMoreRiskSignal">
<img src="./assets/btn.png" alt="" />
查看更多
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import router from "@/router";
const list = ref([
{
id: 1,
title: "特别重大",
content: "保护美国资金与专业知识免受敌对研究利用法案",
time: "一天前"
},
{
id: 2,
title: "特别重大",
content: "美国国土安全部终止哈佛大学SEVP认证",
time: "一天前"
},
{
id: 3,
title: "重大风险",
content: "众议院“美中战略竞争特别委员会”向国会提...",
time: "一天前"
},
{
id: 4,
title: "重大风险",
content: '2026财年拨款法案要求重启"中国行动计划"',
time: "一天前"
}
]);
// 跳转详情
const handleClickToDetail = () => {
// router.push("/decreeLayout");
const route = router.resolve("/ruleRestrictions/detail");
window.open(route.href, "_blank");
};
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
window.open(route.href, "_blank");
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.data-new {
width: 1600px;
height: 460px;
display: flex;
justify-content: space-between;
.left {
width: 1064px;
height: 460px;
margin-right: 16px;
border-radius: 10px;
background-color: #fff;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-btn {
width: 24px;
height: 48px;
position: absolute;
top: 223px;
left: 0px;
cursor: pointer;
}
.right-btn {
width: 24px;
height: 48px;
position: absolute;
top: 223px;
right: 0px;
cursor: pointer;
}
.left-top {
width: 100%;
height: 48px;
position: relative;
border-bottom: 1px solid rgb(234, 236, 238);
img {
width: 18px;
height: 18px;
position: absolute;
top: 15px;
left: 23px;
}
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
position: absolute;
top: 19px;
right: 40px;
color: rgb(5, 95, 194);
cursor: pointer;
}
.left-top-title {
margin-left: 60px;
width: 152px;
height: 48px;
background-color: rgb(5, 95, 194);
color: #fff;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
text-align: center;
padding: 11px 16px;
}
}
.left-center {
width: 967px;
height: 208px;
margin-top: 33px;
margin-left: 62px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 148px;
height: 148px;
margin-right: 21px;
}
display: flex;
.left-center-main {
width: 758px;
height: 175px;
.left-center-main-title {
margin-left: 19px;
margin-bottom: 17px;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
}
.left-center-main-ul {
// width: 439px;
height: 132px;
ul {
list-style-position: inside;
li {
width: 100%;
height: 24px;
margin-bottom: 12px;
.ul-title {
display: inline-block;
width: 120px;
height: 24px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.ul-content {
color: rgb(59, 65, 75);
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
.ul-pie {
display: inline-block;
box-sizing: border-box;
padding: 2px 8px;
border: 1px solid;
border-radius: 4px;
margin-right: 8px;
}
.cl1 {
border-color: rgba(186, 224, 255, 1);
background-color: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.cl2 {
border-color: rgba(255, 163, 158, 1);
background-color: rgba(255, 241, 240, 1);
color: rgba(245, 34, 45, 1);
}
.cl3 {
border-color: rgba(135, 232, 222, 1);
background-color: rgba(230, 255, 251, 1);
color: rgba(19, 168, 168, 1);
}
.cl4 {
border-color: rgba(211, 173, 247, 1);
background-color: rgba(249, 240, 255, 1);
color: rgba(114, 46, 209, 1);
}
}
}
}
}
.left-center-title {
padding: 3px 8px 5px;
height: 32px;
border-radius: 4px;
background-color: rgba(231, 243, 255, 1);
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
right: 0px;
top: -1px;
}
}
.left-bottom {
margin: 17px 0 0 62px;
ul {
list-style-position: inside;
.left-bottom-li {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 10px;
}
}
.left-bottom-content {
width: 943px;
margin-left: 22px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
}
}
}
.right {
width: 520px;
height: 460px;
border-radius: 10px;
background-color: #fff;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.right-top {
width: 520px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 21px;
height: 16.84px;
position: absolute;
top: 15.1px;
left: 19.5px;
}
.right-top-title {
padding: 11px 16px;
width: 148px;
height: 48px;
background-color: rgb(206, 79, 81);
font-size: 20px;
font-family: "Microsoft YaHei";
font-weight: 700;
line-height: 26px;
text-align: center;
color: #fff;
margin-left: 60px;
span {
display: inline-block;
width: 24px;
height: 20px;
background-color: rgba(255, 255, 255, 0.3);
font-size: 14px;
font-family: "Microsoft YaHei";
font-weight: 400;
line-height: 22px;
text-align: center;
color: #fff;
border-radius: 100px;
}
}
}
.right-main {
width: 468px;
padding-right: 5px;
height: 47px;
border-radius: 2px;
display: flex;
align-items: center;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.main-left {
width: 40px;
height: 40px;
margin: 4px 13px 3px 2px;
border-radius: 50%;
font-size: 12px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 14px;
padding: 6px 4px;
text-align: center;
}
.cl4 {
background-color: rgba(255, 241, 240, 1);
color: rgb(206, 79, 81);
}
.cl5 {
background-color: rgba(255, 247, 230, 1);
color: rgba(250, 140, 22, 1);
}
.main-center {
width: 347px;
height: 30px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
margin-right: 2px;
}
.main-right {
width: 60px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
text-align: right;
}
}
.right-mainbtn {
width: 460px;
height: 42px;
border-radius: 6px;
position: absolute;
left: 26px;
bottom: 21px;
background-color: rgb(5, 95, 194);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 8px;
}
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
}
}
}
</style>
<template>
<div class="datasub">
<div class="left">
<div class="left-title">
<img src="./assets/icon01.png" alt="" />
<div class="tit">各类型合作限制政策对比</div>
<el-select v-model="value1" placeholder="Select" class="select">
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="left-main">
<div class="left-main-echarts" ref="leftChartRef"></div>
</div>
</div>
<div class="right">
<div class="right-title">
<img src="./assets/icon02.png" alt="" />
<div class="tit">各领域规则分布情况</div>
<el-select v-model="value2" placeholder="Select" class="select1">
<el-option v-for="item in options2" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="value" placeholder="Select" class="select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="right-main">
<div class="right-main-echarts" ref="rightChartRef"></div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import * as echarts from "echarts";
const value = ref("近十年");
const value1 = ref("2025年");
const value2 = ref("全部限制手段");
const options = [
{
value: "近十年",
label: "近十年"
},
{
value: "近五年",
label: "近五年"
}
];
const options1 = [
{
value: "2025年",
label: "2025年"
},
{
value: "2024年",
label: "2024年"
}
];
const options2 = [
{
value: "全部限制手段",
label: "全部限制手段"
},
{
value: "人工智能",
label: "人工智能"
},
{
value: "集成电路",
label: "集成电路"
}
];
const leftChartRef = ref(null);
const rightChartRef = ref(null);
let leftChart;
let rightChart;
const initLeftDonut = () => {
if (!leftChartRef.value) return;
if (leftChart) leftChart.dispose();
leftChart = echarts.init(leftChartRef.value);
const data = [
{ name: "集成电路", value: 50 },
{ name: "人工智能", value: 46 },
{ name: "通信网络", value: 40 },
{ name: "能源", value: 32 },
{ name: "先进制造", value: 31 },
{ name: "生物科技", value: 31 },
{ name: "航空航天", value: 30 },
{ name: "新材料", value: 24 }
];
const colors = [
"rgba(105, 177, 255, 1)", // 集成电路
"rgba(255, 192, 105, 1)", // 人工智能
"rgba(135, 232, 222, 1)", // 通信网络
"rgba(89, 126, 247, 1)", // 能源
"rgba(214, 228, 255, 1)", // 先进制造
"rgba(255, 120, 117, 1)", // 生物科技
"rgba(179, 127, 235, 1)", // 航空航天
"rgba(255, 163, 158, 1)" // 新材料
];
const option = {
color: colors,
tooltip: { trigger: "item", formatter: ({ name, value, percent }) => `${name}<br/>${value}${percent}%` },
series: [{
type: "pie",
radius: [96, 120],
center: ["50%", "50%"],
avoidLabelOverlap: true,
itemStyle: { borderWidth: 0 },
label: {
show: true,
position: "outside",
alignTo: 'edge',
formatter: ({ name, value, percent }) => `{name|${name}} {value|${value}项} {percent|${percent}%}`,
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
name: { fontSize: 16, fontFamily: "Microsoft YaHei", fontWeight: 700, lineHeight: 24, color: "rgb(59, 65, 75)" },
value: { fontSize: 14, fontFamily: "Microsoft YaHei", fontWeight: 400, lineHeight: 22, color: "rgb(95, 101, 108)" },
percent: { fontSize: 14, fontFamily: "Microsoft YaHei", fontWeight: 400, lineHeight: 22, color: "rgb(95, 101, 108)" }
}
},
labelLine: {
show: true,
length: 30,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < leftChart.getWidth() / 2;
const points = params.labelLinePoints;
// 导航线终点在标签下方
const lineY = params.labelRect.y + params.labelRect.height;
points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
points[2][1] = lineY;
points[1][1] = lineY;
return {
labelLinePoints: points
};
},
data: data.map((d, i) => ({
...d,
labelLine: { lineStyle: { color: colors[i], width: 1 } }
}))
}]
};
leftChart.setOption(option);
};
const initRightLine = () => {
if (!rightChartRef.value) return;
if (rightChart) rightChart.dispose();
rightChart = echarts.init(rightChartRef.value);
const years = ['2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025'];
const seriesData = [
{ name: '人工智能', color: 'rgb(5, 95, 194)', data: [150, 90, 65, 95, 75, 95, 130, 150, 140, 170, 175, 185] },
{ name: '集成电路', color: 'rgba(19, 168, 168, 1)', data: [65, 95, 125, 115, 135, 145, 165, 165, 165, 175, 180, 175] },
{ name: '量子科技', color: 'rgba(114, 46, 209, 1)', data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12] },
{ name: '生物科技', color: 'rgba(250, 140, 22, 1)', data: [12, 8, 8, 12, 12, 15, 20, 30, 25, 30, 42, 42] },
{ name: '通信网络', color: 'rgba(105, 177, 255, 1)', data: [42, 38, 45, 52, 52, 48, 52, 72, 65, 62, 65, 58] },
{ name: '能源', color: 'rgb(206, 79, 81)', data: [98, 75, 62, 82, 62, 72, 82, 122, 118, 148, 138, 105] }
];
const option = {
color: seriesData.map(s => s.color),
legend: {
top: 10,
left: 'center',
itemWidth: 12,
itemHeight: 12,
itemGap: 20,
icon: 'circle',
textStyle: {
fontSize: 16,
fontWeight: 400,
lineHeight: 24,
fontFamily: 'Microsoft YaHei',
color: 'rgb(95, 101, 108)'
}
},
grid: {
top: 60,
left: 50,
right: 40,
bottom: 40
},
xAxis: {
type: 'category',
data: years,
boundaryGap: false,
axisLine: {
lineStyle: { color: '#E5E7EB' }
},
axisLabel: {
color: 'rgba(132, 136, 142, 1)',
fontSize: 14,
fontWeight: 400,
lineHeight: 22,
fontFamily: 'Microsoft YaHei'
}
},
yAxis: {
type: 'value',
min: 0,
max: 200,
interval: 40,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
color: 'rgba(132, 136, 142, 1)',
fontSize: 14,
fontWeight: 400,
lineHeight: 22,
fontFamily: 'Microsoft YaHei'
},
splitLine: {
lineStyle: { color: '#E5E7EB' }
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'line'
}
},
series: [
{
name: '人工智能',
type: 'line',
data: seriesData[0].data,
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: { width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(5, 95, 194, 0.25)' },
{ offset: 1, color: 'rgba(5, 95, 194, 0.05)' }
])
}
},
{
name: '集成电路',
type: 'line',
data: seriesData[1].data,
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: { width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(19, 168, 168, 0.25)' },
{ offset: 1, color: 'rgba(19, 168, 168, 0.05)' }
])
}
},
{
name: '量子科技',
type: 'line',
data: seriesData[2].data,
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: { width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(114, 46, 209, 0.25)' },
{ offset: 1, color: 'rgba(114, 46, 209, 0.05)' }
])
}
},
{
name: '生物科技',
type: 'line',
data: seriesData[3].data,
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: { width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(250, 140, 22, 0.25)' },
{ offset: 1, color: 'rgba(250, 140, 22, 0.05)' }
])
}
},
{
name: '通信网络',
type: 'line',
data: seriesData[4].data,
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: { width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(105, 177, 255, 0.25)' },
{ offset: 1, color: 'rgba(105, 177, 255, 0.05)' }
])
}
},
{
name: '能源',
type: 'line',
data: seriesData[5].data,
smooth: false,
symbol: 'circle',
symbolSize: 6,
lineStyle: { width: 2 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(206, 79, 81, 0.25)' },
{ offset: 1, color: 'rgba(206, 79, 81, 0.05)' }
])
}
}
]
};
rightChart.setOption(option);
};
const handleResize = () => {
if (leftChart) leftChart.resize();
if (rightChart) rightChart.resize();
};
onMounted(() => {
initLeftDonut();
initRightLine();
window.addEventListener("resize", handleResize);
});
onBeforeUnmount(() => {
window.removeEventListener("resize", handleResize);
if (leftChart) { leftChart.dispose(); leftChart = null; }
if (rightChart) { rightChart.dispose(); rightChart = null; }
});
</script>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
}
.datasub {
width: 1600px;
height: 460px;
display: flex;
justify-content: space-between;
.left {
width: 792px;
height: 460px;
margin-right: 16px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.left-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
}
.select {
width: 120px;
height: 28px;
padding: 0px 12px;
position: absolute;
top: 11px;
right: 31px;
}
}
.left-main {
width: 792px;
height: 412px;
padding: 52px 60px 78px 61px;
.left-main-echarts {
width: 100%;
height: 100%;
}
}
}
.right {
width: 792px;
height: 460px;
border-radius: 10px;
// border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.right-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
}
.select1 {
width: 155px;
height: 28px;
padding: 0px 12px;
position: absolute;
top: 11px;
right: 163px;
}
.select {
width: 120px;
height: 28px;
padding: 0px 12px;
position: absolute;
top: 11px;
right: 31px;
}
}
.right-main {
width: 792px;
height: 421px;
padding: 15px 37px 25px 46px;
.right-main-echarts {
width: 100%;
height: 100%;
}
}
}
}
</style>
<template>
<div class="reslib-page">
<div class="nav">
<div
v-for="item in navList"
:key="item"
class="nav-item"
:class="{ active: item === activeItem }"
@click="handleClickNav(item)"
>
{{ item }}
</div>
</div>
<el-select v-model="value" placeholder="Select" class="select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div class="main" v-show="isShow">
<div class="left">
<div class="left-ti1"></div>
<div class="left-ti2"></div>
<div class="left-title">发布时间</div>
<div class="left-content">
<div v-for="(item, i) in dataList" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }}
</div>
</div>
<div class="left-title cl1">涉及领域</div>
<div class="left-content">
<div v-for="(item, i) in dataList2" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }}
</div>
</div>
</div>
<div class="right">
<div class="right-title">
<img src="./assets/icon01.png" alt="" />
<div>规则限制历程</div>
</div>
<div class="right-main">
<div class="main-content">
<div v-for="item in mainDataList" :key="item.id" class="main-item">
<div class="date">{{ item.date }}</div>
<img :src="item.img" alt="" class="img" />
<div class="box">
<div class="title" @click="handleClick(item)">{{ item.title }}</div>
<div class="content" @click="handleClick(item)">{{ item.content }}</div>
<div class="domain">
<div v-for="(domain, i) in item.domain" :key="i" class="domain-item">{{ domain }}</div>
</div>
<div
class="type"
:class="{
type1: item.type === '行政令',
type2: item.type === '法案',
type3: item.type === '301调查'
}"
>
{{ item.type }}
</div>
</div>
</div>
</div>
<div class="line"></div>
<div class="page">
<div class="count">共1205项调查</div>
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="total"
layout="prev, pager, next"
background
@current-change="handlePageChange"
/>
</div>
</div>
</div>
</div>
<div class="main" v-show="!isShow">
<div class="left-unshow">
<div class="left-ti1"></div>
<div class="left-ti2"></div>
<div class="left-ti3"></div>
<div class="left-title">发布时间</div>
<div class="left-content">
<div v-for="(item, i) in dataList" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }}
</div>
</div>
<div class="left-title cl1">涉及领域</div>
<div class="left-content">
<div v-for="(item, i) in dataList2" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }}
</div>
</div>
<div class="left-title cl2">涉及国家</div>
<div class="left-content">
<div v-for="(item, i) in dataList3" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }}
</div>
</div>
</div>
<div class="right-unshow">
<div class="top">
<div v-for="item in unionDataList" :key="item.id" class="top-item">
<div class="title">
<img :src="item.img" alt="">
<div>
<span class="name">{{ item.name }}</span><span class="abb">{{ item.abb }}</span>
<div class="compose">{{ item.compose }}</div>
</div>
<div class="type" :class="{ type1: item.type === '通信网络', type2: item.type === '集成电路', type3: item.type === '' }">{{ item.type }}</div>
</div>
<div class="content">{{ item.content }}</div>
</div>
</div>
<div class="bottom">
<div class="count">共1205项调查</div>
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="total"
layout="prev, pager, next"
background
@current-change="handlePageChange"
/>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
// import whitehouse from "./assets/白宫.png";
// import guohui from "./assets/国会.png";
// import guotuanquanbu from "./assets/国土安全部.png";
// import guowuyuan from "./assets/国务院.png";
// import weishengyanjiuyuan from "./assets/卫生研究院.png";
// import zhongyiyuan from "./assets/众议院.png";
import fda from "./assets/FDA.png";
import swb from "./assets/商务部.png";
import fcc from "./assets/FCC.png";
import flag01 from "./assets/flag01.png"
import flag02 from "./assets/flag02.png"
import flag03 from "./assets/flag03.png"
import flag04 from "./assets/flag04.png"
import flag05 from "./assets/flag05.png"
import flag06 from "./assets/flag06.png"
import flag07 from "./assets/flag07.png"
import flag08 from "./assets/flag08.png"
import flag09 from "./assets/flag09.png"
const router = useRouter();
const handleClick = item => {
router.push({
path: "/ruleRestriction/detail",
query: {
id: item.id
}
});
};
const isShow = ref(true);
const navList = ref(["规则限制政令", "排华科技联盟"]);
const activeItem = ref("规则限制政令");
const handleClickNav = item => {
activeItem.value = item;
if (item === "规则限制政令") {
isShow.value = true;
} else {
isShow.value = false;
}
};
const value = ref("发布时间");
const options = [
{
value: "发布时间",
label: "发布时间"
},
{
value: "发布日期",
label: "发布日期"
}
];
const dataList = ref([
{
id: 1,
name: "全部时间"
},
{
id: 2,
name: "2025年"
},
{
id: 3,
name: "2024年"
},
{
id: 4,
name: "2023年"
},
{
id: 5,
name: "2022年"
},
{
id: 6,
name: "2021年"
},
{
id: 7,
name: "2020年"
},
{
id: 8,
name: "更早"
}
]);
const dataList2 = ref([
{
id: 1,
name: "全部领域"
},
{
id: 2,
name: "人工智能"
},
{
id: 3,
name: "集成电路"
},
{
id: 4,
name: "通信网络"
},
{
id: 5,
name: "量子科技"
},
{
id: 6,
name: "能源"
},
{
id: 7,
name: "生物科技"
},
{
id: 8,
name: "航空航天"
},
{
id: 9,
name: "海洋"
},
{
id: 10,
name: "先进制造"
}
]);
const dataList3 = ref([
{
id: 1,
name: "全部国家"
},
{
id: 2,
name: "美国"
},
{
id: 3,
name: "日本"
},
{
id: 4,
name: "韩国"
},
{
id: 5,
name: "英国"
},
{
id: 6,
name: "澳大利亚"
},
{
id: 7,
name: "新西兰"
},
{
id: 8,
name: "加拿大"
},
{
id: 9,
name: "欧盟"
},
{
id: 10,
name: "中国台湾"
}
]);
const mainDataList = ref([
{
id: 1,
title: "美国FDA:针对两家中国第三方检测机构的数据完整性问题采取行动",
content:
"FDA因发现数据伪造或无效问题,向两家中国第三方检测公司(天津中联科技检测有限公司和苏州大学卫生与环境技术研究所)正式发出“一般信函”。",
date: "2025年10月15日",
domain: ["生物科技"],
type: "行政令",
img: fda
},
{
id: 2,
title: "美国商务部:扩大实体清单制裁范围,对中企子公司实施同等管制",
content:
"任何被列入美国出口管制“实体清单”或“军事最终用户清单”的企业,如果其直接或间接持有另一家公司 ​50%或以上的股权,那么这家被控股的公司也将自动受到与清单上母公司同等的出口管制限制",
date: "2025年9月30日",
domain: ["生物科技"],
type: "301调查",
img: swb
},
{
id: 3,
title: "美国商务部:出台全面半导体出口管制",
content: "美国商务部宣称将“至少每年”更新一次管制规则,以堵塞已发现的政策“漏洞”。",
date: "2025年9月15日",
domain: ["生物科技"],
type: "行政令",
img: swb
},
{
id: 4,
title: "美国FCC:出台电信设备市场准入认证新规",
content: "将国家安全审查全面嵌入设备授权程序,对实验室资质、测试标准以及供应链设置严格限制。",
date: "2025年9月8日",
domain: ["生物科技", "通信网络"],
type: "行政令",
img: fcc
},
{
id: 5,
title: "美国FCC:发布“清洁购物车”行动,要求电商平台下架违规中国电子产品",
content:
"在亚马逊、eBay等美国主流电商平台销售的华为、海康威视、中兴、大华等中国品牌的消费电子产品(如家用监控摄像头、智能手表)。",
date: "2025年9月1日",
domain: ["集成电路", "人工智能", "通信网络"],
type: "行政令",
img: fcc
},
{
id: 6,
title: "美国FDA:紧急叫停涉及将美国公民活体细胞送往中国等“敌对国家”实验室的临床试验",
content: "涉及将人类生物样本(如活体细胞)转移至中国进行基因工程等研究的临床试验项目,相关研究被叫停。",
date: "2025年8月26日",
domain: ["生物科技"],
type: "行政令",
img: fda
},
{
id: 7,
title: "美国FDA:更新进口预警措施,对多家中国食品企业产品实施​“自动扣留”​​",
content:
"多家中国食品及农产品出口企业(如广东企业罗非鱼、辽宁企业宠物零食等),被扣留的货物必须在FDA或其认可的实验室内检验合格后方可放行。",
date: "2025年8月22日",
domain: ["生物科技"],
type: "行政令",
img: fda
},
{
id: 8,
title: "美国FCC:禁止使用清单内企业零部件的新设备获得授权,并首次可追溯撤销已获批设备的销售许可",
content: "对“受管制清单”实施技术性补封,建立​“回溯机制”​​ 并封闭​“模块发射器”漏洞。",
date: "2025年8月15日",
domain: ["通信网络"],
type: "行政令",
img: fcc
},
{
id: 9,
title: "美国FDA:针对两家中国第三方检测机构的数据完整性问题采取行动",
content:
"FDA因发现数据伪造或无效问题,向两家中国第三方检测公司(天津中联科技检测有限公司和苏州大学卫生与环境技术研究所)正式发出“一般信函”。",
date: "2025年10月15日",
domain: ["生物科技"],
type: "行政令",
img: fda
},
{
id: 10,
title: "美国商务部:出台全面半导体出口管制",
content: "美国商务部宣称将“至少每年”更新一次管制规则,以堵塞已发现的政策“漏洞”。",
date: "2025年9月15日",
domain: ["生物科技"],
type: "行政令",
img: swb
}
]);
const unionDataList = ref([
{
id:1,
name:"AI-RAN联盟",
abb:"QUAD",
compose:"2024年成立 · 美国、英国、日本、韩国、法国、加拿大等10国",
content:"由英伟达牵头,联合软银、亚马逊云科技、微软、爱立信、诺基亚、三星、T-Mobile等多家行业领导者成立了的人工智能无线接入网络技术联盟。",
type:"通信网络",
img:flag01
},
{
id:2,
name:"Next G联盟",
abb:"",
compose:"2021年成立 · 美国、瑞典、芬兰、韩国",
content:"在6G技术研发和未来标准制定上抢先布局,旨在主导6G发展方向,其联盟的排他性被解读为针对中国。",
type:"通信网络",
img:flag02
},
{
id:3,
name:"美日印澳“四边机制”",
abb:"QUAD",
compose:"2021年成立 · 美国、日本、印度、澳大利亚",
content:"在地区安全、基础设施、新兴技术和供应链(特别是半导体)等领域开展排他性合作,筹备构建“印太版北约” 。",
type:"集成电路",
img:flag03
},
{
id:4,
name:"美国半导体联盟",
abb:"SIAC",
compose:"2021年成立 · 美国、韩国、中国台湾、荷兰",
content:"初始核心任务是游说美国政府对本土芯片产业提供补贴(如500亿美元的《芯片法案》),但其成员构成未纳入中国大陆企业,具有明显的“排华”倾向。",
type:"集成电路",
img:flag04
},
{
id:5,
name:"Next G联盟",
abb:"",
compose:"2021年成立 · 美国、瑞典、芬兰、韩国",
content:"在6G技术研发和未来标准制定上抢先布局,旨在主导6G发展方向,其联盟的排他性被解读为针对中国。",
type:"通信网络",
img:flag05
},
{
id:6,
name:"芯片四方联盟",
abb:"Chip 4",
compose:"2020年成立 · 美国、日本、韩国、中国台湾",
content:"构建将中国大陆排除在外的半导体供应链体系,意图在芯片设计、生产到供应环节形成闭环,限制先进芯片技术对华出口。",
type:"集成电路",
img:flag06
},
{
id:7,
name:"美英澳三边安全伙伴关系",
abb:"AUKUS",
compose:"2020年成立 · 美国、英国、澳大利亚",
content:"美英两国支持澳大利亚建立核潜艇部队,旨在深化三国在安全和防务能力上的合作。",
type:"",
img:flag07
},
{
id:8,
name:"印太经济框架",
abb:"IPEF",
compose:"2020年成立 · 美国、英国、澳大利亚",
content:"重点在供应链领域制定新协议,增强透明度与安全性,确保对半导体等关键产品和技术的获取,推动供应链“去中国化”。",
type:"集成电路",
img:flag08
},
{
id:9,
name:"清洁网络计划",
abb:"",
compose:"2019年成立 · 美国、英国、荷兰",
content:"在全球5G网络部署和软件应用生态中排除中国的企业和设备,涉及电信运营商、移动应用、应用商店、云服务和海底光缆等多个层面。",
type:"通信网络",
img:flag09
},
{
id:10,
name:"清洁网络计划",
abb:"",
compose:"2019年成立 · 美国、英国、荷兰",
content:"在全球5G网络部署和软件应用生态中排除中国的企业和设备,涉及电信运营商、移动应用、应用商店、云服务和海底光缆等多个层面。",
type:"通信网络",
img:flag09
}
])
const total = ref(1205);
const pageSize = ref(121);
const currentPage = ref(5);
const handlePageChange = p => {
currentPage.value = p;
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.reslib-page {
width: 1600px;
height: 1565px;
position: relative;
.nav {
width: 332px;
height: 42px;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 34px;
.nav-item {
cursor: pointer;
padding: 8px 20px;
font-size: 20px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(59, 65, 75);
}
.active {
background-color: rgb(5, 95, 194);
border-radius: 21px;
color: #fff;
font-weight: 700;
}
}
.select {
width: 128px;
position: absolute;
top: 7px;
right: 0px;
}
.main {
width: 1600px;
height: 1489px;
display: flex;
.left {
width: 300px;
height: 429px;
margin-right: 16px;
border-radius: 10px;
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-ti1 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 17px;
left: 0px;
}
.left-ti2 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 207px;
left: 0px;
}
.left-title {
margin-left: 25px;
color: rgb(5, 95, 194);
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
margin-top: 13px;
}
.left-content {
width: 253px;
height: 132px;
margin-left: 25px;
margin-top: 13px;
display: flex;
flex-wrap: wrap;
.left-item {
width: 120px;
height: 30px;
margin-bottom: 4px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
input[type="checkbox"] {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
margin-right: 8px;
border: 1px solid rgb(200, 204, 210);
border-radius: 4px;
background-color: #fff;
vertical-align: middle;
}
input[type="checkbox"]:checked {
background-color: rgb(5, 95, 194);
border-color: rgb(5, 95, 194);
}
input[type="checkbox"]:checked::after {
content: "";
display: block;
width: 4px;
height: 8px;
margin: 1px auto 0;
border: 2px solid #fff;
border-top: none;
border-left: none;
transform: rotate(45deg);
}
}
}
.cl1 {
margin-top: 21px;
}
}
.right {
width: 1284px;
height: 1489px;
border-radius: 10px;
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.right-title {
width: 1284px;
height: 48px;
border-bottom: 1px solid rgb(235, 238, 242);
position: relative;
img {
width: 22px;
height: 19px;
position: absolute;
top: 15px;
left: 20px;
}
div {
width: 120px;
height: 48px;
margin-left: 60px;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
padding: 11px 0;
}
}
.right-main {
width: 1284px;
height: 1441px;
padding: 22px 43px 15px 20px;
position: relative;
.main-content {
width: 1221px;
height: 1345px;
.main-item {
width: 1221px;
min-height: 116px;
max-height: 140px;
margin-bottom: 16px;
position: relative;
.date {
position: absolute;
top: 4px;
left: 10px;
width: 62px;
height: 68px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
text-align: right;
}
.img {
width: 24px;
height: 24px;
position: absolute;
top: 13px;
left: 90px;
z-index: 100;
}
.box {
width: 1086px;
min-height: 91px;
max-height: 114px;
position: absolute;
top: 10px;
left: 135px;
.title {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(59, 65, 75);
margin-bottom: 8px;
cursor: pointer;
}
.content {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
margin-bottom: 9px;
cursor: pointer;
}
.type {
padding: 2px 8px;
border-radius: 20px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
position: absolute;
top: 0px;
right: 0px;
}
.type1 {
background-color: rgba(232, 189, 11, 0.1);
color: rgb(232, 189, 11);
}
.type2 {
background-color: rgba(206, 79, 81, 0.1);
color: rgb(206, 79, 81);
}
.type3 {
background-color: rgba(255, 149, 77, 0.1);
color: rgb(255, 149, 77);
}
.domain {
margin-bottom: 15px;
display: flex;
.domain-item {
padding: 2px 8px;
border-radius: 4px;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 20px;
margin-right: 8px;
color: rgb(5, 95, 194);
background-color: rgba(231, 243, 255, 1);
}
}
}
}
}
.line {
height: 1150px;
border: 2px solid rgb(235, 238, 242);
position: absolute;
top: 75px;
left: 120px;
z-index: 1;
}
.page {
width: 1221px;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
position: absolute;
bottom: 20px;
left: 20px;
padding-left: 11px;
.count {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
// box-shadow: 0 0 0 2px rgba(47, 122, 229, 0.15) inset;
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
}
}
}
.left-unshow {
width: 300px;
height: 654px;
margin-right: 16px;
border-radius: 10px;
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-ti1 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 17px;
left: 0px;
}
.left-ti2 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 207px;
left: 0px;
}
.left-ti3 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 434px;
left: 0px;
}
.left-title {
margin-left: 25px;
color: rgb(5, 95, 194);
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
margin-top: 13px;
}
.left-content {
width: 253px;
height: 132px;
margin-left: 25px;
margin-top: 13px;
display: flex;
flex-wrap: wrap;
.left-item {
width: 120px;
height: 30px;
margin-bottom: 4px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
input[type="checkbox"] {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
margin-right: 8px;
border: 1px solid rgb(200, 204, 210);
border-radius: 4px;
background-color: #fff;
vertical-align: middle;
}
input[type="checkbox"]:checked {
background-color: rgb(5, 95, 194);
border-color: rgb(5, 95, 194);
}
input[type="checkbox"]:checked::after {
content: "";
display: block;
width: 4px;
height: 8px;
margin: 1px auto 0;
border: 2px solid #fff;
border-top: none;
border-left: none;
transform: rotate(45deg);
}
}
}
.cl1 {
margin-top: 21px;
}
.cl2 {
margin-top: 58px;
}
}
.right-unshow {
width: 1284px;
height: 1020px;
position: relative;
.top {
width: 1284px;
height: 964px;
display: flex;
flex-wrap: wrap;
margin-bottom: 24px;
.top-item {
width: 634px;
height: 180px;
background-color: #fff;
margin-bottom: 16px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
padding: 18px 33px 18px 26px;
.title {
width: 574px;
height: 72px;
display: flex;
position: relative;
border-bottom: 1px solid rgb(234, 236, 238);
margin-bottom: 12px;
img {
width: 52px;
height: 52px;
margin-right: 16px;
}
.type {
position: absolute;
top: 0;
right: 0;
border-radius: 4px;
border: 1px solid;
padding: 2px 8px;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 20px;
}
.name {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(59, 65, 75);
display: inline-block;
margin-bottom: 4px;
margin-right: 10px;
}
.abb {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.compose {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.type1 {
border-color: rgba(145, 202, 255, 1);
color: rgba(22, 119, 255, 1);
background-color: rgba(230, 244, 255, 1);
}
.type2 {
border-color: rgba(255, 163, 158, 1);
color: rgba(245, 34, 45, 1);
background-color: rgba(255, 241, 240, 1);
}
.type3 {
border: none;
}
}
.content {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(95, 101, 108);
}
}
.top-item:nth-child(2n) {
margin-right: 0px;
}
.top-item:nth-child(2n-1) {
margin-right: 16px;
}
}
.bottom {
width: 1284px;
height: 32px;
display: flex;
align-items: center;
justify-content: space-between;
position: absolute;
bottom: 0px;
left: 0px;
.count {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
// box-shadow: 0 0 0 2px rgba(47, 122, 229, 0.15) inset;
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
}
}
}
}
</style>
<template>
<div class="cooperation-restrictions-detail">
<div class="nav">
<div class="nav-main">
<img src="./assets/image01.png" alt="" />
<div class="content">
<div class="cl1">美国联邦通信委员会(FCC)启动程序撤销对 TUV/宁波的认可</div>
<div class="cl2">FCC Begins Proceedings to Withdraw Recognition of TUV/Ningbo</div>
<div class="cl3">2025年10月24日 10:33 · 美国联邦通信委员会</div>
</div>
<div class="btn">
<button class="btn1"><img src="./assets/icon01.png" alt="" />查看原文</button>
<button class="btn1"><img src="./assets/icon02.png" alt="" />查看官网</button>
<button class="btn1 active"><img src="./assets/icon03.png" alt="" />分析报告</button>
</div>
</div>
</div>
<div class="title">
<span class="title-one">当前合作限制数据已关联至行政令:</span>
<span class="title-two">《美国联邦通信委员会(FCC)启动程序撤销对 TUV/宁波的认可》2025年10月24日</span>
<img src="./assets/right.png" alt="" />
</div>
<div class="main">
<div class="left">
<!-- 制裁概况 -->
<div class="left-top">
<img class="img1" src="./assets/bluetitle.png" alt="" />
<div class="left-top-title">制裁概况</div>
<img class="img2" src="./assets/下载按钮.png" alt="" />
<img class="img3" src="./assets/收藏按钮.png" alt="" />
<div class="left-top-content">
<span
>美国联邦通信委员会(FCC)启动程序撤销对德国莱茵 TÜV 集团/中国检验认证集团(宁波)有限公司作为测试认可实验室的认证。</span
>
</div>
<div class="left-top-bottom">
<div><span class="tit">限制时间:</span><span class="tit1">2025年10月24日</span></div>
<div><span class="tit">限制机构:</span><span class="tit1 tit2">美国联邦通信委员会(FCC) ></span></div>
<div><span class="tit">限制手段:</span><span class="tit1">行政令</span></div>
<div><span class="tit">限制领域:</span><span class="tit3">集成电路</span></div>
</div>
</div>
<!-- 受限实体 -->
<div class="left-bottom">
<img class="img1" src="./assets/bluetitle.png" alt="" />
<div class="left-bottom-title">受限实体</div>
<img class="img2" src="./assets/下载按钮.png" alt="" />
<img class="img3" src="./assets/收藏按钮.png" alt="" />
<div class="left-bottom-main">
<div v-for="item in dataList" :key="item.id" class="main-box">
<img :src="item.img" alt="" />
<div class="name">{{ item.name }}</div>
<div class="type">{{ item.type }}</div>
</div>
<img src="./assets/注意.png" alt="">
</div>
</div>
<!-- 规则限制事件脉络 -->
<div class="left-bottom-B">
<img class="img1" src="./assets/bluetitle.png" alt="" />
<div class="left-bottom-title">规则限制事件脉络</div>
<img class="img2" src="./assets/下载按钮.png" alt="" />
<img class="img3" src="./assets/收藏按钮.png" alt="" />
<div class="left-bottom-main">
<div v-for="item in objList" :key="item.id" class="main-box">
<img :src="item.img" alt="" />
<div class="time">{{ item.time }}</div>
<div class="name">{{ item.name }}</div>
</div>
<div class="btn">查看更多 <img src="./assets/doubleLine.png" alt=""></div>
<div class="line"></div>
</div>
</div>
</div>
<div class="right">
<!-- 背景分析 -->
<div class="right-bottom">
<img class="img1" src="./assets/bluetitle.png" alt="" />
<div class="right-bottom-title">背景分析</div>
<div class="right-bottom-content1">
<div class="right-bottom-content1-title">
<span>(一)法律框架 </span>
<img src="./assets/打开按钮.png" alt="">
</div>
<div class="right-bottom-content1-content">
《法案》第302条授权联邦通信委员会(以下简称委员会或FCC)制定符合公共利益的规则,管理能够发射射频(RF)能量设备的干扰潜力。该法案还允许委员会授权私人机构(测试实验室)进行符合这些规则的合规性测试,并为这些测试实验室建立适当的资质和标准。委员会不会认可未能满足所有适当标准的任何测试实验室,包括与测试实验室的诚信和可靠性相关的标准。委员会的规则部分规定,“确保参与FCC设备授权计划的测试实验室不受对国家安全构成风险的不可信行为者的所有权、指挥或控制。”
</div>
</div>
<div class="right-bottom-content2">
<div class="right-bottom-content2-title">
<span>(二)事实背景 </span>
<img src="./assets/打开按钮.png" alt="">
</div>
<div class="right-bottom-content2-content">
TUV/宁波是一家位于中国浙江宁波的认可测试实验室,被FCC认可可对各种射频设备进行测试,以确保符合适用的FCC规则。根据美国实验室认可协会(A2LA)的信息,TUV/宁波的认证表明该实验室已按照公认的国际标准ISO/IEC 17025:2017《测试和校准实验室能力的一般要求》获得认可。自首次获得认证以来,TUV/宁波已进行的测试促成了数百项设备认证。TUV/宁波通过与中国检验认证集团有限公司(CCIC集团,一家国有企业)的合作与中国政府相连接。作为CCIC集团的分支机构,TUV/宁波直接隶属于一家与中华人民共和国政府有重要联系和监督关系的国有企业。美国商务部已认定中华人民共和国是一个外国对手。
</div>
</div>
<div class="right-bottom-content3">
<div class="right-bottom-content3-title">
<span>(二)其他背景 </span>
<img src="./assets/打开按钮.png" alt="">
</div>
<div class="right-bottom-content3-content">
中华人民共和国(PRC)是一个禁止实体,根据委员会规则第2.902条的规定进行识别。OET 已初步确定 TUV/宁波由中华人民共和国拥有、控制或受其指令管理,根据委员会规则第2.951(d)(1)条和第2.902条,中华人民共和国是一个禁止实体。TUV/宁波在其为 FCC 设备认证申请出具的测试实验室报告中,将自己标识为“莱茵TÜV/CCIC(宁波)有限公司”,并将其网站地址标识为“www.tuv.com”。TUV/宁波的合资企业隶属于 CCIC 集团。CCIC 集团的网站列出了中国检验认证集团宁波有限公司(TUV/宁波合资企业的一部分)作为其在中国的子公司之一。CCIC 集团是一家国有企业,经中华人民共和国国务院批准成立,并受国务院国有资产监督管理委员会(SASAC)监管。SASAC 对国有资产和企业行使全面控制和监督,其职能直接由中央委员会授权。
</div>
</div>
</div>
<!-- 限制条款 -->
<div class="right-top">
<img class="img1" src="./assets/bluetitle.png" alt="" />
<div class="right-top-title">限制条款</div>
<div class="right-top-content">
<div v-for="item in dataList2" :key="item.id" class="right-top-item">
<span class="id">{{ item.id }}</span>
<span class="name">{{ item.name }}</span>
<img src="./assets/打开按钮.png" alt="" />
</div>
</div>
</div>
<!-- 相关举措 -->
<div class="right-top-b">
<img class="img1" src="./assets/bluetitle.png" alt="" />
<div class="right-top-title">相关举措</div>
<div class="right-top-content">
<div v-for="item in dataList3" :key="item.id" class="right-top-item">
<img :src="item.img" alt="">
<div class="name">{{ item.name }}</div>
<div class="time">{{ item.time }}</div>
<div class="type" :class="{'type1': item.type === '行政令', 'type2': item.type === '法案'}">{{ item.type }}</div>
<div class="content">{{ item.content }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import ningbo from "./assets/ningbo.png"
import deguo from "./assets/deguo.png"
import cycle from "./assets/cycle.png"
import swb from "./assets/商务部.png"
import bg from "./assets/白宫.png"
import czb from "./assets/财政部.png"
import gh from "./assets/国会.png"
const dataList = ref([
{
id: 1,
name: "中国检验认证集团(宁波)有限公司",
type: "",
img: ningbo
},
{
id: 2,
name: "德国莱茵 TÜV 集团",
type: "",
img: deguo
}
]);
const objList = ref([
{
id: 1,
name: "撤销多家中国实验室对进入美国市场电子产品的测试认证许可。",
time: "2025-08-30",
img: cycle
},
{
id: 2,
name: "禁止被认定存在“国家安全风险”的中国实验室为进入美国市场的电子设备(如手机、电脑)提供FCC要求的合规性测试与认...",
time: "2025-08-30",
img: cycle
},
{
id: 3,
name: "禁止授权进口或销售任何新设备。新规进一步禁止新设备中使用这些清单内公司的零部件,并允许FCC撤销已授权设备的许可。",
time: "2025-08-30",
img: cycle
},
{
id: 4,
name: "撤销或终止中国电信运营商在美国提供国际电信服务的授权。",
time: "2025-08-30",
img: cycle
},
{
id: 5,
name: "禁止使用特定中国技术和设备的公司建造或运营连接美国的通信电缆。",
time: "2025-08-30",
img: cycle
}
])
const dataList2 = ref([
{
id: 1,
name: "根据本命令,OET认定TUV/宁波没有说明委员会为何不应开始撤销其作为认可测试实验室资格的程序。在其回应中,TUV/宁波声称其不受委员会规则下的禁止实体控制或指挥,但未说明其被禁止实体持有的股权。TUV/宁波的公司治理文件显示,CCIC是公司的股东,并出资占公司创立资本的49%."
},
{
id: 2,
name: "TUV/宁波必须在本命令发布后三十五(35)天内提交回复,说明委员会为何不应撤销其认可。如果未能及时回复或提交说明委员会不应撤销其认可的合理依据的回复,可能会导致撤销认可。公司的回复必须包含一份书面详细事实说明,充分说明公司是否由中华人民共和国拥有、控制或受其指示。"
},
{
id: 3,
name: "OET 根据《法案》第302(e)条以及委员会规则第2.951(d)和(e)条启动了一个程序,以最终确定是否撤销对TUV/Ningbo作为认可测试实验室的认可。此程序为公司提供了额外的通知和机会,以提交书面回应,说明委员会为何不应撤销其当前的认可。"
}
]);
const dataList3 = ref([
{
id: 1,
name: "美国商务部工业与安全局发布实体清单,涉及多家中国半导体企业",
time: "2025年9月12日",
content:"23家中国实体,包括复旦微电旗下多家公司、华岭股份等,指控这些实体“违背美国国家安全或外交政策利益”,包括为中国的...",
type:'行政令',
img: swb
},
{
id: 2,
name: "美国白宫发布总统政令,提出将发展美国人工智能产业硬件支持放在新任期的科技首要地位",
time: "2025年9月11日",
content:"9个中国实体​(8家企业和1名个人),例如湖北奇卡工业有限公司、广州雅凯国际货运代理有限公司等,指控这些实体为也门胡塞...",
type:'行政令',
img: bg
},
{
id: 3,
name: "美国财政部外国资产控制办公室指控中国企业及船只",
time: "2025年3月13日",
content:"​4家中国企业和3艘关联船只​(如香港和顺运贸有限公司、华夏贸易有限公司等),指控这些公司拥有或运营向中国运送伊朗石油或...",
type:'行政令',
img: czb
},
{
id: 4,
name: "美国国会通过《芯片科学》法案",
time: "2025年1月3日",
content:"​多家中国实体,包括成都雷电微力科技股份有限公司、中国科学院长春光学精密机械与物理研究所等,指控这些实体与中国高超音...",
type:'法案',
img: gh
},
])
</script>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
}
.cooperation-restrictions-detail {
width: 100%;
height: 100%;
background: rgba(243, 243, 244, 1);
overflow: auto;
padding-bottom: 50px;
.nav {
width: 100%;
height: 120px;
padding: 19px 0 20px;
background: rgba(255, 255, 255, 1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.nav-main {
width: 1600px;
height: 81px;
margin: 0 auto;
display: flex;
align-items: center;
img {
width: 72px;
height: 72px;
margin-right: 16px;
}
.content {
width: 758px;
height: 81px;
margin-right: 378px;
.cl1 {
font-size: 24px;
font-weight: 700;
line-height: 32px;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
margin-bottom: 1px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
margin-bottom: 1px;
}
.cl3 {
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
}
}
.btn {
width: 376px;
height: 36px;
display: flex;
.btn1 {
border-radius: 6px;
border: 1px solid rgb(230, 231, 232);
width: 120px;
height: 36px;
background-color: #fff;
margin-right: 8px;
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 8px;
}
font-size: 16px;
font-weight: 400;
line-height: 22px;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
}
.active {
background-color: rgb(5, 95, 194);
color: #fff;
}
}
}
}
.title {
width: 1600px;
height: 50px;
margin: 16px auto;
border-radius: 10px;
border: 1px solid rgba(174, 214, 255, 1);
background-color: rgba(246, 250, 255, 1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
display: flex;
align-items: center;
position: relative;
.title-one {
margin-left: 23px;
font-size: 16px;
font-weight: 400;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(59, 65, 75);
}
.title-two {
font-size: 16px;
font-weight: 700;
line-height: 24px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
cursor: pointer;
}
img {
width: 24px;
height: 24px;
position: absolute;
top: 13px;
right: 13px;
cursor: pointer;
}
}
.main {
width: 1600px;
height: 1373px;
margin: 0 auto;
display: flex;
.left {
width: 520px;
height: 1157px;
margin-right: 17px;
.left-top {
margin-bottom: 16px;
width: 520px;
height: 368px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-top-title {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
position: absolute;
top: 14px;
left: 22px;
}
.img1 {
width: 8px;
height: 20px;
position: absolute;
left: 0px;
top: 18px;
}
.img2 {
width: 28px;
height: 28px;
position: absolute;
top: 14px;
right: 44px;
cursor: pointer;
}
.img3 {
width: 28px;
height: 28px;
position: absolute;
top: 14px;
right: 12px;
cursor: pointer;
}
.left-top-content {
width: 470px;
height: 122px;
border-radius: 4px;
border: 1px solid rgba(231, 243, 255, 1);
background-color: rgba(246, 250, 255, 1);
position: absolute;
top: 58px;
left: 26px;
display: flex;
justify-content: center;
align-items: center;
padding: 16px 24px;
span {
font-size: 16px;
font-weight: 700;
line-height: 30px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
}
}
.left-top-bottom {
width: 460px;
height: 144px;
position: absolute;
top: 200px;
left: 26px;
div {
height: 24px;
margin-bottom: 16px;
.tit {
display: inline-block;
width: 120px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.tit1 {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
}
.tit2 {
color: rgb(5, 95, 194);
cursor: pointer;
}
.tit3 {
display: inline-block;
border-radius: 4px;
background-color: rgba(255, 241, 240, 1);
border: 1px solid rgba(255, 163, 158, 1);
color: rgba(245, 34, 45, 1);
padding: 2px 8px;
}
}
}
}
.left-bottom {
width: 520px;
height: 190px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
margin-bottom: 16px;
.left-bottom-title {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
position: absolute;
top: 14px;
left: 22px;
}
.img1 {
width: 8px;
height: 20px;
position: absolute;
left: 0px;
top: 18px;
}
.img2 {
width: 28px;
height: 28px;
position: absolute;
top: 14px;
right: 44px;
cursor: pointer;
}
.img3 {
width: 28px;
height: 28px;
position: absolute;
top: 14px;
right: 12px;
cursor: pointer;
}
.left-bottom-main {
width: 478px;
height: 108px;
position: absolute;
top: 60px;
left: 21px;
img {
position: absolute;
top: 12px;
right: 12px;
}
.main-box {
width: 480px;
height: 48px;
border-radius: 50px;
border: 1px solid rgb(234, 236, 238);
margin-bottom: 12px;
position: relative;
cursor: pointer;
img {
width: 24px;
height: 24px;
position: absolute;
top: 12px;
left: 16px;
}
.name {
position: absolute;
top: 12px;
left: 52px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.type {
position: absolute;
top: 12px;
right: 12px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
}
}
}
.left-bottom-B {
width: 520px;
height: 567px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-bottom-title {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
position: absolute;
top: 14px;
left: 22px;
}
.img1 {
width: 8px;
height: 20px;
position: absolute;
left: 0px;
top: 18px;
}
.img2 {
width: 28px;
height: 28px;
position: absolute;
top: 14px;
right: 44px;
cursor: pointer;
}
.img3 {
width: 28px;
height: 28px;
position: absolute;
top: 14px;
right: 12px;
cursor: pointer;
}
.left-bottom-main {
width: 478px;
height: 446px;
position: absolute;
top: 60px;
left: 24px;
.main-box {
width: 495px;
margin-bottom: 16px;
padding: 0 22px 0 0px;
position: relative;
img {
width: 10px;
height: 10px;
position: absolute;
top: 6px;
left: 0;
z-index: 100;
}
.time {
margin-left: 21px;
margin-bottom: 4px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
}
.name {
margin-left: 21px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
}
}
.btn {
cursor: pointer;
width: 100%;
margin-top: 3px;
text-align: center;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgb(5, 95, 194);
img {
width: 16px;
height: 16px;
}
}
.line {
position: absolute;
height: 360px;
border: 2px solid rgb(235, 238, 242);
top: 5px;
left: 2.5px;
}
}
}
}
.right {
width: 1063px;
height: 1800px;
.right-top {
margin-bottom: 16px;
width: 1063px;
height: 396px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
padding: 60px 19px 24px 22px;
.right-top-title {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
position: absolute;
top: 14px;
left: 22px;
}
.img1 {
width: 8px;
height: 20px;
position: absolute;
left: 0px;
top: 18px;
}
.right-top-content {
width: 1022px;
height: 312px;
.right-top-item {
width: 1022px;
padding: 12px 0px;
position: relative;
display: flex;
align-items: center;
border-top: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
}
// .right-top-item:nth-child(odd) {
// background-color: rgb(247, 248, 249);
// border-top: 1px solid rgb(234, 236, 238);
// border-bottom: 1px solid rgb(234, 236, 238);
// }
.right-top-item .id {
display: inline-block;
width: 24px;
height: 24px;
font-size: 12px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
background-color: rgba(231, 243, 255, 1);
text-align: center;
border-radius: 50%;
position: absolute;
top: 16px;
left: 24px;
}
.right-top-item .name {
display: inline-block;
width: 902px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
margin-left: 64px;
}
.right-top-item img {
width: 16px;
height: 31px;
position: absolute;
top: 12px;
right: 24px;
cursor: pointer;
}
}
.btn {
padding: 2px 8px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
border-radius: 4px;
border: 1px solid rgb(230, 231, 232);
background-color: #fff;
cursor: pointer;
position: absolute;
z-index: 100;
}
.cl1 {
top: 14px;
right: 107px;
}
.cl2 {
top: 14px;
right: 19px;
}
.active {
color: rgb(5, 95, 194);
background-color: rgba(246, 250, 255, 1);
border-color: rgb(5, 95, 194);
}
}
.right-bottom {
width: 1063px;
height: 817px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
margin-bottom: 16px;
.right-bottom-title {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
position: absolute;
top: 14px;
left: 22px;
}
.img1 {
width: 8px;
height: 20px;
position: absolute;
left: 0px;
top: 18px;
}
.btn {
padding: 2px 8px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
border-radius: 4px;
border: 1px solid rgb(230, 231, 232);
background-color: #fff;
cursor: pointer;
position: absolute;
z-index: 100;
}
.cl1 {
top: 14px;
right: 107px;
}
.cl2 {
top: 14px;
right: 19px;
}
.active {
color: rgb(5, 95, 194);
background-color: rgba(246, 250, 255, 1);
border-color: rgb(5, 95, 194);
}
.right-bottom-content1 {
width: 1022px;
height: 199px;
position: absolute;
top: 60px;
left: 22px;
margin-bottom: 24px;
.right-bottom-content1-title {
width: 1022px;
height: 55px;
padding: 14px 56px 17px 24px;
display: flex;
align-items: center;
position: relative;
background-color: rgb(247, 248, 249);
border-top: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
img {
width: 16px;
height: 31px;
position: absolute;
right: 24px;
top: 14px;
cursor: pointer;
}
}
.right-bottom-content1-content {
width: 1022px;
height: 144px;
padding: 12px 24px 12px 78px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
border-bottom: 1px solid rgb(234, 236, 238);
}
}
.right-bottom-content2 {
width: 1022px;
height: 229px;
position: absolute;
top: 283px;
left: 22px;
margin-bottom: 24px;
.right-bottom-content2-title {
width: 1022px;
height: 55px;
padding: 14px 56px 17px 24px;
display: flex;
align-items: center;
position: relative;
background-color: rgb(247, 248, 249);
border-top: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
img {
width: 16px;
height: 31px;
position: absolute;
right: 24px;
top: 14px;
cursor: pointer;
}
}
.right-bottom-content2-content {
width: 1022px;
height: 174px;
padding: 12px 24px 12px 78px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
border-bottom: 1px solid rgb(234, 236, 238);
}
}
.right-bottom-content3 {
width: 1022px;
height: 169px;
position: absolute;
top: 536px;
left: 22px;
margin-bottom: 24px;
.right-bottom-content3-title {
width: 1022px;
height: 55px;
padding: 14px 56px 17px 24px;
display: flex;
align-items: center;
position: relative;
background-color: rgb(247, 248, 249);
border-top: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
img {
width: 16px;
height: 31px;
position: absolute;
right: 24px;
top: 14px;
cursor: pointer;
}
}
.right-bottom-content3-content {
width: 1022px;
height: 114px;
padding: 12px 24px 12px 78px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
border-bottom: 1px solid rgb(234, 236, 238);
}
}
}
.right-top-b {
margin-bottom: 50px;
width: 1063px;
height: 509px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
padding: 60px 19px 28px 22px;
.right-top-title {
font-size: 20px;
font-weight: 700;
line-height: 26px;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
position: absolute;
top: 14px;
left: 22px;
}
.img1 {
width: 8px;
height: 20px;
position: absolute;
left: 0px;
top: 18px;
}
.right-top-content {
width: 1022px;
height: 421px;
.right-top-item {
width: 1022px;
height: 104px;
border-bottom: 1px solid rgb(234, 236, 238);
border-top: 1px solid rgb(234, 236, 238);
padding: 12px 0;
position: relative;
img {
width: 24px;
height: 24px;
position: absolute;
left: 26px;
top: 12px;
}
.type {
position: absolute;
right: 48px;
top: 11px;
padding: 2px 8px;
border-radius: 20px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
}
.type1 {
background-color: rgba(232, 189, 11, 0.1);
color: rgb(232, 189, 11);
}
.type2 {
background-color: rgba(231, 243, 255, 1);
color: rgb(5, 95, 194);
}
.name {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
margin-left: 65px;
margin-bottom: 4px;
}
.time {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
margin-left: 65px;
}
.content {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(95, 101, 108);
margin-left: 65px;
}
}
}
}
}
}
}
</style>
<template>
<div class="coop-page">
<!-- 面包屑 -->
<div class="breadcrumb">
<div class="breadcrumb-box">
<div class="breadcrumb-item">国家科技安全</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div>
<div class="breadcrumb-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div>
<div class="breadcrumb-item">规则限制</div>
</div>
</div>
<!-- 主页面 -->
<div class="main-content">
<!-- 搜索栏部分 -->
<div class="search">
<div class="search-main">
<input v-model="input" placeholder="搜索规则限制" class="search-input" />
<div class="search-btn">
<img src="./assets/icons/search-icon.png" alt="" />
搜索
</div>
</div>
<div class="search-center">
<div class="search-item">
<div class="search-item-num">190</div>
<div class="search-item-name">规则限制政令</div>
</div>
<div class="search-item">
<div class="search-item-num">125</div>
<div class="search-item-name">规则限制实体</div>
</div>
<div class="search-item">
<div class="search-item-num">18</div>
<div class="search-item-name">排华科技联盟</div>
</div>
<div class="search-item">
<div class="search-item-num">12</div>
<div class="search-item-name">排华国家数量</div>
</div>
</div>
<div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div>
<div class="btn-icon">></div>
</div>
<div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-icon">></div>
</div>
<div class="btn" @click="scrollToTop('position3')">
<div class="btn-text">数据总览</div>
<div class="btn-icon">></div>
</div>
<div class="btn" @click="scrollToTop('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">></div>
</div>
</div>
</div>
<!-- 最新动态 -->
<div class="newdata" id="position1">
<com-title title="最新动态" />
<div class="newdata-main">
<newData />
</div>
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<div class="ask-main">
<askPage />
</div>
</div>
<!-- 数据总览 -->
<div class="datasub" id="position3">
<com-title title="数据总览" />
<div class="datasub-main">
<dataSub />
</div>
</div>
<!-- 资源库 -->
<div class="reslib" id="position4">
<com-title title="资源库" />
<div class="reslib-main">
<resLib />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import comTitle from "./common/comTitle.vue";
import newData from "./components/dataNew/index.vue";
import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow";
// 搜索框
const input = ref("");
const router = useRouter();
// 返回首页
const handleBackHome = () => {
router.push({
path: "/overview"
});
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.coop-page {
width: 100%;
height: 100%;
.breadcrumb {
width: 100%;
height: 64px;
background-image: url("./assets/images/bread-bg.png");
background-size: cover;
padding: 17px 0px 21px 0px;
.breadcrumb-box {
margin-left: 160px;
display: flex;
// align-items: center;
.breadcrumb-item {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 30px;
color: #fff;
}
.back-item {
cursor: pointer;
&:hover {
color: #999;
}
}
}
}
.main-content {
overflow: auto;
width: 100%;
height: calc(100% - 64px);
background: url("./assets/images/background.png");
background-size: 100% 100%;
padding: 44px 160px 30px 160px;
.search {
width: 960px;
height: 225px;
margin: 0 auto 68px auto;
.search-main {
display: flex;
padding-right: 3px;
align-items: center;
justify-content: space-between;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
width: 960px;
height: 48px;
background-color: rgba(255, 255, 255, 0.65);
border-radius: 10px;
border: 1px solid #fff;
&:hover{
border: 1px solid var(--color-main-active);
}
.search-input {
border: none;
outline: none;
width: 800px;
height: 48px;
background-color: transparent;
font-size: 16px;
padding: 12px 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
}
.search-btn {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 46px;
margin-right: -3px;
border-radius: 8px;
background-color: rgb(5, 95, 194);
font-size: 18px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: #fff;
img {
width: 22px;
height: 22px;
margin-right: 8px;
}
}
}
.search-center {
width: 600px;
height: 57px;
margin: 36px auto;
display: flex;
align-items: center;
justify-content: space-between;
.search-item {
box-sizing: border-box;
width: 120px;
height: 57px;
.search-item-num {
width: 120px;
height: 22px;
font-size: 36px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgb(5, 95, 194);
text-align: center;
cursor: pointer;
}
.search-item-name {
width: 120px;
height: 24px;
margin-top: 11px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
text-align: center;
}
}
}
.search-bottom {
width: 688px;
height: 48px;
margin: 0 auto;
display: flex;
justify-content: space-between;
// gap: 16px;
.btn {
display: flex;
width: 160px;
height: 48px;
border: 1px solid rgba(174, 214, 255, 1);
box-sizing: border-box;
border-radius: 32px;
justify-content: center;
align-items: center;
background: rgba(231, 243, 255, 1);
position: relative;
cursor: pointer;
padding: 10px 40px 12px 36px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
&:hover {
background: #cae3fc;
}
.btn-text {
color: rgb(5, 95, 194);
font-family: "Microsoft YaHei";
font-size: 20px;
font-weight: 400;
line-height: 26px;
height: 26px;
}
.btn-icon {
position: absolute;
top: 14px;
right: 19px;
color: rgb(5, 95, 194);
font-size: 20px;
font-weight: 400;
}
}
}
}
.newdata {
width: 1600px;
height: 538px;
margin: 36px auto 64px auto;
.newdata-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.ask {
width: 1600px;
height: 528px;
margin: 0 auto 64px auto;
.ask-main {
width: 1600px;
height: 450px;
margin-top: 36px;
}
}
.datasub {
width: 1600px;
height: 538px;
margin: 0 auto 88px auto;
.datasub-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.reslib {
width: 1600px;
height: 1633px;
margin: 0 auto 0px auto;
.reslib-main {
width: 1600px;
height: 1565px;
margin-top: 26px;
}
}
}
}
</style>
<template>
<div class="com-title">
<div class="cl1"></div>
<div class="cl2"></div>
<div class="title">{{ title }}</div>
<div class="cl3"></div>
</div>
</template>
<script setup>
import { ref } from "vue";
// 传入的title数据
const props = defineProps({
title: {
type: String,
default: ""
}
});
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.com-title {
width: 1575px;
height: 42px;
display: flex;
align-items: center;
.cl1 {
width: 24px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.cl2 {
width: 8px;
height: 30px;
background-color: rgba(174, 214, 255, 1);
margin-right: 8px;
}
.title {
width: 152px;
height: 42px;
text-align: center;
font-size: 32px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 42px;
margin-right: 8px;
}
.cl3 {
width: 1367px;
height: 1px;
background-color: rgba(174, 214, 255, 1);
box-sizing: border-box;
}
}
</style>
<template>
<div class="ask-page">
<div class="left">
<div class="left-title">
<img src="./assets/icon01.png" alt="">
<div class="tit">新闻资讯</div>
<div class="more" @click="handleToMoreNews">更多 +</div>
</div>
<div class="left-main">
<div v-for="item in leftList" :key="item.id" class="main-item">
<img :src="item.image" alt="">
<div class="item-content">
<div class="title">{{item.title}}</div>
<div class="content">{{item.content}}</div>
<div class="time">{{item.time}}</div>
</div>
</div>
</div>
</div>
<div class="right">
<div class="right-title">
<img src="./assets/icon02.png" alt="">
<div class="tit">社交媒体</div>
<div class="more">更多 +</div>
</div>
<div class="right-main">
<div class="trump">
<img src="./assets/title01.png" alt="">
<div class="trump-main">
<div class="cl1">{{ rightList[0].name }}</div>
<div class="cl2">{{ rightList[0].content }}</div>
<div class="cl3">{{ rightList[0].time }}</div>
</div>
</div>
<div class="mask">
<img src="./assets/title02.png" alt="">
<div class="mask-main">
<div class="cl1">{{ rightList[1].name }}</div>
<div class="cl2">{{ rightList[1].content }}</div>
<div class="cl3">{{ rightList[1].time }}</div>
</div>
</div>
<div class="malaby">
<img src="./assets/title03.png" alt="">
<div class="malaby-main">
<div class="cl1">{{ rightList[2].name }}</div>
<div class="cl2">{{ rightList[2].content }}</div>
<div class="cl3">{{ rightList[2].time }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import router from "@/router"
import image01 from './assets/image01.png'
import image02 from './assets/image02.png'
import image03 from './assets/image03.png'
import image04 from './assets/image04.png'
import image05 from './assets/image05.png'
import title01 from './assets/title01.png'
import title02 from './assets/title02.png'
import title03 from './assets/title03.png'
const leftList = ref([
{
id:1,
title:'美国NSF寻求建立政企共同资助的研究生奖学金模式',
content:'美国国家科学基金会(NSF)开始寻求建立与行业合作伙伴共同资助的新研究生奖学金计划...',
time:'11-4 · 华盛顿邮报',
image:image01
},
{
id:2,
title:'美国NSF投资2.8亿美元支持人工智能项目开发',
content:'自7月23日白宫发布《赢得人工智能竞赛:美国人工智能行动计划》以来,美国国家科学基...',
time:'11-4 · 纽约时报',
image:image02
},
{
id:3,
title:'美国NASA资助地球观测和大型望远镜新技术',
content:'美国国家航空航天局(NASA)先后资助两项任务,以促进地球观测和大型望远镜新技术的...',
time:'11-3 · 洛杉矶时报',
image:image03
},
{
id:4,
title:'美国NSF、NIH和FDA支持数字医学孪生技术应用开发',
content:'美国国家科学基金会(NSF)、美国国立卫生研究院(NIH)和美国食品药品监督管理局(F...',
time:'11-3 · 今日美国',
image:image04
},
{
id:5,
title:'美国NIH拨款推进All of Us研究计划数据集应用',
content:'美国国立卫生研究院(NIH)宣布拨款970万美元,支持利用“All of Us”研究计划的数据...',
time:'11-2 · ​福克斯新闻网',
image:image05
}
])
const rightList = ref([
{
id:1,
name:'唐纳德·特朗普',
content:'埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。',
time:'15:23 · 发布于真实社交',
title:title01
},
{
id:2,
name:'埃隆·马斯克',
content:'如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。',
time:'14:49 · 发布于X',
title:title02
},
{
id:3,
name:'塞巴斯蒂安·马拉比',
content:'提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。',
time:'11:05 · 发布于X',
title:title03
}
])
// 查看更多新闻资讯
const handleToMoreNews = () => {
const route = router.resolve("/newsBrief");
window.open(route.href, "_blank");
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.ask-page {
width: 1600px;
height: 450px;
display: flex;
justify-content: space-between;
.left {
width: 792px;
height: 450px;
margin-right: 16px;
border-radius: 10px;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.left-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
width: 80px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 26px;
color: rgb(5, 95, 194);
}
.more {
width: 49px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
top: 12px;
right: 27px;
cursor: pointer;
}
}
.left-main {
width: 792px;
height: 402px;
padding: 20px 22px 21px 21px;
.main-item {
width: 749px;
height: 64px;
display: flex;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin-bottom: 14px;
img {
width: 72px;
height: 48px;
margin-right: 20px;
cursor: pointer;
}
.item-content {
width: 657px;
height: 50px;
position: relative;
.title {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
cursor: pointer;
}
.content {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
cursor: pointer;
}
.time {
position: absolute;
top: 0px;
right: 0px;
font-size: 14px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 22px;
color: rgb(95, 101, 108);
cursor: pointer;
}
}
}
}
}
.right {
width: 792px;
height: 450px;
border-radius: 10px;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.right-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
width: 80px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 26px;
color: rgb(5, 95, 194);
}
.more {
width: 49px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
top: 12px;
right: 27px;
cursor: pointer;
}
}
.right-main {
width: 792px;
height: 402px;
padding: 23px 30px 25px 21px;
.trump {
width: 740px;
height: 148px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.trump-main {
width: 695.6px;
height: 148px;
background-image: url('./assets/title01bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
.mask {
width: 740px;
height: 76px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.mask-main {
width: 695.6px;
height: 76px;
background-image: url('./assets/title02bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
.malaby {
width: 740px;
height: 98px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.malaby-main {
width: 695.6px;
height: 98px;
background-image: url('./assets/title03bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
}
}
}
</style>
\ No newline at end of file
<template>
<div class="data-new">
<div class="left">
<img src="./assets/leftbtn.png" alt="" class="left-btn" />
<img src="./assets/rightbtn.png" alt="" class="right-btn" />
<div class="left-top">
<img src="./assets/icon01.png" alt="" />
<div class="left-top-title">最新资助项目</div>
<span>查看详情 ></span>
</div>
<div class="left-center">
<img src="./assets/usImg.png" alt="" />
<div class="left-center-main">
<div class="left-center-main-title">
NSF 在 EPSCoR 的管辖区投资 3000 万美元,用于能源、半导体、纳米技术和生物技术领域的研究和人才发展
</div>
<div class="left-center-main-ul">
<ul>
<li>
<span class="ul-title">投资主体:</span>
<span class="ul-content">美国国家科学基金会</span>
</li>
<li>
<span class="ul-title">发布日期:</span>
<span class="ul-content">2025年11月26日</span>
</li>
<li>
<span class="ul-title">资助经费:</span>
<span class="ul-content">3,000</span>
</li>
<li>
<span class="ul-title">涉及领域:</span>
<span class="ul-pie cl1">能源</span>
<span class="ul-pie cl2">集成电路</span>
<span class="ul-pie cl3">新材料</span>
<span class="ul-pie cl4">生物科技</span>
</li>
<li>
<span class="ul-title">资助对象:</span>
<span class="ul-content">蒙大拿理工大学、博伊西州立大学、路易斯安那州立大学等6个资助对象</span>
</li>
</ul>
</div>
</div>
<!-- <div class="left-center-title">国会法案</div> -->
</div>
<div class="left-bottom">
<ul>
<li class="left-bottom-li">内容摘要:</li>
</ul>
<div class="left-bottom-content">
美国国家科学基金会正在蒙大拿州、爱达荷州和路易斯安那州投资约 3000 万美元,建立 NSF EPSCoR
科学与技术卓越研究中心(NSF EPSCoR CREST 中心)。这些中心旨在扩展 STEM
知识,提升科研产出,并吸引更多来自这些地区的学生进入 STEM 领域。
</div>
</div>
</div>
<div class="right">
<div class="right-top">
<img src="./assets/icon02.png" alt="" />
<div class="right-top-title">
风险信号
<span>6</span>
</div>
</div>
<div style="margin: 6px 34px 0 23px">
<div v-for="item in list" :key="item.id" class="right-main">
<div
class="main-left"
:class="{
cl4: item.title === '特别重大',
cl5: item.title === '重大风险',
cl6: item.title === '一般风险'
}"
>
{{ item.title }}
</div>
<div class="main-center">{{ item.content }}</div>
<div class="main-right">{{ item.time }}</div>
</div>
</div>
<div class="right-mainbtn" @click="handleToMoreRiskSignal">
<img src="./assets/btn.png" alt="" />
查看更多
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import router from "@/router";
const list = ref([
{
id: 1,
title: "特别重大",
content: "NSF宣布新的“新兴技术体验式学习”计划资...",
time: "一天前"
},
{
id: 2,
title: "一般风险",
content: "美国NASA公布NIAC计划2025年度第一轮资助",
time: "一天前"
},
{
id: 3,
title: "特别重大",
content: "美国NASA公布“早期创新计划”2026年资助...",
time: "一天前"
},
{
id: 4,
title: "重大风险",
content: '美国NIH冻结多所顶尖大学资金引发广泛争议"',
time: "一天前"
},
{
id: 5,
title: "重大风险",
content: "美国NIH终止哥伦比亚大学研究项目拨款引发...",
time: "一天前"
},
{
id: 6,
title: "特别重大",
content: "美国DARPA资助可调控生物功能微系统技术开发",
time: "一天前"
}
]);
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
window.open(route.href, "_blank");
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.data-new {
width: 1600px;
height: 460px;
display: flex;
justify-content: space-between;
.left {
width: 1064px;
height: 460px;
margin-right: 16px;
border-radius: 10px;
background-color: #fff;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-btn {
width: 24px;
height: 48px;
position: absolute;
top: 223px;
left: 0px;
cursor: pointer;
}
.right-btn {
width: 24px;
height: 48px;
position: absolute;
top: 223px;
right: 0px;
cursor: pointer;
}
.left-top {
width: 100%;
height: 48px;
position: relative;
border-bottom: 1px solid rgb(234, 236, 238);
img {
width: 22px;
height: 22px;
position: absolute;
top: 15px;
left: 23px;
}
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
position: absolute;
top: 19px;
right: 40px;
color: rgb(5, 95, 194);
cursor: pointer;
}
.left-top-title {
margin-left: 60px;
width: 152px;
height: 48px;
background-color: rgb(5, 95, 194);
color: #fff;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
text-align: center;
padding: 11px 16px;
}
}
.left-center {
width: 967px;
height: 250px;
margin-top: 33px;
margin-left: 62px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 148px;
height: 148px;
margin-right: 21px;
}
display: flex;
.left-center-main {
width: 758px;
height: 175px;
.left-center-main-title {
margin-left: 19px;
margin-bottom: 17px;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
color: rgb(5, 95, 194);
}
.left-center-main-ul {
// width: 439px;
height: 132px;
ul {
list-style-position: inside;
li {
width: 100%;
height: 24px;
margin-bottom: 12px;
.ul-title {
display: inline-block;
width: 120px;
height: 24px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
.ul-content {
color: rgb(59, 65, 75);
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 400;
line-height: 24px;
}
.ul-pie {
display: inline-block;
box-sizing: border-box;
padding: 2px 8px;
border: 1px solid;
border-radius: 4px;
margin-right: 8px;
}
.cl1 {
border-color: rgba(186, 224, 255, 1);
background-color: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.cl2 {
border-color: rgba(255, 163, 158, 1);
background-color: rgba(255, 241, 240, 1);
color: rgba(245, 34, 45, 1);
}
.cl3 {
border-color: rgba(135, 232, 222, 1);
background-color: rgba(230, 255, 251, 1);
color: rgba(19, 168, 168, 1);
}
.cl4 {
border-color: rgba(211, 173, 247, 1);
background-color: rgba(249, 240, 255, 1);
color: rgba(114, 46, 209, 1);
}
}
}
}
}
.left-center-title {
padding: 3px 8px 5px;
height: 32px;
border-radius: 4px;
background-color: rgba(231, 243, 255, 1);
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
position: absolute;
right: 0px;
top: -1px;
}
}
.left-bottom {
margin: 17px 0 0 62px;
ul {
list-style-position: inside;
.left-bottom-li {
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 10px;
}
}
.left-bottom-content {
width: 943px;
margin-left: 22px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
}
}
}
.right {
width: 520px;
height: 460px;
border-radius: 10px;
background-color: #fff;
border: 1px solid rgb(234, 236, 238);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.right-top {
width: 520px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 21px;
height: 16.84px;
position: absolute;
top: 15.1px;
left: 19.5px;
}
.right-top-title {
padding: 11px 16px;
width: 148px;
height: 48px;
background-color: rgb(206, 79, 81);
font-size: 20px;
font-family: "Microsoft YaHei";
font-weight: 700;
line-height: 26px;
text-align: center;
color: #fff;
margin-left: 60px;
span {
display: inline-block;
width: 24px;
height: 20px;
background-color: rgba(255, 255, 255, 0.3);
font-size: 14px;
font-family: "Microsoft YaHei";
font-weight: 400;
line-height: 22px;
text-align: center;
color: #fff;
border-radius: 100px;
}
}
}
.right-main {
width: 468px;
padding-right: 5px;
height: 47px;
border-radius: 2px;
display: flex;
align-items: center;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.main-left {
width: 40px;
height: 40px;
margin: 4px 13px 3px 2px;
border-radius: 50%;
font-size: 12px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 14px;
padding: 6px 4px;
text-align: center;
}
.cl4 {
background-color: rgba(255, 241, 240, 1);
color: rgb(206, 79, 81);
}
.cl5 {
background-color: rgba(255, 247, 230, 1);
color: rgba(250, 140, 22, 1);
}
.cl6 {
background-color: rgba(246, 255, 237, 1);
color: rgba(82, 196, 26, 1);
}
.main-center {
width: 347px;
height: 30px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
margin-right: 2px;
}
.main-right {
width: 60px;
height: 24px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
text-align: right;
}
}
.right-mainbtn {
width: 460px;
height: 42px;
border-radius: 6px;
position: absolute;
left: 26px;
bottom: 21px;
background-color: rgb(5, 95, 194);
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
img {
width: 16px;
height: 16px;
margin-right: 8px;
}
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
}
}
}
</style>
<template>
<div class="datasub">
<div class="datasub-left">
<div class="left">
<div class="left-title">
<img src="./assets/icon01.png" alt="" />
<div class="tit">资助领域分布情况</div>
<el-select v-model="value1" placeholder="Select" class="select">
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="left-main">
<div class="left-main-echarts" ref="leftChartRef"></div>
</div>
</div>
<div class="left">
<div class="left-title">
<img src="./assets/icon03.png" alt="" />
<div class="tit">机构资助领域情况</div>
<el-select v-model="value2" placeholder="Select" class="select">
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="left-main1">
<div class="left-sankey-echarts" ref="leftSankeyRef"></div>
</div>
</div>
</div>
<div class="datasub-right">
<div class="right">
<div class="right-title">
<img src="./assets/icon02.png" alt="" />
<div class="tit">资助经费变化情况</div>
<el-select v-model="value" placeholder="Select" class="select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="right-main">
<div class="right-main-echarts" ref="rightChartRef"></div>
<div class="right-main-tit">亿美元</div>
</div>
</div>
<div class="right">
<div class="right-title">
<img src="./assets/icon03.png" alt="" />
<div class="tit">承研主体排名</div>
<el-select v-model="value3" placeholder="Select" class="select">
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<div class="right-main1">
<div class="uni-item" v-for="(item, index) in universityData" :key="index">
<div class="uni-left">
<img :src="item.img" class="uni-img" />
<div class="uni-name">{{ item.name }}</div>
</div>
<div class="uni-middle">
<div class="uni-bar" :style="{ width: (item.value / 24) * 100 + '%', background: item.color }"></div>
</div>
<div class="uni-right">{{ item.value }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import * as echarts from "echarts";
import NSF from "./assets/NSF.png";
import DARPA from "./assets/DARPA.png";
import NASA from "./assets/NASA.png";
import NIH from "./assets/NIH.png";
import NIST from "./assets/NIST.png";
import img01 from "./assets/斯坦福大学.png"
import img02 from "./assets/加州大学旧金山分校.png"
import img03 from "./assets/宾夕法尼亚大学.png"
import img04 from "./assets/约翰斯·霍普金斯大学.png"
import img05 from "./assets/康奈尔大学.png"
import img06 from "./assets/华盛顿大学.png"
import img07 from "./assets/麻省理工大学.png"
const value = ref("近十年");
const value1 = ref("2025年");
const value2 = ref("2025年");
const value3 = ref("2025年");
const universityData = [
{
name: "斯坦福大学",
img: img01,
value: 24,
color: "linear-gradient(270deg, #D15054 0%, rgba(209,80,84,0) 100%)"
},
{
name: "加州大学旧金山分校",
img: img02,
value: 18,
color: "linear-gradient(270deg, #F69C45 0%, rgba(246,156,69,0) 100%)"
},
{
name: "宾夕法尼亚大学",
img: img03,
value: 12,
color: "linear-gradient(270deg, #EBC818 0%, rgba(235,200,24,0) 100%)"
},
{
name: "约翰斯·霍普金斯大学",
img: img04,
value: 11,
color: "linear-gradient(270deg, #236EF6 0%, rgba(35,110,246,0) 100%)"
},
{
name: "康奈尔大学",
img: img05,
value: 10,
color: "linear-gradient(270deg, #236EF6 0%, rgba(35,110,246,0) 100%)"
},
{
name: "华盛顿大学(圣路易斯)",
img: img06,
value: 6,
color: "linear-gradient(270deg, #236EF6 0%, rgba(35,110,246,0) 100%)"
},
{
name: "麻省理工大学",
img: img07,
value: 4,
color: "linear-gradient(270deg, #236EF6 0%, rgba(35,110,246,0) 100%)"
}
];
const options = [
{
value: "近十年",
label: "近十年"
},
{
value: "近五年",
label: "近五年"
}
];
const options1 = [
{
value: "2025年",
label: "2025年"
},
{
value: "2024年",
label: "2024年"
}
];
const leftChartRef = ref(null);
const rightChartRef = ref(null);
const leftSankeyRef = ref(null);
let leftChart;
let rightChart;
let leftSankey;
const initLeftDonut = () => {
if (!leftChartRef.value) return;
if (leftChart) leftChart.dispose();
leftChart = echarts.init(leftChartRef.value);
const data = [
{ name: "集成电路", value: 50 },
{ name: "人工智能", value: 46 },
{ name: "通信网络", value: 40 },
{ name: "能源", value: 32 },
{ name: "先进制造", value: 31 },
{ name: "生物科技", value: 31 },
{ name: "航空航天", value: 30 },
{ name: "新材料", value: 24 }
];
const colors = [
"rgba(105, 177, 255, 1)", // 集成电路
"rgba(255, 192, 105, 1)", // 人工智能
"rgba(135, 232, 222, 1)", // 通信网络
"rgba(89, 126, 247, 1)", // 能源
"rgba(214, 228, 255, 1)", // 先进制造
"rgba(255, 120, 117, 1)", // 生物科技
"rgba(179, 127, 235, 1)", // 航空航天
"rgba(255, 163, 158, 1)" // 新材料
];
const option = {
color: colors,
tooltip: { trigger: "item", formatter: ({ name, value, percent }) => `${name}<br/>${value}${percent}%` },
series: [
{
type: "pie",
radius: [96, 120],
center: ["50%", "50%"],
avoidLabelOverlap: true,
itemStyle: { borderWidth: 0 },
label: {
show: true,
position: "outside",
alignTo: "edge",
formatter: ({ name, value, percent }) => `{name|${name}} {value|${value}项} {percent|${percent}%}`,
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
name: {
fontSize: 16,
fontFamily: "Microsoft YaHei",
fontWeight: 700,
lineHeight: 24,
color: "rgb(59, 65, 75)"
},
value: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: "rgb(95, 101, 108)"
},
percent: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: "rgb(95, 101, 108)"
}
}
},
labelLine: {
show: true,
length: 30,
length2: 0,
maxSurfaceAngle: 80
},
labelLayout: function (params) {
const isLeft = params.labelRect.x < leftChart.getWidth() / 2;
const points = params.labelLinePoints;
// 导航线终点在标签下方
const lineY = params.labelRect.y + params.labelRect.height;
points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
points[2][1] = lineY;
points[1][1] = lineY;
return {
labelLinePoints: points
};
},
data: data.map((d, i) => ({
...d,
labelLine: { lineStyle: { color: colors[i], width: 1 } }
}))
}
]
};
leftChart.setOption(option);
};
const initRightLine = () => {
if (!rightChartRef.value) return;
if (rightChart) rightChart.dispose();
rightChart = echarts.init(rightChartRef.value);
const years = ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"];
const nsf = [75, 35, 45, 60, 72, 68, 95, 85, 82, 80, 80, 86];
const darpa = [55, 40, 48, 42, 60, 65, 70, 78, 60, 92, 85, 80];
const nasa = [60, 42, 28, 25, 30, 35, 40, 52, 38, 60, 36, 42];
const nih = [38, 25, 22, 28, 30, 34, 40, 60, 28, 35, 22, 34];
const nist = [40, 28, 22, 20, 24, 26, 30, 50, 25, 20, 18, 15];
const colorMap = {
NSF: "rgba(20, 89, 187, 1)",
DARPA: "rgba(206, 79, 81, 1)",
NASA: "rgba(255, 172, 77, 1)",
NIH: "rgba(19, 168, 168, 1)",
NIST: "rgba(114, 46, 209, 1)"
};
const option = {
color: [colorMap.NSF, colorMap.DARPA, colorMap.NASA, colorMap.NIH, colorMap.NIST],
grid: { left: 40, right: 80, top: 20, bottom: 40 },
tooltip: { trigger: "axis" },
legend: { show: false },
xAxis: {
type: "category",
data: years,
boundaryGap: false,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
color: "rgba(132, 136, 142, 1)",
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22
}
},
yAxis: {
type: "value",
min: 0,
max: 100,
splitLine: { show: true, lineStyle: { color: "#e6e6e6", type: "dashed" } },
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
color: "rgba(132, 136, 142, 1)",
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22
}
},
series: [
{
name: "NSF",
type: "line",
data: nsf,
symbol: "none",
showSymbol: false,
endLabel: {
show: true,
formatter: () => `{NSF| } {t_NSF|NSF}`,
rich: {
NSF: { backgroundColor: { image: NSF }, width: 16, height: 16 },
t_NSF: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: colorMap.NSF
}
}
},
areaStyle: { color: "rgba(20,89,187,0.12)" }
},
{
name: "DARPA",
type: "line",
data: darpa,
symbol: "none",
showSymbol: false,
endLabel: {
show: true,
formatter: () => `{DARPA| } {t_DARPA|DARPA}`,
rich: {
DARPA: { backgroundColor: { image: DARPA }, width: 16, height: 16 },
t_DARPA: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: colorMap.DARPA
}
}
},
areaStyle: { color: "rgba(206,79,81,0.12)" }
},
{
name: "NASA",
type: "line",
data: nasa,
symbol: "none",
showSymbol: false,
endLabel: {
show: true,
formatter: () => `{NASA| } {t_NASA|NASA}`,
rich: {
NASA: { backgroundColor: { image: NASA }, width: 16, height: 16 },
t_NASA: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: colorMap.NASA
}
}
},
areaStyle: { color: "rgba(255,172,77,0.12)" }
},
{
name: "NIH",
type: "line",
data: nih,
symbol: "none",
showSymbol: false,
endLabel: {
show: true,
formatter: () => `{NIH| } {t_NIH|NIH}`,
rich: {
NIH: { backgroundColor: { image: NIH }, width: 16, height: 16 },
t_NIH: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: colorMap.NIH
}
}
},
areaStyle: { color: "rgba(19,168,168,0.12)" }
},
{
name: "NIST",
type: "line",
data: nist,
symbol: "none",
showSymbol: false,
endLabel: {
show: true,
formatter: () => `{NIST| } {t_NIST|NIST}`,
rich: {
NIST: { backgroundColor: { image: NIST }, width: 16, height: 16 },
t_NIST: {
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22,
color: colorMap.NIST
}
}
},
areaStyle: { color: "rgba(114,46,209,0.12)" }
}
]
};
rightChart.setOption(option);
};
const initLeftSankey = () => {
if (!leftSankeyRef.value) return;
if (leftSankey) leftSankey.dispose();
leftSankey = echarts.init(leftSankeyRef.value);
const leftNodes = [
{ name: "美国国防高级研究计划局DARPA" },
{ name: "美国国家科学基金会NSF" },
{ name: "美国国家航空航天局NASA" },
{ name: "美国国立卫生研究院NIH" },
{ name: "美国农业部USDA" },
{ name: "国家标准与技术研究院NIST" },
{ name: "美国能源部DOE" }
];
const rightNodes = [
{ name: "人工智能" },
{ name: "生物科技" },
{ name: "量子科技" },
{ name: "新材料" },
{ name: "集成电路" },
{ name: "通信网络" },
{ name: "能源" },
{ name: "先进制造" },
{ name: "航空航天" }
];
const nodes = [...leftNodes, ...rightNodes];
const links = [
{ source: "美国国防高级研究计划局DARPA", target: "人工智能", value: 20 },
{ source: "美国国防高级研究计划局DARPA", target: "量子科技", value: 10 },
{ source: "美国国防高级研究计划局DARPA", target: "通信网络", value: 8 },
{ source: "美国国家科学基金会NSF", target: "生物科技", value: 16 },
{ source: "美国国家科学基金会NSF", target: "集成电路", value: 12 },
{ source: "美国国家科学基金会NSF", target: "新材料", value: 9 },
{ source: "美国国家航空航天局NASA", target: "航空航天", value: 22 },
{ source: "美国国家航空航天局NASA", target: "通信网络", value: 6 },
{ source: "美国国立卫生研究院NIH", target: "生物科技", value: 24 },
{ source: "美国农业部USDA", target: "先进制造", value: 8 },
{ source: "国家标准与技术研究院NIST", target: "集成电路", value: 14 },
{ source: "国家标准与技术研究院NIST", target: "新材料", value: 10 },
{ source: "美国能源部DOE", target: "能源", value: 18 },
{ source: "美国能源部DOE", target: "通信网络", value: 6 }
];
const leftColor = {
"美国国防高级研究计划局DARPA": "#722ED1",
"美国国家科学基金会NSF": "#0A57A6",
"美国国家航空航天局NASA": "#2266FF",
"美国国立卫生研究院NIH": "#FFCC00",
"美国农业部USDA": "#AA0000",
"国家标准与技术研究院NIST": "#FF8888",
"美国能源部DOE": "#0088AA"
};
const rightColor = {
人工智能: "#B05FA0",
生物科技: "#5070DD",
量子科技: "#8AAA7C",
新材料: "#6D7860",
集成电路: "#0CA8DF",
通信网络: "#6D7860",
能源: "#8AAA7C",
先进制造: "#B47B5D",
航空航天: "#A7C74C"
};
const option = {
tooltip: { trigger: "item" },
series: [{
type: "sankey",
data: nodes.map(n => ({ name: n.name, itemStyle: { color: leftColor[n.name] || rightColor[n.name] || "#bbb" } })),
links: [
{ source: "美国国防高级研究计划局DARPA", target: "人工智能", value: 25 },
{ source: "美国国防高级研究计划局DARPA", target: "量子科技", value: 8 },
{ source: "美国国防高级研究计划局DARPA", target: "新材料", value: 10 },
{ source: "美国国防高级研究计划局DARPA", target: "集成电路", value: 10 },
{ source: "美国国防高级研究计划局DARPA", target: "通信网络", value: 9 },
{ source: "美国国防高级研究计划局DARPA", target: "先进制造", value: 8 },
{ source: "美国国家科学基金会NSF", target: "人工智能", value: 20 },
{ source: "美国国家科学基金会NSF", target: "生物科技", value: 12 },
{ source: "美国国家科学基金会NSF", target: "量子科技", value: 8 },
{ source: "美国国家科学基金会NSF", target: "新材料", value: 12 },
{ source: "美国国家科学基金会NSF", target: "集成电路", value: 20 },
{ source: "美国国家科学基金会NSF", target: "通信网络", value: 9 },
{ source: "美国国家科学基金会NSF", target: "能源", value: 4 },
{ source: "美国国家科学基金会NSF", target: "先进制造", value: 10 },
{ source: "美国国家科学基金会NSF", target: "航空航天", value: 6 },
{ source: "美国国家航空航天局NASA", target: "人工智能", value: 15 },
{ source: "美国国家航空航天局NASA", target: "量子科技", value: 6 },
{ source: "美国国家航空航天局NASA", target: "集成电路", value: 15 },
{ source: "美国国家航空航天局NASA", target: "通信网络", value: 9 },
{ source: "美国国家航空航天局NASA", target: "能源", value: 6 },
{ source: "美国国家航空航天局NASA", target: "先进制造", value: 10 },
{ source: "美国国家航空航天局NASA", target: "航空航天", value: 18 },
{ source: "美国国立卫生研究院NIH", target: "人工智能", value: 20 },
{ source: "美国国立卫生研究院NIH", target: "量子科技", value: 4 },
{ source: "美国国立卫生研究院NIH", target: "集成电路", value: 15 },
{ source: "美国国立卫生研究院NIH", target: "通信网络", value: 8 },
{ source: "美国国立卫生研究院NIH", target: "能源", value: 6 },
{ source: "美国国立卫生研究院NIH", target: "先进制造", value: 10 },
{ source: "美国国立卫生研究院NIH", target: "航空航天", value: 4 },
{ source: "美国农业部USDA", target: "人工智能", value: 20 },
{ source: "美国农业部USDA", target: "新材料", value: 11 },
{ source: "美国农业部USDA", target: "通信网络", value: 5 },
{ source: "美国农业部USDA", target: "能源", value: 2 },
{ source: "美国农业部USDA", target: "先进制造", value: 10 },
{ source: "美国农业部USDA", target: "航空航天", value: 4 },
{ source: "国家标准与技术研究院NIST", target: "量子科技", value: 4 },
{ source: "国家标准与技术研究院NIST", target: "先进制造", value: 4 },
{ source: "国家标准与技术研究院NIST", target: "航空航天", value: 4 },
{ source: "美国能源部DOE", target: "新材料", value: 11 },
{ source: "美国能源部DOE", target: "集成电路", value: 20 },
{ source: "美国能源部DOE", target: "通信网络", value: 5 },
{ source: "美国能源部DOE", target: "能源", value: 12 },
{ source: "美国能源部DOE", target: "先进制造", value: 8 },
{ source: "美国能源部DOE", target: "航空航天", value: 4 }
],
sort: 'none',
layoutIterations: 0,
draggable: false,
nodeAlign: "justify",
orient: "horizontal",
left: 10,
right: 70,
top: 0,
bottom: 0,
nodeWidth: 40,
nodeGap: 10,
lineStyle: { color: "#E7E7E8", opacity: 0.8, curveness: 0.5 },
emphasis: { focus: "adjacency" },
label: {
show: true,
color: "rgb(59, 65, 75)",
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 16,
formatter: (params) => {
const map = {
"美国国防高级研究计划局DARPA": "美国国防高级研究计划局\nDARPA",
"美国国家科学基金会NSF": "美国国家科学基金会\nNSF",
"美国国家航空航天局NASA": "美国国家航空航天局\nNASA",
"美国国立卫生研究院NIH": "美国国立卫生研究院\nNIH",
"美国农业部USDA": "美国农业部\nUSDA",
"国家标准与技术研究院NIST": "国家标准与技术研究院\nNIST",
"美国能源部DOE": "美国能源部\nDOE"
};
return map[params.name] || params.name;
},
position: 'right'
}
}]
};
leftSankey.setOption(option);
};
const handleResize = () => {
if (leftChart) leftChart.resize();
if (rightChart) rightChart.resize();
if (leftSankey) leftSankey.resize();
};
onMounted(() => {
initLeftDonut();
initRightLine();
initLeftSankey();
window.addEventListener("resize", handleResize);
});
onBeforeUnmount(() => {
window.removeEventListener("resize", handleResize);
if (leftChart) {
leftChart.dispose();
leftChart = null;
}
if (rightChart) {
rightChart.dispose();
rightChart = null;
}
if (leftSankey) {
leftSankey.dispose();
leftSankey = null;
}
});
</script>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
}
.datasub {
width: 1600px;
height: 936px;
display: flex;
justify-content: space-between;
.datasub-left {
width: 792px;
height: 936px;
.left {
width: 792px;
height: 460px;
margin-right: 16px;
margin-bottom: 16px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.left-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
}
.select {
width: 120px;
height: 28px;
padding: 0px 12px;
position: absolute;
top: 11px;
right: 31px;
}
}
.left-main {
width: 792px;
height: 412px;
padding: 52px 60px 78px 61px;
.left-main-echarts {
width: 100%;
height: 100%;
}
}
.left-main1 {
width: 792px;
height: 412px;
padding: 30px 30px 30px 30px;
.left-sankey-echarts {
width: 100%;
height: 100%;
}
}
}
}
.datasub-right {
width: 792px;
height: 936px;
.right {
width: 792px;
height: 460px;
border-radius: 10px;
margin-bottom: 16px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background-color: #fff;
.right-title {
width: 792px;
height: 48px;
border-bottom: 1px solid rgb(234, 236, 238);
position: relative;
img {
width: 19px;
height: 19px;
position: absolute;
top: 16px;
left: 21px;
}
.tit {
margin-left: 60px;
height: 48px;
padding: 11px 0;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
}
.select1 {
width: 155px;
height: 28px;
padding: 0px 12px;
position: absolute;
top: 11px;
right: 163px;
}
.select {
width: 120px;
height: 28px;
padding: 0px 12px;
position: absolute;
top: 11px;
right: 31px;
}
}
.right-main {
width: 792px;
height: 421px;
padding: 40px 5px 30px 22px;
position: relative;
.right-main-echarts {
width: 100%;
height: 100%;
}
.right-main-tit {
position: absolute;
top: 18px;
right: 83px;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgb(132, 136, 142);
}
}
.right-main1 {
width: 792px;
height: 421px;
padding: 43px 29px 45px 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
.uni-item {
width: 100%;
height: 24px;
display: flex;
align-items: center;
.uni-left {
width: 280px;
display: flex;
align-items: center;
.uni-img {
width: 24px;
height: 24px;
margin-right: 15px;
}
.uni-name {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
}
.uni-middle {
flex: 1;
height: 8px;
display: flex;
align-items: center;
padding-left: 20px;
.uni-bar {
height: 8px;
border-radius: 4px;
}
}
.uni-right {
width: 50px;
text-align: right;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
}
}
}
}
}
</style>
<template>
<div class="reslib-page">
<div class="nav">
<div
v-for="item in navList"
:key="item"
class="nav-item"
:class="{ active: item === activeItem }"
@click="activeItem = item"
>
{{ item }}
</div>
</div>
<el-select v-model="value" placeholder="Select" class="select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<div class="main">
<div class="left">
<div class="left-ti1"></div>
<div class="left-ti2"></div>
<div class="left-title">项目经费</div>
<div class="left-content">
<div v-for="(item, i) in dataList" :key="item.id" class="left-item">
<input type="checkbox" checked />{{ item.name }}
</div>
</div>
<div class="left-title cl1">涉及领域</div>
<div class="left-content">
<div v-for="(item, i) in dataList2" :key="item.id" class="left-item">
<input type="checkbox" :checked="i === 0" />{{ item.name }}
</div>
</div>
</div>
<div class="right">
<div class="right-title">
<img src="./assets/icon01.png" alt="" />
<div>资助项目</div>
</div>
<div class="right-main">
<div v-for="(item, i) in mainList" :key="item.id" class="right-item">
<img :src="item.img" alt="" />
<div class="right-item-title">{{ item.title }}</div>
<div class="right-item-content">{{ item.content }}</div>
<div class="right-item-pie">
<div
v-for="(pie, i) in item.pie"
:key="i"
class="right-item-pie-item"
:class="{
cl1: pie === '新材料',
cl2: pie === '人工智能',
cl3: pie === '量子科技',
cl4: pie === '能源',
cl5: pie === '生物科技',
cl6: pie === '航空航天'
}"
>
{{ pie }}
</div>
</div>
<div class="right-item-time">{{ item.time }}</div>
<div class="right-item-money" :style="{ color: item.color }">{{ item.money }}</div>
</div>
<div class="page">
<div class="count">共1205项调查</div>
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="total"
layout="prev, pager, next"
background
@current-change="handlePageChange"
/>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import NSF from "./assets/NSF.png";
import DARPA from "./assets/DARPA.png";
import NASA from "./assets/NASA.png";
import NIH from "./assets/NIH.png";
import DOE from "./assets/DOE.png";
const navList = ref(["全部限制", "NSF", "DARPA", "NASA", "NIH", "DOE", "NIST"]);
const activeItem = ref("全部限制");
const value = ref("发布时间");
const options = [
{
value: "发布时间",
label: "发布时间"
},
{
value: "发布日期",
label: "发布日期"
}
];
const dataList = ref([
{
id: 1,
name: ">1亿美元"
},
{
id: 2,
name: ">1000万美元"
},
{
id: 3,
name: ">100万美元"
},
{
id: 4,
name: "<100万美元"
}
]);
const dataList2 = ref([
{
id: 1,
name: "全部领域"
},
{
id: 2,
name: "人工智能"
},
{
id: 3,
name: "集成电路"
},
{
id: 4,
name: "通信网络"
},
{
id: 5,
name: "量子科技"
},
{
id: 6,
name: "能源"
},
{
id: 7,
name: "生物科技"
},
{
id: 8,
name: "航空航天"
},
{
id: 9,
name: "海洋"
}
]);
const mainList = ref([
{
id: 1,
title: "NSF:量子化学合作研究项目",
content: "美国国家科学基金会和英国研究与创新(UKRI)正在投资八个联合研究项目,这些项目有望为量子计算带来突破......",
pie: ["新材料", "量子科技"],
time: "2025年11月26日",
money: "$1,000万",
color:"rgb(255, 149, 77)",
img: NSF
},
{
id: 2,
title: "NIH:All of Us研究计划数据集应用",
content:
"美国国立卫生研究院(NIH)宣布拨款970万美元,支持利用“All of Us”研究计划的数据集开展生物医学研究,并开发数据分析的新模型...",
pie: ["生物科技"],
time: "2025年11月26日",
money: "$970万",
color:"rgb(232, 189, 11)",
img: NIH
},
{
id: 3,
title: "NSF:EPSCoR管辖区投资 计划",
content:
"美国国家科学基金会正在蒙大拿州、爱达荷州和路易斯安那州的机构投资约 3000 万美元,以建立 NSF EPSCoR 科学卓越研究中心......",
pie: ["人工智能", "新材料", "量子科技"],
time: "2025年11月26日",
money: "$3,000万",
color:"rgb(255, 149, 77)",
img: NSF
},
{
id: 4,
title: "NASA:创新型早期空间技术研究资助项目",
content:
"NASA宣布对11所大学的研究提案进行资助(表1),这些项目旨在通过对创新型早期技术的研究,解决美国空间计划中具有较高优先度的...",
pie: ["航空航天"],
time: "2025年11月26日",
money: "$2.8亿",
color:"rgb(206, 79, 81)",
img: NASA
},
{
id: 5,
title: "DARPA:可调控生物功能微系统技术开发",
content:
"美国国防高级研究计划局(DARPA)宣布通过“微系统诱导催化”(MICA)项目资助巴特尔纪念研究所1030万美元[1],探索使用微系统...",
pie: ["生物科技"],
time: "2025年11月26日",
money: "$1,030万",
color:"rgb(255, 149, 77)",
img: DARPA
},
{
id: 6,
title: "NSF:国家人工智能研究资源运营中心",
content: "美国国家科学基金会今日宣布一项新招标,旨在建立国家人工智能研究资源运营中心(NAIRR-OC)。这标志着一个关键......",
pie: ["人工智能"],
time: "2025年11月26日",
money: "$1.05亿",
color:"rgb(206, 79, 81)",
img: NSF
},
{
id: 7,
title: "NASA:“人体研究计划”和“空间生物学计划”的16个研究提案",
content:
"NASA将与俄罗斯联邦航天局(Roscosmos)合作开展国际空间站一年期驻留任务,以评估长期空间飞行对人的影响[3]。 入选“人体研究...",
pie: ["生物科技", "航空航天"],
time: "2025年11月26日",
money: "$1.9亿",
color:"rgb(206, 79, 81)",
img: NASA
},
{
id: 8,
title: "NSF:NVIDIA 合作 Ai2 模型创新",
content: "美国国家科学基金会宣布与英伟达合作,开发一套人工智能模型,这将彻底改变美国科学家利用人工智能的能力......",
pie: ["人工智能"],
time: "2025年11月26日",
money: "$240万",
color:"rgb(232, 189, 11)",
img: NSF
},
{
id: 9,
title: "NASA:新一轮机器人研发",
content:
"美国国家科学基金会(NSF)宣布将联合国家航空航天局(NASA)、国立卫生研究院(NIH)、农业部(USDA)、国防部(DoD)支持...",
pie: ["人工智能"],
time: "2025年11月26日",
money: "$850万",
color:"rgb(232, 189, 11)",
img: NASA
},
{
id: 10,
title: "DOE:微电网及储能技术研发",
content: "美国能源部电力办公室宣布两项资助信息,共计投入2210万美元,推进微电网和电网级储能技术创新发展。",
pie: ["能源"],
time: "2025年11月26日",
money: "$2,210万",
color:"rgb(255, 149, 77)",
img: DOE
}
]);
const total = ref(1205);
const pageSize = ref(121);
const currentPage = ref(5);
const handlePageChange = p => {
currentPage.value = p;
};
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.reslib-page {
width: 1600px;
height: 1565px;
position: relative;
.nav {
width: 721px;
height: 42px;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 34px;
.nav-item {
cursor: pointer;
padding: 8px 20px;
font-size: 20px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(59, 65, 75);
}
.active {
background-color: rgb(5, 95, 194);
border-radius: 21px;
color: #fff;
font-weight: 700;
}
}
.select {
width: 128px;
position: absolute;
top: 7px;
right: 0px;
}
.main {
width: 1600px;
height: 1489px;
display: flex;
.left {
width: 300px;
height: 565px;
margin-right: 16px;
border-radius: 10px;
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative;
.left-ti1 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 17px;
left: 0px;
}
.left-ti2 {
width: 8px;
height: 16px;
background-color: rgb(5, 95, 194);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
position: absolute;
top: 207px;
left: 0px;
}
.left-title {
margin-left: 25px;
color: rgb(5, 95, 194);
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
margin-top: 13px;
}
.left-content {
width: 253px;
height: 132px;
margin-left: 25px;
margin-top: 13px;
.left-item {
width: 120px;
height: 30px;
margin-bottom: 4px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
input[type="checkbox"] {
-webkit-appearance: none;
appearance: none;
width: 14px;
height: 14px;
margin-right: 8px;
border: 1px solid rgb(200, 204, 210);
border-radius: 4px;
background-color: #fff;
vertical-align: middle;
}
input[type="checkbox"]:checked {
background-color: rgb(5, 95, 194);
border-color: rgb(5, 95, 194);
}
input[type="checkbox"]:checked::after {
content: "";
display: block;
width: 4px;
height: 8px;
margin: 1px auto 0;
border: 2px solid #fff;
border-top: none;
border-left: none;
transform: rotate(45deg);
}
}
}
.cl1 {
margin-top: 21px;
}
}
.right {
width: 1284px;
height: 1489px;
border-radius: 10px;
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.right-title {
width: 1284px;
height: 48px;
border-bottom: 1px solid rgb(235, 238, 242);
position: relative;
img {
width: 22px;
height: 19px;
position: absolute;
top: 15px;
left: 20px;
}
div {
width: 120px;
height: 48px;
margin-left: 60px;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(5, 95, 194);
padding: 11px 0;
}
}
.right-main {
width: 1284px;
height: 1441px;
padding: 19px 34px 20px 29px;
position: relative;
.right-item {
width: 1221px;
height: 124px;
border-bottom: 1px solid rgb(234, 236, 238);
margin-bottom: 8px;
position: relative;
img {
width: 32px;
height: 32px;
position: absolute;
top: 9px;
left: 7px;
}
.right-item-title {
position: absolute;
top: 10px;
left: 56px;
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
color: rgb(59, 65, 75);
}
.right-item-content {
position: absolute;
top: 44px;
left: 56px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.right-item-pie {
position: absolute;
top: 76px;
left: 56px;
display: flex;
.right-item-pie-item {
padding: 2px 8px;
border-radius: 4px;
margin-right: 8px;
border: 1px solid;
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 20px;
}
.cl1 {
background-color: rgba(230, 255, 251, 1);
border-color: rgba(135, 232, 222, 1);
color: rgba(19, 168, 168, 1);
}
.cl2 {
background-color: rgba(255, 241, 240, 1);
border-color: rgba(255, 163, 158, 1);
color: rgba(245, 34, 45, 1);
}
.cl3 {
background-color: rgba(249, 240, 255, 1);
border-color: rgba(211, 173, 247, 1);
color: rgba(114, 46, 209, 1);
}
.cl4 {
background-color: rgba(230, 255, 251, 1);
border-color: rgba(135, 232, 222, 1);
color: rgba(19, 168, 168, 1);
}
.cl5 {
background-color: rgba(230, 244, 255, 1);
border-color: rgba(145, 202, 255, 1);
color: rgba(22, 119, 255, 1);
}
.cl6 {
background-color: rgba(240, 245, 255, 1);
border-color: rgba(173, 198, 255, 1);
color: rgba(47, 84, 235, 1);
}
}
.right-item-time {
position: absolute;
top: 13px;
right: 0;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.right-item-money {
position: absolute;
top: 76px;
right: 0;
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
}
}
.page {
width: 1221px;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
position: absolute;
bottom: 20px;
left: 20px;
padding-left: 11px;
.count {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
// box-shadow: 0 0 0 2px rgba(47, 122, 229, 0.15) inset;
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
}
}
}
}
}
</style>
<template>
<div class="coop-page">
<!-- 面包屑 -->
<div class="breadcrumb">
<div class="breadcrumb-box">
<div class="breadcrumb-item">国家科技安全</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div>
<div class="breadcrumb-item back-item" @click="handleBackHome">中美博弈概览</div>
<div class="breadcrumb-item">&nbsp;>&nbsp;</div>
<div class="breadcrumb-item">科研资助体系</div>
</div>
</div>
<!-- 主页面 -->
<div class="main-content">
<!-- 搜索栏部分 -->
<div class="search">
<div class="search-main">
<input v-model="input" placeholder="搜索科研资助实体、资助记录" class="search-input" />
<div class="search-btn">
<img src="./assets/icons/search-icon.png" alt="" />
搜索
</div>
</div>
<div class="search-center">
<div class="search-item">
<div class="search-item-num">18</div>
<div class="search-item-name">科研资助机构</div>
</div>
<div class="search-item">
<div class="search-item-num">633</div>
<div class="search-item-name">科研资助动态</div>
</div>
<div class="search-item">
<div class="search-item-num">312</div>
<div class="search-item-name">科研资助项目</div>
</div>
<div class="search-item">
<div class="search-item-num">15,556</div>
<div class="search-item-name">经费总额(亿美元)</div>
</div>
</div>
<div class="search-bottom">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">最新动态</div>
<div class="btn-icon">></div>
</div>
<div class="btn" @click="scrollToTop('position2')">
<div class="btn-text">咨询要闻</div>
<div class="btn-icon">></div>
</div>
<div class="btn" @click="scrollToTop('position3')">
<div class="btn-text">数据总览</div>
<div class="btn-icon">></div>
</div>
<div class="btn" @click="scrollToTop('position4')">
<div class="btn-text">资源库</div>
<div class="btn-icon">></div>
</div>
</div>
</div>
<!-- 6个数据 -->
<div class="data">
<div v-for="item in dataList" :key="item.id" class="data-item">
<img :src="item.image" alt="" />
<div class="data-item-title">{{ item.title }}</div>
<div class="data-item-name">{{ item.name }}</div>
<div class="data-item-abb">{{ item.abb }}</div>
<div class="data-item-num" :style="{ color: item.color }">{{ item.num }}</div>
</div>
</div>
<!-- 最新动态 -->
<div class="newdata" id="position1">
<com-title title="最新动态" />
<div class="newdata-main">
<newData />
</div>
</div>
<!-- 资讯要问 -->
<div class="ask" id="position2">
<com-title title="咨询要闻" />
<div class="ask-main">
<askPage />
</div>
</div>
<!-- 数据总览 -->
<div class="datasub" id="position3">
<com-title title="数据总览" />
<div class="datasub-main">
<dataSub />
</div>
</div>
<!-- 资源库 -->
<div class="reslib" id="position4">
<com-title title="资源库" />
<div class="reslib-main">
<resLib />
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import comTitle from "./common/comTitle.vue";
import newData from "./components/dataNew/index.vue";
import askPage from "./components/askPage/index.vue";
import dataSub from "./components/dataSub/index.vue";
import resLib from "./components/resLib/index.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow";
import img01 from "./assets/images/img01.png";
import img02 from "./assets/images/img02.png";
import img03 from "./assets/images/img03.png";
import img04 from "./assets/images/img04.png";
import img05 from "./assets/images/img05.png";
import img06 from "./assets/images/img06.png";
// 搜索框
const input = ref("");
const router = useRouter();
// 返回首页
const handleBackHome = () => {
router.push({
path: "/overview"
});
};
// 固定数据
const dataList = ref([
{
id: 1,
title: "NSF",
name: "美国国家科学基金会",
abb: "National Science Foundation",
num: "218项",
image: img01,
color: "rgb(206, 79, 81)"
},
{
id: 2,
title: "DARPA",
name: "美国国防高级研究计划局",
abb: "Defense Advanced Research Projects Agency",
num: "95项",
image: img02,
color: "rgba(114, 46, 209, 1)"
},
{
id: 3,
title: "NIH",
name: "美国国立卫生研究院",
abb: "National Institutes of Health",
num: "90项",
image: img03,
color: "rgba(19, 168, 168, 1)"
},
{
id: 4,
title: "NASA",
name: "美国国家航空航天局",
abb: "National Aeronautics and Space...",
num: "42项",
image: img04,
color: "rgba(64, 150, 255, 1)"
},
{
id: 5,
title: "DOE",
name: "美国能源部",
abb: "Department of Energy",
num: "95项",
image: img05,
color: "rgb(33, 129, 57)"
},
{
id: 6,
title: "NIST",
name: "国家标准与技术研究院",
abb: "National Institute of Standards and ...",
num: "218项",
image: img06,
color: "rgb(5, 95, 194)"
}
]);
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.coop-page {
width: 100%;
height: 100%;
.breadcrumb {
width: 100%;
height: 64px;
background-image: url("./assets/images/bread-bg.png");
background-size: cover;
padding: 17px 0px 21px 0px;
.breadcrumb-box {
margin-left: 160px;
display: flex;
// align-items: center;
.breadcrumb-item {
font-size: 20px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 30px;
color: #fff;
}
.back-item {
cursor: pointer;
&:hover {
color: #999;
}
}
}
}
.main-content {
overflow: auto;
width: 100%;
height: calc(100% - 64px);
background: url("./assets/images/background.png");
background-size: 100% 100%;
padding: 44px 160px 30px 160px;
.search {
width: 960px;
height: 225px;
margin: 0 auto 52px auto;
.search-main {
display: flex;
padding-right: 3px;
align-items: center;
justify-content: space-between;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
width: 960px;
height: 48px;
background-color: rgba(255, 255, 255, 0.65);
border-radius: 10px;
border: 1px solid #fff;
&:hover {
border: 1px solid var(--color-main-active);
}
.search-input {
border: none;
outline: none;
width: 800px;
height: 48px;
background-color: transparent;
font-size: 16px;
padding: 12px 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(132, 136, 142);
}
.search-btn {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
width: 120px;
height: 46px;
margin-right: -3px;
border-radius: 8px;
background-color: rgb(5, 95, 194);
font-size: 18px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: #fff;
img {
width: 22px;
height: 22px;
margin-right: 8px;
}
}
}
.search-center {
width: 680px;
height: 57px;
margin: 36px auto;
display: flex;
align-items: center;
justify-content: space-between;
.search-item {
box-sizing: border-box;
width: 120px;
height: 57px;
.search-item-num {
width: 120px;
height: 22px;
font-size: 36px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 22px;
color: rgb(5, 95, 194);
text-align: center;
cursor: pointer;
}
.search-item-name {
width: 128px;
height: 24px;
margin-top: 11px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
text-align: center;
}
}
}
.search-bottom {
width: 688px;
height: 48px;
margin: 0 auto;
display: flex;
justify-content: space-between;
// gap: 16px;
.btn {
display: flex;
width: 160px;
height: 48px;
border: 1px solid rgba(174, 214, 255, 1);
box-sizing: border-box;
border-radius: 32px;
justify-content: center;
align-items: center;
background: rgba(231, 243, 255, 1);
position: relative;
cursor: pointer;
padding: 10px 40px 12px 36px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
&:hover {
background: #cae3fc;
}
.btn-text {
color: rgb(5, 95, 194);
font-family: "Microsoft YaHei";
font-size: 20px;
font-weight: 400;
line-height: 26px;
height: 26px;
}
.btn-icon {
position: absolute;
top: 14px;
right: 19px;
color: rgb(5, 95, 194);
font-size: 20px;
font-weight: 400;
}
}
}
}
.data {
width: 1600px;
height: 316px;
margin: 0 auto 64px auto;
display: flex;
justify-content: space-between;
align-content: space-between;
flex-wrap: wrap;
.data-item {
width: 520px;
height: 150px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
box-sizing: border-box;
position: relative;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
img {
width: 88px;
height: 88px;
position: absolute;
top: 30px;
left: 23px;
}
.data-item-title {
position: absolute;
top: 19px;
left: 132px;
font-size: 32px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 42px;
color: rgb(59, 65, 75);
}
.data-item-name {
position: absolute;
top: 71px;
left: 134px;
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.data-item-abb {
position: absolute;
top: 101px;
left: 134px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
.data-item-num {
position: absolute;
top: 19px;
right: 25px;
font-size: 32px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 42px;
color: rgb(95, 101, 108);
}
}
}
.newdata {
width: 1600px;
height: 538px;
margin: 36px auto 64px auto;
.newdata-main {
width: 1600px;
height: 460px;
margin-top: 36px;
}
}
.ask {
width: 1600px;
height: 528px;
margin: 0 auto 64px auto;
.ask-main {
width: 1600px;
height: 450px;
margin-top: 36px;
}
}
.datasub {
width: 1600px;
height: 1014px;
margin: 0 auto 88px auto;
.datasub-main {
width: 1600px;
height: 936px;
margin-top: 36px;
}
}
.reslib {
width: 1600px;
height: 1633px;
margin: 0 auto 0px auto;
.reslib-main {
width: 1600px;
height: 1565px;
margin-top: 26px;
}
}
}
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论