Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
cf7baa70
提交
cf7baa70
authored
4月 23, 2026
作者:
闫鹏
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'yp-dev' 到 'pre'
Yp dev 查看合并请求
!390
上级
7b398dc9
9688726b
流水线
#630
已通过 于阶段
in 5 分 7 秒
变更
23
流水线
1
隐藏空白字符变更
内嵌
并排
正在显示
23 个修改的文件
包含
5140 行增加
和
781 行删除
+5140
-781
index.js
src/api/finance/index.js
+10
-0
request.js
src/api/request.js
+26
-0
index.js
src/router/index.js
+2
-0
index.vue
...omponents/fourSuppress/components/allGovernment/index.vue
+6
-4
index-back.vue
src/views/exportControl/index-back.vue
+3864
-0
index.vue
src/views/exportControl/index.vue
+265
-105
index.vue
...ontrol/v2.0EntityList/components/dataStatistics/index.vue
+164
-136
index.vue
...ortControl/v2.0EntityList/components/deepMining/index.vue
+2
-2
index.vue
...s/sanctionsOverview/components/introductionPage/index.vue
+73
-70
index.vue
...omponents/sanctionsOverview/components/listPage/index.vue
+161
-102
index.vue
...ol/v2.0SingleSanction/components/dataStatistics/index.vue
+5
-5
index.vue
...ontrol/v2.0SingleSanction/components/deepMining/index.vue
+6
-1
index.vue
...ents/impactAnalysis/components/industrialImpact/index.vue
+25
-79
icon-pd.png
src/views/finance/assets/icons/icon-pd.png
+0
-0
icon-radar.png
src/views/finance/assets/icons/icon-radar.png
+0
-0
icon-sanction.png
src/views/finance/assets/icons/icon-sanction.png
+0
-0
icon-zc.png
src/views/finance/assets/icons/icon-zc.png
+0
-0
title.vue
src/views/finance/components/title.vue
+1
-1
index.vue
src/views/finance/entityList/components/deepMining/index.vue
+5
-3
index.vue
...s/sanctionsOverview/components/introductionPage/index.vue
+68
-23
index.vue
...omponents/sanctionsOverview/components/listPage/index.vue
+29
-77
index.vue
...finance/entityList/components/sanctionsOverview/index.vue
+1
-1
index.vue
src/views/finance/index.vue
+427
-172
没有找到文件。
src/api/finance/index.js
浏览文件 @
cf7baa70
...
@@ -137,6 +137,16 @@ export function getReasonAndSan(sanRecordId) {
...
@@ -137,6 +137,16 @@ export function getReasonAndSan(sanRecordId) {
return
http
.
get
(
`/api/sanctionList/invFin/getReasonAndSan?sanRecordId=
${
sanRecordId
}
`
);
return
http
.
get
(
`/api/sanctionList/invFin/getReasonAndSan?sanRecordId=
${
sanRecordId
}
`
);
}
}
/**
* 分页查询制裁实体清单
* url:/sanctionList/pageQuery
*/
export
function
getEntitiesList
(
params
)
{
return
http
.
post
(
"/api/sanctionList/pageQuery"
,
params
);
}
/**
/**
* 制裁历程
* 制裁历程
* url:/entitiesDataCount/getSanRecord
* url:/entitiesDataCount/getSanRecord
...
...
src/api/request.js
浏览文件 @
cf7baa70
...
@@ -8,6 +8,28 @@ import {
...
@@ -8,6 +8,28 @@ import {
// Token管理
// Token管理
const
TOKEN_KEY
=
'auth_token'
const
TOKEN_KEY
=
'auth_token'
// 定义全局控制器,以便在取消后重新赋值
let
currentMainAbortController
=
new
AbortController
()
/**
* 获取当前有效的 AbortSignal
* 供 axios 拦截器和 fetch 请求共同使用
*/
export
const
getMainAbortSignal
=
()
=>
{
return
currentMainAbortController
.
signal
}
/**
* 取消所有正在进行的请求
* 路由守卫中调用此方法
*/
export
const
cancelAllMainRequests
=
()
=>
{
// 1. 终止当前控制器的所有请求
currentMainAbortController
.
abort
()
// 2. 创建一个新的控制器,供后续新请求使用
currentMainAbortController
=
new
AbortController
()
}
// ===== 兼容导出(勿删):历史代码仍会 import formatBearerAuthorization =====
// ===== 兼容导出(勿删):历史代码仍会 import formatBearerAuthorization =====
// 说明:当前线上版本后端用 `token` 头,不用 Authorization;但为了不影响其它模块编译/运行,这里保留该方法导出。
// 说明:当前线上版本后端用 `token` 头,不用 Authorization;但为了不影响其它模块编译/运行,这里保留该方法导出。
const
formatBearerAuthorization
=
(
raw
)
=>
{
const
formatBearerAuthorization
=
(
raw
)
=>
{
...
@@ -70,6 +92,10 @@ service.interceptors.request.use(config => {
...
@@ -70,6 +92,10 @@ service.interceptors.request.use(config => {
config
.
headers
[
'X-API-Key'
]
=
aiApiKey
config
.
headers
[
'X-API-Key'
]
=
aiApiKey
}
}
}
}
if
(
!
config
.
signal
)
{
config
.
signal
=
getMainAbortSignal
()
}
return
config
return
config
},
error
=>
{
},
error
=>
{
console
.
log
(
error
)
console
.
log
(
error
)
...
...
src/router/index.js
浏览文件 @
cf7baa70
...
@@ -3,6 +3,7 @@ import { setToken, removeToken, getToken } from "@/api/request.js";
...
@@ -3,6 +3,7 @@ import { setToken, removeToken, getToken } from "@/api/request.js";
import
{
AUTH_LOGOUT_CHANNEL
}
from
"@/utils/authCrossTabLogout.js"
;
import
{
AUTH_LOGOUT_CHANNEL
}
from
"@/utils/authCrossTabLogout.js"
;
import
{
cancelAllRequests
}
from
"@/api/finance/service.js"
import
{
cancelAllRequests
}
from
"@/api/finance/service.js"
import
{
cancelAllMainRequests
}
from
"@/api/request.js"
/** localStorage:跨标签页记录当前前端的 bootId(与 vite define 的 __APP_BOOT_ID__ 对齐) */
/** localStorage:跨标签页记录当前前端的 bootId(与 vite define 的 __APP_BOOT_ID__ 对齐) */
const
VITE_BOOT_STORAGE_KEY
=
"app_vite_boot_id"
;
const
VITE_BOOT_STORAGE_KEY
=
"app_vite_boot_id"
;
...
@@ -149,6 +150,7 @@ const router = createRouter({
...
@@ -149,6 +150,7 @@ const router = createRouter({
router
.
beforeEach
((
to
,
from
,
next
)
=>
{
router
.
beforeEach
((
to
,
from
,
next
)
=>
{
// 在每次路由跳转开始前,取消上一个页面所有未完成的请求
// 在每次路由跳转开始前,取消上一个页面所有未完成的请求
// 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力
// 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力
cancelAllMainRequests
();
cancelAllRequests
();
cancelAllRequests
();
if
(
import
.
meta
.
env
.
DEV
)
{
if
(
import
.
meta
.
env
.
DEV
)
{
clearTokenIfNewDevBoot
();
clearTokenIfNewDevBoot
();
...
...
src/views/ZMOverView/components/fourSuppress/components/allGovernment/index.vue
浏览文件 @
cf7baa70
...
@@ -117,9 +117,10 @@
...
@@ -117,9 +117,10 @@
</div>
</div>
</el-tooltip>
</el-tooltip>
<div
class=
"dynamic-item-tags"
>
<div
class=
"dynamic-item-tags"
>
<span
v-for=
"(tag, tIndex) in item.tags"
:key=
"tIndex"
class=
"tag"
:class=
"getTagClass(tag)"
>
<
!--
<
span
v-for=
"(tag, tIndex) in item.tags"
:key=
"tIndex"
class=
"tag"
:class=
"getTagClass(tag)"
>
{{
tag
}}
{{
tag
}}
</span>
</span>
-->
<AreaTag
v-for=
"(tag, tIndex) in item.tags"
:key=
"tIndex"
:tagName=
"tag"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -278,6 +279,7 @@ import { onMounted, ref, computed, inject, watch, onUnmounted } from "vue";
...
@@ -278,6 +279,7 @@ import { onMounted, ref, computed, inject, watch, onUnmounted } from "vue";
import
{
useRouter
}
from
"vue-router"
;
import
{
useRouter
}
from
"vue-router"
;
import
Echarts
from
"@/components/Chart/index.vue"
;
import
Echarts
from
"@/components/Chart/index.vue"
;
import
SimplePagination
from
"@/components/SimplePagination.vue"
;
import
SimplePagination
from
"@/components/SimplePagination.vue"
;
import
AreaTag
from
"@/components/base/AreaTag/index.vue"
;
import
*
as
echarts
from
"echarts"
;
import
*
as
echarts
from
"echarts"
;
import
defaultIcon
from
"../../assets/defaultIcon.png"
;
import
defaultIcon
from
"../../assets/defaultIcon.png"
;
import
leftBtn
from
"../../assets/left-btn.png"
;
import
leftBtn
from
"../../assets/left-btn.png"
;
...
@@ -510,8 +512,8 @@ const handleNewsClick = item => {
...
@@ -510,8 +512,8 @@ const handleNewsClick = item => {
// }
// }
// });
// });
// window.open(href, "_blank");
// window.open(href, "_blank");
gotoNewsDetail
(
item
.
id
);
gotoNewsDetail
(
item
.
id
);
};
};
// 点击联合制裁项-如果是政令则跳转详情
// 点击联合制裁项-如果是政令则跳转详情
...
...
src/views/exportControl/index-back.vue
0 → 100644
浏览文件 @
cf7baa70
<
template
>
<div
class=
"home-wrapper"
>
<div
class=
"home-main"
ref=
"homeMainRef"
>
<div
class=
"home-top-bg"
></div>
<div
class=
"home-main-header"
>
<SearchContainer
style=
"margin-bottom: 0; margin-top: 48px; height: fit-content"
v-if=
"homeMainRef"
placeholder=
"搜索出口管制"
:containerRef=
"homeMainRef"
areaName=
"实体清单"
/>
<div
class=
"home-main-header-footer-info"
>
<InfoCard
v-for=
"(item, index) in infoList"
:key=
"item.id"
:title=
"item.nameZh"
:subtitle=
"item.nameAbbr"
:description=
"item.description"
:quantity=
"item.postCount"
:unit=
"item.unit"
:color=
"infoListColor[index]"
@
click=
"handleToEntityListNoId(item)"
/>
</div>
</div>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 528px; margin-top: 64px"
>
<CustomTitle
id=
"position1"
title=
"最新动态"
/>
<el-col
:span=
"16"
style=
"padding-left: 0px"
>
<custom-container
titleType=
"primary"
title=
"最新出口管制政策"
:titleIcon=
"houseIcon"
height=
"450px"
>
<template
#
header-right
>
<el-button
type=
"primary"
@
click=
"handleToEntityList"
link
>
{{
"查看详情 >"
}}
</el-button>
</
template
>
<
template
#
default
>
<div
class=
"box1"
>
<div
class=
"box1-left-arrow"
@
click=
"handleSwithCurPolicy('left')"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/box1-left.png"
alt=
""
/>
</div>
</div>
<div
class=
"box1-right-arrow"
@
click=
"handleSwithCurPolicy('right')"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/box1-right.png"
alt=
""
/>
</div>
</div>
<el-carousel
ref=
"carouselRef"
height=
"370px"
:autoplay=
"false"
:interval=
"3000"
arrow=
"never"
indicator-position=
"none"
@
change=
"handleCarouselChange"
>
<el-carousel-item
v-for=
"(item, index) in entitiesDataInfoList"
:key=
"item.id + index"
>
<div>
<div
class=
"box1-top"
>
<div
class=
"box1-top-title"
>
{{
item
.
postDate
}}
——
{{
item
.
name
}}
</div>
<div
class=
"box1-top-content"
>
<div
class=
"box1-top-content-item"
>
<span
class=
"box1-top-content-item-title"
>
· 发布机构:
</span>
<span
class=
"box1-top-content-item-content"
>
{{
item
.
postOrgName
}}
</span>
</div>
<div
class=
"box1-top-content-item"
>
<span
class=
"box1-top-content-item-title"
>
· 生效日期:
</span>
<span
class=
"box1-top-content-item-content"
>
{{
item
.
postDate
}}
</span>
</div>
<div
class=
"box1-top-content-item"
>
<span
class=
"box1-top-content-item-title"
>
· 涉及领域:
</span>
<AreaTag
v-for=
"(domainItem, index) in item.domains"
:key=
"index"
:tagName=
"domainItem"
/>
</div>
</div>
</div>
<div
class=
"box1-bottom"
>
<div
class=
"box1-bottom-sanTypeId"
v-if=
"item.sanEntities?.length"
>
<div
class=
"box1-bottom-title"
>
· 涉及主要实体:
</div>
<div
class=
"box1-bottom-content"
>
<div
class=
"box1-bottom-content-item"
v-for=
"(ett, index) in item.sanEntities"
:key=
"index"
@
click=
"handleEntityClick(ett)"
>
<el-image
v-if=
"ett.img"
class=
"box1-bottom-content-item-img"
:src=
"ett.img"
alt=
""
></el-image>
<div
v-else
class=
"box1-bottom-content-item-imgUndefined"
>
{{
(
ett
.
orgName
||
ett
.
orgNameZh
)?.
match
(
/
[\u
4e00-
\u
9fa5a-zA-Z0-9
]
/
)?.[
0
]
}}
</div>
<div
class=
"box1-bottom-content-item-txt"
>
{{
ett
.
orgName
||
ett
.
orgNameZh
}}
</div>
</div>
</div>
</div>
<div
class=
"box1-bottom-sanTypeId"
v-if=
"item.sanItems?.length > 0"
>
<div
class=
"box1-bottom-title"
>
· 涉及管制物项:
</div>
<div
class=
"box1-bottom-content__wx"
>
<div
class=
"box1-bottom-content__wx-item"
v-for=
"(ett, index) in item.sanItems"
:key=
"index"
@
click=
"handleWxClick(item)"
>
<div
class=
"box1-bottom-content__wx-item-id"
>
{{
ett
.
id
}}
</div>
<div
class=
"box1-bottom-content__wx-item-txt"
>
{{
ett
.
name
}}
</div>
</div>
</div>
</div>
</div>
<div
class=
"box1-absolute"
@
click=
"handleToDataLibrary(item)"
>
<div
class=
"box1-absolute-des"
>
<el-icon>
<Warning
color=
"rgba(206, 79, 81, 1)"
/>
</el-icon>
<span>
{{
item
.
sanTypeId
==
allSanTypeIds
[
0
]
?
"新增中国实体"
:
"新增物项"
}}
</span>
</div>
<div
class=
"box1-absolute-num"
>
{{
item
.
cnEntityCount
}}{{
item
.
sanTypeId
==
allSanTypeIds
[
0
]
?
"家"
:
"项"
}}
</div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
</
template
>
</custom-container>
</el-col>
<el-col
:span=
"8"
style=
"padding-right: 0px"
>
<RiskSignal
:list=
"warningList"
@
item-click=
"handleToRiskSignalDetail"
@
more-click=
"handleToMoreRiskSignal"
riskLevel=
"signalLevel"
postDate=
"signalTime"
name=
"signalTitle"
/>
</el-col>
</el-row>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 50px; margin-top: 64px"
>
<CustomTitle
id=
"position2"
title=
"资讯要闻"
/>
</el-row>
<div
class=
"center-center"
>
<NewsList
:newsList=
"newsList"
@
item-click=
"handleNewsInfoClick"
@
more-click=
"handleToMoreNews"
content=
"newsContent"
/>
<MessageBubble
:messageList=
"socialMediaList"
@
person-click=
"handlePerClick"
imageUrl=
"avatar"
@
more-click=
"handleToSocialDetail"
/>
</div>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 510px; margin-top: 64px"
>
<CustomTitle
id=
"position3"
title=
"数据总览"
/>
<el-col
:span=
"24"
style=
"padding: 0"
>
<custom-container
title=
"发布频次统计"
:titleIcon=
"box3Icon"
height=
"420px"
>
<
template
#
default
>
<div
class=
"box3"
>
<div
class=
"box3-content"
>
<div
class=
"box3-content-title"
>
实体清单发布频次统计
</div>
<el-table
:data=
"entityListReleaseFreq"
stripe
style=
"width: 100%"
@
row-click=
"handleEntityRowClick"
>
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
label=
"发布次数"
width=
"300"
>
<template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center; cursor: pointer"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
:percentage=
"scope.row.percent * 100"
:show-text=
"false"
:status=
"getStatus(scope.row.percent)"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"重点领域"
width=
"220"
align=
"center"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<AreaTag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:tagName=
"tag"
/>
</div>
</
template
>
</el-table-column>
</el-table>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
@
mouseenter=
"handleShowAiPane('entityListReleaseFreqChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.entityListReleaseFreqChart"
:aiContent=
"overviewAiContent.entityListReleaseFreqChart"
@
mouseleave=
"handleHideAiPane('entityListReleaseFreqChart')"
/>
</div>
</div>
<div
class=
"box3-content"
>
<div
class=
"box3-content-title"
>
商业管制清单发布频次统计
</div>
<el-table
:data=
"commerceControlListReleaseFreq"
stripe
style=
"width: 100%"
@
row-click=
"handleCommercialRowClick"
>
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
label=
"发布次数"
width=
"300"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center; cursor: pointer"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
:percentage=
"scope.row.percent * 100"
:show-text=
"false"
:status=
"getStatus(scope.row.percent)"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"重点领域"
width=
"220"
align=
"center"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<AreaTag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:tagName=
"tag"
/>
</div>
</
template
>
</el-table-column>
</el-table>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
@
mouseenter=
"handleShowAiPane('commerceControlListReleaseFreqChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.commerceControlListReleaseFreqChart"
:aiContent=
"overviewAiContent.commerceControlListReleaseFreqChart"
@
mouseleave=
"handleHideAiPane('commerceControlListReleaseFreqChart')"
/>
</div>
</div>
<div
class=
"box3-content"
style=
"display: none"
>
<div
class=
"box3-content-title"
>
关键与新兴技术清单(CETs)
</div>
<el-table
:data=
"entityListReleaseFreq"
stripe
style=
"width: 100%"
>
<el-table-column
prop=
"year"
label=
"年份"
width=
"100"
/>
<el-table-column
label=
"发布次数"
width=
"180"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
:percentage=
"scope.row.percent * 100"
:show-text=
"false"
:status=
"getStatus(scope.row.percent)"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"重点领域"
width=
"180"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center; gap: 5px"
>
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
</div>
</
template
>
</el-table-column>
</el-table>
</div>
</div>
</template>
</custom-container>
</el-col>
</el-row>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 540px; margin-top: 16px"
>
<el-col
:span=
"8"
style=
"padding-left: 0"
>
<custom-container
title=
"实体清单领域分布情况"
:titleIcon=
"radarIcon"
height=
"540px"
>
<
template
#
header-right
>
<el-checkbox
v-model=
"domainChecked"
label=
"50%规则"
size=
"large"
/>
</
template
>
<
template
#
default
>
<EChart
:option=
"radarOption"
autoresize
:style=
"
{ height: '420px' }"
@chart-click="handleRadarChartClick"
/>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
@
mouseenter=
"handleShowAiPane('radarChart')"
/>
<AiPane
:aiContent=
"overviewAiContent.radarChart"
@
mouseleave=
"handleHideAiPane('radarChart')"
/>
</div>
</
template
>
</custom-container>
</el-col>
<el-col
:span=
"16"
style=
"padding-right: 0"
>
<custom-container
title=
"制裁清单数量增长趋势"
:titleIcon=
"qushiIcon"
height=
"540px"
>
<
template
#
header-right
>
<div
style=
"display: flex; align-items: center; gap: 16px"
>
<el-checkbox
v-if=
"selectedEntityId != '13'"
v-model=
"trendChecked"
label=
"50%规则"
size=
"large"
/>
<el-select
v-model=
"selectedEntityId"
placeholder=
"请选择清单类型"
style=
"width: 160px"
>
<el-option
v-for=
"item in infoList"
:key=
"item.id"
:label=
"item.nameZh"
:value=
"item.id"
/>
</el-select>
</div>
</
template
>
<
template
#
default
>
<EChart
:option=
"trendOption"
autoresize
:style=
"
{ height: '420px' }"
@chart-click="handleMultiBarChartClick"
/>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
@
mouseenter=
"handleShowAiPane('trendChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.trendChart"
:aiContent=
"overviewAiContent.trendChart"
@
mouseleave=
"handleHideAiPane('trendChart')"
/>
</div>
</
template
>
</custom-container>
</el-col>
</el-row>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px"
>
<CustomTitle
id=
"position4"
title=
"出口管制数据库"
style=
"margin-top: 0px"
/>
<div
class=
"resource-tabs"
>
<div
v-for=
"tab in resourceTabs"
:key=
"tab.value"
class=
"resource-tab-item"
:class=
"{ active: activeResourceTab == tab.value, disabled: tab.disabled }"
@
click=
"handleResourceTabClick(tab)"
>
{{ tab.label }}
</div>
</div>
<
template
v-if=
"activeResourceTab === 'entity'"
>
<el-col
:span=
"8"
style=
"padding-left: 0"
>
<custom-container
title=
"历次制裁过程"
:titleIcon=
"listIcon"
height=
"845px"
>
<template
#
default
>
<div
class=
"box4"
>
<div
style=
"height: 90%; overflow-y: auto; padding-top: 10px"
>
<div
class=
"box4-item"
v-for=
"(item, idx) in sanctionProcessList"
:key=
"item.title"
>
<div
class=
"box4-item-left"
>
<el-image
:src=
"dotIcon"
alt=
"图片"
class=
"box4-item-left-icon"
/>
<div
class=
"box4-item-left-line"
v-if=
"idx + 1 != sanctionProcessList.length"
></div>
</div>
<div
class=
"box4-item-right"
>
<div
class=
"box4-item-right-header"
@
click=
"handleSanc(item)"
>
<span
class=
"box4-item-right-header-title"
>
{{
item
.
postDate
}}
—
{{
item
.
title
}}
</span
>
<span
class=
"box4-item-right-header-desc"
>
{{
item
.
desc
}}
</span>
</div>
<el-tooltip
effect=
"dark"
:content=
"item.content"
popper-class=
"common-prompt-popper"
placement=
"top"
:show-after=
"500"
>
<div
class=
"box4-item-right-content"
>
{{
item
.
content
}}
</div>
</el-tooltip>
</div>
</div>
</div>
<div
class=
"box4-footer"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
>
<el-button
type=
"primary"
link
@
click=
"handleGetMore"
>
查看更多
<el-icon>
<DArrowRight
/>
</el-icon>
</el-button>
</div>
</div>
</
template
>
</custom-container>
</el-col>
<el-col
:span=
"16"
style=
"padding-right: 0"
>
<custom-container
title=
"制裁实体清单"
:titleIcon=
"entityIcon"
height=
"845px"
>
<
template
#
header-right
>
<div
class=
"box5-header-right"
>
共
{{
total
}}
家实体
</div>
</
template
>
<
template
#
default
>
<div
class=
"box5"
>
<el-table
:data=
"entitiesList"
class=
"sanction-table"
stripe
empty-text=
"暂无数据"
height=
"700px"
header-row-class-name=
"table-header"
row-class-name=
"table-row"
>
<el-table-column
prop=
"name"
label=
"实体名称"
min-width=
"200"
>
<template
#
default=
"scope"
>
<div
class=
"tableName"
@
click=
"handleCompClick(scope.row)"
>
<el-image
v-if=
"scope.row.img"
class=
"box1-bottom-content-item-img"
:src=
"scope.row.img"
alt=
""
></el-image>
<div
v-else
class=
"box1-bottom-content-item-imgUndefined"
>
{{
(
scope
.
row
.
name
||
scope
.
row
.
enName
)?.
match
(
/
[\u
4e00-
\u
9fa5a-zA-Z0-9
]
/
)?.[
0
]
}}
</div>
<CommonPrompt
:content=
"scope.row.name"
style=
"flex: 1; overflow: hidden"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"domains"
label=
"涉及领域"
min-width=
"150"
>
<
template
#
default=
"scope"
>
<div
class=
"domain-tags"
>
<AreaTag
v-for=
"tag in scope.row.domains"
:key=
"tag"
:tagName=
"tag"
/>
</div>
<!--
<div
class=
"domain-tags"
>
<el-tag
v-for=
"tag in scope.row.domains"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
</div>
-->
</
template
>
</el-table-column>
<el-table-column
prop=
"sanctionDate"
label=
"制裁时间"
width=
"120"
align=
"center"
>
<
template
#
default=
"scope"
>
{{
scope
.
row
.
sanctionDate
}}
</
template
>
</el-table-column>
<el-table-column
prop=
"revenue"
label=
"50%规则子企业"
width=
"280"
align=
"right"
>
<
template
#
default=
"scope"
>
<div
class=
"num-item"
v-if=
"scope.row.ruleOrgCount > 0"
>
<div
class=
"name-item"
:class=
"[
'revenue-cell',
scope.row.revenue === '无营收数据' ? 'no-revenue' : ''
]"
>
{{
scope
.
row
.
ruleOrgList
[
0
].
orgName
}}
...等
</div>
<div
style=
"width: 50px; color: #409eff; cursor: pointer"
@
click=
"handleOrgClick(scope.row)"
>
{{
scope
.
row
.
ruleOrgCount
}}
家>
</div>
</div>
</
template
>
</el-table-column>
</el-table>
<div
class=
"table-footer"
>
<!-- <div class="pagination-info">
第{{ currentPage }}页,共{{ totalPages }}页
</div> -->
<el-pagination
v-model:current-page=
"currentPage"
:page-size=
"pageSize"
:total=
"total"
:pager-count=
"5"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChange"
/>
</div>
</div>
</template>
</custom-container>
</el-col>
</template>
<
template
v-if=
"activeResourceTab === 'all'"
>
<el-col
:span=
"24"
style=
"padding: 0"
>
<!--
<div
style=
"min-height: 500px; display: flex; justify-content: center; align-items: center; background: #fff; border-radius: 4px;"
>
暂无内容
</div>
-->
<div
class=
"all-content"
>
<div
class=
"left"
>
<div
class=
"title"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
科技领域
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
v-model=
"checkedTech"
>
<div
class=
"checkbox-grid"
>
<el-checkbox
v-for=
"item in techOptions"
:key=
"item.value"
:label=
"item.value"
>
{{
item
.
label
}}
</el-checkbox>
</div>
</el-checkbox-group>
</div>
<div
class=
"title"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
制裁时间
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
v-model=
"checkedTime"
>
<div
class=
"checkbox-grid"
>
<el-checkbox
v-for=
"item in timeOptions"
:key=
"item.value"
:label=
"item.label"
>
{{
item
.
label
}}
</el-checkbox>
</div>
</el-checkbox-group>
<div
v-if=
"timeOptions.find(i => i.value === 'custom' && i.checked)"
class=
"custom-date-picker"
>
<el-date-picker
v-model=
"customDateRange"
type=
"daterange"
range-separator=
"-"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
/>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right-title"
>
<img
:src=
"icon01"
alt=
""
/>
<div>
出口管制制裁措施
</div>
</div>
<div
class=
"right-main"
>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"time"
>
<div
class=
"year"
>
{{
item
.
year
}}
</div>
<div
class=
"date"
>
{{
item
.
dateStr
}}
</div>
</div>
<img
:src=
"item.orgLogoUrl || comTitle"
alt=
""
/>
<div
class=
"main"
>
<div
class=
"main-title"
@
click=
"handleTitleClick(item)"
>
{{
item
.
title
}}
</div>
<div
class=
"main-desc"
>
{{
item
.
desc
}}
</div>
<div
class=
"tag-box"
>
<div
v-for=
"tag in item.tags"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
</div>
<div
:class=
"
{ 'count-tag': item.countTag }">
{{
item
.
countTag
}}
</div>
</div>
</div>
</div>
<div
class=
"right-footer"
>
<div
class=
"total-count"
>
共
{{
totalAll
}}
项
</div>
<el-pagination
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</div>
</el-col>
</
template
>
<
template
v-if=
"activeResourceTab === 'commerce'"
>
<div
class=
"commerce-wrapper"
:style=
"
{ minHeight: '500px' }">
<listPage
/>
</div>
</
template
>
</el-row>
</div>
<RuleSubsidiaryDialog
v-model=
"dialogVisible"
:company-name=
"currentRuleCompany"
:total-count=
"currentRuleCount"
:data-list=
"currentOrgList"
/>
</div>
<el-dialog
v-model=
"mediaVisible"
title=
"社交媒体信息"
width=
"500"
:before-close=
"handleMediaClose"
>
<div
class=
"dialog-content"
>
{{ currentMedia }}
</div>
<
template
#
footer
>
<div
class=
"dialog-footer"
>
<!--
<el-button
@
click=
"mediaVisible = false"
>
Cancel
</el-button>
-->
<el-button
type=
"primary"
@
click=
"mediaVisible = false"
>
确定
</el-button>
</div>
</
template
>
</el-dialog>
<RiskSignalOverviewDetailDialog
v-model=
"isRiskOverviewDetailOpen"
:row=
"riskOverviewDetailRow"
name-field=
"signalTitle"
post-date-field=
"signalTime"
risk-level-field=
"signalLevel"
/>
</template>
<
script
setup
>
//这是一个备注
import
NewsList
from
"@/components/base/newsList/index.vue"
;
import
RiskSignal
from
"@/components/base/riskSignal/index.vue"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis/index"
;
import
RiskSignalOverviewDetailDialog
from
"@/components/base/RiskSignalOverviewDetailDialog/index.vue"
;
import
{
onMounted
,
ref
,
computed
,
reactive
,
shallowRef
,
watch
,
nextTick
}
from
"vue"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
const
homeMainRef
=
ref
(
null
);
const
{
isShow
}
=
useContainerScroll
(
homeMainRef
);
import
setChart
from
"@/utils/setChart"
;
import
listPage
from
"./v2.0CommercialControlList/components/sanctionsOverview/components/listPage/index.vue"
;
import
EChart
from
"@/components/Chart/index.vue"
;
import
tipsIcon
from
"./assets/icons/info-icon.png"
;
import
AiButton
from
"@/components/base/Ai/AiButton/index.vue"
;
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
import
AreaTag
from
"@/components/base/AreaTag/index.vue"
;
import
{
useChartInterpretation
}
from
"@/views/exportControl/utils/common"
;
import
{
TAGTYPE
}
from
"@/public/constant"
;
import
{
useGotoCompanyPages
}
from
"@/router/modules/company"
;
import
{
useGotoNewsDetail
}
from
"@/router/modules/news"
;
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
gotoNewsDetail
=
useGotoNewsDetail
();
const
trendChart
=
useChartInterpretation
();
const
radarChart
=
useChartInterpretation
();
const
entityListReleaseFreqChart
=
useChartInterpretation
();
const
commerceControlListReleaseFreqChart
=
useChartInterpretation
();
import
{
useRouter
}
from
"vue-router"
;
import
{
navigateToViewRiskSignal
}
from
"@/utils/riskSignalOverviewNavigate"
;
const
router
=
useRouter
();
import
CustomContainer
from
"@/components/Container/index.vue"
;
import
ClickableCard
from
"./components/link.vue"
;
import
InfoCard
from
"./components/info.vue"
;
import
CustomTitle
from
"./components/title.vue"
;
import
CommonPrompt
from
"./commonPrompt/index.vue"
;
import
RuleSubsidiaryDialog
from
"./components/RuleSubsidiaryDialog.vue"
;
import
trumpAvatar
from
"@/assets/images/icon-trump.png"
;
import
elongAvatar
from
"@/assets/images/icon-elong.png"
;
import
newsIcon
from
"@/assets/images/icon-news.png"
;
import
dialogIcon
from
"@/assets/images/icon-duihua.png"
;
import
houseIcon
from
"@/assets/images/icon-house.png"
;
import
dangerIcon
from
"./assets/images/box2-header-icon.png"
;
import
box1Image
from
"./assets/images/box1-image.png"
;
import
box3Icon
from
"./assets/images/box1-header-icon.png"
;
import
radarIcon
from
"./assets/images/icon-radar.png"
;
import
qushiIcon
from
"./assets/images/icon-qushi.png"
;
import
listIcon
from
"./assets/images/icon-list.png"
;
import
dotIcon
from
"./assets/images/info2-icon.png"
;
import
entityIcon
from
"./assets/images/icon-entity.png"
;
import
comTitle
from
"./assets/images/panel1_1.png"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
import
icon01
from
"./assets/images/jianzhu.png"
;
import
{
getEntitiesDataCount
,
getEntitiesDataInfo
,
getIndustryCountByYear
,
getCountDomainByYear
,
getSanctionsInfoCount
,
getEntitiesList
,
getSanctionProcess
,
getSanDomainCount
,
getRiskSignal
,
getSocialMediaInfo
,
getNewsInfo
,
getExportControlList
}
from
"@/api/exportControl"
;
import
{
getMultipleBarChart_m
}
from
"./utils/charts"
;
import
{
formatAnyDateToChinese
}
from
"./utils"
;
import
_
from
"lodash"
;
const
currentRuleCompany
=
ref
(
""
);
const
currentRuleCount
=
ref
(
0
);
const
currentRuleList
=
ref
([]);
const
handleToPosi
=
id
=>
{
const
element
=
document
.
getElementById
(
id
);
if
(
element
&&
homeMainRef
.
value
)
{
// 1. 如果是从完整搜索框跳转,先强制切换状态稳定布局
if
(
!
isShow
.
value
)
{
isShow
.
value
=
true
;
}
// 2. 使用 nextTick 等待 DOM 布局(如高度切换)完成后再进行坐标计算
nextTick
(()
=>
{
const
containerRect
=
homeMainRef
.
value
.
getBoundingClientRect
();
const
elementRect
=
element
.
getBoundingClientRect
();
// 使用 getBoundingClientRect 计算元素相对于容器顶部的绝对距离,不受嵌套布局影响
const
top
=
elementRect
.
top
-
containerRect
.
top
+
homeMainRef
.
value
.
scrollTop
;
homeMainRef
.
value
.
scrollTo
({
top
:
top
,
behavior
:
"smooth"
});
});
}
};
const
isRiskOverviewDetailOpen
=
ref
(
false
);
const
riskOverviewDetailRow
=
ref
(
null
);
const
handleToRiskSignalDetail
=
item
=>
{
riskOverviewDetailRow
.
value
=
item
??
null
;
isRiskOverviewDetailOpen
.
value
=
true
;
};
const
sanctionList
=
ref
([]);
const
techOptions
=
[
{
label
:
"全部领域"
,
value
:
0
},
{
label
:
"人工智能"
,
value
:
1
},
{
label
:
"生物科技"
,
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
:
"深海"
,
value
:
11
},
{
label
:
"极地"
,
value
:
12
},
{
label
:
"太空"
,
value
:
13
},
{
label
:
"核"
,
value
:
14
}
];
const
customDateRange
=
ref
(
""
);
const
timeOptions
=
[
{
label
:
"全部时间"
,
value
:
"all"
,
checked
:
true
},
{
label
:
"2025年"
,
value
:
"2025"
,
checked
:
false
},
{
label
:
"2024年"
,
value
:
"2024"
,
checked
:
false
},
{
label
:
"2023年"
,
value
:
"2023"
,
checked
:
false
},
{
label
:
"2022年"
,
value
:
"2022"
,
checked
:
false
},
{
label
:
"2021年"
,
value
:
"2021"
,
checked
:
false
},
{
label
:
"自定义"
,
value
:
"custom"
,
checked
:
false
}
];
const
checkedTech
=
ref
([
0
]);
const
checkedTime
=
ref
([
"全部时间"
]);
// 跳转到单条制裁页面,单独打开一个新页面
const
handleTitleClick
=
item
=>
{
if
(
item
.
sanTypeId
==
"13"
)
{
handleWxClick
(
item
);
return
;
}
window
.
sessionStorage
.
setItem
(
"curTabName"
,
`
${
item
.
year
}
-
${
item
.
dateStr
}
《
${
item
.
title
}
》`
);
const
route
=
router
.
resolve
({
path
:
"/exportControl/singleSanction"
,
query
:
{
id
:
item
.
id
,
sanTypeId
:
item
.
sanTypeId
,
date
:
`
${
item
.
year
}
-
${
item
.
dateStr
}
`
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
const
handleCompClick
=
item
=>
{
// console.log("item", item);
if
(
!
item
.
id
)
return
;
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
gotoCompanyPages
(
item
.
entityId
);
// const route = router.resolve({
// name: "companyPages",
// params: {
// id: item.id,
// sanTypeId: item.sanTypeId
// }
// });
// window.open(route.href, "_blank");
};
const
tagsType
=
[
"primary"
,
"success"
,
"warning"
,
"danger"
];
const
getTagType
=
tag
=>
{
if
(
!
tag
)
return
"info"
;
const
strTag
=
String
(
tag
).
trim
();
const
tagColorMap
=
{
通信网络
:
"primary"
,
人工智能
:
"danger"
,
集成电路
:
"warning"
,
量子科技
:
"success"
,
生物技术
:
"info"
,
新一代信息技术
:
"primary"
,
新能源
:
"success"
,
航空航天
:
"primary"
,
先进制造
:
"warning"
,
海洋
:
"info"
,
新材料
:
"danger"
,
深海
:
"primary"
,
极地
:
"info"
,
核
:
"danger"
,
其他
:
"info"
};
if
(
tagColorMap
[
strTag
])
{
return
tagColorMap
[
strTag
];
}
const
hash
=
strTag
.
split
(
""
).
reduce
((
acc
,
char
)
=>
acc
+
char
.
charCodeAt
(
0
),
0
);
return
TAGTYPE
[
hash
%
TAGTYPE
.
length
];
};
//数据定义
const
entitiesDataInfoList
=
shallowRef
([]);
// 趋势图
const
trendOption
=
ref
({});
const
trendChecked
=
ref
(
false
);
const
selectedEntityId
=
ref
(
1
);
// 发布频度
const
entityListReleaseFreq
=
ref
([]);
// CCL发布频度
const
commerceControlListReleaseFreq
=
ref
([]);
// 历次制裁过程
const
sanctionProcessList
=
ref
([]);
const
sanctionPage
=
ref
(
1
);
// 制裁实体清单
const
entitiesList
=
ref
([]);
// 风险信号
const
riskSignalList
=
ref
([]);
// 社交媒体信息
const
socialMediaList
=
ref
([]);
// 新闻资讯
const
newsList
=
ref
([]);
onMounted
(
async
()
=>
{
try
{
const
[
dataCount
,
entitiesDataInfo
,
industryCountByYear
,
cclList
]
=
await
Promise
.
all
([
getEntitiesDataCount
(),
getEntitiesDataInfo
(),
getIndustryCountByYear
(
1
),
getIndustryCountByYear
(
13
)
]);
// 交换第二个和第三个元素
// [dataCount[1], dataCount[2]] = [dataCount[2], dataCount[1]];
infoList
.
value
=
dataCount
.
slice
(
0
,
2
).
map
((
item
,
idx
)
=>
{
return
{
...
item
,
unit
:
idx
==
0
?
"家"
:
"项"
};
});
allSanTypeIds
.
value
=
infoList
.
value
.
map
(
item
=>
item
.
id
);
resourceTabs
.
value
=
infoList
.
value
.
map
(
item
=>
({
label
:
item
.
nameZh
,
value
:
tabMap
[
item
.
id
],
id
:
item
.
id
,
disabled
:
false
}));
resourceTabs
.
value
.
unshift
({
label
:
"全部制裁"
,
value
:
"all"
,
id
:
""
,
disabled
:
false
});
console
.
log
(
"返回的数据结构 infoList =》"
,
resourceTabs
.
value
);
entitiesDataInfoList
.
value
=
entitiesDataInfo
||
[];
const
list
=
_
.
chain
(
industryCountByYear
).
filter
(
"year"
).
orderBy
(
"year"
,
"desc"
).
value
().
slice
(
0
,
5
);
const
cclList1
=
_
.
chain
(
cclList
).
filter
(
"year"
).
orderBy
(
"year"
,
"desc"
).
value
().
slice
(
0
,
5
);
const
total
=
_
.
sumBy
(
list
,
"count"
);
const
maxCountItem
=
_
.
maxBy
(
list
,
"count"
);
const
maxCountForList
=
maxCountItem
?
maxCountItem
.
count
:
0
;
const
maxCountItem1
=
_
.
maxBy
(
cclList1
,
"count"
);
const
maxCountForList1
=
maxCountItem1
?
maxCountItem1
.
count
:
0
;
entityListReleaseFreq
.
value
=
_
.
map
(
list
,
item
=>
{
return
{
year
:
item
.
year
,
num
:
item
.
count
,
percent
:
item
.
count
/
maxCountForList
,
tags
:
item
.
domain
};
});
entityListReleaseFreqChartData
.
value
=
entityListReleaseFreq
.
value
;
// entityListReleaseFreqChart.interpret({
// type: "柱状图",
// name: "美国商务部发布实体清单的频次",
// data: entityListReleaseFreq.value
// });
commerceControlListReleaseFreq
.
value
=
_
.
map
(
cclList1
,
item
=>
{
return
{
year
:
item
.
year
,
num
:
item
.
count
,
percent
:
item
.
count
/
maxCountForList1
,
tags
:
item
.
domain
};
});
commerceControlListReleaseFreqChartData
.
value
=
commerceControlListReleaseFreq
.
value
;
// commerceControlListReleaseFreqChart.interpret({
// type: "柱状图",
// name: "美国商务部发布商业管制清单的频次",
// data: commerceControlListReleaseFreq.value
// });
// 获取趋势图数据
await
fetchTrendData
();
await
fetchRiskSignals
(
"0103"
);
// 获取社交媒体信息
await
fetchSocialMediaInfo
();
// 获取新闻资讯
await
fetchNewsInfo
();
await
fetchEntitiesList
(
currentPage
.
value
,
pageSize
.
value
);
await
fetchSanctionProcess
(
sanctionPage
.
value
,
10
);
// 获取雷达图数据
await
fetchRadarData
(
domainChecked
.
value
);
// 获取出口管制制裁措施
await
fetchSanctionList
();
}
catch
(
err
)
{
console
.
log
(
err
);
}
});
// 查看社交媒体详情
const
handleToSocialDetail
=
item
=>
{
const
route
=
router
.
resolve
({
path
:
"/characterPage"
,
query
:
{
personId
:
item
.
id
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 获取趋势图数据
const
fetchTrendData
=
async
()
=>
{
try
{
const
res
=
await
getCountDomainByYear
({
isRule
:
selectedEntityId
.
value
!=
"13"
&&
trendChecked
.
value
,
startYear
:
"2020"
,
endYear
:
String
(
new
Date
().
getFullYear
()),
sanTypeId
:
selectedEntityId
.
value
});
if
(
res
&&
res
[
0
]
&&
res
[
0
].
yearDomainCount
)
{
trendOption
.
value
=
processYearDomainCountData
(
res
[
0
].
yearDomainCount
);
trendChartData
.
value
=
res
[
0
].
yearDomainCount
;
// trendChart.interpret({ type: "柱状图", name: "制裁清单数量增长趋势", data: res[0].yearDomainCount });
}
}
catch
(
error
)
{
console
.
error
(
"获取趋势图数据失败:"
,
error
);
}
};
const
requestAiPaneContent
=
async
key
=>
{
if
(
!
key
||
aiPaneLoading
.
value
[
key
]
||
aiPaneFetched
.
value
[
key
])
return
;
aiPaneLoading
.
value
=
{
...
aiPaneLoading
.
value
,
[
key
]:
true
};
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
"智能总结生成中..."
};
try
{
const
payload
=
buildAiChartPayload
(
key
);
const
res
=
await
getChartAnalysis
(
{
text
:
JSON
.
stringify
(
payload
)
},
{
onChunk
:
chunk
=>
{
const
current
=
overviewAiContent
.
value
[
key
];
const
base
=
current
===
"智能总结生成中..."
?
""
:
current
;
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
base
+
chunk
};
}
}
);
const
list
=
res
?.
data
;
const
first
=
Array
.
isArray
(
list
)
?
list
[
0
]
:
null
;
const
interpretation
=
first
?.
解读
||
first
?.[
"解读"
];
// 流式已渲染过内容,最终用解析出的解读覆盖(保证显示格式统一)
if
(
interpretation
)
{
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
interpretation
};
}
aiPaneFetched
.
value
=
{
...
aiPaneFetched
.
value
,
[
key
]:
true
};
}
catch
(
error
)
{
console
.
error
(
"获取图表解读失败"
,
error
);
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
"智能总结生成失败"
};
}
finally
{
aiPaneLoading
.
value
=
{
...
aiPaneLoading
.
value
,
[
key
]:
false
};
}
};
const
trendChartData
=
ref
([]);
const
radarChartData
=
ref
([]);
const
entityListReleaseFreqChartData
=
ref
([]);
const
commerceControlListReleaseFreqChartData
=
ref
([]);
const
aiPaneVisible
=
ref
({
trendChart
:
false
,
radarChart
:
false
,
entityListReleaseFreqChart
:
false
,
commerceControlListReleaseFreqChart
:
false
});
const
overviewAiContent
=
ref
({
trendChart
:
"智能总结生成中..."
,
radarChart
:
"智能总结生成中..."
,
entityListReleaseFreqChart
:
"智能总结生成中..."
,
commerceControlListReleaseFreqChart
:
"智能总结生成中..."
});
const
aiPaneFetched
=
ref
({
trendChart
:
false
,
radarChart
:
false
,
entityListReleaseFreqChart
:
false
,
commerceControlListReleaseFreqChart
:
false
});
const
aiPaneLoading
=
ref
({
trendChart
:
false
,
radarChart
:
false
,
entityListReleaseFreqChart
:
false
,
commerceControlListReleaseFreqChart
:
false
});
const
chartLoading
=
ref
({
trendChart
:
false
,
radarChart
:
false
,
entityListReleaseFreqChart
:
false
,
commerceControlListReleaseFreqChart
:
false
});
const
buildAiChartPayload
=
key
=>
{
if
(
key
===
"trendChart"
)
{
return
{
type
:
"柱状图"
,
name
:
"制裁清单数量增长趋势"
,
data
:
trendChartData
.
value
};
}
if
(
key
===
"radarChart"
)
{
return
{
type
:
"雷达图"
,
name
:
"实体清单领域分布情况"
,
data
:
radarChartData
.
value
};
}
if
(
key
===
"entityListReleaseFreqChart"
)
{
return
{
type
:
"柱状图"
,
name
:
"美国商务部发布实体清单的频次"
,
data
:
entityListReleaseFreqChartData
.
value
};
}
if
(
key
===
"commerceControlListReleaseFreqChart"
)
{
return
{
type
:
"柱状图"
,
name
:
"美国商务部发布商业管制清单的频次"
,
data
:
commerceControlListReleaseFreqChartData
.
value
};
}
return
{
type
:
""
,
name
:
""
,
data
:
[]
};
};
const
handleShowAiPane
=
key
=>
{
aiPaneVisible
.
value
=
{
...
aiPaneVisible
.
value
,
[
key
]:
true
};
requestAiPaneContent
(
key
);
};
const
handleHideAiPane
=
key
=>
{
aiPaneVisible
.
value
=
{
...
aiPaneVisible
.
value
,
[
key
]:
false
};
};
watch
(
()
=>
[
trendChecked
.
value
,
selectedEntityId
.
value
],
()
=>
{
fetchTrendData
();
}
);
// 新增函数:处理 yearDomainCount 数据并使用 getMultipleBarChart_m 方法生成图表配置
const
processYearDomainCountData
=
yearDomainCountData
=>
{
// 提取所有年份并排序
const
years
=
[...
new
Set
(
yearDomainCountData
.
map
(
item
=>
item
.
year
))].
sort
();
// 提取所有领域名称
const
allDomains
=
[...
new
Set
(
yearDomainCountData
.
flatMap
(
item
=>
item
.
domainCountInfo
.
map
(
domain
=>
domain
.
name
)))];
console
.
log
(
"不同领域的数据 =>"
,
allDomains
);
// 构造 getMultipleBarChart_m 所需的数据结构
const
chartData
=
{
domains
:
allDomains
,
data
:
years
.
map
(
year
=>
{
const
yearData
=
yearDomainCountData
.
find
(
item
=>
item
.
year
===
year
);
const
domainCounts
=
{};
// 初始化所有领域的计数为0
allDomains
.
forEach
(
domain
=>
{
domainCounts
[
domain
]
=
0
;
});
// 填充实际数据
if
(
yearData
&&
yearData
.
domainCountInfo
)
{
yearData
.
domainCountInfo
.
forEach
(
domain
=>
{
domainCounts
[
domain
.
name
]
=
domain
.
count
;
});
}
return
{
year
:
year
,
domainNum
:
domainCounts
};
})
};
console
.
log
(
"不同领域的数据 chartData"
,
chartData
);
// 使用 getMultipleBarChart_m 生成图表配置
return
getMultipleBarChart_m
(
chartData
);
};
const
handleEntityClick
=
item
=>
{
console
.
log
(
"item"
,
item
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
||
item
.
entityNameZh
);
gotoCompanyPages
(
item
.
id
);
};
const
handleWxClick
=
item
=>
{
const
routeData
=
router
.
resolve
({
path
:
"/exportControl/commercialControlList"
,
query
:
{
sanTypeId
:
item
.
sanTypeId
,
key
:
item
.
id
}
});
// 打开一个新页面
window
.
open
(
routeData
.
href
,
"_blank"
);
};
const
carouselRef
=
ref
(
null
);
const
currentCarouselIndex
=
ref
(
0
);
const
handleCarouselChange
=
index
=>
{
currentCarouselIndex
.
value
=
index
;
};
// 跳转到V2.0单次制裁
const
handleToEntityList
=
item
=>
{
console
.
log
(
"这是什么数据1 =>"
,
item
);
let
id
=
item
?.
id
;
let
sanTypeId
=
item
?.
sanTypeId
||
1
;
if
(
!
id
)
{
const
currentItem
=
entitiesDataInfoList
.
value
[
currentCarouselIndex
.
value
];
id
=
currentItem
?.
id
;
sanTypeId
=
currentItem
?.
sanTypeId
||
1
;
}
window
.
sessionStorage
.
setItem
(
"curTabName"
,
entitiesDataInfoList
.
value
[
currentCarouselIndex
.
value
].
postDate
+
" 《实体清单新增条目》"
);
let
date
=
entitiesDataInfoList
.
value
[
currentCarouselIndex
.
value
].
postDate
;
const
routeData
=
router
.
resolve
({
path
:
"/exportControl/singleSanction"
,
query
:
{
id
,
sanTypeId
,
date
}
});
// 打开一个新页面
window
.
open
(
routeData
.
href
,
"_blank"
);
};
// 跳转到V2.0实体清单无ID
const
handleToEntityListNoId
=
item
=>
{
console
.
log
(
"这是什么数据 =>"
,
item
);
if
(
item
.
nameZh
==
"实体清单"
)
{
const
routeData
=
router
.
resolve
({
path
:
"/exportControl/entityList"
,
query
:
{
sanTypeId
:
item
.
id
}
});
// 打开一个新页面
window
.
open
(
routeData
.
href
,
"_blank"
);
}
else
if
(
item
.
nameZh
==
"商业管制清单"
)
{
const
routeData
=
router
.
resolve
({
path
:
"/exportControl/commercialControlList"
,
query
:
{
sanTypeId
:
item
.
id
}
});
// 打开一个新页面
window
.
open
(
routeData
.
href
,
"_blank"
);
}
else
{
return
;
}
};
// const billList = ref([]);
// const curBillListIndex = ref(0);
const
searchExportControlText
=
ref
(
""
);
const
infoListColor
=
ref
([
"rgba(206, 79, 81, 1)"
,
"rgba(114, 46, 209, 1)"
,
"rgba(132, 136, 142, 1)"
,
"rgba(132, 136, 142, 1)"
]);
const
infoList
=
ref
([]);
const
allSanTypeIds
=
ref
([
"1"
,
"13"
]);
// 雷达图
const
domainChecked
=
ref
(
false
);
const
radarOption
=
ref
({
title
:
{
text
:
""
},
tooltip
:
{
// trigger: "item",
confine
:
true
,
trigger
:
"axis"
,
formatter
:
function
(
params
)
{
// params 包含所有系列的数据
if
(
!
params
||
params
.
length
===
0
)
return
""
;
const
radarData
=
params
[
0
];
const
indicator
=
radarData
.
axisValue
;
// 当前角度对应的指标名
const
value
=
radarData
.
value
;
// 只显示当前角度对应的指标
return
`
${
indicator
}
:
${
value
}
`
;
}
},
legend
:
{
show
:
false
,
top
:
"0%"
,
icon
:
"circle"
,
itemWidth
:
12
,
itemHeight
:
12
,
textStyle
:
{
fontSize
:
16
,
fontWeight
:
400
,
fontFamily
:
"Microsoft YaHei"
,
color
:
"rgb(95, 101, 108)"
,
lineHeight
:
24
,
verticalAlign
:
"middle"
,
padding
:
[
2
,
0
,
0
,
0
]
},
data
:
[]
},
grid
:
{
top
:
"5%"
,
bottom
:
"5%"
},
radar
:
{
radius
:
"60%"
,
center
:
[
"50%"
,
"50%"
],
// shape: 'circle',
indicator
:
[],
axisName
:
{
formatter
:
"{value}"
,
color
:
"rgba(59, 65, 75, 1)"
,
fontSize
:
16
,
fontWeight
:
700
}
},
series
:
[
{
name
:
""
,
type
:
"radar"
,
symbol
:
"none"
,
// 隐藏节点圆圈
data
:
[]
}
]
});
// 获取雷达图数据
const
fetchRadarData
=
async
checked
=>
{
try
{
const
data
=
await
getSanDomainCount
(
checked
,
allSanTypeIds
.
value
.
join
(
","
));
if
(
data
&&
Array
.
isArray
(
data
)
&&
data
.
length
>
0
)
{
// 收集所有可能的领域名称
const
allDomains
=
new
Set
();
data
.
forEach
(
item
=>
{
if
(
item
.
domainCountInfo
)
{
item
.
domainCountInfo
.
forEach
(
domain
=>
{
allDomains
.
add
(
domain
.
name
);
});
}
});
const
domainNames
=
Array
.
from
(
allDomains
);
// 为每个制裁类型准备数据
const
radarColors
=
[
"rgba(45, 123, 248, 1)"
,
"rgba(206, 79, 81, 1)"
,
"rgba(255, 197, 61, 1)"
,
"rgba(255, 182, 193, 1)"
,
"rgba(159, 122, 234, 1)"
,
"rgba(90, 200, 220, 1)"
];
const
seriesData
=
data
.
map
((
sanItem
,
index
)
=>
{
// 创建一个映射,将领域名称映射到数量
const
domainMap
=
{};
if
(
sanItem
.
domainCountInfo
)
{
sanItem
.
domainCountInfo
.
forEach
(
domain
=>
{
domainMap
[
domain
.
name
]
=
domain
.
count
;
});
}
// 按照统一的领域顺序创建值数组
const
values
=
domainNames
.
map
(
name
=>
domainMap
[
name
]
||
0
);
// 确定颜色
const
solidColor
=
radarColors
[
index
%
radarColors
.
length
];
const
areaColor
=
solidColor
.
replace
(
"1)"
,
"0.2)"
);
return
{
value
:
values
,
name
:
sanItem
.
sanTypeName
,
itemStyle
:
{
color
:
solidColor
},
areaStyle
:
{
color
:
areaColor
}
};
});
// 更新雷达图指标
let
maxValue
=
Math
.
max
(...
seriesData
.
flatMap
(
item
=>
item
.
value
))
*
1.2
;
// 向上取整到最近的100的倍数,避免小数导致 ticks 不可读警告
maxValue
=
Math
.
ceil
(
maxValue
/
100
)
*
100
;
const
indicators
=
domainNames
.
map
(
name
=>
({
name
:
name
,
max
:
maxValue
||
100
// 防止max为0的情况
}));
// 更新雷达图配置
radarOption
.
value
.
radar
.
indicator
=
indicators
;
radarOption
.
value
.
series
[
0
].
data
=
seriesData
;
radarOption
.
value
.
legend
.
data
=
seriesData
.
map
(
item
=>
{
return
{
name
:
item
.
name
,
itemStyle
:
{
color
:
item
.
itemStyle
.
color
}
};
});
radarChartData
.
value
=
data
;
// radarChart.interpret({ type: "雷达图", name: "实体清单领域分布情况", data: data });
}
}
catch
(
error
)
{
console
.
error
(
"获取雷达图数据失败:"
,
error
);
}
};
watch
(
()
=>
domainChecked
.
value
,
()
=>
fetchRadarData
(
domainChecked
.
value
)
);
// 进度条状态
const
getStatus
=
_percent
=>
{
const
percent
=
_percent
*
100
;
if
(
percent
>=
90
)
{
return
"exception"
;
}
else
if
(
percent
>=
50
)
{
return
"warning"
;
}
else
{
return
"success"
;
}
};
// 制裁实体
const
currentPage
=
ref
(
1
);
// 默认显示第5页
const
pageSize
=
ref
(
10
);
const
total
=
ref
(
0
);
// 全部制裁分页
const
currentPageAll
=
ref
(
1
);
const
pageSizeAll
=
ref
(
10
);
const
totalAll
=
ref
(
0
);
const
fetchSanctionList
=
async
()
=>
{
try
{
const
techDomains
=
checkedTech
.
value
.
includes
(
0
)
?
null
:
checkedTech
.
value
.
map
(
String
);
let
years
=
null
;
if
(
!
checkedTime
.
value
.
includes
(
"全部时间"
))
{
years
=
checkedTime
.
value
.
map
(
t
=>
{
const
match
=
t
.
match
(
/
(\d{4})
/
);
return
match
?
parseInt
(
match
[
1
])
:
null
;
})
.
filter
(
y
=>
y
!==
null
);
if
(
years
.
length
===
0
)
years
=
null
;
const
customTime
=
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"custom"
);
if
(
customTime
&&
customTime
.
checked
&&
customDateRange
.
value
&&
customDateRange
.
value
.
length
===
2
)
{
const
start
=
new
Date
(
customDateRange
.
value
[
0
]);
const
end
=
new
Date
(
customDateRange
.
value
[
1
]);
startDate
=
`
${
start
.
getFullYear
()}
-
${
String
(
start
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
)}
-
${
String
(
start
.
getDate
()
).
padStart
(
2
,
"0"
)}
`
;
endDate
=
`
${
end
.
getFullYear
()}
-
${
String
(
end
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
)}
-
${
String
(
end
.
getDate
()).
padStart
(
2
,
"0"
)}
`
;
}
}
const
params
=
{
pageNum
:
currentPageAll
.
value
,
pageSize
:
pageSizeAll
.
value
,
techDomainIds
:
techDomains
,
years
:
years
,
isCn
:
false
,
// typeName: "实体清单"
sanTypeIds
:
allSanTypeIds
.
value
};
const
res
=
await
getExportControlList
(
params
);
if
(
res
&&
res
.
content
)
{
sanctionList
.
value
=
res
.
content
.
map
(
item
=>
{
const
tags
=
Array
.
isArray
(
item
.
techDomains
)
?
item
.
techDomains
:
item
.
techDomain
?
[
item
.
techDomain
]
:
item
.
techDomainList
||
[];
const
fullTime
=
item
.
startTime
?
formatAnyDateToChinese
(
item
.
startTime
)
:
item
.
postDate
||
item
.
publishDate
||
item
.
date
;
let
year
=
""
;
let
dateStr
=
fullTime
;
if
(
typeof
fullTime
===
"string"
)
{
if
(
fullTime
.
includes
(
"年"
))
{
const
parts
=
fullTime
.
split
(
"年"
);
year
=
parts
[
0
];
dateStr
=
parts
[
1
].
replace
(
/
\s
+/g
,
""
);
}
else
if
(
fullTime
.
includes
(
"-"
))
{
const
parts
=
fullTime
.
split
(
"-"
);
year
=
parts
[
0
];
dateStr
=
parts
.
slice
(
1
).
join
(
"-"
);
}
}
return
{
...
item
,
time
:
fullTime
,
year
,
dateStr
,
title
:
item
.
entityNameZh
||
item
.
entityName
||
item
.
title
||
item
.
name
,
desc
:
item
.
sanReason
||
item
.
description
||
item
.
summary
||
item
.
content
,
tags
:
tags
,
countTag
:
item
.
cnEntityCount
?
`
${
item
.
cnEntityCount
}
家中国实体`
:
item
.
ruleOrgCount
?
`
${
item
.
ruleOrgCount
}
家关联实体`
:
item
.
countTag
||
""
};
});
totalAll
.
value
=
res
.
totalElements
;
}
}
catch
(
error
)
{}
};
const
handlePageChangeAll
=
val
=>
{
currentPageAll
.
value
=
val
;
fetchSanctionList
();
handleToPosi
(
"position4"
);
};
watch
(
checkedTech
,
(
newVal
,
oldVal
)
=>
{
let
isModified
=
false
;
if
(
newVal
.
includes
(
0
))
{
if
(
!
oldVal
.
includes
(
0
))
{
checkedTech
.
value
=
[
0
];
isModified
=
true
;
}
else
if
(
newVal
.
length
>
1
)
{
checkedTech
.
value
=
newVal
.
filter
(
v
=>
v
!==
0
);
isModified
=
true
;
}
}
else
if
(
newVal
.
length
===
0
)
{
checkedTech
.
value
=
[
0
];
isModified
=
true
;
}
if
(
isModified
)
return
;
currentPageAll
.
value
=
1
;
fetchSanctionList
();
},
{
deep
:
true
}
);
watch
(
checkedTime
,
(
newVal
,
oldVal
)
=>
{
let
isModified
=
false
;
if
(
newVal
.
includes
(
"全部时间"
))
{
if
(
!
oldVal
.
includes
(
"全部时间"
))
{
checkedTime
.
value
=
[
"全部时间"
];
isModified
=
true
;
}
else
if
(
newVal
.
length
>
1
)
{
checkedTime
.
value
=
newVal
.
filter
(
v
=>
v
!==
"全部时间"
);
isModified
=
true
;
}
}
else
if
(
newVal
.
length
===
0
)
{
checkedTime
.
value
=
[
"全部时间"
];
isModified
=
true
;
}
if
(
isModified
)
return
;
currentPageAll
.
value
=
1
;
fetchSanctionList
();
},
{
deep
:
true
}
);
// 获取实体清单数据
const
fetchEntitiesList
=
async
(
page
=
1
,
size
=
10
)
=>
{
try
{
console
.
log
(
"activeResourceTabItem.value.id"
,
activeResourceTabItem
.
value
.
id
);
if
(
!
activeResourceTabItem
.
value
.
id
)
return
;
const
res
=
await
getEntitiesList
(
activeResourceTabItem
.
value
.
id
,
page
,
size
);
if
(
res
)
{
entitiesList
.
value
=
res
.
content
.
map
(
item
=>
({
...
item
,
name
:
item
.
entityNameZh
||
item
.
entityName
,
enName
:
item
.
entityName
,
domains
:
item
.
techDomains
,
sanctionDate
:
item
.
startTime
}));
total
.
value
=
res
.
totalElements
;
currentPage
.
value
=
res
.
number
+
1
;
// API返回的页码从0开始,前端从1开始
}
}
catch
(
err
)
{
console
.
error
(
err
);
}
};
const
handleGetMore
=
async
()
=>
{
sanctionPage
.
value
++
;
try
{
const
sanTypeid
=
activeResourceTabItem
.
value
.
id
?
[
activeResourceTabItem
.
value
.
id
]
:
allSanTypeIds
.
value
;
const
res
=
await
getSanctionProcess
(
sanTypeid
,
sanctionPage
.
value
,
10
);
if
(
res
&&
res
.
content
)
{
// 将新数据合并到现有列表中
const
newData
=
res
.
content
.
map
(
item
=>
({
...
item
,
title
:
item
.
name
,
desc
:
`
${
item
.
cnEntityCount
}
家中国实体`
,
content
:
item
.
summary
||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
}));
// 合并新数据到现有列表
sanctionProcessList
.
value
=
[...
sanctionProcessList
.
value
,
...
newData
];
}
}
catch
(
err
)
{
console
.
error
(
err
);
// 如果请求失败,回退页码
sanctionPage
.
value
--
;
}
};
// 获取历次制裁过程数据
const
fetchSanctionProcess
=
async
(
page
=
1
,
size
=
10
)
=>
{
try
{
const
res
=
await
getSanctionProcess
(
activeResourceTabItem
.
value
.
id
?
[
activeResourceTabItem
.
value
.
id
]
:
allSanTypeIds
.
value
,
page
,
size
);
if
(
res
)
{
// 暂无商业管制清单数据
sanctionProcessList
.
value
=
res
.
content
.
map
(
item
=>
({
...
item
,
title
:
item
.
name
,
desc
:
`
${
item
.
cnEntityCount
}
家中国实体`
,
content
:
item
.
summary
||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
}));
}
}
catch
(
err
)
{
console
.
error
(
err
);
}
};
// 分页改变时的处理函数
const
handlePageChange
=
page
=>
{
currentPage
.
value
=
page
;
fetchEntitiesList
(
page
,
pageSize
.
value
);
};
const
searchKeyword
=
ref
(
""
);
// 资源库 Tab 数据
const
resourceTabs
=
ref
([
// { label: "全部制裁", value: "all", disabled: false },
// { label: "实体清单", value: "entity", disabled: false },
// { label: "商业管制清单", value: "commerce", disabled: true }
// { label: "关键与新兴技术清单", value: "tech", disabled: true },
// { label: "军事最终用户清单", value: "military", disabled: true }
]);
const
activeResourceTab
=
ref
(
"all"
);
const
activeResourceTabItem
=
ref
({});
// 数据对应,便宜行事
const
tabMap
=
{
1
:
"entity"
,
13
:
"commerce"
};
const
handleResourceTabClick
=
tab
=>
{
// if (tab.disabled) return;
console
.
log
(
"选项点击"
,
tab
);
activeResourceTab
.
value
=
tab
.
value
;
activeResourceTabItem
.
value
=
tab
;
fetchSanctionProcess
();
console
.
log
(
"tabMap[tab.id]"
,
tabMap
[
tab
.
id
]);
if
(
tab
.
value
===
"entity"
)
{
fetchEntitiesList
();
}
};
const
strengthLabels
=
{
strong
:
"强"
,
medium
:
"中"
,
weak
:
"弱"
,
none
:
"无"
};
// 获取风险信号数据
const
fetchRiskSignals
=
async
()
=>
{
try
{
const
data
=
await
getRiskSignal
();
if
(
data
&&
Array
.
isArray
(
data
))
{
console
.
log
(
data
);
warningList
.
value
=
data
.
map
(
item
=>
({
...
item
,
title
:
item
.
signalTitle
,
time
:
item
.
signalTime
,
status
:
item
.
signalLevel
,
id
:
item
.
signalId
,
sanId
:
item
.
sanId
}));
}
}
catch
(
err
)
{
console
.
error
(
"获取风险信号数据失败:"
,
err
);
}
};
// 添加获取社交媒体信息的方法
const
fetchSocialMediaInfo
=
async
()
=>
{
try
{
const
data
=
await
getSocialMediaInfo
();
if
(
data
&&
Array
.
isArray
(
data
))
{
// console.log(data);
socialMediaList
.
value
=
data
.
map
(
item
=>
({
...
item
,
avatar
:
item
.
personImage
,
name
:
item
.
personName
,
time
:
formatTime
(
item
.
time
),
source
:
item
.
orgName
,
content
:
item
.
remarks
,
personId
:
item
.
personId
}));
}
}
catch
(
err
)
{
console
.
error
(
"获取社交媒体信息失败:"
,
err
);
}
};
// 添加获取新闻资讯的方法
const
fetchNewsInfo
=
async
()
=>
{
try
{
const
data
=
await
getNewsInfo
();
if
(
data
&&
Array
.
isArray
(
data
))
{
newsList
.
value
=
data
.
map
(
item
=>
({
...
item
,
img
:
item
.
newsImage
,
title
:
item
.
newsTitle
,
content
:
item
.
newsContent
,
from
:
item
.
newsDate
+
(
item
.
newsOrg
?
" · "
+
item
.
newsOrg
:
""
)
}));
}
}
catch
(
err
)
{
console
.
error
(
"获取新闻资讯失败:"
,
err
);
}
};
const
handlePerClick
=
item
=>
{
console
.
log
(
"点击了社交媒体消息:"
,
item
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
const
route
=
router
.
resolve
({
path
:
"/characterPage"
,
query
:
{
type
:
item
.
personType
||
[
1
,
2
,
3
][
Math
.
floor
(
Math
.
random
()
*
3
)],
personId
:
item
.
personId
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 处理点击社交媒体消息的方法
// const handleInfoClick = item => {
// console.log("点击了社交媒体消息的更多信息:", item);
// // 这里可以添加打开详情页的逻辑
// ElMessageBox.alert(`${item.content}`, "信息详情", {
// confirmButtonText: "确定",
// callback: action => {
// ElMessage({
// type: "info",
// message: `action: ${action}`
// });
// }
// });
// };
// 添加格式化时间的方法
const
formatTime
=
timeStr
=>
{
// 空值兜底,避免报错
if
(
!
timeStr
)
return
"暂无时间"
;
// 核心:替换T为空格
return
timeStr
.
replace
(
"T"
,
" "
);
};
const
warningList
=
ref
([]);
const
curBillList
=
ref
([]);
const
releaseTime
=
ref
(
"近一年发布"
);
const
categoryList
=
ref
([]);
const
activeCate
=
ref
(
"全部分类"
);
const
activeHylyId
=
ref
(
""
);
// 获取领域分类
const
handleGetHylyList
=
async
()
=>
{
try
{
const
res
=
await
getHylyList
();
console
.
log
(
"行业领域列表"
);
categoryList
.
value
=
res
.
data
;
const
obj
=
{
id
:
0
,
hylyid
:
""
,
hylymc
:
"全部分类"
};
categoryList
.
value
=
[
obj
,
...
categoryList
.
value
];
}
catch
(
error
)
{}
};
const
chart1Data
=
ref
({
title
:
[
"2024-09"
,
"2024-10"
,
"2024-11"
,
"2024-12"
,
"2025-01"
,
"2025-02"
,
"2025-03"
,
"2025-04"
,
"2025-05"
,
"2025-06"
,
"2025-07"
,
"2025-08"
],
data
:
[
{
name
:
"提出法案"
,
value
:
[
145
,
52
,
84
,
99
,
71
,
96
,
128
,
144
,
140
,
168
,
188
,
172
]
},
{
name
:
"通过法案"
,
value
:
[
6
,
3
,
4
,
6
,
11
,
5
,
2
,
14
,
16
,
27
,
28
,
44
]
}
]
});
const
handleSanc
=
item
=>
{
console
.
log
(
"activeResourceTabItem.value.id"
,
activeResourceTabItem
.
value
.
id
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
`
${
item
.
postDate
}
《
${
item
.
title
}
》`
);
const
route
=
router
.
resolve
({
path
:
"/exportControl/singleSanction"
,
query
:
{
id
:
item
.
id
,
sanTypeId
:
activeResourceTabItem
.
value
.
id
,
date
:
item
.
postDate
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 查看更多风险信号
const
handleToMoreRiskSignal
=
()
=>
{
navigateToViewRiskSignal
(
router
);
};
// 查看更多新闻资讯
const
handleToMoreNews
=
()
=>
{
const
route
=
router
.
resolve
(
"/newsBrief"
);
window
.
open
(
route
.
href
,
"_blank"
);
// router.push("/newsBrief")
};
const
handleNewsInfoClick
=
item
=>
{
console
.
log
(
"点击了社交媒体消息的更多信息:"
,
item
);
// 应该跳转至哪儿???
// const route = router.resolve({
// path: "/newsAnalysis",
// query: {
// newsId: item.newsId
// }
// });
// window.open(route.href, "_blank");
gotoNewsDetail
(
item
.
newsId
);
};
// 切换当前出口管制政策
const
handleSwithCurPolicy
=
name
=>
{
if
(
name
===
"left"
)
{
carouselRef
.
value
.
prev
();
}
else
{
carouselRef
.
value
.
next
();
}
};
const
handleSearch
=
()
=>
{
window
.
sessionStorage
.
setItem
(
"curTabName"
,
`搜索-
${
searchExportControlText
.
value
}
`
);
const
curRoute
=
router
.
resolve
({
path
:
"/searchResults"
,
query
:
{
searchText
:
searchExportControlText
.
value
,
areaName
:
"实体清单"
}
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
};
// 点击实体清单发布频次统计
const
handleEntityRowClick
=
row
=>
{
console
.
log
(
"row"
,
row
);
const
params
=
{
// domains: row.tags[0],
selectedDate
:
JSON
.
stringify
([
row
.
year
+
"-01-01"
,
row
.
year
+
"-12-31"
])
};
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityListEvent"
,
query
:
params
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 点击商业管制清单发布频次统计
const
handleCommercialRowClick
=
row
=>
{
console
.
log
(
"row"
,
row
);
const
params
=
{
// domains: row.tags[0],
selectedDate
:
JSON
.
stringify
([
row
.
year
+
"-01-01"
,
row
.
year
+
"-12-31"
])
};
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataCommerceControlListEvent"
,
query
:
params
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 点击实体清单领域分布情况
const
handleRadarChartClick
=
value
=>
{
// console.log('value', value);
// alert(domainChecked.value)
const
params
=
{
isHalfRule
:
domainChecked
.
value
};
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 点击制裁清单数量增长趋势
const
handleMultiBarChartClick
=
val
=>
{
const
params
=
{
isHalfRule
:
trendChecked
.
value
,
domains
:
val
.
seriesName
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
val
.
name
+
"-01-01"
,
val
.
name
+
"-12-31"
])
};
const
route
=
router
.
resolve
({
path
:
selectedEntityId
.
value
===
1
?
"/dataLibrary/dataEntityList"
:
"/dataLibrary/dataCommerceControlList"
,
query
:
params
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 跳转到数据资源库
const
handleToDataLibrary
=
item
=>
{
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
query
:
{
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
item
.
postDate
,
item
.
postDate
])
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
onMounted
(
async
()
=>
{
handleGetHylyList
();
let
chart1
=
getMultiLineChart
(
chart1Data
.
value
.
title
,
chart1Data
.
value
.
data
[
0
].
value
,
chart1Data
.
value
.
data
[
1
].
value
);
setChart
(
chart1
,
"chart1"
);
});
const
dialogVisible
=
ref
(
false
);
const
currentOrgList
=
ref
([]);
const
handleClose
=
()
=>
{
dialogVisible
.
value
=
false
;
};
const
handleOrgClick
=
item
=>
{
// console.log(item, item.name);
currentRuleCompany
.
value
=
item
.
name
;
currentRuleCount
.
value
=
item
.
ruleOrgCount
;
currentOrgList
.
value
=
item
.
ruleOrgList
;
dialogVisible
.
value
=
true
;
};
const
mediaVisible
=
ref
(
false
);
const
currentMedia
=
ref
(
""
);
const
handleMediaClose
=
()
=>
{
mediaVisible
.
value
=
false
;
};
const
handleMediaClick
=
item
=>
{
// console.log(item, item.name);
currentMedia
.
value
=
item
.
content
;
mediaVisible
.
value
=
true
;
};
</
script
>
<
style
lang=
"scss"
scoped
>
.list-page
{
padding-top
:
0
;
}
.home-header
{
height
:
64px
;
background
:
url("@/assets/images/nav-bg.png")
;
box-sizing
:
border-box
;
padding-left
:
160px
;
display
:
flex
;
justify-content
:
space-between
;
padding
:
0
160px
;
}
.box1
{
display
:
flex
;
flex-direction
:
column
;
gap
:
20px
;
position
:
relative
;
width
:
1036px
;
.box1-left-arrow
{
position
:
absolute
;
z-index
:
9999
;
left
:
-24px
;
top
:
135px
;
width
:
24px
!
important
;
height
:
48px
;
background
:
#e7f1ff
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
cursor
:
pointer
;
.icon
{
width
:
11px
;
height
:
18px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
.box1-right-arrow
{
position
:
absolute
;
z-index
:
9999
;
right
:
0px
;
top
:
135px
;
width
:
24px
;
height
:
48px
;
background
:
#e7f1ff
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
cursor
:
pointer
;
.icon
{
width
:
11px
;
height
:
18px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
.box1-absolute
{
position
:
absolute
;
width
:
240px
;
height
:
89px
;
top
:
12px
;
right
:
-24px
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
justify-content
:
center
;
padding-right
:
50px
;
box-sizing
:
border-box
;
background
:
linear-gradient
(
to
right
,
rgba
(
206
,
79
,
81
,
0
)
,
rgba
(
206
,
79
,
81
,
0
.3
));
cursor
:
pointer
;
&
-des
{
display
:
flex
;
gap
:
5px
;
align-items
:
center
;
font-size
:
18px
;
font-weight
:
700
;
color
:
rgba
(
206
,
79
,
81
,
1
);
}
&
-num
{
font-size
:
32px
;
font-weight
:
700
;
color
:
rgba
(
206
,
79
,
81
,
1
);
}
}
.box1-top
{
// display: flex;
// flex-direction: column;
// gap: 10px;
padding-left
:
30px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
&
-title
{
font-size
:
20px
;
font-weight
:
700
;
color
:
$base-color
;
margin-top
:
10px
;
margin-bottom
:
15px
;
max-width
:
80%
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
&
-content
{
display
:
flex
;
flex-direction
:
column
;
gap
:
10px
;
margin-bottom
:
20px
;
&
-item
{
display
:
flex
;
gap
:
5px
;
&
-title
{
font-size
:
16px
;
font-weight
:
700
;
color
:
rgba
(
59
,
65
,
75
,
1
);
}
}
}
}
.box1-bottom
{
padding-left
:
30px
;
height
:
172px
;
padding-top
:
16px
;
box-sizing
:
border-box
;
padding-right
:
24px
;
&
-title
{
font-size
:
16px
;
font-weight
:
700
;
color
:
rgba
(
59
,
65
,
75
,
1
);
margin-bottom
:
15px
;
}
&
-content__wx
{
display
:
flex
;
flex-direction
:
column
;
gap
:
10px
;
justify-content
:
flex-start
;
padding-left
:
10px
;
height
:
156px
;
overflow
:
auto
;
&
-item
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
gap
:
10px
;
cursor
:
pointer
;
&
-id
{
font-family
:
"Source Han Sans CN"
;
font-size
:
16px
;
font-weight
:
700
;
color
:
rgb
(
95
,
101
,
108
);
}
&
-txt
{
font-size
:
16px
;
font-weight
:
400
;
color
:
rgba
(
95
,
101
,
108
,
1
);
line-height
:
24px
;
}
}
}
&
-content
{
display
:
flex
;
gap
:
15px
;
flex-wrap
:
wrap
;
justify-content
:
space-between
;
padding-left
:
10px
;
height
:
156px
;
overflow
:
auto
;
&
-item
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
width
:
48%
;
/* 留出2%的间距 */
// margin-bottom: 6px;
box-sizing
:
border-box
;
gap
:
10px
;
cursor
:
pointer
;
&
-img
{
width
:
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
{
font-size
:
16px
;
font-weight
:
400
;
color
:
rgba
(
95
,
101
,
108
,
1
);
}
}
}
}
.box1-right
{
display
:
flex
;
flex-direction
:
column
;
gap
:
10px
;
.box1-right-title
{
font-size
:
20px
;
font-weight
:
700
;
color
:
$base-color
;
}
.box1-right-tags
{
display
:
flex
;
gap
:
10px
;
}
.box1-right-content
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-size
:
16px
;
font-weight
:
400
;
line-height
:
28px
;
}
.box1-right-footer
{
margin-top
:
auto
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
.box1-right-footer-time
{
color
:
rgba
(
95
,
101
,
108
,
1
);
font-size
:
14px
;
font-weight
:
400
;
}
}
}
}
.box2-main
{
height
:
320px
;
overflow-y
:
auto
;
.box2-main-item
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
gap
:
8px
;
box-sizing
:
border-box
;
padding-right
:
3px
;
cursor
:
pointer
;
&
:hover
{
background
:
var
(
--
color-bg-hover
);
}
.itemLeftStatus1
{
color
:
rgba
(
82
,
196
,
26
,
1
)
!
important
;
background
:
rgba
(
246
,
255
,
237
,
1
)
!
important
;
}
.itemLeftStatus2
{
color
:
rgba
(
250
,
140
,
22
,
1
)
!
important
;
background
:
rgba
(
255
,
247
,
230
,
1
)
!
important
;
}
.item-left
{
display
:
flex
;
align-items
:
center
;
width
:
40px
;
height
:
40px
;
padding
:
5px
;
border-radius
:
100%
;
background
:
rgba
(
255
,
241
,
240
);
color
:
rgba
(
245
,
34
,
45
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
12px
;
font-weight
:
400
;
line-height
:
14px
;
box-sizing
:
border-box
;
text-align
:
center
;
flex-shrink
:
0
;
}
.item-right
{
margin-left
:
13px
;
width
:
100%
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
gap
:
8px
;
height
:
47px
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
.text
{
font-family
:
Microsoft
YaHei
;
line-height
:
47px
;
width
:
260px
;
font-size
:
16px
;
font-weight
:
400
;
color
:
rgba
(
59
,
65
,
75
,
1
);
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
}
.time
{
margin-left
:
10px
;
line-height
:
47px
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
}
}
}
}
.box2-footer
{
position
:
absolute
;
left
:
0
;
right
:
0
;
bottom
:
20px
;
width
:
461px
;
height
:
42px
;
display
:
flex
;
flex-direction
:
row
;
justify-content
:
center
;
align-items
:
center
;
border-radius
:
6px
;
background
:
var
(
--
color-main-active
);
margin
:
0
auto
;
cursor
:
pointer
;
.icon
{
width
:
16px
;
height
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.text
{
margin-left
:
8px
;
color
:
rgba
(
255
,
255
,
255
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
22px
;
}
}
.box3
{
display
:
flex
;
justify-content
:
center
;
// align-items: flex-start;
gap
:
100px
;
flex
:
1
;
.box3-content
{
display
:
flex
;
flex-direction
:
column
;
// gap: 20px;
flex
:
1
;
position
:
relative
;
}
.box3-content-title
{
font-size
:
18px
;
font-weight
:
700
;
font-family
:
Microsoft
YaHei
;
// width: 640px;
width
:
100%
;
height
:
36px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
background-color
:
rgba
(
247
,
248
,
249
,
1
);
color
:
$base-color
;
margin-bottom
:
15px
;
}
.box3-content
{
// flex: 1;
.el-progress--line
{
width
:
82px
;
}
}
}
.box4
{
height
:
786px
;
overflow
:
auto
;
display
:
flex
;
flex-direction
:
column
;
// justify-content: space-between;
padding-top
:
16px
;
// padding-bottom: 50px;
position
:
relative
;
.box4-item
{
display
:
flex
;
gap
:
10px
;
align-items
:
flex-start
;
padding-bottom
:
35px
;
position
:
relative
;
.box4-item-left
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
.box4-item-left-icon
{
width
:
10px
;
height
:
10px
;
}
.box4-item-left-line
{
width
:
1px
;
height
:
100%
;
position
:
absolute
;
border-left
:
1px
solid
rgba
(
10
,
87
,
166
,
0
.3
);
}
}
.box4-item-right
{
display
:
flex
;
flex-direction
:
column
;
.box4-item-right-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
position
:
relative
;
top
:
-7
.5px
;
padding-bottom
:
8px
;
cursor
:
pointer
;
&
-title
{
font-size
:
18px
;
color
:
$base-color
;
font-weight
:
700
;
}
&
-desc
{
font-size
:
16px
;
font-weight
:
700
;
color
:
rgba
(
59
,
65
,
75
,
1
);
}
}
.box4-item-right-content
{
font-size
:
16px
;
font-weight
:
400
;
color
:
rgba
(
95
,
101
,
108
,
1
);
overflow
:
hidden
;
display
:
-
webkit-box
;
-webkit-line-clamp
:
3
;
-webkit-box-orient
:
vertical
;
text-overflow
:
ellipsis
;
line-height
:
25px
;
}
}
}
.box4-footer
{
position
:
absolute
;
// margin-top: auto;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
bottom
:
30px
;
left
:
50%
;
margin-left
:
-30px
;
// margin-bottom: 30px;
}
}
.box5
{
height
:
115%
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
align-items
:
center
;
}
:deep
(
.table-header
)
{
font-size
:
16px
;
font-weight
:
700
;
color
:
rgba
(
59
,
65
,
75
,
1
);
}
:deep
(
.table-row
)
{
height
:
64px
;
}
.domain-tags
{
display
:
flex
;
gap
:
8px
;
}
.box5-header-right
{
font-size
:
16px
;
font-weight
:
700
;
color
:
$base-color
;
}
.table-footer
{
margin-top
:
20px
;
}
.home-wrapper
{
width
:
100%
;
height
:
100%
;
position
:
relative
;
overflow-y
:
hidden
;
.home-main
{
position
:
relative
;
width
:
100%
;
height
:
100%
;
overflow-y
:
auto
;
.home-top-bg
{
background
:
url("./assets/images/background.png")
,
linear-gradient
(
180deg
,
rgba
(
229
,
241
,
254
,
1
)
0%
,
rgba
(
246
,
251
,
255
,
0
)
30%
);
background-size
:
100%
100%
;
position
:
absolute
;
width
:
100%
;
height
:
100%
;
z-index
:
-100
;
top
:
-64px
;
}
.home-main-header
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
.home-main-header-center
{
margin-top
:
51px
;
width
:
960px
;
height
:
48px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
22
,
119
,
255
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
box-sizing
:
border-box
;
padding
:
1px
;
position
:
relative
;
border
:
1px
solid
transparent
;
&
:hover
{
border
:
1px
solid
var
(
--
color-main-active
);
}
.search
{
position
:
absolute
;
right
:
-1px
;
top
:
0px
;
width
:
120px
;
height
:
46px
;
border-radius
:
10px
;
background
:
var
(
--
color-main-active
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
cursor
:
pointer
;
.search-icon
{
width
:
18px
;
height
:
18px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.search-text
{
margin-left
:
8px
;
height
:
22px
;
color
:
#fff
;
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
22px
;
}
}
}
.home-main-header-footer
{
margin-top
:
64px
;
width
:
700px
;
height
:
64px
;
box-sizing
:
border-box
;
padding
:
0
108px
;
display
:
flex
;
justify-content
:
space-between
;
.home-main-header-footer-item
{
padding
:
0
10px
;
text-align
:
center
;
.item-top
{
height
:
22px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
36px
;
font-weight
:
700
;
line-height
:
22px
;
}
.item-footer
{
margin-top
:
10px
;
height
:
30px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
}
}
}
.home-main-header-footer-link
,
.home-main-header-footer-info
{
// width: 100%;
max-width
:
1600px
;
display
:
flex
;
justify-content
:
center
;
gap
:
16px
;
// padding: 30px 0;
}
.home-main-header-footer-info
{
margin-top
:
36px
;
}
.home-main-header-btn-box
{
width
:
688px
;
margin
:
0
auto
;
margin-top
:
39px
;
display
:
flex
;
justify-content
:
space-between
;
.btn
{
display
:
flex
;
align-items
:
center
;
gap
:
9px
;
width
:
160px
;
height
:
48px
;
border
:
1px
solid
#aed6ff
;
box-sizing
:
border-box
;
border-radius
:
24px
;
background
:
#e7f3ff
;
cursor
:
pointer
;
position
:
relative
;
&
:hover
{
background
:
#cae3fc
;
}
.btn-text
{
width
:
80px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
400
;
line-height
:
48px
;
margin-left
:
36px
;
text-align
:
center
;
}
.btn-icon
{
position
:
absolute
;
top
:
16px
;
right
:
19px
;
width
:
6px
;
height
:
12px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
}
}
.home-main-center
{
margin-top
:
64px
;
.center-top
{
height
:
450px
;
display
:
flex
;
gap
:
20px
;
.box1
{
display
:
flex
;
gap
:
10px
;
position
:
relative
;
.box1-header
{
height
:
53px
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
display
:
flex
;
justify-content
:
space-between
;
.box1-header-left
{
display
:
flex
;
.icon
{
width
:
18px
;
height
:
18px
;
margin-top
:
19px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.title
{
height
:
22px
;
margin-left
:
18px
;
margin-top
:
16px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
22px
;
}
}
.box1-header-right
{
margin-top
:
19px
;
height
:
16px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
16px
;
cursor
:
pointer
;
}
}
.box1-main
{
display
:
flex
;
height
:
354px
;
margin-top
:
22px
;
.box1-main-top
{
height
:
68px
;
display
:
flex
;
justify-content
:
space-between
;
.box1-main-top-left
{
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
700
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.box1-main-top-right
{
margin-left
:
20px
;
display
:
flex
;
.num
{
padding
:
1px
8px
;
height
:
24px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
145
,
202
,
255
,
1
);
border-radius
:
4px
;
background
:
rgba
(
230
,
244
,
255
,
1
);
}
.tag
{
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
135
,
232
,
222
,
1
);
border-radius
:
4px
;
background
:
rgba
(
230
,
255
,
251
,
1
);
}
}
}
}
}
.box2
{
flex
:
1
;
padding-right
:
20px
;
height
:
450px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
22
,
119
,
255
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
.box2-header
{
height
:
54px
;
display
:
flex
;
.icon
{
width
:
24px
;
height
:
22px
;
margin-left
:
33px
;
margin-top
:
18px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.text
{
margin-left
:
22px
;
margin-top
:
16px
;
height
:
22px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
22px
;
}
.num
{
width
:
24px
;
height
:
16px
;
text-align
:
center
;
color
:
rgba
(
255
,
255
,
255
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
12px
;
margin-left
:
6px
;
margin-top
:
17px
;
border
:
1px
solid
rgba
(
255
,
255
,
255
,
1
);
border-radius
:
100px
;
background
:
rgba
(
255
,
77
,
79
,
1
);
}
.more
{
margin-top
:
19px
;
margin-left
:
256px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
16px
;
}
}
.box2-main
{
height
:
282px
;
overflow-y
:
auto
;
.box2-main-item
{
margin-left
:
23px
;
height
:
47px
;
width
:
464px
;
display
:
flex
;
.itemLeftStatus1
{
color
:
rgba
(
82
,
196
,
26
,
1
)
!
important
;
background
:
rgba
(
246
,
255
,
237
,
1
)
!
important
;
}
.itemLeftStatus2
{
color
:
rgba
(
250
,
140
,
22
,
1
)
!
important
;
background
:
rgba
(
255
,
247
,
230
,
1
)
!
important
;
}
.item-left
{
margin-top
:
4px
;
margin-left
:
2px
;
width
:
40px
;
height
:
40px
;
border-radius
:
20px
;
background
:
rgba
(
255
,
241
,
240
);
color
:
rgba
(
245
,
34
,
45
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
12px
;
font-weight
:
400
;
line-height
:
14px
;
box-sizing
:
border-box
;
padding
:
6px
4px
;
text-align
:
center
;
}
.item-right
{
margin-left
:
13px
;
width
:
408px
;
height
:
47px
;
border-top
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
display
:
flex
;
.text
{
width
:
348px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
47px
;
}
.time
{
margin-left
:
10px
;
line-height
:
47px
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
}
}
}
}
.box2-footer
{
position
:
absolute
;
left
:
26px
;
bottom
:
20px
;
width
:
430px
;
height
:
42px
;
display
:
flex
;
flex-direction
:
row
;
justify-content
:
center
;
align-items
:
center
;
border-radius
:
6px
;
background
:
rgba
(
22
,
119
,
255
,
1
);
cursor
:
pointer
;
.icon
{
width
:
16px
;
height
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.text
{
margin-left
:
8px
;
color
:
rgba
(
255
,
255
,
255
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
}
}
}
}
.center-footer
{
margin-top
:
21px
;
height
:
450px
;
display
:
flex
;
.box3
{
width
:
900px
;
height
:
450px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
22
,
119
,
255
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box3-header
{
height
:
53px
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
margin
:
0
auto
;
display
:
flex
;
justify-content
:
space-between
;
padding
:
0
20px
;
.box3-header-left
{
display
:
flex
;
.box3-header-icon
{
margin-top
:
15px
;
width
:
13px
;
height
:
13px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.box3-header-title
{
margin-top
:
16px
;
margin-left
:
22px
;
height
:
22px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
22px
;
}
}
.box3-header-right
{
display
:
flex
;
justify-content
:
flex-end
;
width
:
178px
;
height
:
22px
;
.right-box
{
display
:
flex
;
margin-top
:
16px
;
width
:
89px
;
height
:
22px
;
justify-content
:
flex-end
;
.icon1
{
margin-top
:
5px
;
width
:
12px
;
height
:
12px
;
border-radius
:
6px
;
background
:
rgba
(
20
,
89
,
187
,
1
);
}
.icon2
{
margin-top
:
5px
;
width
:
12px
;
height
:
12px
;
border-radius
:
6px
;
background
:
rgba
(
250
,
140
,
22
,
1
);
}
.text
{
margin-left
:
5px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
}
}
}
}
.box3-main
{
height
:
397px
;
}
}
.box4
{
margin-left
:
20px
;
width
:
521px
;
height
:
450px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
22
,
119
,
255
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box4-header
{
width
:
452px
;
margin
:
0
auto
;
height
:
53px
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
display
:
flex
;
.header-icon
{
margin-top
:
18px
;
width
:
18px
;
height
:
18px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.header-title
{
margin-top
:
16px
;
margin-left
:
26px
;
height
:
22px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
22px
;
}
}
.box4-main
{
width
:
452px
;
margin
:
0
auto
;
margin-top
:
8px
;
height
:
360px
;
overflow-y
:
auto
;
.box4-main-item
{
margin-top
:
6px
;
height
:
30px
;
display
:
flex
;
.leftStatus3
{
color
:
rgba
(
255
,
197
,
61
,
1
)
!
important
;
}
.leftStatus2
{
color
:
rgba
(
255
,
169
,
64
,
1
)
!
important
;
}
.left
{
width
:
44px
;
text-align
:
left
;
font-family
:
Microsoft
YaHei
;
font-size
:
18px
;
font-weight
:
700
;
line-height
:
30px
;
color
:
rgba
(
206
,
79
,
81
,
1
);
}
.center
{
width
:
300px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
}
.right
{
width
:
108px
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
30px
;
text-align
:
right
;
}
}
}
}
}
}
.home-main-footer
{
// width: 100%;
// height: 911px;
background
:
rgba
(
248
,
249
,
250
,
1
);
.home-main-footer-header
{
margin-top
:
37px
;
margin-bottom
:
36px
;
// width: 1600px;
height
:
42px
;
// background: orange;
display
:
flex
;
justify-content
:
space-between
;
.btn-box
{
width
:
1300px
;
display
:
flex
;
justify-content
:
space-between
;
.btn
{
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
42px
;
padding
:
0
24px
;
border-radius
:
21px
;
background
:
rgba
(
20
,
89
,
187
,
0
);
cursor
:
pointer
;
&
:hover
{
background
:
rgba
(
20
,
89
,
187
,
0
.1
);
}
}
.btnActive
{
padding
:
0
24px
;
border-radius
:
21px
;
background
:
rgba
(
20
,
89
,
187
,
1
);
color
:
#fff
;
&
:hover
{
color
:
#fff
;
background
:
rgba
(
20
,
89
,
187
,
1
);
}
}
}
.select-box
{
height
:
42px
;
box-sizing
:
border-box
;
padding
:
5px
0
;
}
}
.home-main-footer-main
{
width
:
100%
;
// background: orange;
display
:
flex
;
flex-wrap
:
wrap
;
// justify-content: space-between;
// justify-content: center;
.main-item
{
width
:
240px
;
height
:
320px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
22
,
119
,
255
,
0
.1
);
background
:
#fff
;
margin-bottom
:
24px
;
margin-right
:
25px
;
.main-item-box1
{
margin-top
:
20px
;
margin-left
:
45px
;
width
:
150px
;
height
:
200px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
img
{
width
:
100%
;
height
:
100%
;
}
}
.main-item-box2
{
margin-top
:
26px
;
text-align
:
center
;
height
:
30px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
30px
;
}
.main-item-box3
{
text-align
:
center
;
height
:
30px
;
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
}
}
}
}
}
}
.tableName
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
30px
;
letter-spacing
:
0px
;
text-align
:
justify
;
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
cursor
:
pointer
;
.box1-bottom-content-item-imgUndefined
{
width
:
24px
;
height
:
24px
;
font-size
:
14px
;
font-weight
:
700
;
flex-shrink
:
0
;
color
:
rgb
(
5
,
95
,
194
);
background-color
:
rgb
(
236
,
245
,
255
);
line-height
:
24px
;
text-align
:
center
;
border-radius
:
12px
;
}
}
.num-item
{
width
:
280px
;
display
:
flex
;
.name-item
{
width
:
215px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.dialog-title
{
text-align
:
center
;
font-size
:
24px
;
font-weight
:
700
;
font-family
:
$base-font-family
;
padding-bottom
:
10px
;
border-bottom
:
1px
solid
#eee
;
}
.dialog-ett-wrpper
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
10px
;
height
:
500px
;
.box1-bottom-content
{
display
:
flex
;
gap
:
15px
;
flex-wrap
:
wrap
;
justify-content
:
space-between
;
padding-left
:
10px
;
height
:
156px
;
overflow
:
auto
;
&
-item
{
display
:
flex
;
// align-items: center;
justify-content
:
flex-start
;
width
:
48%
;
/* 留出2%的间距 */
// margin-bottom: 6px;
box-sizing
:
border-box
;
gap
:
10px
;
cursor
:
pointer
;
&
-img
{
width
:
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
{
font-size
:
16px
;
font-weight
:
400
;
color
:
rgba
(
95
,
101
,
108
,
1
);
}
}
}
}
:deep
(
.el-input__wrapper
)
{
box-shadow
:
none
;
// border-radius: 10px;
}
:deep
(
.el-input__wrapper
:hover
)
{
// box-shadow: none !important;
}
:deep
(
.el-input__wrapper.is-focus
)
{
// box-shadow: none !important;
}
:deep
(
.el-table
thead
)
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
:deep
(
.el-table
tr
)
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
justify
;
}
.resource-tabs
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
margin-top
:
6px
;
margin-bottom
:
36px
;
// padding-left: 10px;
.resource-tab-item
{
margin-right
:
12px
;
cursor
:
pointer
;
font-size
:
20px
;
color
:
rgb
(
59
,
65
,
75
);
font-weight
:
400
;
font-family
:
"Microsoft YaHei"
;
padding
:
8px
24px
;
border-radius
:
21px
;
transition
:
all
0
.3s
;
&
:last-child
{
margin-right
:
0
;
}
&
.active
{
background
:
rgb
(
5
,
95
,
194
);
color
:
#ffffff
;
font-weight
:
700
;
}
&
.disabled
{
cursor
:
not
-
allowed
;
color
:
#999999
;
background
:
transparent
;
}
&
:hover:not
(
.active
)
:not
(
.disabled
)
{
color
:
#0a57a6
;
}
}
}
.all-content
{
width
:
100%
;
height
:
auto
;
padding-bottom
:
30px
;
display
:
flex
;
justify-content
:
space-between
;
// align-items: center;
gap
:
16px
;
.left
{
width
:
360px
;
height
:
auto
;
align-self
:
flex-start
;
background
:
#fff
;
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
.title
{
width
:
100%
;
height
:
56px
;
display
:
flex
;
align-items
:
center
;
padding
:
14px
12px
16px
0
;
.box
{
width
:
8px
;
height
:
20px
;
background-color
:
rgb
(
5
,
95
,
194
);
border-bottom-right-radius
:
4px
;
border-top-right-radius
:
4px
;
margin-right
:
14px
;
}
.text
{
font-size
:
16px
;
font-weight
:
700
;
font-family
:
"Source Han Sans CN"
;
line-height
:
24px
;
color
:
rgb
(
5
,
95
,
194
);
}
}
.left-main
{
width
:
100%
;
height
:
auto
;
padding-left
:
24px
;
.checkbox-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
1fr
);
row-gap
:
16px
;
padding-bottom
:
16px
;
}
:deep
(
.el-checkbox
)
{
margin-right
:
0
;
height
:
auto
;
}
:deep
(
.el-checkbox__label
)
{
font-size
:
16px
;
color
:
#666666
;
font-weight
:
400
;
}
}
}
.right
{
width
:
1224px
;
height
:
auto
;
background
:
#fff
;
border-radius
:
4px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
.right-title
{
width
:
100%
;
height
:
48px
;
border-bottom
:
1px
solid
rgb
(
234
,
236
,
238
);
display
:
flex
;
align-items
:
center
;
img
{
width
:
22px
;
height
:
18px
;
margin-left
:
19px
;
}
div
{
font-size
:
20px
;
font-weight
:
700
;
font-family
:
"Microsoft YaHei"
;
line-height
:
26px
;
color
:
rgb
(
5
,
95
,
194
);
margin-left
:
19px
;
}
}
.right-main
{
width
:
100%
;
height
:
auto
;
padding
:
24px
35px
0
20px
;
.sanction-list
{
width
:
1169px
;
padding
:
0px
0
12px
0
;
display
:
flex
;
position
:
relative
;
&
:not
(
:last-child
)
::after
{
content
:
""
;
position
:
absolute
;
left
:
111px
;
// 80px(time width) + 16px(margin) + 15px(30px img half)
top
:
44px
;
// 14px(img margin-top) + 30px(img height)
bottom
:
-14px
;
// 延伸到下一个图标的顶部
width
:
2px
;
background-color
:
rgb
(
234
,
236
,
238
);
z-index
:
1
;
}
// justify-content: flex-start;
.time
{
width
:
80px
;
// height: 50px;
// font-size: 16px;
// font-weight: 700;
// line-height: 24px;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
5
,
95
,
194
);
margin-right
:
16px
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
.year
{
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
}
.date
{
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
}
}
img
{
width
:
30px
;
height
:
30px
;
border-radius
:
50%
;
margin-top
:
14px
;
margin-right
:
16px
;
}
.main
{
width
:
1027px
;
padding-top
:
14px
;
position
:
relative
;
.main-title
{
width
:
800px
;
font-size
:
20px
;
font-weight
:
700
;
line-height
:
26px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
59
,
65
,
75
);
margin-bottom
:
11px
;
cursor
:
pointer
;
}
.main-desc
{
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
95
,
101
,
108
);
margin-bottom
:
9px
;
}
.tag-box
{
display
:
flex
;
.tag-item
{
padding
:
1px
8px
;
margin-right
:
8px
;
border-radius
:
4px
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
5
,
95
,
194
);
background-color
:
rgba
(
231
,
243
,
255
,
1
);
}
}
.count-tag
{
position
:
absolute
;
padding
:
2px
8px
;
top
:
0
;
right
:
0
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
206
,
79
,
81
);
border-radius
:
20px
;
background-color
:
rgba
(
206
,
79
,
81
,
0
.1
);
}
}
}
}
.right-footer
{
width
:
100%
;
height
:
73px
;
border-top
:
1px
solid
rgb
(
234
,
236
,
238
);
padding
:
0
31px
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
.total-count
{
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
59
,
65
,
75
);
}
}
}
}
.search-header
{
width
:
100%
;
height
:
144px
;
background
:
#fff
;
overflow
:
hidden
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.3
);
.home-main-header-center
{
margin-top
:
20px
;
margin-left
:
200px
;
width
:
800px
;
height
:
48px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
22
,
119
,
255
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
box-sizing
:
border-box
;
padding
:
1px
;
position
:
relative
;
border
:
1px
solid
transparent
;
&
:hover
{
border
:
1px
solid
var
(
--
color-main-active
);
}
.search
{
position
:
absolute
;
right
:
-1px
;
top
:
0px
;
width
:
120px
;
height
:
46px
;
border-radius
:
10px
;
background
:
var
(
--
color-main-active
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
cursor
:
pointer
;
.search-icon
{
width
:
18px
;
height
:
18px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.search-text
{
margin-left
:
8px
;
height
:
22px
;
color
:
#fff
;
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
22px
;
}
}
}
.home-main-header-btn-box
{
margin-top
:
20px
;
margin-left
:
200px
;
display
:
flex
;
gap
:
16px
;
.btn
{
display
:
flex
;
align-items
:
center
;
gap
:
9px
;
width
:
160px
;
height
:
48px
;
border
:
1px
solid
#aed6ff
;
box-sizing
:
border-box
;
border-radius
:
24px
;
background
:
#e7f3ff
;
cursor
:
pointer
;
position
:
relative
;
&
:hover
{
background
:
#cae3fc
;
}
.btn-text
{
width
:
80px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
400
;
line-height
:
48px
;
margin-left
:
36px
;
text-align
:
center
;
}
.btn-icon
{
position
:
absolute
;
top
:
16px
;
right
:
19px
;
width
:
6px
;
height
:
12px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
}
}
.scroll-main
{
// height: calc(100% - 144px) !important;
}
.center-center
{
width
:
1600px
;
margin
:
0
auto
;
margin-top
:
21px
;
height
:
450px
;
display
:
flex
;
gap
:
16px
;
.center-center-news
{
flex-shrink
:
0
;
}
.boxs4
{
margin-left
:
20px
;
width
:
792px
;
height
:
450px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
25
,
69
,
130
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
}
}
.data-origin-box
{
width
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-start
;
padding
:
22px
0
;
.data-origin-icon
{
width
:
16px
;
height
:
16px
;
font-size
:
0px
;
margin-right
:
8px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.data-origin-text
{
font-family
:
Source
Han
Sans
CN
;
font-size
:
14px
;
color
:
var
(
--
text-primary-50-color
);
}
}
.ai-pane
{
position
:
absolute
;
right
:
0px
;
bottom
:
15px
;
z-index
:
999
;
:deep
(
.ai-pane-wrapper
)
{
display
:
none
;
}
:deep
(
.ai-button-wrapper
)
{
display
:
flex
;
}
&
:hover
{
width
:
100%
;
bottom
:
0px
;
:deep
(
.ai-pane-wrapper
)
{
display
:
block
;
}
:deep
(
.ai-button-wrapper
)
{
display
:
none
;
}
}
}
</
style
>
src/views/exportControl/index.vue
浏览文件 @
cf7baa70
...
@@ -197,7 +197,7 @@
...
@@ -197,7 +197,7 @@
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
label=
"发布次数"
width=
"300"
>
<el-table-column
label=
"发布次数"
width=
"300"
>
<template
#
default=
"scope"
>
<template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center"
>
<div
style=
"display: flex; align-items: center
; cursor: pointer
"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
<el-progress
:percentage=
"scope.row.percent * 100"
:percentage=
"scope.row.percent * 100"
...
@@ -243,7 +243,7 @@
...
@@ -243,7 +243,7 @@
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
label=
"发布次数"
width=
"300"
>
<el-table-column
label=
"发布次数"
width=
"300"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center"
>
<div
style=
"display: flex; align-items: center
; cursor: pointer
"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
<el-progress
:percentage=
"scope.row.percent * 100"
:percentage=
"scope.row.percent * 100"
...
@@ -379,7 +379,7 @@
...
@@ -379,7 +379,7 @@
</el-row>
</el-row>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px"
>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px"
>
<CustomTitle
id=
"position4"
title=
"
资源
库"
style=
"margin-top: 0px"
/>
<CustomTitle
id=
"position4"
title=
"
出口管制数据
库"
style=
"margin-top: 0px"
/>
<div
class=
"resource-tabs"
>
<div
class=
"resource-tabs"
>
<div
<div
v-for=
"tab in resourceTabs"
v-for=
"tab in resourceTabs"
...
@@ -393,7 +393,7 @@
...
@@ -393,7 +393,7 @@
</div>
</div>
<
template
v-if=
"activeResourceTab === 'entity'"
>
<
template
v-if=
"activeResourceTab === 'entity'"
>
<el-col
:span=
"8"
style=
"padding-left: 0"
>
<el-col
:span=
"8"
style=
"padding-left: 0"
>
<custom-container
title=
"历次制裁过程"
:titleIcon=
"listIcon"
height=
"
845px
"
>
<custom-container
title=
"历次制裁过程"
:titleIcon=
"listIcon"
height=
"
auto
"
>
<template
#
default
>
<template
#
default
>
<div
class=
"box4"
>
<div
class=
"box4"
>
<div
style=
"height: 90%; overflow-y: auto; padding-top: 10px"
>
<div
style=
"height: 90%; overflow-y: auto; padding-top: 10px"
>
...
@@ -407,12 +407,15 @@
...
@@ -407,12 +407,15 @@
</div>
</div>
<div
class=
"box4-item-right"
>
<div
class=
"box4-item-right"
>
<div
class=
"box4-item-right-header"
@
click=
"handleSanc(item)"
>
<div
class=
"box4-item-right-header"
@
click=
"handleSanc(item)"
>
<span
class=
"box4-item-right-header-title"
<div
class=
"box4-item-right-header-top"
>
>
{{
item
.
postDate
}}
—
{{
item
.
title
}}
</span
<span
class=
"box4-item-right-header-title"
>
{{
item
.
postDate
}}
</span>
>
<span
class=
"box4-item-right-header-desc"
>
{{
item
.
desc
}}
</span>
<span
class=
"box4-item-right-header-desc"
>
{{
item
.
desc
}}
</span>
</div>
<div
class=
"box4-item-right-header-bottom"
>
<span
class=
"box4-item-right-header-title"
>
{{
item
.
title
}}
</span>
</div>
</div>
</div>
<el-tooltip
<
!--
<
el-tooltip
effect=
"dark"
effect=
"dark"
:content=
"item.content"
:content=
"item.content"
popper-class=
"common-prompt-popper"
popper-class=
"common-prompt-popper"
...
@@ -422,7 +425,10 @@
...
@@ -422,7 +425,10 @@
<div
class=
"box4-item-right-content"
>
<div
class=
"box4-item-right-content"
>
{{
item
.
content
}}
{{
item
.
content
}}
</div>
</div>
</el-tooltip>
</el-tooltip>
-->
<div
class=
"box4-item-right-content"
>
{{
item
.
content
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -430,12 +436,18 @@
...
@@ -430,12 +436,18 @@
class=
"box4-footer"
class=
"box4-footer"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
>
>
<el-button
type=
"primary"
link
@
click=
"handleGetMore"
<
!--
<
el-button
type=
"primary"
link
@
click=
"handleGetMore"
>
查看更多
>
查看更多
<el-icon>
<el-icon>
<DArrowRight
/>
<DArrowRight
/>
</el-icon>
</el-icon>
</el-button>
</el-button>
-->
<simple-pagination
v-model:current-page=
"sanctionPage"
:page-size=
"listPageSize"
:total=
"totalNum"
@
page-change=
"handleListPageChange"
/>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
...
@@ -564,13 +576,34 @@
...
@@ -564,13 +576,34 @@
<div
class=
"text"
>
制裁时间
</div>
<div
class=
"text"
>
制裁时间
</div>
</div>
</div>
<div
class=
"left-main"
>
<div
class=
"left-main"
>
<el-checkbox-group
v-model=
"checkedTime"
>
<
!--
<
el-checkbox-group
v-model=
"checkedTime"
>
<div
class=
"checkbox-grid"
>
<div
class=
"checkbox-grid"
>
<el-checkbox
v-for=
"item in timeOptions"
:key=
"item
"
:label=
"item
"
>
{{
<el-checkbox
v-for=
"item in timeOptions"
:key=
"item
.value"
:label=
"item.label
"
>
{{
item
item
.
label
}}
</el-checkbox>
}}
</el-checkbox>
</div>
</div>
</el-checkbox-group>
</el-checkbox-group>
-->
<div
class=
"checkbox-grid"
>
<el-checkbox
v-for=
"(item, index) in timeOptions"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
@
change=
"handleFilterChange(item, timeOptions, 'time')"
/>
<div
v-if=
"timeOptions.find(i => i.value === 'custom' && i.checked)"
class=
"custom-date-picker"
>
<el-date-picker
v-model=
"customDateRange"
type=
"daterange"
range-separator=
"-"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
...
@@ -578,34 +611,39 @@
...
@@ -578,34 +611,39 @@
<img
:src=
"icon01"
alt=
""
/>
<img
:src=
"icon01"
alt=
""
/>
<div>
出口管制制裁措施
</div>
<div>
出口管制制裁措施
</div>
</div>
</div>
<div
class=
"right-main"
>
<div
class=
"right-main-box"
v-loading=
"sancLoading"
>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"right-main-wrapper"
v-if=
"sanctionList.length > 0"
>
<div
class=
"time"
>
<div
class=
"right-main"
>
<div
class=
"year"
>
{{
item
.
year
}}
</div>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"date"
>
{{
item
.
dateStr
}}
</div>
<div
class=
"time"
>
</div>
<div
class=
"year"
>
{{
item
.
year
}}
</div>
<img
:src=
"item.orgLogoUrl || comTitle"
alt=
""
/>
<div
class=
"date"
>
{{
item
.
dateStr
}}
</div>
<div
class=
"main"
>
</div>
<div
class=
"main-title"
@
click=
"handleTitleClick(item)"
>
{{
item
.
title
}}
</div>
<img
:src=
"item.orgLogoUrl || comTitle"
alt=
""
/>
<div
class=
"main-desc"
>
{{
item
.
desc
}}
</div>
<div
class=
"main"
>
<div
class=
"tag-box"
>
<div
class=
"main-title"
@
click=
"handleTitleClick(item)"
>
{{
item
.
title
}}
</div>
<div
v-for=
"tag in item.tags"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
<div
class=
"main-desc"
>
{{
item
.
desc
}}
</div>
</div>
<div
class=
"tag-box"
>
<div
v-for=
"tag in item.tags"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
</div>
<div
:class=
"
{ 'count-tag': item.countTag }">
{{
item
.
countTag
}}
</div>
<div
:class=
"
{ 'count-tag': item.countTag }">
{{
item
.
countTag
}}
</div>
</div>
</div>
</div>
<div
class=
"right-footer"
>
<div
class=
"total-count"
>
共
{{
totalAll
}}
项
</div>
<el-pagination
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</div>
</div>
</div>
<el-empty
v-else
/>
<div
class=
"right-footer"
>
<div
class=
"total-count"
>
共
{{
totalAll
}}
项
</div>
<el-pagination
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -649,6 +687,7 @@
...
@@ -649,6 +687,7 @@
//这是一个备注
//这是一个备注
import
NewsList
from
"@/components/base/newsList/index.vue"
;
import
NewsList
from
"@/components/base/newsList/index.vue"
;
import
RiskSignal
from
"@/components/base/riskSignal/index.vue"
;
import
RiskSignal
from
"@/components/base/riskSignal/index.vue"
;
import
SimplePagination
from
"@/components/SimplePagination.vue"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis/index"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis/index"
;
import
RiskSignalOverviewDetailDialog
from
"@/components/base/RiskSignalOverviewDetailDialog/index.vue"
;
import
RiskSignalOverviewDetailDialog
from
"@/components/base/RiskSignalOverviewDetailDialog/index.vue"
;
import
{
onMounted
,
ref
,
computed
,
reactive
,
shallowRef
,
watch
,
nextTick
}
from
"vue"
;
import
{
onMounted
,
ref
,
computed
,
reactive
,
shallowRef
,
watch
,
nextTick
}
from
"vue"
;
...
@@ -669,10 +708,10 @@ import { useGotoCompanyPages } from "@/router/modules/company";
...
@@ -669,10 +708,10 @@ import { useGotoCompanyPages } from "@/router/modules/company";
import
{
useGotoNewsDetail
}
from
"@/router/modules/news"
;
import
{
useGotoNewsDetail
}
from
"@/router/modules/news"
;
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
gotoNewsDetail
=
useGotoNewsDetail
();
const
gotoNewsDetail
=
useGotoNewsDetail
();
const
trendChart
=
useChartInterpretation
();
//
const trendChart = useChartInterpretation();
const
radarChart
=
useChartInterpretation
();
//
const radarChart = useChartInterpretation();
const
entityListReleaseFreqChart
=
useChartInterpretation
();
//
const entityListReleaseFreqChart = useChartInterpretation();
const
commerceControlListReleaseFreqChart
=
useChartInterpretation
();
//
const commerceControlListReleaseFreqChart = useChartInterpretation();
import
{
useRouter
}
from
"vue-router"
;
import
{
useRouter
}
from
"vue-router"
;
import
{
navigateToViewRiskSignal
}
from
"@/utils/riskSignalOverviewNavigate"
;
import
{
navigateToViewRiskSignal
}
from
"@/utils/riskSignalOverviewNavigate"
;
...
@@ -754,7 +793,7 @@ const handleToRiskSignalDetail = item => {
...
@@ -754,7 +793,7 @@ const handleToRiskSignalDetail = item => {
riskOverviewDetailRow
.
value
=
item
??
null
;
riskOverviewDetailRow
.
value
=
item
??
null
;
isRiskOverviewDetailOpen
.
value
=
true
;
isRiskOverviewDetailOpen
.
value
=
true
;
};
};
const
sancLoading
=
ref
(
false
);
const
sanctionList
=
ref
([]);
const
sanctionList
=
ref
([]);
const
techOptions
=
[
const
techOptions
=
[
...
@@ -774,36 +813,18 @@ const techOptions = [
...
@@ -774,36 +813,18 @@ const techOptions = [
{
label
:
"太空"
,
value
:
13
},
{
label
:
"太空"
,
value
:
13
},
{
label
:
"核"
,
value
:
14
}
{
label
:
"核"
,
value
:
14
}
];
];
const
timeOptions
=
[
const
customDateRange
=
ref
(
""
);
"全部时间"
,
const
timeOptions
=
ref
([
"2025年"
,
{
label
:
"全部时间"
,
value
:
"all"
,
checked
:
true
},
"2024年"
,
{
label
:
"2026年"
,
value
:
"2026"
,
checked
:
false
},
"2023年"
,
{
label
:
"2025年"
,
value
:
"2025"
,
checked
:
false
},
"2022年"
,
{
label
:
"2024年"
,
value
:
"2024"
,
checked
:
false
},
"2021年"
,
{
label
:
"2023年"
,
value
:
"2023"
,
checked
:
false
},
"2020年"
,
{
label
:
"2022年"
,
value
:
"2022"
,
checked
:
false
},
"2019年"
,
{
label
:
"自定义"
,
value
:
"custom"
,
checked
:
false
}
"2018年"
,
]);
"2017年"
,
"2016年"
,
"2015年"
,
"2014年"
,
"2013年"
,
"2012年"
,
"2011年"
,
"2010年"
,
"2009年"
,
"2008年"
,
"2007年"
,
"2006年"
,
"2005年"
,
"2004年"
,
"2003年"
,
"2002年"
,
"2001年"
];
const
checkedTech
=
ref
([
0
]);
const
checkedTech
=
ref
([
0
]);
const
checkedTime
=
ref
([
"
全部时间
"
]);
const
checkedTime
=
ref
([
"
all
"
]);
// 跳转到单条制裁页面,单独打开一个新页面
// 跳转到单条制裁页面,单独打开一个新页面
const
handleTitleClick
=
item
=>
{
const
handleTitleClick
=
item
=>
{
...
@@ -825,17 +846,9 @@ const handleTitleClick = item => {
...
@@ -825,17 +846,9 @@ const handleTitleClick = item => {
const
handleCompClick
=
item
=>
{
const
handleCompClick
=
item
=>
{
// console.log("item", item);
// console.log("item", item);
// if (item.entityType != 2
) return;
if
(
!
item
.
id
)
return
;
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
gotoCompanyPages
(
item
.
entityId
);
gotoCompanyPages
(
item
.
entityId
);
// const route = router.resolve({
// name: "companyPages",
// params: {
// id: item.id,
// sanTypeId: item.sanTypeId
// }
// });
// window.open(route.href, "_blank");
};
};
const
tagsType
=
[
"primary"
,
"success"
,
"warning"
,
"danger"
];
const
tagsType
=
[
"primary"
,
"success"
,
"warning"
,
"danger"
];
...
@@ -880,6 +893,7 @@ const commerceControlListReleaseFreq = ref([]);
...
@@ -880,6 +893,7 @@ const commerceControlListReleaseFreq = ref([]);
// 历次制裁过程
// 历次制裁过程
const
sanctionProcessList
=
ref
([]);
const
sanctionProcessList
=
ref
([]);
const
sanctionPage
=
ref
(
1
);
const
sanctionPage
=
ref
(
1
);
const
totalNum
=
ref
(
0
);
// 制裁实体清单
// 制裁实体清单
const
entitiesList
=
ref
([]);
const
entitiesList
=
ref
([]);
// 风险信号
// 风险信号
...
@@ -964,7 +978,7 @@ onMounted(async () => {
...
@@ -964,7 +978,7 @@ onMounted(async () => {
// 获取新闻资讯
// 获取新闻资讯
await
fetchNewsInfo
();
await
fetchNewsInfo
();
await
fetchEntitiesList
(
currentPage
.
value
,
pageSize
.
value
);
await
fetchEntitiesList
(
currentPage
.
value
,
pageSize
.
value
);
await
fetchSanctionProcess
(
sanctionPage
.
value
,
10
);
await
fetchSanctionProcess
(
sanctionPage
.
value
,
listPageSize
.
value
);
// 获取雷达图数据
// 获取雷达图数据
await
fetchRadarData
(
domainChecked
.
value
);
await
fetchRadarData
(
domainChecked
.
value
);
// 获取出口管制制裁措施
// 获取出口管制制裁措施
...
@@ -1426,18 +1440,86 @@ const currentPageAll = ref(1);
...
@@ -1426,18 +1440,86 @@ const currentPageAll = ref(1);
const
pageSizeAll
=
ref
(
10
);
const
pageSizeAll
=
ref
(
10
);
const
totalAll
=
ref
(
0
);
const
totalAll
=
ref
(
0
);
// 筛选逻辑处理
const
handleFilterChange
=
(
item
,
list
,
type
)
=>
{
debugger
;
// 如果点击的是"全部"
if
(
item
.
value
===
"all"
)
{
if
(
item
.
checked
)
{
// 选中全部,取消其他所有
list
.
forEach
(
i
=>
{
if
(
i
.
value
!==
"all"
)
i
.
checked
=
false
;
});
}
else
{
// 取消全部(通常不允许全部取消,至少得选一个,这里如果取消全部,就默认为全部选中)
item
.
checked
=
true
;
}
}
else
{
// 点击的是具体项
if
(
item
.
checked
)
{
// 选中具体项,取消"全部"
const
allItem
=
list
.
find
(
i
=>
i
.
value
===
"all"
);
if
(
allItem
)
allItem
.
checked
=
false
;
// 特殊处理制裁时间的自定义和其他年份互斥
if
(
type
===
"time"
)
{
if
(
item
.
value
===
"custom"
)
{
list
.
forEach
(
i
=>
{
if
(
i
.
value
!==
"custom"
&&
i
.
value
!==
"all"
)
i
.
checked
=
false
;
});
}
else
{
const
customItem
=
list
.
find
(
i
=>
i
.
value
===
"custom"
);
if
(
customItem
)
customItem
.
checked
=
false
;
}
}
}
else
{
// 取消具体项,检查是否还有选中的
const
anyChecked
=
list
.
some
(
i
=>
i
.
checked
);
if
(
!
anyChecked
)
{
const
allItem
=
list
.
find
(
i
=>
i
.
value
===
"all"
);
if
(
allItem
)
allItem
.
checked
=
true
;
}
}
}
// 重置页码并查询
currentPageAll
.
value
=
1
;
fetchSanctionList
();
};
watch
(
customDateRange
,
()
=>
{
if
(
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"custom"
&&
item
.
checked
))
{
currentPageAll
.
value
=
1
;
fetchSanctionList
();
}
});
const
fetchSanctionList
=
async
()
=>
{
const
fetchSanctionList
=
async
()
=>
{
try
{
try
{
sancLoading
.
value
=
true
;
const
techDomains
=
checkedTech
.
value
.
includes
(
0
)
?
null
:
checkedTech
.
value
.
map
(
String
);
const
techDomains
=
checkedTech
.
value
.
includes
(
0
)
?
null
:
checkedTech
.
value
.
map
(
String
);
let
years
=
null
;
let
years
=
null
;
if
(
!
checkedTime
.
value
.
includes
(
"全部时间"
))
{
let
startDate
=
undefined
;
years
=
checkedTime
.
value
let
endDate
=
undefined
;
.
map
(
t
=>
{
const
allTime
=
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"all"
);
const
match
=
t
.
match
(
/
(\d{4})
/
);
console
.
log
(
"allTime"
,
allTime
);
return
match
?
parseInt
(
match
[
1
])
:
null
;
if
(
!
allTime
||
!
allTime
.
checked
)
{
})
years
=
timeOptions
.
value
.
filter
(
y
=>
y
!==
null
);
.
filter
(
item
=>
item
.
checked
&&
item
.
value
!==
"all"
&&
item
.
value
!==
"custom"
)
if
(
years
.
length
===
0
)
years
=
null
;
.
map
(
item
=>
Number
(
item
.
value
));
const
customTime
=
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"custom"
);
if
(
customTime
&&
customTime
.
checked
&&
customDateRange
.
value
&&
customDateRange
.
value
.
length
===
2
)
{
const
start
=
new
Date
(
customDateRange
.
value
[
0
]);
const
end
=
new
Date
(
customDateRange
.
value
[
1
]);
startDate
=
`
${
start
.
getFullYear
()}
-
${
String
(
start
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
)}
-
${
String
(
start
.
getDate
()
).
padStart
(
2
,
"0"
)}
`
;
endDate
=
`
${
end
.
getFullYear
()}
-
${
String
(
end
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
)}
-
${
String
(
end
.
getDate
()).
padStart
(
2
,
"0"
)}
`
;
}
}
}
const
params
=
{
const
params
=
{
...
@@ -1447,10 +1529,13 @@ const fetchSanctionList = async () => {
...
@@ -1447,10 +1529,13 @@ const fetchSanctionList = async () => {
years
:
years
,
years
:
years
,
isCn
:
false
,
isCn
:
false
,
// typeName: "实体清单"
// typeName: "实体清单"
sanTypeIds
:
allSanTypeIds
.
value
sanTypeIds
:
allSanTypeIds
.
value
,
startDate
:
startDate
,
endDate
:
endDate
};
};
const
res
=
await
getExportControlList
(
params
);
const
res
=
await
getExportControlList
(
params
);
sancLoading
.
value
=
false
;
if
(
res
&&
res
.
content
)
{
if
(
res
&&
res
.
content
)
{
sanctionList
.
value
=
res
.
content
.
map
(
item
=>
{
sanctionList
.
value
=
res
.
content
.
map
(
item
=>
{
const
tags
=
Array
.
isArray
(
item
.
techDomains
)
const
tags
=
Array
.
isArray
(
item
.
techDomains
)
...
@@ -1493,7 +1578,10 @@ const fetchSanctionList = async () => {
...
@@ -1493,7 +1578,10 @@ const fetchSanctionList = async () => {
});
});
totalAll
.
value
=
res
.
totalElements
;
totalAll
.
value
=
res
.
totalElements
;
}
}
}
catch
(
error
)
{}
}
catch
(
error
)
{
console
.
error
(
"错误信息"
,
error
);
sancLoading
.
value
=
false
;
}
};
};
const
handlePageChangeAll
=
val
=>
{
const
handlePageChangeAll
=
val
=>
{
...
@@ -1533,16 +1621,16 @@ watch(
...
@@ -1533,16 +1621,16 @@ watch(
(
newVal
,
oldVal
)
=>
{
(
newVal
,
oldVal
)
=>
{
let
isModified
=
false
;
let
isModified
=
false
;
if
(
newVal
.
includes
(
"
全部时间
"
))
{
if
(
newVal
.
includes
(
"
all
"
))
{
if
(
!
oldVal
.
includes
(
"
全部时间
"
))
{
if
(
!
oldVal
.
includes
(
"
all
"
))
{
checkedTime
.
value
=
[
"
全部时间
"
];
checkedTime
.
value
=
[
"
all
"
];
isModified
=
true
;
isModified
=
true
;
}
else
if
(
newVal
.
length
>
1
)
{
}
else
if
(
newVal
.
length
>
1
)
{
checkedTime
.
value
=
newVal
.
filter
(
v
=>
v
!==
"
全部时间
"
);
checkedTime
.
value
=
newVal
.
filter
(
v
=>
v
!==
"
all
"
);
isModified
=
true
;
isModified
=
true
;
}
}
}
else
if
(
newVal
.
length
===
0
)
{
}
else
if
(
newVal
.
length
===
0
)
{
checkedTime
.
value
=
[
"
全部时间
"
];
checkedTime
.
value
=
[
"
all
"
];
isModified
=
true
;
isModified
=
true
;
}
}
...
@@ -1576,6 +1664,26 @@ const fetchEntitiesList = async (page = 1, size = 10) => {
...
@@ -1576,6 +1664,26 @@ const fetchEntitiesList = async (page = 1, size = 10) => {
}
}
};
};
const
listPageSize
=
ref
(
5
);
const
handleListPageChange
=
async
page
=>
{
console
.
log
(
"页面修改 =>"
,
page
);
sanctionPage
.
value
=
page
;
fetchSanctionProcess
(
page
,
listPageSize
.
value
);
// if (res && res.content) {
// // 将新数据合并到现有列表中
// const newData = res.content.map(item => ({
// ...item,
// title: item.name,
// desc: `${item.cnEntityCount} 家中国实体`,
// content:
// item.summary ||
// "2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
// }));
// // 合并新数据到现有列表
// sanctionProcessList.value = [...newData];
// }
};
const
handleGetMore
=
async
()
=>
{
const
handleGetMore
=
async
()
=>
{
sanctionPage
.
value
++
;
sanctionPage
.
value
++
;
try
{
try
{
...
@@ -1603,7 +1711,7 @@ const handleGetMore = async () => {
...
@@ -1603,7 +1711,7 @@ const handleGetMore = async () => {
};
};
// 获取历次制裁过程数据
// 获取历次制裁过程数据
const
fetchSanctionProcess
=
async
(
page
=
1
,
size
=
10
)
=>
{
const
fetchSanctionProcess
=
async
(
page
=
1
,
size
=
listPageSize
.
value
)
=>
{
try
{
try
{
const
res
=
await
getSanctionProcess
(
const
res
=
await
getSanctionProcess
(
activeResourceTabItem
.
value
.
id
?
[
activeResourceTabItem
.
value
.
id
]
:
allSanTypeIds
.
value
,
activeResourceTabItem
.
value
.
id
?
[
activeResourceTabItem
.
value
.
id
]
:
allSanTypeIds
.
value
,
...
@@ -1620,6 +1728,8 @@ const fetchSanctionProcess = async (page = 1, size = 10) => {
...
@@ -1620,6 +1728,8 @@ const fetchSanctionProcess = async (page = 1, size = 10) => {
item
.
summary
||
item
.
summary
||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
}));
}));
totalNum
.
value
=
res
.
totalElements
;
// currentPage.value = res.number + 1; // API返回的页码从0开始,前端从1开始
}
}
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
err
);
console
.
error
(
err
);
...
@@ -2401,7 +2511,7 @@ const handleMediaClick = item => {
...
@@ -2401,7 +2511,7 @@ const handleMediaClick = item => {
}
}
.box4
{
.box4
{
height
:
786
px
;
min-height
:
980
px
;
overflow
:
auto
;
overflow
:
auto
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
...
@@ -2441,18 +2551,27 @@ const handleMediaClick = item => {
...
@@ -2441,18 +2551,27 @@ const handleMediaClick = item => {
.box4-item-right-header
{
.box4-item-right-header
{
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
center
;
//
align-items: center;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
position
:
relative
;
position
:
relative
;
top
:
-7
.5px
;
top
:
-7
.5px
;
padding-bottom
:
8px
;
padding-bottom
:
8px
;
cursor
:
pointer
;
cursor
:
pointer
;
&
-top
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
5px
;
}
&
-title
{
&
-title
{
font-size
:
18px
;
font-size
:
18px
;
color
:
$base-color
;
color
:
$base-color
;
font-weight
:
700
;
font-weight
:
700
;
&
:hover
{
text-decoration
:
underline
;
background
:
var
(
--
color-primary-2
);
}
}
}
&
-desc
{
&
-desc
{
...
@@ -2477,7 +2596,7 @@ const handleMediaClick = item => {
...
@@ -2477,7 +2596,7 @@ const handleMediaClick = item => {
}
}
.box4-footer
{
.box4-footer
{
position
:
absolute
;
//
position: absolute;
// margin-top: auto;
// margin-top: auto;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
...
@@ -3498,6 +3617,47 @@ const handleMediaClick = item => {
...
@@ -3498,6 +3617,47 @@ const handleMediaClick = item => {
color
:
#666666
;
color
:
#666666
;
font-weight
:
400
;
font-weight
:
400
;
}
}
.custom-date-picker
{
width
:
100%
;
margin-top
:
8px
;
padding-right
:
24px
;
box-sizing
:
border-box
;
grid-column
:
1
/
-1
;
:deep
(
.el-date-editor
)
{
width
:
100%
;
height
:
32px
;
box-shadow
:
none
;
border
:
1px
solid
#dcdfe6
;
border-radius
:
4px
;
padding
:
0
10px
;
&
:hover
{
border-color
:
#c0c4cc
;
}
&
.is-active
{
border-color
:
#409eff
;
}
.el-range-input
{
font-size
:
14px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
95
,
101
,
108
);
}
.el-range-separator
{
color
:
rgb
(
95
,
101
,
108
);
line-height
:
30px
;
}
.el-input__icon
{
line-height
:
32px
;
color
:
rgb
(
95
,
101
,
108
);
}
}
}
}
}
}
}
...
...
src/views/exportControl/v2.0EntityList/components/dataStatistics/index.vue
浏览文件 @
cf7baa70
...
@@ -129,8 +129,14 @@
...
@@ -129,8 +129,14 @@
<div
class=
"data-origin-text"
>
进入实体清单的中国实体数量变化趋势,数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
进入实体清单的中国实体数量变化趋势,数据来源:美国商务部官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<!-- <AiButton />
<AiPane
:aiContent=
"sanctionCountChart.interpretation"
/>
<AiPane :aiContent="sanctionCountChart.interpretation" /> -->
<AiButton
@
mouseenter=
"handleShowAiPane('sanctionCountChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.sanctionCountChart"
:aiContent=
"overviewAiContent.sanctionCountChart"
@
mouseleave=
"handleHideAiPane('sanctionCountChart')"
/>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
...
@@ -165,17 +171,6 @@
...
@@ -165,17 +171,6 @@
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div class="bottom">
<div class="ai">
<div class="left">
<img :src="ai" alt="" class="icon1" />
<div class="text">我国被制裁实体多分布于沿海经济活跃省份。</div>
</div>
<div class="right">
<img :src="right" alt="" class="icon2" />
</div>
</div>
</div> -->
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
...
@@ -183,8 +178,14 @@
...
@@ -183,8 +178,14 @@
<div
class=
"data-origin-text"
>
进入实体清单的中国实体各省分布情况,数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
进入实体清单的中国实体各省分布情况,数据来源:美国商务部官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<!-- <AiButton />
<AiPane
:aiContent=
"rankChart.interpretation"
/>
<AiPane :aiContent="rankChart.interpretation" /> -->
<AiButton
@
mouseenter=
"handleShowAiPane('rankChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.rankChart"
:aiContent=
"overviewAiContent.rankChart"
@
mouseleave=
"handleHideAiPane('rankChart')"
/>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
...
@@ -202,17 +203,6 @@
...
@@ -202,17 +203,6 @@
:style=
"{ height: '300px', padding: '0 20px' }"
:style=
"{ height: '300px', padding: '0 20px' }"
@
chart-click=
"handleToDataLibrary6"
@
chart-click=
"handleToDataLibrary6"
/>
/>
<!-- <div class="bottom">
<div class="ai">
<div class="left">
<img :src="ai" alt="" class="icon1" />
<div class="text">美国对中国的制裁集中在半导体、人工智能等领域。</div>
</div>
<div class="right">
<img :src="right" alt="" class="icon2" />
</div>
</div>
</div> -->
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
...
@@ -220,8 +210,14 @@
...
@@ -220,8 +210,14 @@
<div
class=
"data-origin-text"
>
进入实体清单的中国实体领域分布情况,数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
进入实体清单的中国实体领域分布情况,数据来源:美国商务部官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<!-- <AiButton />
<AiPane
:aiContent=
"domainChart.interpretation"
/>
<AiPane :aiContent="domainChart.interpretation" /> -->
<AiButton
@
mouseenter=
"handleShowAiPane('domainChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.domainChart"
:aiContent=
"overviewAiContent.domainChart"
@
mouseleave=
"handleHideAiPane('domainChart')"
/>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
...
@@ -239,17 +235,6 @@
...
@@ -239,17 +235,6 @@
:style=
"{ height: '300px', padding: '0 20px' }"
:style=
"{ height: '300px', padding: '0 20px' }"
@
chart-click=
"handleToDataLibrary7"
@
chart-click=
"handleToDataLibrary7"
/>
/>
<!-- <div class="bottom">
<div class="ai">
<div class="left">
<img :src="ai" alt="" class="icon1" />
<div class="text">我国被制裁实体以企业、科研院所和高校为主。</div>
</div>
<div class="right">
<img :src="right" alt="" class="icon2" />
</div>
</div>
</div> -->
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
...
@@ -257,8 +242,14 @@
...
@@ -257,8 +242,14 @@
<div
class=
"data-origin-text"
>
进入实体清单的中国实体类型分布情况,数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
进入实体清单的中国实体类型分布情况,数据来源:美国商务部官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<!-- <AiButton />
<AiPane
:aiContent=
"typeChart.interpretation"
/>
<AiPane :aiContent="typeChart.interpretation" /> -->
<AiButton
@
mouseenter=
"handleShowAiPane('typeChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.typeChart"
:aiContent=
"overviewAiContent.typeChart"
@
mouseleave=
"handleHideAiPane('typeChart')"
/>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
...
@@ -286,7 +277,7 @@ import tipsIcon from "../../../assets/icons/info-icon.png";
...
@@ -286,7 +277,7 @@ import tipsIcon from "../../../assets/icons/info-icon.png";
import
AiButton
from
"@/components/base/Ai/AiButton/index.vue"
;
import
AiButton
from
"@/components/base/Ai/AiButton/index.vue"
;
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
import
{
useChartInterpretation
}
from
"@/views/exportControl/utils/common"
;
import
{
useChartInterpretation
}
from
"@/views/exportControl/utils/common"
;
const
sanctionCountChart
=
useChartInterpretation
();
//
const sanctionCountChart = useChartInterpretation();
const
domainChart
=
useChartInterpretation
();
const
domainChart
=
useChartInterpretation
();
const
typeChart
=
useChartInterpretation
();
const
typeChart
=
useChartInterpretation
();
const
rankChart
=
useChartInterpretation
();
const
rankChart
=
useChartInterpretation
();
...
@@ -313,7 +304,7 @@ const getTypeCountData = async () => {
...
@@ -313,7 +304,7 @@ const getTypeCountData = async () => {
name
:
item
.
name
,
name
:
item
.
name
,
value
:
item
.
count
||
item
.
value
value
:
item
.
count
||
item
.
value
}));
}));
typeChart
.
interpret
({
type
:
"饼图"
,
name
:
"制裁实体类型分布情况"
,
data
:
data
});
//
typeChart.interpret({ type: "饼图", name: "制裁实体类型分布情况", data: data });
updateTypeChart
();
updateTypeChart
();
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
...
@@ -342,7 +333,7 @@ const getDomainCountData = async () => {
...
@@ -342,7 +333,7 @@ const getDomainCountData = async () => {
value
:
item
.
count
||
item
.
value
value
:
item
.
count
||
item
.
value
}));
}));
updateDomainChart
();
updateDomainChart
();
domainChart
.
interpret
({
type
:
"饼图"
,
name
:
"制裁实体领域分布情况"
,
data
:
data
});
//
domainChart.interpret({ type: "饼图", name: "制裁实体领域分布情况", data: data });
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"获取实体清单-数据统计-制裁实体领域分布情况失败:"
,
error
);
console
.
error
(
"获取实体清单-数据统计-制裁实体领域分布情况失败:"
,
error
);
...
@@ -379,7 +370,7 @@ const getRegionCountData = async () => {
...
@@ -379,7 +370,7 @@ const getRegionCountData = async () => {
}));
}));
// Sort by value descending
// Sort by value descending
rankData
.
value
.
sort
((
a
,
b
)
=>
b
.
value
-
a
.
value
);
rankData
.
value
.
sort
((
a
,
b
)
=>
b
.
value
-
a
.
value
);
rankChart
.
interpret
({
type
:
"柱状图"
,
name
:
"制裁实体各省分布情况"
,
data
:
data
});
//
rankChart.interpret({ type: "柱状图", name: "制裁实体各省分布情况", data: data });
updateMapChart
();
updateMapChart
();
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
...
@@ -400,7 +391,7 @@ const getSanctionCountChangeData = async () => {
...
@@ -400,7 +391,7 @@ const getSanctionCountChangeData = async () => {
const
res
=
await
getSanctionCountChange
(
param
);
const
res
=
await
getSanctionCountChange
(
param
);
sanctionCountChange
.
value
=
res
.
data
||
[];
sanctionCountChange
.
value
=
res
.
data
||
[];
updateSanctionCountChart
();
updateSanctionCountChart
();
sanctionCountChart
.
interpret
({
type
:
"饼图"
,
name
:
"制裁实体数量变化情况"
,
data
:
res
.
data
});
//
sanctionCountChart.interpret({ type: "饼图", name: "制裁实体数量变化情况", data: res.data });
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"获取实体清单-数据统计-制裁实体数量变化情况失败:"
,
error
);
console
.
error
(
"获取实体清单-数据统计-制裁实体数量变化情况失败:"
,
error
);
}
}
...
@@ -1039,96 +1030,6 @@ const updateTypeChart = () => {
...
@@ -1039,96 +1030,6 @@ const updateTypeChart = () => {
// }
// }
typeChartOption
.
value
.
series
[
0
].
data
=
topData
;
typeChartOption
.
value
.
series
[
0
].
data
=
topData
;
}
}
// const option = {
// tooltip: {
// trigger: "item",
// formatter: params => {
// if (params.name === "其他" && params.data.extra) {
// let listStr = params.data.extra
// .map(item => {
// const percent = totalValue ? ((item.value / totalValue) * 100).toFixed(2) : 0;
// return `
<
div
style
=
"display:flex;justify-content:space-between;gap:10px;"
><
span
>
$
{
item
.
name
}
<
/span><span style="font-weight:bold">${item.value}家
(
${percent}%
)
</
span
><
/div>`
;
// })
// .join("");
// return `
<
div
style
=
"text-align:left;"
>
//
<
div
style
=
"font-weight:bold;margin-bottom:5px;"
>
其他
(
$
{
params
.
value
}
家
$
{
params
.
percent
}
%
)
<
/div
>
// ${listStr}
//
<
/div>`
;
// }
// return `${params.name}: ${params.value} (${params.percent}%)`;
// }
// },
// color: [
// "#3B82F6", // 企业 - 蓝色
// "#feb64d", // 高校 - 橙色
// "#ff9f9f" // 科研院所 - 粉红
// ],
// series: [
// {
// name: "制裁实体类型分布",
// type: "pie",
// radius: [73.5, 89.5],
// center: ["50%", "50%"],
// startAngle: -90,
// data: data,
// label: {
// show: true,
// alignTo: "edge",
// minMargin: 5,
// edgeDistance: 10,
// formatter: params => {
// return "{name|" + params.name + "}\n{value|" + params.value + "家 " + params.percent + "%}";
// },
// rich: {
// name: {
// fontSize: 18,
// fontWeight: 700,
// color: "rgb(59, 65, 75)",
// padding: [0, 0, 5, 0],
// fontFamily: "Microsoft YaHei",
// lineHeight: 26
// },
// value: {
// fontSize: 16,
// fontWeight: 400,
// color: "rgb(95, 101, 108)",
// fontFamily: "Microsoft YaHei",
// lineHeight: 24,
// padding: [5, 0, 0, 0]
// }
// }
// },
// labelLine: {
// show: true,
// length: 15,
// length2: 0,
// maxSurfaceAngle: 80,
// lineStyle: {
// width: 1
// }
// },
// labelLayout: function (params) {
// const isLeft = params.labelRect.x
<
chart
.
getWidth
()
/
2
;
// const points = params.labelLinePoints;
// // Update the end point.
// points[2][0] = isLeft ? params.labelRect.x : params.labelRect.x + params.labelRect.width;
// return {
// labelLinePoints: points
// };
// },
// itemStyle: {
// borderWidth: 0
// }
// }
// ]
// };
// chart.setOption(option);
// window.addEventListener("resize", () => {
// chart.resize();
// });
};
};
const
initTypeChart
=
()
=>
{
const
initTypeChart
=
()
=>
{
...
@@ -1239,6 +1140,133 @@ const handleToDataLibrary3 = time => {
...
@@ -1239,6 +1140,133 @@ const handleToDataLibrary3 = time => {
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
};
};
const
requestAiPaneContent
=
async
key
=>
{
if
(
!
key
||
aiPaneLoading
.
value
[
key
]
||
aiPaneFetched
.
value
[
key
])
return
;
aiPaneLoading
.
value
=
{
...
aiPaneLoading
.
value
,
[
key
]:
true
};
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
"智能总结生成中..."
};
try
{
const
payload
=
buildAiChartPayload
(
key
);
const
res
=
await
getChartAnalysis
(
{
text
:
JSON
.
stringify
(
payload
)
},
{
onChunk
:
chunk
=>
{
const
current
=
overviewAiContent
.
value
[
key
];
const
base
=
current
===
"智能总结生成中..."
?
""
:
current
;
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
base
+
chunk
};
}
}
);
const
list
=
res
?.
data
;
const
first
=
Array
.
isArray
(
list
)
?
list
[
0
]
:
null
;
const
interpretation
=
first
?.
解读
||
first
?.[
"解读"
];
// 流式已渲染过内容,最终用解析出的解读覆盖(保证显示格式统一)
if
(
interpretation
)
{
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
interpretation
};
}
aiPaneFetched
.
value
=
{
...
aiPaneFetched
.
value
,
[
key
]:
true
};
}
catch
(
error
)
{
console
.
error
(
"获取图表解读失败"
,
error
);
overviewAiContent
.
value
=
{
...
overviewAiContent
.
value
,
[
key
]:
"智能总结生成失败"
};
}
finally
{
aiPaneLoading
.
value
=
{
...
aiPaneLoading
.
value
,
[
key
]:
false
};
}
};
// const sanctionCountChart = useChartInterpretation();
// const domainChart = useChartInterpretation();
// const typeChart = useChartInterpretation();
// const rankChart = useChartInterpretation();
const
sanctionCountChartData
=
ref
([]);
const
domainChartData
=
ref
([]);
const
typeChartData
=
ref
([]);
const
rankChartData
=
ref
([]);
const
aiPaneVisible
=
ref
({
sanctionCountChart
:
false
,
domainChart
:
false
,
typeChart
:
false
,
rankChart
:
false
});
const
overviewAiContent
=
ref
({
sanctionCountChart
:
"智能总结生成中..."
,
domainChart
:
"智能总结生成中..."
,
typeChart
:
"智能总结生成中..."
,
rankChart
:
"智能总结生成中..."
});
const
aiPaneFetched
=
ref
({
sanctionCountChart
:
false
,
domainChart
:
false
,
typeChart
:
false
,
rankChart
:
false
});
const
aiPaneLoading
=
ref
({
sanctionCountChart
:
false
,
domainChart
:
false
,
typeChart
:
false
,
rankChart
:
false
});
const
chartLoading
=
ref
({
sanctionCountChart
:
false
,
domainChart
:
false
,
typeChart
:
false
,
rankChart
:
false
});
const
buildAiChartPayload
=
key
=>
{
if
(
key
===
"sanctionCountChart"
)
{
return
{
type
:
"饼图"
,
name
:
"制裁实体数量变化情况"
,
data
:
sanctionCountChange
.
value
};
}
if
(
key
===
"domainChart"
)
{
return
{
type
:
"饼图"
,
name
:
"制裁实体领域分布情况"
,
data
:
domainData
.
value
};
}
if
(
key
===
"typeChart"
)
{
return
{
type
:
"饼图"
,
name
:
"制裁实体类型分布情况"
,
data
:
typeData
.
value
};
}
if
(
key
===
"rankChart"
)
{
return
{
type
:
"柱状图"
,
name
:
"制裁实体各省分布情况"
,
data
:
rankData
.
value
};
}
return
{
type
:
""
,
name
:
""
,
data
:
[]
};
};
const
handleShowAiPane
=
key
=>
{
aiPaneVisible
.
value
=
{
...
aiPaneVisible
.
value
,
[
key
]:
true
};
requestAiPaneContent
(
key
);
};
const
handleHideAiPane
=
key
=>
{
aiPaneVisible
.
value
=
{
...
aiPaneVisible
.
value
,
[
key
]:
false
};
};
onMounted
(()
=>
{
onMounted
(()
=>
{
sanTypeId
.
value
=
route
.
query
.
sanTypeId
||
""
;
sanTypeId
.
value
=
route
.
query
.
sanTypeId
||
""
;
console
.
log
(
"数据统计页面接收到的 sanTypeId:"
,
sanTypeId
.
value
);
console
.
log
(
"数据统计页面接收到的 sanTypeId:"
,
sanTypeId
.
value
);
...
...
src/views/exportControl/v2.0EntityList/components/deepMining/index.vue
浏览文件 @
cf7baa70
...
@@ -49,8 +49,8 @@
...
@@ -49,8 +49,8 @@
:class=
"
{ active: currentSanctionId === item.id }"
:class=
"
{ active: currentSanctionId === item.id }"
@click="handleSanctionSelect(item.id)"
@click="handleSanctionSelect(item.id)"
>
>
<
!--
<div
class=
"item-left"
>
{{
item
.
date
}}
-
{{
item
.
title
}}
</div>
--
>
<
div
class=
"item-left"
>
{{
item
.
date
}}
-
{{
item
.
title
}}
</div
>
<
div
class=
"item-left"
>
{{
item
.
date
}}
-实体清单更新
</div
>
<
!--
<div
class=
"item-left"
>
{{
item
.
date
}}
-实体清单更新
</div>
--
>
<div
class=
"item-right"
>
{{
item
.
count
}}{{
item
.
unit
}}
</div>
<div
class=
"item-right"
>
{{
item
.
count
}}{{
item
.
unit
}}
</div>
</div>
</div>
</div>
</div>
...
...
src/views/exportControl/v2.0EntityList/components/sanctionsOverview/components/introductionPage/index.vue
浏览文件 @
cf7baa70
...
@@ -29,55 +29,20 @@
...
@@ -29,55 +29,20 @@
</AnalysisBox>
</AnalysisBox>
</div>
</div>
<div
class=
"left-bottom"
>
<div
class=
"left-bottom"
>
<!--
<div
class=
"title"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
实体清单更新历史
</div>
<div
class=
"filters"
>
<el-select
v-model=
"selectedDomain"
placeholder=
"Select"
style=
"width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for=
"item in domainOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<el-checkbox
v-model=
"onlyChina"
>
只看涉华动态
</el-checkbox>
</div>
<div
class=
"btn"
>
<img
src=
"../../../../assets/下载按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/收藏按钮.png"
alt=
""
/>
</div>
</div>
<div
class=
"left-bottom-main"
>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"time"
>
<div
class=
"year"
>
{{
item
.
year
}}
</div>
<div
class=
"date"
>
{{
item
.
date
}}
</div>
</div>
<img
:src=
"item.icon || title"
alt=
""
/>
<div
class=
"main"
>
<div
class=
"main-title"
@
click=
"handleClick(item)"
>
{{
item
.
name
}}
</div>
<el-tooltip
effect=
"dark"
:content=
"item.summary"
popper-class=
"common-prompt-popper"
placement=
"top"
:show-after=
"500"
>
<div
class=
"main-desc"
>
{{
item
.
summary
}}
</div>
</el-tooltip>
<div
class=
"tag-box"
>
<div
v-for=
"tag in item.techDomainList"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
</div>
<div
:class=
"
{ 'count-tag': item.cnEntityCount }">
{{
item
.
cnEntityCount
?
`${item.cnEntityCount
}
家中国实体`
:
""
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"left-footer"
>
<
div
class
=
"total-count"
>
共
{{
totalAll
}}
项
<
/div
>
<
el
-
pagination
v
-
model
:
current
-
page
=
"currentPageAll"
:
page
-
size
=
"pageSizeAll"
:
total
=
"totalAll"
layout
=
"prev, pager, next"
background
@
current
-
change
=
"handlePageChangeAll"
/>
<
/div> --
>
<AnalysisBox
title=
"实体清单更新历史"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"实体清单更新历史"
:showAllBtn=
"false"
>
<template
#
header-btn
>
<template
#
header-btn
>
<div
class=
"filters"
>
<div
class=
"filters"
>
<
el
-
select
v
-
model
=
"selectedDomain"
placeholder
=
"Select"
<el-select
style
=
"width: 150px; height: 32px; margin-right: 16px"
>
v-model=
"selectedDomain"
<
el
-
option
v
-
for
=
"item in domainOptions"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
placeholder=
"Select"
style=
"width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for=
"item in domainOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</el-select>
<el-checkbox
v-model=
"onlyChina"
>
只看涉华动态
</el-checkbox>
<el-checkbox
v-model=
"onlyChina"
>
只看涉华动态
</el-checkbox>
</div>
</div>
...
@@ -91,8 +56,13 @@
...
@@ -91,8 +56,13 @@
<img
:src=
"item.icon || title"
alt=
""
/>
<img
:src=
"item.icon || title"
alt=
""
/>
<div
class=
"main"
>
<div
class=
"main"
>
<div
class=
"main-title"
@
click=
"handleClick(item)"
>
{{ item.name }}
</div>
<div
class=
"main-title"
@
click=
"handleClick(item)"
>
{{ item.name }}
</div>
<
el
-
tooltip
effect
=
"dark"
:
content
=
"item.summary"
popper
-
class
=
"common-prompt-popper"
placement
=
"top"
<el-tooltip
:
show
-
after
=
"500"
>
effect=
"dark"
:content=
"item.summary"
popper-class=
"common-prompt-popper"
placement=
"top"
:show-after=
"500"
>
<div
class=
"main-desc"
>
{{ item.summary }}
</div>
<div
class=
"main-desc"
>
{{ item.summary }}
</div>
</el-tooltip>
</el-tooltip>
<div
class=
"tag-box"
>
<div
class=
"tag-box"
>
...
@@ -107,14 +77,20 @@
...
@@ -107,14 +77,20 @@
</div>
</div>
<div
class=
"left-footer"
>
<div
class=
"left-footer"
>
<div
class=
"total-count"
>
共 {{ totalAll }} 项
</div>
<div
class=
"total-count"
>
共 {{ totalAll }} 项
</div>
<
el
-
pagination
v
-
model
:
current
-
page
=
"currentPageAll"
:
page
-
size
=
"pageSizeAll"
:
total
=
"totalAll"
<el-pagination
layout
=
"prev, pager, next"
background
@
current
-
change
=
"handlePageChangeAll"
/>
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<
AnalysisBox
title
=
"发布机构"
:
showAllBtn
=
"false"
>
<AnalysisBox
title=
"发布机构"
:showAllBtn=
"false"
:height=
"auto"
>
<div
class=
"right-main"
>
<div
class=
"right-main"
>
<div
class=
"right-main-title"
@
click=
"handleClickOrg(publishInfo)"
>
<div
class=
"right-main-title"
@
click=
"handleClickOrg(publishInfo)"
>
<img
:src=
"publishInfo.imageUrl"
alt=
""
/>
<img
:src=
"publishInfo.imageUrl"
alt=
""
/>
...
@@ -130,8 +106,12 @@
...
@@ -130,8 +106,12 @@
<span>
关键人物
</span>
<span>
关键人物
</span>
</div>
</div>
<div
class=
"key-person-list"
>
<div
class=
"key-person-list"
>
<
div
class
=
"person-item"
v
-
for
=
"(item, index) in publishInfo.personList"
:
key
=
"index"
<div
@
click
=
"handlePerClick(item)"
>
class=
"person-item"
v-for=
"(item, index) in publishInfo.personList"
:key=
"index"
@
click=
"handlePerClick(item)"
>
<img
:src=
"item.imageUrl"
alt=
""
/>
<img
:src=
"item.imageUrl"
alt=
""
/>
<div
class=
"person-info"
>
<div
class=
"person-info"
>
<CommonPrompt
:content=
"item.name"
>
<CommonPrompt
:content=
"item.name"
>
...
@@ -160,11 +140,19 @@
...
@@ -160,11 +140,19 @@
</div>
</div>
</div>
</div>
</div>
</div>
<
div
class
=
"more-btn"
v
-
if
=
"publishOrgInfo.length < dynamicTotal"
@
click
=
"handleLoadMoreDynamic"
>
<
!-- <
div class="more-btn" v-if="publishOrgInfo.length < dynamicTotal" @click="handleLoadMoreDynamic">
<span>查看更多</span>
<span>查看更多</span>
<el-icon>
<el-icon>
<ArrowDown />
<ArrowDown />
</el-icon>
</el-icon>
</div> -->
<div
class=
"dynamic-footer"
>
<simple-pagination
v-model:current-page=
"dynamicPage"
:page-size=
"dynamicPageSize"
:total=
"dynamicTotal"
@
page-change=
"handleListPageChange"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -176,6 +164,7 @@
...
@@ -176,6 +164,7 @@
<
script
setup
>
<
script
setup
>
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
router
from
"@/router"
;
import
router
from
"@/router"
;
import
SimplePagination
from
"@/components/SimplePagination.vue"
;
import
title
from
"../../../../assets/title.png"
;
import
title
from
"../../../../assets/title.png"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png"
;
import
icon01
from
"../../assets/icon01.png"
;
import
icon01
from
"../../assets/icon01.png"
;
...
@@ -376,7 +365,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => {
...
@@ -376,7 +365,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => {
console
.
error
(
"获取发布机构动态失败:"
,
error
);
console
.
error
(
"获取发布机构动态失败:"
,
error
);
}
}
};
};
const
handleListPageChange
=
val
=>
{
dynamicPage
.
value
=
val
;
getPublishOrgInfoFn
(
false
);
};
const
handleLoadMoreDynamic
=
()
=>
{
const
handleLoadMoreDynamic
=
()
=>
{
dynamicPage
.
value
++
;
dynamicPage
.
value
++
;
getPublishOrgInfoFn
(
true
);
getPublishOrgInfoFn
(
true
);
...
@@ -401,17 +393,16 @@ const getEntityInfoFn = async id => {
...
@@ -401,17 +393,16 @@ const getEntityInfoFn = async id => {
const
sanTypeId
=
ref
(
""
);
const
sanTypeId
=
ref
(
""
);
// 跳转到数据资源库
// 跳转到数据资源库
const
handleToDataLibrary
=
(
item
)
=>
{
const
handleToDataLibrary
=
item
=>
{
console
.
log
(
'item'
,
item
);
console
.
log
(
"item"
,
item
);
let
domainStr
=
domainOptions
.
filter
(
item
=>
item
.
value
===
selectedDomain
.
value
)[
0
].
label
let
domainStr
=
domainOptions
.
filter
(
item
=>
item
.
value
===
selectedDomain
.
value
)[
0
].
label
;
let
params
let
params
;
if
(
domainStr
===
'全部领域'
)
{
if
(
domainStr
===
"全部领域"
)
{
params
=
{
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
item
.
postDate
,
item
.
postDate
])
selectedDate
:
JSON
.
stringify
([
item
.
postDate
,
item
.
postDate
])
}
}
;
}
else
{
}
else
{
params
=
{
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
,
...
@@ -424,8 +415,7 @@ const handleToDataLibrary = (item) => {
...
@@ -424,8 +415,7 @@ const handleToDataLibrary = (item) => {
query
:
params
query
:
params
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
};
onMounted
(()
=>
{
onMounted
(()
=>
{
sanTypeId
.
value
=
route
.
query
.
sanTypeId
;
sanTypeId
.
value
=
route
.
query
.
sanTypeId
;
...
@@ -616,7 +606,7 @@ onMounted(() => {
...
@@ -616,7 +606,7 @@ onMounted(() => {
border-radius
:
20px
;
border-radius
:
20px
;
background-color
:
rgba
(
206
,
79
,
81
,
0
.1
);
background-color
:
rgba
(
206
,
79
,
81
,
0
.1
);
cursor
:
pointer
;
cursor
:
pointer
;
&
:
hover
{
&
:hover
{
text-decoration
:
underline
;
text-decoration
:
underline
;
}
}
}
}
...
@@ -646,11 +636,13 @@ onMounted(() => {
...
@@ -646,11 +636,13 @@ onMounted(() => {
.right
{
.right
{
width
:
520px
;
width
:
520px
;
height
:
1020
px
;
height
:
auto
;
// min-height: 900px;
max-height
:
1280px
;
.right-main
{
.right-main
{
padding
:
7px
24px
20px
23px
;
padding
:
7px
24px
20px
23px
;
height
:
100%
;
.right-main-title
{
.right-main-title
{
cursor
:
pointer
;
cursor
:
pointer
;
width
:
473px
;
width
:
473px
;
...
@@ -767,7 +759,12 @@ onMounted(() => {
...
@@ -767,7 +759,12 @@ onMounted(() => {
.right-main-dynamic
{
.right-main-dynamic
{
width
:
100%
;
width
:
100%
;
height
:
900px
;
display
:
flex
;
flex-direction
:
column
;
// justify-content: space-between;
// height: auto;
position
:
relative
;
.dynamic-title
{
.dynamic-title
{
display
:
flex
;
display
:
flex
;
align-items
:
center
;
align-items
:
center
;
...
@@ -788,8 +785,9 @@ onMounted(() => {
...
@@ -788,8 +785,9 @@ onMounted(() => {
}
}
.dynamic-list
{
.dynamic-list
{
max
-
height
:
500
px
;
// max-height: 500px;
overflow
-
y
:
auto
;
height
:
auto
;
// overflow-y: auto;
padding-right
:
10px
;
padding-right
:
10px
;
/* 滚动条样式 */
/* 滚动条样式 */
...
@@ -880,6 +878,11 @@ onMounted(() => {
...
@@ -880,6 +878,11 @@ onMounted(() => {
margin-right
:
4px
;
margin-right
:
4px
;
}
}
}
}
.dynamic-footer
{
position
:
absolute
;
bottom
:
50px
;
left
:
180px
;
}
}
}
}
}
}
}
...
...
src/views/exportControl/v2.0EntityList/components/sanctionsOverview/components/listPage/index.vue
浏览文件 @
cf7baa70
...
@@ -5,9 +5,10 @@
...
@@ -5,9 +5,10 @@
<el-input
v-model=
"searchKeyword"
class=
"search-input"
placeholder=
"搜索实体"
:suffix-icon=
"Search"
/>
<el-input
v-model=
"searchKeyword"
class=
"search-input"
placeholder=
"搜索实体"
:suffix-icon=
"Search"
/>
<div
class=
"filters"
>
<div
class=
"filters"
>
<el-checkbox
v-model=
"onlyChina"
label=
"只看中国实体"
/>
<el-checkbox
v-model=
"onlyChina"
label=
"只看中国实体"
/>
<el-select
v-model=
"order"
placeholder=
"请选择排序方式"
style=
"width: 160px"
>
<
!--
<
el-select
v-model=
"order"
placeholder=
"请选择排序方式"
style=
"width: 160px"
>
<el-option
v-for=
"item in orderOptions"
:value=
"item.value"
:key=
"item.value"
:label=
"item.name"
/>
<el-option
v-for=
"item in orderOptions"
:value=
"item.value"
:key=
"item.value"
:label=
"item.name"
/>
</el-select>
</el-select>
-->
<TimeSortSelectBox
@
handle-px-change=
"handleTimePx"
/>
</div>
</div>
</div>
</div>
<div
class=
"main"
>
<div
class=
"main"
>
...
@@ -17,95 +18,51 @@
...
@@ -17,95 +18,51 @@
<div
class=
"text"
>
科技领域
</div>
<div
class=
"text"
>
科技领域
</div>
</div>
</div>
<div
class=
"checkbox-group"
>
<div
class=
"checkbox-group"
>
<el-checkbox
v-for=
"(item, index) in techFields"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
<el-checkbox
@
change=
"handleFilterChange(item, techFields, 'tech')"
/>
v-for=
"(item, index) in techFields"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
@
change=
"handleFilterChange(item, techFields, 'tech')"
/>
</div>
</div>
<div
class=
"title"
>
<div
class=
"title"
>
<div
class=
"box"
></div>
<div
class=
"box"
></div>
<div
class=
"text"
>
实体类型
</div>
<div
class=
"text"
>
实体类型
</div>
</div>
</div>
<div
class=
"checkbox-group"
>
<div
class=
"checkbox-group"
>
<el-checkbox
v-for=
"(item, index) in entityTypes"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
<el-checkbox
@
change=
"handleFilterChange(item, entityTypes, 'type')"
/>
v-for=
"(item, index) in entityTypes"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
@
change=
"handleFilterChange(item, entityTypes, 'type')"
/>
</div>
</div>
<div
class=
"title"
>
<div
class=
"title"
>
<div
class=
"box"
></div>
<div
class=
"box"
></div>
<div
class=
"text"
>
制裁时间
</div>
<div
class=
"text"
>
制裁时间
</div>
</div>
</div>
<div
class=
"checkbox-group"
>
<div
class=
"checkbox-group"
>
<el-checkbox
v-for=
"(item, index) in sanctionTimes"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
<el-checkbox
@
change=
"handleFilterChange(item, sanctionTimes, 'time')"
/>
v-for=
"(item, index) in sanctionTimes"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
@
change=
"handleFilterChange(item, sanctionTimes, 'time')"
/>
<div
v-if=
"sanctionTimes.find(i => i.value === 'custom' && i.checked)"
class=
"custom-date-picker"
>
<div
v-if=
"sanctionTimes.find(i => i.value === 'custom' && i.checked)"
class=
"custom-date-picker"
>
<el-date-picker
v-model=
"customDateRange"
type=
"daterange"
range-separator=
"-"
start-placeholder=
"开始日期"
<el-date-picker
end-placeholder=
"结束日期"
/>
v-model=
"customDateRange"
type=
"daterange"
range-separator=
"-"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<!--
<div
class=
"title"
>
<div
class=
"left-wrapper"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
实体清单
</div>
</div>
<div
class=
"right-wrapper"
>
<div
class=
"stats"
>
<div
class=
"dot"
></div>
<div
class=
"count-text"
>
共
<span
class=
"highlight"
>
{{
ruleCount
.
totalCount
}}
</span>
家
</div>
<div
class=
"rule-text"
>
(50%规则涉及
<span
class=
"highlight"
>
{{
ruleCount
.
ruleCount
}}
</span>
家)
</div>
</div>
<div
class=
"btn"
>
<img
src=
"../../../../assets/下载按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/收藏按钮.png"
alt=
""
/>
</div>
</div>
</div>
-->
<!--
<div
class=
"right-table"
>
<el-table
:data=
"entityRows"
table-layout=
"fixed"
:row-class-name=
"tableRowClassName"
:header-cell-style=
"
{ background: '#fff' }">
<el-table-column
label=
"实体名称"
min-width=
"200"
>
<template
#
default=
"
{ row }">
<div
class=
"entity-name-cell"
@
click=
"handleCompClick(row)"
>
<el-image
v-if=
"row.img"
class=
"avatar"
:src=
"row.img"
alt=
""
></el-image>
<div
v-else
class=
"avatar-undefined"
>
{{
(
row
.
entityNameZh
||
row
.
entityName
)?.
match
(
/
[\u
4e00-
\u
9fa5a-zA-Z0-9
]
/
)?.[
0
]
}}
</div>
<CommonPrompt
:content=
"row.entityNameZh || row.entityName"
style=
"flex: 1; overflow: hidden"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"涉及领域"
min-width=
"150"
>
<
template
#
default=
"{ row }"
>
<div
class=
"domain-cell"
>
<el-tag
v-for=
"tag in row.techDomains"
:key=
"tag"
class=
"domain-tag"
effect=
"plain"
:disable-transitions=
"true"
:style=
"getTagStyle(tag)"
>
{{
tag
}}
</el-tag>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"startTime"
label=
"制裁时间"
width=
"140"
show-overflow-tooltip
align=
"center"
/>
<el-table-column
label=
"50%规则子企业"
min-width=
"280"
show-overflow-tooltip
align=
"right"
>
<
template
#
default=
"{ row }"
>
<div
class=
"rule-cell"
v-if=
"row.ruleOrgCount > 0"
>
<div
class=
"rule-text"
:title=
"row.ruleOrgList?.[0]?.orgName || ''"
>
{{
row
.
ruleOrgList
?.[
0
]?.
orgName
||
''
}}
...等
</div>
<el-link
class=
"rule-link"
type=
"primary"
:underline=
"false"
@
click=
"handleRuleClick(row)"
>
{{
row
.
ruleOrgCount
}}
家 >
</el-link>
</div>
</
template
>
</el-table-column>
</el-table>
</div>
<div
class=
"tight-footer"
>
<div
class=
"total-text"
>
共 {{ total }} 项
</div>
<el-pagination
:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:total=
"total"
layout=
"prev, pager, next"
prev-text=
"<"
next-text=
">"
@
current-change=
"handleCurrentChange"
/>
</div>
-->
<AnalysisBox
title=
"实体清单"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"实体清单"
:showAllBtn=
"false"
>
<template
#
header-btn
>
<template
#
header-btn
>
<div
class=
"stats"
>
<div
class=
"stats"
>
...
@@ -114,13 +71,24 @@
...
@@ -114,13 +71,24 @@
共
<span
class=
"highlight"
@
click=
"handlToDataLibrary"
>
{{
ruleCount
.
totalCount
}}
</span>
家
共
<span
class=
"highlight"
@
click=
"handlToDataLibrary"
>
{{
ruleCount
.
totalCount
}}
</span>
家
</div>
</div>
<div
class=
"rule-text"
>
<div
class=
"rule-text"
>
(50%规则涉及
<span
class=
"highlight"
@
click=
"handlToDataLibrary1"
>
{{
ruleCount
.
ruleCount
}}
</span>
家)
(50%规则涉及
<span
class=
"highlight"
@
click=
"handlToDataLibrary1"
>
{{
ruleCount
.
ruleCount
}}
</span
>
家)
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<div
class=
"right-table"
>
<div
class=
"right-table"
>
<el-table
:data=
"entityRows"
table-layout=
"fixed"
:row-class-name=
"tableRowClassName"
<el-table
:header-cell-style=
"{ background: '#fff' }"
>
:data=
"entityRows"
table-layout=
"fixed"
:row-class-name=
"tableRowClassName"
:header-cell-style=
"{ background: '#fff' }"
v-loading=
"tableLoading"
>
<
template
#
empty
>
<el-empty
description=
"暂无数据"
/>
</
template
>
<el-table-column
label=
"实体名称"
min-width=
"200"
>
<el-table-column
label=
"实体名称"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<div
class=
"entity-name-cell"
@
click=
"handleCompClick(row)"
>
<div
class=
"entity-name-cell"
@
click=
"handleCompClick(row)"
>
...
@@ -128,30 +96,61 @@
...
@@ -128,30 +96,61 @@
<div
v-else
class=
"avatar-undefined"
>
<div
v-else
class=
"avatar-undefined"
>
{{
(
row
.
entityNameZh
||
row
.
entityName
)?.
match
(
/
[\u
4e00-
\u
9fa5a-zA-Z0-9
]
/
)?.[
0
]
}}
{{
(
row
.
entityNameZh
||
row
.
entityName
)?.
match
(
/
[\u
4e00-
\u
9fa5a-zA-Z0-9
]
/
)?.[
0
]
}}
</div>
</div>
<CommonPrompt
:content=
"row.entityNameZh || row.entityName"
style=
"flex: 1; overflow: hidden"
/>
<CommonPrompt
:content=
"row.entityNameZh || row.entityName"
style=
"flex: 1; overflow: hidden"
/>
</div>
</div>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"涉及领域"
min-width=
"
15
0"
>
<el-table-column
label=
"涉及领域"
min-width=
"
20
0"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<div
class=
"domain-cell"
>
<div
class=
"domain-cell"
>
<el-tag
v-for=
"tag in row.techDomains"
:key=
"tag"
class=
"domain-tag"
effect=
"plain"
<!--
<el-tag
:disable-transitions=
"true"
:style=
"getTagStyle(tag)"
>
v-for=
"tag in row.techDomains"
:key=
"tag"
class=
"domain-tag"
effect=
"plain"
:disable-transitions=
"true"
:style=
"getTagStyle(tag)"
>
{{
tag
}}
{{
tag
}}
</el-tag>
</el-tag>
-->
<AreaTag
v-for=
"(tag, index) in getDisplayTags(row.techDomains)"
:key=
"index"
:tagName=
"tag"
/>
</div>
</div>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
prop=
"listingLocation"
label=
"上市地点"
width=
"140"
show-overflow-tooltip
align=
"center"
/>
<el-table-column
<el-table-column
prop=
"startTime"
label=
"制裁时间"
width=
"140"
show-overflow-tooltip
align=
"center"
/>
prop=
"listingLocation"
label=
"上市地点"
width=
"140"
show-overflow-tooltip
align=
"center"
/>
<el-table-column
prop=
"startTime"
label=
"制裁时间"
width=
"140"
show-overflow-tooltip
align=
"center"
/>
<el-table-column
label=
"50%规则子企业"
min-width=
"280"
show-overflow-tooltip
align=
"right"
>
<el-table-column
label=
"50%规则子企业"
min-width=
"280"
show-overflow-tooltip
align=
"right"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<div
class=
"rule-cell"
v-if=
"row.ruleOrgCount > 0"
>
<div
class=
"rule-cell"
v-if=
"row.ruleOrgCount > 0"
>
<div
class=
"rule-text"
:title=
"row.ruleOrgList?.[0]?.orgName || ''"
>
<div
class=
"rule-text"
:title=
"row.ruleOrgList?.[0]?.orgName || ''"
>
{{
row
.
ruleOrgList
?.[
0
]?.
orgName
||
""
}}
...等
{{
row
.
ruleOrgList
?.[
0
]?.
orgName
||
""
}}
...等
</div>
</div>
<el-link
class=
"rule-link"
type=
"primary"
:underline=
"false"
@
click=
"handleRuleClick(row)"
>
{{
<el-link
row
.
ruleOrgCount
}}
家 >
</el-link>
class=
"rule-link"
type=
"primary"
:underline=
"false"
@
click=
"handleRuleClick(row)"
>
{{
row
.
ruleOrgCount
}}
家 >
</el-link
>
</div>
</div>
</
template
>
</
template
>
</el-table-column>
</el-table-column>
...
@@ -159,15 +158,26 @@
...
@@ -159,15 +158,26 @@
</div>
</div>
<div
class=
"tight-footer"
>
<div
class=
"tight-footer"
>
<div
class=
"total-text"
>
共 {{ total }} 项
</div>
<div
class=
"total-text"
>
共 {{ total }} 项
</div>
<el-pagination
:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:total=
"total"
<el-pagination
layout=
"prev, pager, next"
prev-text=
"<"
next-text=
">"
@
current-change=
"handleCurrentChange"
/>
:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:total=
"total"
layout=
"prev, pager, next"
prev-text=
"<"
next-text=
">"
@
current-change=
"handleCurrentChange"
/>
</div>
</div>
</AnalysisBox>
</AnalysisBox>
</div>
</div>
</div>
</div>
</div>
</div>
<RuleSubsidiaryDialog
v-model=
"ruleDialogVisible"
:company-name=
"currentRuleCompany"
:total-count=
"currentRuleCount"
<RuleSubsidiaryDialog
:data-list=
"currentRuleList"
/>
v-model=
"ruleDialogVisible"
:company-name=
"currentRuleCompany"
:total-count=
"currentRuleCount"
:data-list=
"currentRuleList"
/>
</div>
</div>
</template>
</template>
...
@@ -177,16 +187,18 @@ import { useRouter } from "vue-router";
...
@@ -177,16 +187,18 @@ import { useRouter } from "vue-router";
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png"
;
import
RuleSubsidiaryDialog
from
"./RuleSubsidiaryDialog.vue"
;
import
RuleSubsidiaryDialog
from
"./RuleSubsidiaryDialog.vue"
;
import
AreaTag
from
"@/components/base/AreaTag/index.vue"
;
import
{
getExportControlList
,
get50PercentEntityCount
}
from
"@/api/exportControlV2.0.js"
;
import
{
getExportControlList
,
get50PercentEntityCount
}
from
"@/api/exportControlV2.0.js"
;
import
CommonPrompt
from
"@/views/exportControl/commonPrompt/index.vue"
;
import
CommonPrompt
from
"@/views/exportControl/commonPrompt/index.vue"
;
import
{
useGotoCompanyPages
}
from
"@/router/modules/company"
;
import
{
useGotoCompanyPages
}
from
"@/router/modules/company"
;
import
TimeSortSelectBox
from
"@/components/base/TimeSortSelectBox/index.vue"
;
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
order
=
ref
(
"asc"
);
const
order
=
ref
(
"asc"
);
const
orderOptions
=
ref
([
const
orderOptions
=
ref
([
{
name
:
"
正序"
,
value
:
"a
sc"
},
{
name
:
"
倒序"
,
value
:
"de
sc"
},
{
name
:
"
倒序"
,
value
:
"de
sc"
}
{
name
:
"
正序"
,
value
:
"a
sc"
}
]);
]);
// 跳转公司详情页
// 跳转公司详情页
const
handleCompClick
=
item
=>
{
const
handleCompClick
=
item
=>
{
...
@@ -210,6 +222,7 @@ const currentPage = ref(1);
...
@@ -210,6 +222,7 @@ const currentPage = ref(1);
const
pageSize
=
ref
(
10
);
const
pageSize
=
ref
(
10
);
const
total
=
ref
(
0
);
const
total
=
ref
(
0
);
const
tableLoading
=
ref
(
false
);
const
entityRows
=
computed
(()
=>
mainList
.
value
);
const
entityRows
=
computed
(()
=>
mainList
.
value
);
const
handleCurrentChange
=
val
=>
{
const
handleCurrentChange
=
val
=>
{
...
@@ -218,6 +231,43 @@ const handleCurrentChange = val => {
...
@@ -218,6 +231,43 @@ const handleCurrentChange = val => {
getExportControlListApi
();
getExportControlListApi
();
};
};
// 辅助函数:计算需要显示的标签
const
getDisplayTags
=
domains
=>
{
if
(
!
domains
||
domains
.
length
===
0
)
return
[];
// 1. 获取当前用户选中的领域名称 (排除"全部")
const
selectedValues
=
techFields
.
value
.
filter
(
item
=>
item
.
checked
&&
item
.
value
!==
"all"
).
map
(
item
=>
item
.
label
);
// 注意:techFields中存储的是 label 作为显示名称
// 如果没选中任何特定领域(即选中了“全部”或都没选),直接返回前3个
if
(
selectedValues
.
length
===
0
)
{
return
domains
.
slice
(
0
,
3
);
}
// 2. 分离 domains 中 "已选中" 和 "未选中" 的部分
const
matched
=
[];
const
others
=
[];
domains
.
forEach
(
tag
=>
{
if
(
selectedValues
.
includes
(
tag
))
{
matched
.
push
(
tag
);
}
else
{
others
.
push
(
tag
);
}
});
// 3. 组合结果:优先显示匹配的,不足的用其他的补齐,总数限制为3
const
result
=
[...
matched
];
// 如果匹配的不足3个,从 others 中取剩余的配额
if
(
result
.
length
<
3
)
{
const
remainingCount
=
3
-
result
.
length
;
result
.
push
(...
others
.
slice
(
0
,
remainingCount
));
}
// 如果匹配的超过3个,只取前3个(虽然通常匹配不会这么多,但做个保护)
return
result
.
slice
(
0
,
3
);
};
const
getTagStyle
=
tag
=>
{
const
getTagStyle
=
tag
=>
{
// 预设颜色池
// 预设颜色池
const
colorPool
=
[
const
colorPool
=
[
...
@@ -273,11 +323,12 @@ const entityTypes = ref([
...
@@ -273,11 +323,12 @@ const entityTypes = ref([
const
sanctionTimes
=
ref
([
const
sanctionTimes
=
ref
([
{
label
:
"全部时间"
,
value
:
"all"
,
checked
:
true
},
{
label
:
"全部时间"
,
value
:
"all"
,
checked
:
true
},
{
label
:
"2026年"
,
value
:
"2026"
,
checked
:
false
},
{
label
:
"2025年"
,
value
:
"2025"
,
checked
:
false
},
{
label
:
"2025年"
,
value
:
"2025"
,
checked
:
false
},
{
label
:
"2024年"
,
value
:
"2024"
,
checked
:
false
},
{
label
:
"2024年"
,
value
:
"2024"
,
checked
:
false
},
{
label
:
"2023年"
,
value
:
"2023"
,
checked
:
false
},
{
label
:
"2023年"
,
value
:
"2023"
,
checked
:
false
},
{
label
:
"2022年"
,
value
:
"2022"
,
checked
:
false
},
{
label
:
"2022年"
,
value
:
"2022"
,
checked
:
false
},
{
label
:
"2021年"
,
value
:
"2021"
,
checked
:
false
},
//
{ label: "2021年", value: "2021", checked: false },
{
label
:
"自定义"
,
value
:
"custom"
,
checked
:
false
}
{
label
:
"自定义"
,
value
:
"custom"
,
checked
:
false
}
]);
]);
...
@@ -348,11 +399,12 @@ const ruleCount = ref(0);
...
@@ -348,11 +399,12 @@ const ruleCount = ref(0);
let
abortController
=
null
;
let
abortController
=
null
;
const
getExportControlListApi
=
async
()
=>
{
const
getExportControlListApi
=
async
()
=>
{
tableLoading
.
value
=
true
;
// 取消上一轮未完成的请求
// 取消上一轮未完成的请求
if
(
abortController
)
{
if
(
abortController
)
{
try
{
try
{
abortController
.
abort
();
abortController
.
abort
();
}
catch
{
}
}
catch
{}
}
}
abortController
=
new
AbortController
();
abortController
=
new
AbortController
();
isFetching
.
value
=
true
;
isFetching
.
value
=
true
;
...
@@ -413,8 +465,10 @@ const getExportControlListApi = async () => {
...
@@ -413,8 +465,10 @@ const getExportControlListApi = async () => {
try
{
try
{
const
res
=
await
getExportControlList
(
data
,
{
signal
:
abortController
.
signal
});
const
res
=
await
getExportControlList
(
data
,
{
signal
:
abortController
.
signal
});
tableLoading
.
value
=
false
;
// 50%规则涉及实体数
// 50%规则涉及实体数
const
countRes
=
await
get50PercentEntityCount
(
data
);
const
countRes
=
await
get50PercentEntityCount
(
data
);
if
(
countRes
.
code
===
200
)
{
if
(
countRes
.
code
===
200
)
{
ruleCount
.
value
=
countRes
.
data
;
ruleCount
.
value
=
countRes
.
data
;
}
}
...
@@ -426,9 +480,11 @@ const getExportControlListApi = async () => {
...
@@ -426,9 +480,11 @@ const getExportControlListApi = async () => {
if
(
!
error
||
(
error
.
code
!==
"ERR_CANCELED"
&&
error
.
name
!==
"CanceledError"
&&
error
.
name
!==
"AbortError"
))
{
if
(
!
error
||
(
error
.
code
!==
"ERR_CANCELED"
&&
error
.
name
!==
"CanceledError"
&&
error
.
name
!==
"AbortError"
))
{
console
.
error
(
error
);
console
.
error
(
error
);
}
}
tableLoading
.
value
=
false
;
}
finally
{
}
finally
{
isFetching
.
value
=
false
;
isFetching
.
value
=
false
;
abortController
=
null
;
abortController
=
null
;
tableLoading
.
value
=
false
;
}
}
};
};
...
@@ -436,8 +492,13 @@ const getExportControlListApi = async () => {
...
@@ -436,8 +492,13 @@ const getExportControlListApi = async () => {
// currentPage.value = 1;
// currentPage.value = 1;
// getExportControlListApi();
// getExportControlListApi();
// });
// });
const
handleTimePx
=
data
=>
{
watch
([
onlyChina
,
order
],
()
=>
{
console
.
log
(
"选择排序"
,
data
);
currentPage
.
value
=
1
;
order
.
value
=
orderOptions
.
value
[
data
-
1
].
value
;
getExportControlListApi
();
};
watch
([
onlyChina
],
()
=>
{
currentPage
.
value
=
1
;
currentPage
.
value
=
1
;
getExportControlListApi
();
getExportControlListApi
();
});
});
...
@@ -468,26 +529,25 @@ watch(customDateRange, () => {
...
@@ -468,26 +529,25 @@ watch(customDateRange, () => {
// 跳转到数据资源库
// 跳转到数据资源库
const
handlToDataLibrary
=
()
=>
{
const
handlToDataLibrary
=
()
=>
{
const
params
=
{
const
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
};
};
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
query
:
params
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
}
;
const
handlToDataLibrary1
=
()
=>
{
const
handlToDataLibrary1
=
()
=>
{
const
params
=
{
const
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
,
isHalfRule
:
true
,
isHalfRule
:
true
};
};
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
query
:
params
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
};
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
scoped
lang=
"scss"
>
...
@@ -692,7 +752,6 @@ const handlToDataLibrary1 = () => {
...
@@ -692,7 +752,6 @@ const handlToDataLibrary1 = () => {
.highlight
{
.highlight
{
color
:
#cd4246
;
color
:
#cd4246
;
margin
:
0
4px
;
margin
:
0
4px
;
}
}
}
}
...
...
src/views/exportControl/v2.0SingleSanction/components/dataStatistics/index.vue
浏览文件 @
cf7baa70
...
@@ -1080,11 +1080,6 @@ onMounted(() => {
...
@@ -1080,11 +1080,6 @@ onMounted(() => {
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
scoped
lang=
"scss"
>
*
{
margin
:
0
;
padding
:
0
;
}
.data-statistics
{
.data-statistics
{
width
:
1601px
;
width
:
1601px
;
margin
:
0
auto
;
margin
:
0
auto
;
...
@@ -1156,6 +1151,11 @@ onMounted(() => {
...
@@ -1156,6 +1151,11 @@ onMounted(() => {
.number
{
.number
{
display
:
flex
;
display
:
flex
;
align-items
:
baseline
;
align-items
:
baseline
;
&
:hover
{
text-decoration
:
underline
;
text-decoration-color
:
#cd4246
;
background
:
var
(
--
color-primary-2
);
}
.num
{
.num
{
font-size
:
32px
;
font-size
:
32px
;
...
...
src/views/exportControl/v2.0SingleSanction/components/deepMining/index.vue
浏览文件 @
cf7baa70
...
@@ -34,7 +34,12 @@
...
@@ -34,7 +34,12 @@
<el-option
label=
"太空"
value=
"13"
/>
<el-option
label=
"太空"
value=
"13"
/>
<el-option
label=
"核"
value=
"14"
/>
<el-option
label=
"核"
value=
"14"
/>
</el-select>
</el-select>
<el-input
v-model=
"searchText"
placeholder=
"搜索实体"
class=
"search-input"
>
<el-input
v-model=
"searchText"
placeholder=
"搜索实体"
class=
"search-input"
@
keyup
.
enter=
"getSingleSanctionEntityListRequest"
>
<template
#
suffix
>
<template
#
suffix
>
<el-icon
class=
"el-input__icon"
>
<el-icon
class=
"el-input__icon"
>
<Search
/>
<Search
/>
...
...
src/views/exportControl/v2.0SingleSanction/components/impactAnalysis/components/industrialImpact/index.vue
浏览文件 @
cf7baa70
...
@@ -2,51 +2,6 @@
...
@@ -2,51 +2,6 @@
<div
class=
"industrial-impact"
>
<div
class=
"industrial-impact"
>
<div
class=
"main"
>
<div
class=
"main"
>
<div
class=
"left"
>
<div
class=
"left"
>
<!--
<div
class=
"title-com"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
制裁企业列表
</div>
<div
class=
"right-group"
>
<div
class=
"btn"
>
<img
src=
"../../../../assets/数据库按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/下载按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/收藏按钮.png"
alt=
""
/>
</div>
</div>
</div>
<div
class=
"left-main"
>
<div
class=
"top-bar"
>
<el-select
v-model=
"searchDomain"
placeholder=
"全部领域"
class=
"domain-select"
>
<el-option
label=
"全部领域"
value=
""
/>
<el-option
label=
"人工智能"
value=
"1"
/>
<el-option
label=
"生物科技"
value=
"2"
/>
<el-option
label=
"新一代信息技术"
value=
"3"
/>
<el-option
label=
"量子科技"
value=
"4"
/>
<el-option
label=
"新能源"
value=
"5"
/>
<el-option
label=
"集成电路"
value=
"6"
/>
<el-option
label=
"海洋"
value=
"7"
/>
<el-option
label=
"先进制造"
value=
"8"
/>
<el-option
label=
"新材料"
value=
"9"
/>
<el-option
label=
"航空航天"
value=
"10"
/>
<el-option
label=
"深海"
value=
"11"
/>
<el-option
label=
"极地"
value=
"12"
/>
<el-option
label=
"太空"
value=
"13"
/>
<el-option
label=
"核"
value=
"14"
/>
</el-select>
<el-input
v-model=
"searchKeyword"
class=
"search-input"
placeholder=
"搜索实体"
:suffix-icon=
"Search"
/>
</div>
<div
class=
"company-list-container"
>
<div
class=
"list-header"
>
企业名称
</div>
<div
class=
"company-list"
>
<div
class=
"company-item"
:class=
"
{ active: selectedCompanyId === item.id }" v-for="item in entityList"
:key="item.id" @click="selectedCompanyId = item.id">
<div
class=
"icon-wrapper"
>
<img
:src=
"defaultTitle"
alt=
""
/>
</div>
<div
class=
"company-name"
>
{{
item
.
name
}}
</div>
</div>
</div>
</div>
</div>
-->
<AnalysisBox
title=
"制裁企业列表"
>
<AnalysisBox
title=
"制裁企业列表"
>
<div
class=
"left-main"
>
<div
class=
"left-main"
>
<div
class=
"top-bar"
>
<div
class=
"top-bar"
>
...
@@ -91,31 +46,6 @@
...
@@ -91,31 +46,6 @@
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<div
class=
"right-item"
>
<div
class=
"right-item"
>
<!--
<div
class=
"title-com"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
企业规模
</div>
<div
class=
"right-group"
>
<div
class=
"toggle-btns"
>
<div
class=
"t-btn"
:class=
"
{ active: activeScale === item }" v-for="item in scaleOptions" :key="item"
@click="handleScaleClick(item)">
{{
item
}}
</div>
</div>
<div
class=
"btn"
>
<img
src=
"../../../../assets/数据库按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/下载按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/收藏按钮.png"
alt=
""
/>
</div>
</div>
</div>
<div
class=
"right-main"
>
<div
class=
"echarts"
ref=
"chartRef"
></div>
<div
class=
"bottom"
>
<img
:src=
"ai"
class=
"ai-icon"
alt=
""
/>
<span
class=
"text"
>
列入实体清单后企业营收初期下降,后基本趋于稳定。
</span>
<img
:src=
"right"
class=
"right-icon"
alt=
""
/>
</div>
</div>
-->
<AnalysisBox
title=
"企业规模"
>
<AnalysisBox
title=
"企业规模"
>
<template
#
header-btn
>
<template
#
header-btn
>
<div
class=
"toggle-btns"
>
<div
class=
"toggle-btns"
>
...
@@ -130,7 +60,7 @@
...
@@ -130,7 +60,7 @@
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<div
class=
"right-main"
>
<div
class=
"right-main"
v-loading=
"scaleLoading"
>
<!-- <div class="echarts" ref="chartRef"></div> -->
<!-- <div class="echarts" ref="chartRef"></div> -->
<!-- <div class="bottom">
<!-- <div class="bottom">
<img :src="ai" class="ai-icon" alt="" />
<img :src="ai" class="ai-icon" alt="" />
...
@@ -142,7 +72,7 @@
...
@@ -142,7 +72,7 @@
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
</div>
<div
class=
"data-origin-text"
>
企业规模情况,
数据来源:美国各行政机构官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国各行政机构官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiButton
/>
...
@@ -184,7 +114,7 @@
...
@@ -184,7 +114,7 @@
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
</div>
<div
class=
"data-origin-text"
>
企业市值变化情况,
数据来源:美国各行政机构官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国各行政机构官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiButton
/>
...
@@ -245,7 +175,7 @@
...
@@ -245,7 +175,7 @@
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
</div>
<div
class=
"data-origin-text"
>
企业研发投入情况,
数据来源:美国各行政机构官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国各行政机构官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiButton
/>
...
@@ -306,7 +236,7 @@
...
@@ -306,7 +236,7 @@
<div
class=
"data-origin-icon"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
</div>
<div
class=
"data-origin-text"
>
企业市场占比情况,
数据来源:美国各行政机构官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国各行政机构官网
</div>
</div>
</div>
<div
class=
"ai-pane"
>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiButton
/>
...
@@ -453,11 +383,15 @@ const getMarketValue = async () => {
...
@@ -453,11 +383,15 @@ const getMarketValue = async () => {
const
personnelData
=
ref
([]);
const
personnelData
=
ref
([]);
// 单次制裁-影响分析-企业规模-人员-调查
// 单次制裁-影响分析-企业规模-人员-调查
const
getPersonnel
=
async
()
=>
{
const
getPersonnel
=
async
()
=>
{
if
(
!
selectedCompanyId
.
value
)
return
;
if
(
!
selectedCompanyId
.
value
)
{
scaleLoading
.
value
=
false
;
return
;
}
try
{
try
{
const
res
=
await
getSingleSanctionEntityPersonnel
({
const
res
=
await
getSingleSanctionEntityPersonnel
({
id
:
selectedCompanyId
.
value
id
:
selectedCompanyId
.
value
});
});
scaleLoading
.
value
=
false
;
if
(
res
.
code
===
200
)
{
if
(
res
.
code
===
200
)
{
personnelData
.
value
=
res
.
data
||
[];
personnelData
.
value
=
res
.
data
||
[];
...
@@ -478,6 +412,7 @@ const getPersonnel = async () => {
...
@@ -478,6 +412,7 @@ const getPersonnel = async () => {
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
console
.
log
(
error
);
scaleLoading
.
value
=
false
;
}
}
};
};
...
@@ -485,11 +420,15 @@ const getPersonnel = async () => {
...
@@ -485,11 +420,15 @@ const getPersonnel = async () => {
const
netProfitData
=
ref
([]);
const
netProfitData
=
ref
([]);
// 单次制裁-影响分析-企业规模-净利润-调查
// 单次制裁-影响分析-企业规模-净利润-调查
const
getNetProfitData
=
async
()
=>
{
const
getNetProfitData
=
async
()
=>
{
if
(
!
selectedCompanyId
.
value
)
return
;
if
(
!
selectedCompanyId
.
value
)
{
scaleLoading
.
value
=
false
;
return
;
}
try
{
try
{
const
res
=
await
getSingleSanctionEntityNetProfit
({
const
res
=
await
getSingleSanctionEntityNetProfit
({
id
:
selectedCompanyId
.
value
id
:
selectedCompanyId
.
value
});
});
scaleLoading
.
value
=
false
;
if
(
res
.
code
===
200
)
{
if
(
res
.
code
===
200
)
{
netProfitData
.
value
=
res
.
data
||
[];
netProfitData
.
value
=
res
.
data
||
[];
...
@@ -510,6 +449,7 @@ const getNetProfitData = async () => {
...
@@ -510,6 +449,7 @@ const getNetProfitData = async () => {
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
console
.
log
(
error
);
scaleLoading
.
value
=
false
;
}
}
};
};
...
@@ -524,11 +464,15 @@ const sanRecordId = ref("");
...
@@ -524,11 +464,15 @@ const sanRecordId = ref("");
const
revenueData
=
ref
([]);
const
revenueData
=
ref
([]);
// 单次制裁-影响分析-企业规模-营收-查询
// 单次制裁-影响分析-企业规模-营收-查询
const
getRevenueData
=
async
()
=>
{
const
getRevenueData
=
async
()
=>
{
if
(
!
selectedCompanyId
.
value
)
return
;
if
(
!
selectedCompanyId
.
value
)
{
scaleLoading
.
value
=
false
;
return
;
}
try
{
try
{
const
res
=
await
getSingleSanctionEntityRevenue
({
const
res
=
await
getSingleSanctionEntityRevenue
({
id
:
selectedCompanyId
.
value
id
:
selectedCompanyId
.
value
});
});
scaleLoading
.
value
=
false
;
if
(
res
.
code
===
200
)
{
if
(
res
.
code
===
200
)
{
revenueData
.
value
=
res
.
data
||
[];
revenueData
.
value
=
res
.
data
||
[];
// 将数据格式化为图表所需格式
// 将数据格式化为图表所需格式
...
@@ -547,11 +491,13 @@ const getRevenueData = async () => {
...
@@ -547,11 +491,13 @@ const getRevenueData = async () => {
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
log
(
error
);
console
.
log
(
error
);
scaleLoading
.
value
=
false
;
}
}
};
};
const
scaleLoading
=
ref
(
false
);
const
handleScaleClick
=
item
=>
{
const
handleScaleClick
=
item
=>
{
activeScale
.
value
=
item
;
activeScale
.
value
=
item
;
scaleLoading
.
value
=
true
;
if
(
item
===
"营收"
)
{
if
(
item
===
"营收"
)
{
getRevenueData
();
getRevenueData
();
}
else
if
(
item
===
"净利润"
)
{
}
else
if
(
item
===
"净利润"
)
{
...
...
src/views/finance/assets/icons/icon-pd.png
0 → 100644
浏览文件 @
cf7baa70
472 Bytes
src/views/finance/assets/icons/icon-radar.png
0 → 100644
浏览文件 @
cf7baa70
1.1 KB
src/views/finance/assets/icons/icon-sanction.png
0 → 100644
浏览文件 @
cf7baa70
679 Bytes
src/views/finance/assets/icons/icon-zc.png
0 → 100644
浏览文件 @
cf7baa70
1.0 KB
src/views/finance/components/title.vue
浏览文件 @
cf7baa70
...
@@ -43,7 +43,7 @@ defineProps({
...
@@ -43,7 +43,7 @@ defineProps({
.title-text
{
.title-text
{
color
:
rgba
(
10
,
18
,
30
,
1
);
color
:
rgba
(
10
,
18
,
30
,
1
);
font-size
:
32px
;
font-size
:
32px
;
font-family
:
"
Microsoft YaHei
"
;
font-family
:
"
Source Han Sans CN
"
;
font-weight
:
700
;
font-weight
:
700
;
margin-left
:
20px
;
margin-left
:
20px
;
white-space
:
nowrap
;
white-space
:
nowrap
;
...
...
src/views/finance/entityList/components/deepMining/index.vue
浏览文件 @
cf7baa70
...
@@ -50,8 +50,8 @@
...
@@ -50,8 +50,8 @@
:class=
"
{ active: currentSanctionId === item.id }"
:class=
"
{ active: currentSanctionId === item.id }"
@click="handleSanctionSelect(item.id)"
@click="handleSanctionSelect(item.id)"
>
>
<
!--
<div
class=
"item-left"
>
{{
item
.
date
}}
-
{{
item
.
title
}}
</div>
--
>
<
div
class=
"item-left"
>
{{
item
.
date
}}
-
{{
item
.
title
}}
</div
>
<
div
class=
"item-left"
>
{{
item
.
date
}}
-SDN清单更新
</div
>
<
!--
<div
class=
"item-left"
>
{{
item
.
date
}}
-SDN清单更新
</div>
--
>
<div
class=
"item-right"
>
{{
item
.
count
}}{{
item
.
unit
}}
</div>
<div
class=
"item-right"
>
{{
item
.
count
}}{{
item
.
unit
}}
</div>
</div>
</div>
</div>
</div>
...
@@ -455,6 +455,7 @@ const stopAutoPlay = () => {
...
@@ -455,6 +455,7 @@ const stopAutoPlay = () => {
// ✅ 自动下一个(支持循环)
// ✅ 自动下一个(支持循环)
const
handleNextClickAuto
=
()
=>
{
const
handleNextClickAuto
=
()
=>
{
const
currentIndex
=
sanctionList
.
value
.
findIndex
(
item
=>
item
.
id
===
currentSanctionId
.
value
);
const
currentIndex
=
sanctionList
.
value
.
findIndex
(
item
=>
item
.
id
===
currentSanctionId
.
value
);
console
.
log
(
"现在的currentIndex"
,
currentIndex
);
let
nextItem
;
let
nextItem
;
if
(
currentIndex
<
sanctionList
.
value
.
length
-
1
)
{
if
(
currentIndex
<
sanctionList
.
value
.
length
-
1
)
{
...
@@ -473,6 +474,7 @@ const handlePrevClick = () => {
...
@@ -473,6 +474,7 @@ const handlePrevClick = () => {
const
currentIndex
=
sanctionList
.
value
.
findIndex
(
item
=>
item
.
id
===
currentSanctionId
.
value
);
const
currentIndex
=
sanctionList
.
value
.
findIndex
(
item
=>
item
.
id
===
currentSanctionId
.
value
);
if
(
currentIndex
>
0
)
{
if
(
currentIndex
>
0
)
{
const
prevItem
=
sanctionList
.
value
[
currentIndex
-
1
];
const
prevItem
=
sanctionList
.
value
[
currentIndex
-
1
];
console
.
log
(
"prevItem"
,
prevItem
);
handleSanctionSelect
(
prevItem
.
id
);
handleSanctionSelect
(
prevItem
.
id
);
// startAutoPlay();
// startAutoPlay();
}
}
...
@@ -491,7 +493,7 @@ const handleSanctionSelect = id => {
...
@@ -491,7 +493,7 @@ const handleSanctionSelect = id => {
currentSanctionId
.
value
=
id
;
currentSanctionId
.
value
=
id
;
getFishboneData
();
getFishboneData
();
// getCnEntityOnChainData();
// getCnEntityOnChainData();
startAutoPlay
();
//
startAutoPlay();
};
};
const
activeTab
=
ref
([
"制裁时序分析"
,
"限制关联分析"
]);
const
activeTab
=
ref
([
"制裁时序分析"
,
"限制关联分析"
]);
...
...
src/views/finance/entityList/components/sanctionsOverview/components/introductionPage/index.vue
浏览文件 @
cf7baa70
...
@@ -75,9 +75,17 @@
...
@@ -75,9 +75,17 @@
<
AnalysisBox
title
=
"实体清单更新历史"
:
showAllBtn
=
"false"
>
<
AnalysisBox
title
=
"实体清单更新历史"
:
showAllBtn
=
"false"
>
<
template
#
header
-
btn
>
<
template
#
header
-
btn
>
<
div
class
=
"filters"
>
<
div
class
=
"filters"
>
<
el
-
select
v
-
model
=
"selectedDomain"
placeholder
=
"Select"
<
el
-
select
style
=
"width: 150px; height: 32px; margin-right: 16px"
>
v
-
model
=
"selectedDomain"
<
el
-
option
v
-
for
=
"item in domainOptions"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
placeholder
=
"Select"
style
=
"width: 150px; height: 32px; margin-right: 16px"
>
<
el
-
option
v
-
for
=
"item in domainOptions"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/el-select
>
<
el
-
checkbox
v
-
model
=
"onlyChina"
>
只看涉华动态
<
/el-checkbox
>
<
el
-
checkbox
v
-
model
=
"onlyChina"
>
只看涉华动态
<
/el-checkbox
>
<
/div
>
<
/div
>
...
@@ -91,8 +99,13 @@
...
@@ -91,8 +99,13 @@
<
img
:
src
=
"item.icon || title"
alt
=
""
/>
<
img
:
src
=
"item.icon || title"
alt
=
""
/>
<
div
class
=
"main"
>
<
div
class
=
"main"
>
<
div
class
=
"main-title"
@
click
=
"handleClick(item)"
>
{{
item
.
name
}}
<
/div
>
<
div
class
=
"main-title"
@
click
=
"handleClick(item)"
>
{{
item
.
name
}}
<
/div
>
<
el
-
tooltip
effect
=
"dark"
:
content
=
"item.summary"
popper
-
class
=
"common-prompt-popper"
placement
=
"top"
<
el
-
tooltip
:
show
-
after
=
"500"
>
effect
=
"dark"
:
content
=
"item.summary"
popper
-
class
=
"common-prompt-popper"
placement
=
"top"
:
show
-
after
=
"500"
>
<
div
class
=
"main-desc"
>
{{
item
.
summary
}}
<
/div
>
<
div
class
=
"main-desc"
>
{{
item
.
summary
}}
<
/div
>
<
/el-tooltip
>
<
/el-tooltip
>
<
div
class
=
"tag-box"
>
<
div
class
=
"tag-box"
>
...
@@ -107,8 +120,14 @@
...
@@ -107,8 +120,14 @@
<
/div
>
<
/div
>
<
div
class
=
"left-footer"
>
<
div
class
=
"left-footer"
>
<
div
class
=
"total-count"
>
共
{{
totalAll
}}
项
<
/div
>
<
div
class
=
"total-count"
>
共
{{
totalAll
}}
项
<
/div
>
<
el
-
pagination
v
-
model
:
current
-
page
=
"currentPageAll"
:
page
-
size
=
"pageSizeAll"
:
total
=
"totalAll"
<
el
-
pagination
layout
=
"prev, pager, next"
background
@
current
-
change
=
"handlePageChangeAll"
/>
v
-
model
:
current
-
page
=
"currentPageAll"
:
page
-
size
=
"pageSizeAll"
:
total
=
"totalAll"
layout
=
"prev, pager, next"
background
@
current
-
change
=
"handlePageChangeAll"
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/AnalysisBox
>
<
/div
>
<
/div
>
...
@@ -130,8 +149,12 @@
...
@@ -130,8 +149,12 @@
<
span
>
关键人物
<
/span
>
<
span
>
关键人物
<
/span
>
<
/div
>
<
/div
>
<
div
class
=
"key-person-list"
>
<
div
class
=
"key-person-list"
>
<
div
class
=
"person-item"
v
-
for
=
"(item, index) in publishInfo.personList"
:
key
=
"index"
<
div
@
click
=
"handlePerClick(item)"
>
class
=
"person-item"
v
-
for
=
"(item, index) in publishInfo.personList"
:
key
=
"index"
@
click
=
"handlePerClick(item)"
>
<
img
:
src
=
"item.imageUrl"
alt
=
""
/>
<
img
:
src
=
"item.imageUrl"
alt
=
""
/>
<
div
class
=
"person-info"
>
<
div
class
=
"person-info"
>
<
CommonPrompt
:
content
=
"item.name"
>
<
CommonPrompt
:
content
=
"item.name"
>
...
@@ -160,11 +183,19 @@
...
@@ -160,11 +183,19 @@
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"more-btn"
v
-
if
=
"publishOrgInfo.length < dynamicTotal"
@
click
=
"handleLoadMoreDynamic"
>
<
!--
<
div
class
=
"more-btn"
v
-
if
=
"publishOrgInfo.length < dynamicTotal"
@
click
=
"handleLoadMoreDynamic"
>
<
span
>
查看更多
<
/span
>
<
span
>
查看更多
<
/span
>
<
el
-
icon
>
<
el
-
icon
>
<
ArrowDown
/>
<
ArrowDown
/>
<
/el-icon
>
<
/el-icon
>
<
/div> --
>
<
div
class
=
"dynamic-footer"
>
<
simple
-
pagination
v
-
model
:
current
-
page
=
"dynamicPage"
:
page
-
size
=
"dynamicPageSize"
:
total
=
"dynamicTotal"
@
page
-
change
=
"handleListPageChange"
/>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
@@ -177,7 +208,7 @@
...
@@ -177,7 +208,7 @@
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
router
from
"@/router"
;
import
router
from
"@/router"
;
import
title
from
"../../../../assets/title.png"
;
import
title
from
"../../../../assets/title.png"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png
"
;
import
SimplePagination
from
"@/components/SimplePagination.vue
"
;
import
icon01
from
"../../assets/icon01.png"
;
import
icon01
from
"../../assets/icon01.png"
;
import
icon02
from
"../../assets/icon02.png"
;
import
icon02
from
"../../assets/icon02.png"
;
import
{
ArrowDown
}
from
"@element-plus/icons-vue"
;
import
{
ArrowDown
}
from
"@element-plus/icons-vue"
;
...
@@ -376,6 +407,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => {
...
@@ -376,6 +407,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => {
console
.
error
(
"获取发布机构动态失败:"
,
error
);
console
.
error
(
"获取发布机构动态失败:"
,
error
);
}
}
}
;
}
;
const
handleListPageChange
=
val
=>
{
dynamicPage
.
value
=
val
;
getPublishOrgInfoFn
(
false
);
}
;
const
handleLoadMoreDynamic
=
()
=>
{
const
handleLoadMoreDynamic
=
()
=>
{
dynamicPage
.
value
++
;
dynamicPage
.
value
++
;
...
@@ -401,17 +436,16 @@ const getEntityInfoFn = async id => {
...
@@ -401,17 +436,16 @@ const getEntityInfoFn = async id => {
const
sanTypeId
=
ref
(
""
);
const
sanTypeId
=
ref
(
""
);
// 跳转到数据资源库
// 跳转到数据资源库
const
handleToDataLibrary
=
(
item
)
=>
{
const
handleToDataLibrary
=
item
=>
{
// console.log('item', item);
// console.log('item', item);
let
domainStr
=
domainOptions
.
filter
(
item
=>
item
.
value
===
selectedDomain
.
value
)[
0
].
label
;
let
domainStr
=
domainOptions
.
filter
(
item
=>
item
.
value
===
selectedDomain
.
value
)[
0
].
label
let
params
;
let
params
if
(
domainStr
===
"全部领域"
)
{
if
(
domainStr
===
'全部领域'
)
{
params
=
{
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
item
.
postDate
,
item
.
postDate
])
selectedDate
:
JSON
.
stringify
([
item
.
postDate
,
item
.
postDate
])
}
}
;
}
else
{
}
else
{
params
=
{
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
,
...
@@ -424,8 +458,7 @@ const handleToDataLibrary = (item) => {
...
@@ -424,8 +458,7 @@ const handleToDataLibrary = (item) => {
query
:
params
query
:
params
}
);
}
);
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
}
;
onMounted
(()
=>
{
onMounted
(()
=>
{
sanTypeId
.
value
=
route
.
query
.
sanTypeId
;
sanTypeId
.
value
=
route
.
query
.
sanTypeId
;
...
@@ -647,11 +680,13 @@ onMounted(() => {
...
@@ -647,11 +680,13 @@ onMounted(() => {
.
right
{
.
right
{
width
:
520
px
;
width
:
520
px
;
height
:
1020
px
;
height
:
auto
;
// min-height: 900px;
max
-
height
:
1200
px
;
.
right
-
main
{
.
right
-
main
{
padding
:
7
px
24
px
20
px
23
px
;
padding
:
7
px
24
px
20
px
23
px
;
height
:
100
%
;
.
right
-
main
-
title
{
.
right
-
main
-
title
{
cursor
:
pointer
;
cursor
:
pointer
;
width
:
473
px
;
width
:
473
px
;
...
@@ -768,6 +803,10 @@ onMounted(() => {
...
@@ -768,6 +803,10 @@ onMounted(() => {
.
right
-
main
-
dynamic
{
.
right
-
main
-
dynamic
{
width
:
100
%
;
width
:
100
%
;
height
:
900
px
;
display
:
flex
;
flex
-
direction
:
column
;
position
:
relative
;
.
dynamic
-
title
{
.
dynamic
-
title
{
display
:
flex
;
display
:
flex
;
...
@@ -789,8 +828,8 @@ onMounted(() => {
...
@@ -789,8 +828,8 @@ onMounted(() => {
}
}
.
dynamic
-
list
{
.
dynamic
-
list
{
max
-
height
:
500
px
;
//
max-height: 500px;
overflow
-
y
:
auto
;
//
overflow-y: auto;
padding
-
right
:
10
px
;
padding
-
right
:
10
px
;
/* 滚动条样式 */
/* 滚动条样式 */
...
@@ -867,6 +906,12 @@ onMounted(() => {
...
@@ -867,6 +906,12 @@ onMounted(() => {
}
}
}
}
.
dynamic
-
footer
{
position
:
absolute
;
bottom
:
50
px
;
left
:
180
px
;
}
.
more
-
btn
{
.
more
-
btn
{
width
:
100
%
;
width
:
100
%
;
display
:
flex
;
display
:
flex
;
...
...
src/views/finance/entityList/components/sanctionsOverview/components/listPage/index.vue
浏览文件 @
cf7baa70
...
@@ -5,9 +5,10 @@
...
@@ -5,9 +5,10 @@
<el-input
v-model=
"searchKeyword"
class=
"search-input"
placeholder=
"搜索实体"
:suffix-icon=
"Search"
/>
<el-input
v-model=
"searchKeyword"
class=
"search-input"
placeholder=
"搜索实体"
:suffix-icon=
"Search"
/>
<div
class=
"filters"
>
<div
class=
"filters"
>
<el-checkbox
v-model=
"onlyChina"
label=
"只看中国实体"
/>
<el-checkbox
v-model=
"onlyChina"
label=
"只看中国实体"
/>
<el-select
v-model=
"order"
placeholder=
"请选择排序方式"
style=
"width: 160px"
>
<
!--
<
el-select
v-model=
"order"
placeholder=
"请选择排序方式"
style=
"width: 160px"
>
<el-option
v-for=
"item in orderOptions"
:value=
"item.value"
:key=
"item.value"
:label=
"item.name"
/>
<el-option
v-for=
"item in orderOptions"
:value=
"item.value"
:key=
"item.value"
:label=
"item.name"
/>
</el-select>
</el-select>
-->
<TimeSortSelectBox
@
handle-px-change=
"handleTimePx"
/>
</div>
</div>
</div>
</div>
<div
class=
"main"
>
<div
class=
"main"
>
...
@@ -62,79 +63,17 @@
...
@@ -62,79 +63,17 @@
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<!--
<div
class=
"title"
>
<div
class=
"left-wrapper"
>
<div
class=
"box"
></div>
<div
class=
"text"
>
实体清单
</div>
</div>
<div
class=
"right-wrapper"
>
<div
class=
"stats"
>
<div
class=
"dot"
></div>
<div
class=
"count-text"
>
共
<span
class=
"highlight"
>
{{
ruleCount
.
totalCount
}}
</span>
家
</div>
<div
class=
"rule-text"
>
(50%规则涉及
<span
class=
"highlight"
>
{{
ruleCount
.
ruleCount
}}
</span>
家)
</div>
</div>
<div
class=
"btn"
>
<img
src=
"../../../../assets/下载按钮.png"
alt=
""
/>
<img
src=
"../../../../assets/收藏按钮.png"
alt=
""
/>
</div>
</div>
</div>
-->
<!--
<div
class=
"right-table"
>
<el-table
:data=
"entityRows"
table-layout=
"fixed"
:row-class-name=
"tableRowClassName"
:header-cell-style=
"
{ background: '#fff' }">
<el-table-column
label=
"实体名称"
min-width=
"200"
>
<template
#
default=
"
{ row }">
<div
class=
"entity-name-cell"
@
click=
"handleCompClick(row)"
>
<el-image
v-if=
"row.img"
class=
"avatar"
:src=
"row.img"
alt=
""
></el-image>
<div
v-else
class=
"avatar-undefined"
>
{{
(
row
.
entityNameZh
||
row
.
entityName
)?.
match
(
/
[\u
4e00-
\u
9fa5a-zA-Z0-9
]
/
)?.[
0
]
}}
</div>
<CommonPrompt
:content=
"row.entityNameZh || row.entityName"
style=
"flex: 1; overflow: hidden"
/>
</div>
</
template
>
</el-table-column>
<el-table-column
label=
"涉及领域"
min-width=
"150"
>
<
template
#
default=
"{ row }"
>
<div
class=
"domain-cell"
>
<el-tag
v-for=
"tag in row.techDomains"
:key=
"tag"
class=
"domain-tag"
effect=
"plain"
:disable-transitions=
"true"
:style=
"getTagStyle(tag)"
>
{{
tag
}}
</el-tag>
</div>
</
template
>
</el-table-column>
<el-table-column
prop=
"startTime"
label=
"制裁时间"
width=
"140"
show-overflow-tooltip
align=
"center"
/>
<el-table-column
label=
"50%规则子企业"
min-width=
"280"
show-overflow-tooltip
align=
"right"
>
<
template
#
default=
"{ row }"
>
<div
class=
"rule-cell"
v-if=
"row.ruleOrgCount > 0"
>
<div
class=
"rule-text"
:title=
"row.ruleOrgList?.[0]?.orgName || ''"
>
{{
row
.
ruleOrgList
?.[
0
]?.
orgName
||
''
}}
...等
</div>
<el-link
class=
"rule-link"
type=
"primary"
:underline=
"false"
@
click=
"handleRuleClick(row)"
>
{{
row
.
ruleOrgCount
}}
家 >
</el-link>
</div>
</
template
>
</el-table-column>
</el-table>
</div>
<div
class=
"tight-footer"
>
<div
class=
"total-text"
>
共 {{ total }} 项
</div>
<el-pagination
:current-page=
"currentPage"
v-model:page-size=
"pageSize"
:total=
"total"
layout=
"prev, pager, next"
prev-text=
"<"
next-text=
">"
@
current-change=
"handleCurrentChange"
/>
</div>
-->
<AnalysisBox
title=
"实体清单"
:showAllBtn=
"false"
>
<AnalysisBox
title=
"实体清单"
:showAllBtn=
"false"
>
<template
#
header-btn
>
<template
#
header-btn
>
<div
class=
"stats"
>
<div
class=
"stats"
>
<div
class=
"dot"
></div>
<div
class=
"dot"
></div>
<div
class=
"count-text"
>
<div
class=
"count-text"
>
共
<span
class=
"highlight"
@
click=
"handlToDataLibrary"
>
{{
ruleCount
.
totalCount
}}
</span>
家
共
<span
class=
"highlight"
@
click=
"handlToDataLibrary"
>
{{
ruleCount
.
totalCount
}}
</span>
家
</div>
</div>
<div
class=
"rule-text"
>
<div
class=
"rule-text"
>
(50%规则涉及
<span
class=
"highlight"
@
click=
"handlToDataLibrary1"
>
{{
ruleCount
.
ruleCount
}}
</span
(50%规则涉及
<span
class=
"highlight"
@
click=
"handlToDataLibrary1"
>
{{
ruleCount
.
ruleCount
}}
</span
>
家)
>
家)
</div>
</div>
</div>
</div>
...
@@ -145,7 +84,11 @@
...
@@ -145,7 +84,11 @@
table-layout=
"fixed"
table-layout=
"fixed"
:row-class-name=
"tableRowClassName"
:row-class-name=
"tableRowClassName"
:header-cell-style=
"{ background: '#fff' }"
:header-cell-style=
"{ background: '#fff' }"
v-loading=
"tableLoading"
>
>
<
template
#
empty
>
<el-empty
/>
</
template
>
<el-table-column
label=
"实体名称"
min-width=
"200"
>
<el-table-column
label=
"实体名称"
min-width=
"200"
>
<
template
#
default=
"{ row }"
>
<
template
#
default=
"{ row }"
>
<div
class=
"entity-name-cell"
@
click=
"handleCompClick(row)"
>
<div
class=
"entity-name-cell"
@
click=
"handleCompClick(row)"
>
...
@@ -237,6 +180,7 @@
...
@@ -237,6 +180,7 @@
import
{
ref
,
computed
,
onMounted
,
watch
}
from
"vue"
;
import
{
ref
,
computed
,
onMounted
,
watch
}
from
"vue"
;
import
{
useRouter
}
from
"vue-router"
;
import
{
useRouter
}
from
"vue-router"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
TimeSortSelectBox
from
"@/components/base/TimeSortSelectBox/index.vue"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png"
;
import
defaultIcon
from
"../../../../../assets/icons/default-avatar.png"
;
import
RuleSubsidiaryDialog
from
"./RuleSubsidiaryDialog.vue"
;
import
RuleSubsidiaryDialog
from
"./RuleSubsidiaryDialog.vue"
;
import
{
getExportControlList
,
get50PercentEntityCount
}
from
"@/api/exportControlV2.0.js"
;
import
{
getExportControlList
,
get50PercentEntityCount
}
from
"@/api/exportControlV2.0.js"
;
...
@@ -245,10 +189,10 @@ import { useGotoCompanyPages } from "@/router/modules/company";
...
@@ -245,10 +189,10 @@ import { useGotoCompanyPages } from "@/router/modules/company";
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
gotoCompanyPages
=
useGotoCompanyPages
();
const
router
=
useRouter
();
const
router
=
useRouter
();
const
order
=
ref
(
"
a
sc"
);
const
order
=
ref
(
"
de
sc"
);
const
orderOptions
=
ref
([
const
orderOptions
=
ref
([
{
name
:
"
正序"
,
value
:
"a
sc"
},
{
name
:
"
倒序"
,
value
:
"de
sc"
},
{
name
:
"
倒序"
,
value
:
"de
sc"
}
{
name
:
"
正序"
,
value
:
"a
sc"
}
]);
]);
// 跳转公司详情页
// 跳转公司详情页
const
handleCompClick
=
item
=>
{
const
handleCompClick
=
item
=>
{
...
@@ -409,8 +353,14 @@ const mainList = ref([]);
...
@@ -409,8 +353,14 @@ const mainList = ref([]);
const
isFetching
=
ref
(
false
);
const
isFetching
=
ref
(
false
);
const
ruleCount
=
ref
(
0
);
const
ruleCount
=
ref
(
0
);
const
handleTimePx
=
val
=>
{
console
.
log
(
val
);
order
.
value
=
orderOptions
.
value
[
val
-
1
].
value
;
};
const
tableLoading
=
ref
(
false
);
let
abortController
=
null
;
let
abortController
=
null
;
const
getExportControlListApi
=
async
()
=>
{
const
getExportControlListApi
=
async
()
=>
{
tableLoading
.
value
=
true
;
// 取消上一轮未完成的请求
// 取消上一轮未完成的请求
if
(
abortController
)
{
if
(
abortController
)
{
try
{
try
{
...
@@ -475,6 +425,7 @@ const getExportControlListApi = async () => {
...
@@ -475,6 +425,7 @@ const getExportControlListApi = async () => {
try
{
try
{
const
res
=
await
getExportControlList
(
data
,
{
signal
:
abortController
.
signal
});
const
res
=
await
getExportControlList
(
data
,
{
signal
:
abortController
.
signal
});
tableLoading
.
value
=
false
;
// 50%规则涉及实体数
// 50%规则涉及实体数
const
countRes
=
await
get50PercentEntityCount
(
data
);
const
countRes
=
await
get50PercentEntityCount
(
data
);
if
(
countRes
.
code
===
200
)
{
if
(
countRes
.
code
===
200
)
{
...
@@ -488,9 +439,11 @@ const getExportControlListApi = async () => {
...
@@ -488,9 +439,11 @@ const getExportControlListApi = async () => {
if
(
!
error
||
(
error
.
code
!==
"ERR_CANCELED"
&&
error
.
name
!==
"CanceledError"
&&
error
.
name
!==
"AbortError"
))
{
if
(
!
error
||
(
error
.
code
!==
"ERR_CANCELED"
&&
error
.
name
!==
"CanceledError"
&&
error
.
name
!==
"AbortError"
))
{
console
.
error
(
error
);
console
.
error
(
error
);
}
}
tableLoading
.
value
=
false
;
}
finally
{
}
finally
{
isFetching
.
value
=
false
;
isFetching
.
value
=
false
;
abortController
=
null
;
abortController
=
null
;
tableLoading
.
value
=
false
;
}
}
};
};
...
@@ -530,26 +483,25 @@ watch(customDateRange, () => {
...
@@ -530,26 +483,25 @@ watch(customDateRange, () => {
// 跳转到数据资源库
// 跳转到数据资源库
const
handlToDataLibrary
=
()
=>
{
const
handlToDataLibrary
=
()
=>
{
const
params
=
{
const
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
};
};
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/sDNList"
,
path
:
"/dataLibrary/sDNList"
,
query
:
params
query
:
params
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
}
;
const
handlToDataLibrary1
=
()
=>
{
const
handlToDataLibrary1
=
()
=>
{
const
params
=
{
const
params
=
{
isCnEntityOnly
:
true
,
isCnEntityOnly
:
true
,
isHalfRule
:
true
,
isHalfRule
:
true
};
};
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/sDNList"
,
path
:
"/dataLibrary/sDNList"
,
query
:
params
query
:
params
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
};
</
script
>
</
script
>
<
style
scoped
lang=
"scss"
>
<
style
scoped
lang=
"scss"
>
...
@@ -587,7 +539,7 @@ const handlToDataLibrary1 = () => {
...
@@ -587,7 +539,7 @@ const handlToDataLibrary1 = () => {
.filters
{
.filters
{
display
:
flex
;
display
:
flex
;
//
align-items: center;
align-items
:
center
;
.el-checkbox
{
.el-checkbox
{
margin-right
:
20px
;
margin-right
:
20px
;
...
...
src/views/finance/entityList/components/sanctionsOverview/index.vue
浏览文件 @
cf7baa70
...
@@ -29,7 +29,7 @@ import listPage from "./components/listPage/index.vue";
...
@@ -29,7 +29,7 @@ import listPage from "./components/listPage/index.vue";
const
emit
=
defineEmits
([
"update-entity-info"
]);
const
emit
=
defineEmits
([
"update-entity-info"
]);
const
activeTab
=
ref
([
"
实体清单列表"
,
"实体
清单简介"
]);
const
activeTab
=
ref
([
"
SDN清单列表"
,
"SDN
清单简介"
]);
const
activeIndex
=
ref
(
0
);
const
activeIndex
=
ref
(
0
);
const
handleClickTab
=
index
=>
{
const
handleClickTab
=
index
=>
{
...
...
src/views/finance/index.vue
浏览文件 @
cf7baa70
...
@@ -28,7 +28,7 @@
...
@@ -28,7 +28,7 @@
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 528px; margin-top: 64px"
>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 528px; margin-top: 64px"
>
<CustomTitle
id=
"position1"
title=
"最新动态"
/>
<CustomTitle
id=
"position1"
title=
"最新动态"
/>
<el-col
:span=
"16"
style=
"padding-left: 0"
>
<el-col
:span=
"16"
style=
"padding-left: 0"
>
<custom-container
titleType=
"primary"
title=
"最新
出口管
制政策"
:titleIcon=
"houseIcon"
height=
"450px"
>
<custom-container
titleType=
"primary"
title=
"最新
投融资限
制政策"
:titleIcon=
"houseIcon"
height=
"450px"
>
<template
#
header-right
>
<template
#
header-right
>
<el-button
type=
"primary"
@
click=
"handleToEntityList"
link
>
<el-button
type=
"primary"
@
click=
"handleToEntityList"
link
>
{{
"查看详情 >"
}}
{{
"查看详情 >"
}}
...
@@ -207,7 +207,7 @@
...
@@ -207,7 +207,7 @@
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
label=
"发布次数"
width=
"300"
>
<el-table-column
label=
"发布次数"
width=
"300"
>
<template
#
default=
"scope"
>
<template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center"
>
<div
style=
"display: flex; align-items: center
; cursor: pointer
"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
<el-progress
:percentage=
"scope.row.percent * 100"
:percentage=
"scope.row.percent * 100"
...
@@ -220,7 +220,12 @@
...
@@ -220,7 +220,12 @@
<el-table-column
label=
"重点领域"
width=
"220"
align=
"center"
>
<el-table-column
label=
"重点领域"
width=
"220"
align=
"center"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<div
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
style=
"
display: flex;
justify-content: flex-start;
align-items: center;
gap: 5px;
"
>
>
<AreaTag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:tagName=
"tag"
/>
<AreaTag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:tagName=
"tag"
/>
<!--
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
<!--
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
...
@@ -258,7 +263,7 @@
...
@@ -258,7 +263,7 @@
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
prop=
"year"
label=
"年份"
width=
"200"
/>
<el-table-column
label=
"发布次数"
width=
"300"
>
<el-table-column
label=
"发布次数"
width=
"300"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; align-items: center"
>
<div
style=
"display: flex; align-items: center
; cursor: pointer
"
>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<span
style=
"margin-right: 10px; width: 40px"
>
{{
scope
.
row
.
num
}}
次
</span>
<el-progress
<el-progress
:percentage=
"scope.row.percent * 100"
:percentage=
"scope.row.percent * 100"
...
@@ -271,7 +276,12 @@
...
@@ -271,7 +276,12 @@
<el-table-column
label=
"重点领域"
width=
"220"
align=
"center"
>
<el-table-column
label=
"重点领域"
width=
"220"
align=
"center"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<div
<div
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
style=
"
display: flex;
justify-content: flex-start;
align-items: center;
gap: 5px;
"
>
>
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
tag
...
@@ -397,7 +407,7 @@
...
@@ -397,7 +407,7 @@
</el-row>
</el-row>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px"
>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px"
>
<CustomTitle
id=
"position4"
title=
"
资源
库"
style=
"margin-top: 0px"
/>
<CustomTitle
id=
"position4"
title=
"
投融资限制数据
库"
style=
"margin-top: 0px"
/>
<div
class=
"resource-tabs"
>
<div
class=
"resource-tabs"
>
<div
<div
v-for=
"tab in resourceTabs"
v-for=
"tab in resourceTabs"
...
@@ -411,7 +421,7 @@
...
@@ -411,7 +421,7 @@
</div>
</div>
<
template
v-if=
"activeResourceTab === 'entity'"
>
<
template
v-if=
"activeResourceTab === 'entity'"
>
<el-col
:span=
"8"
style=
"padding-left: 0"
>
<el-col
:span=
"8"
style=
"padding-left: 0"
>
<custom-container
title=
"
历次制裁过程"
:titleIcon=
"listIcon"
height=
"845px
"
>
<custom-container
title=
"
制裁历程"
:titleIcon=
"listIcon"
height=
"auto
"
>
<template
#
default
>
<template
#
default
>
<div
class=
"box4"
>
<div
class=
"box4"
>
<div
style=
"height: 90%; overflow-y: auto; padding-top: 10px"
>
<div
style=
"height: 90%; overflow-y: auto; padding-top: 10px"
>
...
@@ -424,23 +434,24 @@
...
@@ -424,23 +434,24 @@
></div>
></div>
</div>
</div>
<div
class=
"box4-item-right"
>
<div
class=
"box4-item-right"
>
<div
class=
"box4-item-right-header"
@
click=
"handleSanc(item)"
>
<
!--
<
div
class=
"box4-item-right-header"
@
click=
"handleSanc(item)"
>
<span
class=
"box4-item-right-header-title"
<span
class=
"box4-item-right-header-title"
>
{{
item
.
postDate
}}
—
{{
item
.
title
}}
</span
>
{{
item
.
postDate
}}
—
{{
item
.
title
}}
</span
>
>
<span
class=
"box4-item-right-header-desc"
>
{{
item
.
desc
}}
</span>
<span
class=
"box4-item-right-header-desc"
>
{{
item
.
desc
}}
</span>
</div>
</div>
-->
<el-tooltip
<div
class=
"box4-item-right-header"
@
click=
"handleSanc(item)"
>
effect=
"dark"
<div
class=
"box4-item-right-header-top"
>
:content=
"item.content"
<span
class=
"box4-item-right-header-title"
>
{{
item
.
postDate
}}
</span>
popper-class=
"common-prompt-popper"
<span
class=
"box4-item-right-header-desc"
>
{{
item
.
desc
}}
</span>
placement=
"top"
</div>
:show-after=
"500"
<div
class=
"box4-item-right-header-bottom"
>
>
<span
class=
"box4-item-right-header-title"
>
{{
item
.
title
}}
</span>
<div
class=
"box4-item-right-content"
>
{{
item
.
content
}}
</div>
</div>
</el-tooltip>
</div>
<div
class=
"box4-item-right-content"
>
{{
item
.
content
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -448,24 +459,76 @@
...
@@ -448,24 +459,76 @@
class=
"box4-footer"
class=
"box4-footer"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
:style=
"
{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
>
>
<
el-button
type=
"primary"
link
@
click=
"handleGetMore"
<
simple-pagination
>
查看更多
v-model:current-page=
"sanctionPage"
<el-icon>
:page-size=
"listPageSize"
<DArrowRight
/>
:total=
"totalNum"
</el-icon>
@
page-change=
"handleListPageChange"
</el-button
>
/
>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
</custom-container>
</custom-container>
</el-col>
</el-col>
<el-col
:span=
"16"
style=
"padding-right: 0"
>
<el-col
:span=
"16"
style=
"padding-right: 0"
>
<custom-container
title=
"
制裁实体清单"
:titleIcon=
"entityIcon"
height=
"845
px"
>
<custom-container
title=
"
清单列表"
:titleIcon=
"entityIcon"
height=
"880
px"
>
<
template
#
header-right
>
<
template
#
header-right
>
<div
class=
"box5-header-right"
>
共
{{
total
}}
家实体
</div>
<div
class=
"box5-header-right"
>
共
{{
total
}}
家实体
</div>
</
template
>
</
template
>
<
template
#
default
>
<
template
#
default
>
<div
class=
"box5"
>
<div
class=
"box5"
>
<div
class=
"filter"
>
<el-input
v-model=
"searchKeyword"
class=
"search-input"
placeholder=
"搜索实体"
:suffix-icon=
"Search"
@
keyup
.
enter=
"handleEntitySearch"
/>
<div
class=
"filter-right"
>
<el-select
v-model=
"filterDomain"
class=
"filter-select"
placeholder=
"涉及领域"
@
change=
"handleFilterDomainChange"
>
<el-option
v-for=
"item in techOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<el-select
v-model=
"entityType"
class=
"filter-select"
placeholder=
"实体类型"
clearable
@
change=
"handleEntityTypeChange"
>
<el-option
v-for=
"item in entityTypes"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<!--
<el-select
v-model=
"year"
class=
"filter-select"
placeholder=
"选择时间"
@
change=
"handleTimeChange"
>
<el-option
v-for=
"item in timeSelectOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
-->
<TimeSortSelectBox
@
handle-px-change=
"handleTimePx"
/>
</div>
</div>
<el-table
<el-table
:data=
"entitiesList"
:data=
"entitiesList"
class=
"sanction-table"
class=
"sanction-table"
...
@@ -475,11 +538,9 @@
...
@@ -475,11 +538,9 @@
header-row-class-name=
"table-header"
header-row-class-name=
"table-header"
row-class-name=
"table-row"
row-class-name=
"table-row"
>
>
<!--
<el-table-column
prop=
"index"
label=
"序号"
width=
"80"
align=
"center"
>
<template
#
empty
>
<template
#
default=
"scope"
>
<el-empty
/>
{{
scope
.
$index
+
1
+
(
currentPage
-
1
)
*
pageSize
}}
</
template
>
</
template
>
</el-table-column>
-->
<el-table-column
prop=
"name"
label=
"实体名称"
min-width=
"200"
>
<el-table-column
prop=
"name"
label=
"实体名称"
min-width=
"200"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
...
@@ -521,25 +582,6 @@
...
@@ -521,25 +582,6 @@
</
template
>
</
template
>
</el-table-column>
</el-table-column>
<!-- <el-table-column prop="strength" label="制裁强度" width="120" align="center">
<template #default="scope">
<div class="sanction-strength">
<div :class="['strength-bar', `strength-${scope.row.strength}`]"></div>
<span>{{ strengthLabels[scope.row.strength] }}</span>
</div>
</template>
</el-table-column> -->
<!-- <el-table-column prop="revenue" label="营收(亿元)" width="140" align="right">
<template #default="scope">
<span
:class="['revenue-cell', scope.row.revenue === '无营收数据' ? 'no-revenue' : '']"
>
{{ scope.row.revenue }}
</span>
</template>
</el-table-column> -->
<el-table-column
prop=
"revenue"
label=
"50%规则子企业"
width=
"280"
align=
"right"
>
<el-table-column
prop=
"revenue"
label=
"50%规则子企业"
width=
"280"
align=
"right"
>
<
template
#
default=
"scope"
>
<
template
#
default=
"scope"
>
<div
class=
"num-item"
v-if=
"scope.row.ruleOrgCount > 0"
>
<div
class=
"num-item"
v-if=
"scope.row.ruleOrgCount > 0"
>
...
@@ -607,48 +649,74 @@
...
@@ -607,48 +649,74 @@
<div
class=
"text"
>
制裁时间
</div>
<div
class=
"text"
>
制裁时间
</div>
</div>
</div>
<div
class=
"left-main"
>
<div
class=
"left-main"
>
<el-checkbox-group
v-model=
"checkedTime"
>
<
!--
<
el-checkbox-group
v-model=
"checkedTime"
>
<div
class=
"checkbox-grid"
>
<div
class=
"checkbox-grid"
>
<el-checkbox
v-for=
"item in timeOptions"
:key=
"item"
:label=
"item"
>
{{
<el-checkbox
v-for=
"item in timeOptions"
:key=
"item"
:label=
"item"
>
{{
item
item
}}
</el-checkbox>
}}
</el-checkbox>
</div>
</div>
</el-checkbox-group>
</el-checkbox-group>
-->
<div
class=
"checkbox-grid"
>
<el-checkbox
v-for=
"(item, index) in timeOptions"
:key=
"index"
v-model=
"item.checked"
:label=
"item.label"
@
change=
"handleFilterChange(item, timeOptions, 'time')"
/>
<div
v-if=
"timeOptions.find(i => i.value === 'custom' && i.checked)"
class=
"custom-date-picker"
>
<el-date-picker
v-model=
"customDateRange"
type=
"daterange"
range-separator=
"-"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right"
>
<div
class=
"right-title"
>
<div
class=
"right-title"
>
<img
:src=
"icon01"
alt=
""
/>
<img
:src=
"icon01"
alt=
""
/>
<div>
出口管
制制裁措施
</div>
<div>
投融资限
制制裁措施
</div>
</div>
</div>
<div
class=
"right-main"
>
<div
class=
"right-main-box"
v-loading=
"sancLoading"
>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"right-main-wrapper"
v-if=
"sanctionList.length > 0"
>
<div
class=
"time"
>
<div
class=
"right-main"
>
<div
class=
"year"
>
{{
item
.
year
}}
</div>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"date"
>
{{
item
.
dateStr
}}
</div>
<div
class=
"time"
>
</div>
<div
class=
"year"
>
{{
item
.
year
}}
</div>
<img
:src=
"item.orgLogoUrl || comTitle"
alt=
""
/>
<div
class=
"date"
>
{{
item
.
dateStr
}}
</div>
<div
class=
"main"
>
</div>
<div
class=
"main-title"
@
click=
"handleTitleClick(item)"
>
{{
item
.
title
}}
</div>
<img
:src=
"item.orgLogoUrl || comTitle"
alt=
""
/>
<div
class=
"main-desc"
>
{{
item
.
desc
}}
</div>
<div
class=
"main"
>
<div
class=
"tag-box"
>
<div
class=
"main-title"
@
click=
"handleTitleClick(item)"
>
{{
item
.
title
}}
</div>
<div
v-for=
"tag in item.tags"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
<div
class=
"main-desc"
>
{{
item
.
desc
}}
</div>
</div>
<div
class=
"tag-box"
>
<div
v-for=
"tag in item.tags"
:key=
"tag"
class=
"tag-item"
>
{{
tag
}}
</div>
</div>
<div
:class=
"
{ 'count-tag': item.countTag }">
{{
item
.
countTag
}}
</div>
<div
:class=
"
{ 'count-tag': item.countTag }">
{{
item
.
countTag
}}
</div>
</div>
</div>
</div>
<div
class=
"right-footer"
>
<div
class=
"total-count"
>
共
{{
totalAll
}}
项
</div>
<el-pagination
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</div>
</div>
</div>
<el-empty
v-else
/>
<div
class=
"right-footer"
>
<div
class=
"total-count"
>
共
{{
totalAll
}}
项
</div>
<el-pagination
v-model:current-page=
"currentPageAll"
:page-size=
"pageSizeAll"
:total=
"totalAll"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChangeAll"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -656,33 +724,6 @@
...
@@ -656,33 +724,6 @@
</
template
>
</
template
>
</el-row>
</el-row>
</div>
</div>
<!-- <el-dialog v-model="dialogVisible" width="800" :before-close="handleClose">
<template #title>
<div class="dialog-title">50%规则子企业</div>
</template>
<div class="dialog-ett-wrpper">
<div
class="box1-bottom-content-item"
v-for="(ett, index) in currentOrgList"
:key="index"
@click="handleEntityClick(ett)"
>
<el-image v-if="ett.img" class="box1-bottom-content-item-img" :src="ett.img" alt=""></el-image>
<div v-else class="box1-bottom-content-item-imgUndefined">
{{ (ett.orgName || ett.enName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
<div class="box1-bottom-content-item-txt">
{{ ett.orgName || ett.orgNameZh }}
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogVisible = false"> 确定 </el-button>
</div>
</template>
</el-dialog> -->
<RuleSubsidiaryDialog
<RuleSubsidiaryDialog
v-model=
"dialogVisible"
v-model=
"dialogVisible"
:company-name=
"currentRuleCompany"
:company-name=
"currentRuleCompany"
...
@@ -722,7 +763,7 @@ const homeMainRef = ref(null);
...
@@ -722,7 +763,7 @@ const homeMainRef = ref(null);
const
{
isShow
}
=
useContainerScroll
(
homeMainRef
);
const
{
isShow
}
=
useContainerScroll
(
homeMainRef
);
import
*
as
echarts
from
"echarts"
;
import
*
as
echarts
from
"echarts"
;
import
setChart
from
"@/utils/setChart"
;
import
setChart
from
"@/utils/setChart"
;
import
{
ElMessage
,
ElMessageBox
}
from
"element-plus
"
;
import
TimeSortSelectBox
from
"@/components/base/TimeSortSelectBox/index.vue
"
;
import
{
DArrowRight
,
Warning
,
Search
}
from
"@element-plus/icons-vue"
;
import
{
DArrowRight
,
Warning
,
Search
}
from
"@element-plus/icons-vue"
;
import
EChart
from
"@/components/Chart/index.vue"
;
import
EChart
from
"@/components/Chart/index.vue"
;
...
@@ -757,23 +798,23 @@ import trumpAvatar from "@/assets/images/icon-trump.png";
...
@@ -757,23 +798,23 @@ import trumpAvatar from "@/assets/images/icon-trump.png";
import
elongAvatar
from
"@/assets/images/icon-elong.png"
;
import
elongAvatar
from
"@/assets/images/icon-elong.png"
;
import
newsIcon
from
"@/assets/images/icon-news.png"
;
import
newsIcon
from
"@/assets/images/icon-news.png"
;
import
dialogIcon
from
"@/assets/images/icon-duihua.png"
;
import
dialogIcon
from
"@/assets/images/icon-duihua.png"
;
import
houseIcon
from
"
@/assets/images/icon-house
.png"
;
import
houseIcon
from
"
./assets/icons/icon-zc
.png"
;
import
dangerIcon
from
"./assets/images/box2-header-icon.png"
;
import
dangerIcon
from
"./assets/images/box2-header-icon.png"
;
import
box1Image
from
"./assets/images/box1-image.png"
;
import
box1Image
from
"./assets/images/box1-image.png"
;
import
box3Icon
from
"./assets/i
mages/box1-header-icon
.png"
;
import
box3Icon
from
"./assets/i
cons/icon-pd
.png"
;
import
radarIcon
from
"./assets/i
mage
s/icon-radar.png"
;
import
radarIcon
from
"./assets/i
con
s/icon-radar.png"
;
import
qushiIcon
from
"./assets/images/icon-qushi.png"
;
import
qushiIcon
from
"./assets/images/icon-qushi.png"
;
import
listIcon
from
"./assets/images/icon-list.png"
;
import
listIcon
from
"./assets/images/icon-list.png"
;
import
dotIcon
from
"./assets/images/info2-icon.png"
;
import
dotIcon
from
"./assets/images/info2-icon.png"
;
import
entityIcon
from
"./assets/i
mages/icon-entity
.png"
;
import
entityIcon
from
"./assets/i
cons/icon-pd
.png"
;
import
comTitle
from
"./assets/images/panel1_1.png"
;
import
comTitle
from
"./assets/images/panel1_1.png"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
import
icon01
from
"./assets/i
mages/jianzhu
.png"
;
import
icon01
from
"./assets/i
cons/icon-sanction
.png"
;
import
{
import
{
getEntitiesDataInfo
,
getEntitiesDataInfo
,
getIndustryCountByYear
,
getIndustryCountByYear
,
getCountDomainByYear
,
getCountDomainByYear
,
getEntitiesList
,
//
getEntitiesList,
getSanctionProcess
,
getSanctionProcess
,
getSanDomainCount
,
getSanDomainCount
,
// getRiskSignal,
// getRiskSignal,
...
@@ -790,7 +831,8 @@ import {
...
@@ -790,7 +831,8 @@ import {
getSocialMediaInfo
,
getSocialMediaInfo
,
getReleaseCount
,
getReleaseCount
,
// getSanDomainCount,
// getSanDomainCount,
getAnnualSanDomain
getAnnualSanDomain
,
getEntitiesList
// getSanctionProcess
// getSanctionProcess
}
from
"@/api/finance"
;
}
from
"@/api/finance"
;
...
@@ -838,9 +880,10 @@ const handleToRiskSignalDetail = item => {
...
@@ -838,9 +880,10 @@ const handleToRiskSignalDetail = item => {
const
handleToMoreRiskSignal
=
()
=>
{
const
handleToMoreRiskSignal
=
()
=>
{
navigateToViewRiskSignal
(
router
);
navigateToViewRiskSignal
(
router
);
};
};
const
sancLoading
=
ref
(
false
);
const
sanctionList
=
ref
([]);
const
sanctionList
=
ref
([]);
const
filterDomain
=
ref
(
0
);
const
techOptions
=
[
const
techOptions
=
[
{
label
:
"全部领域"
,
value
:
0
},
{
label
:
"全部领域"
,
value
:
0
},
{
label
:
"人工智能"
,
value
:
1
},
{
label
:
"人工智能"
,
value
:
1
},
...
@@ -858,34 +901,16 @@ const techOptions = [
...
@@ -858,34 +901,16 @@ const techOptions = [
{
label
:
"太空"
,
value
:
13
},
{
label
:
"太空"
,
value
:
13
},
{
label
:
"核"
,
value
:
14
}
{
label
:
"核"
,
value
:
14
}
];
];
const
timeOptions
=
[
const
customDateRange
=
ref
(
""
);
"全部时间"
,
const
timeOptions
=
ref
([
"2025年"
,
{
label
:
"全部时间"
,
value
:
"all"
,
checked
:
true
},
"2024年"
,
{
label
:
"2026年"
,
value
:
"2026"
,
checked
:
false
},
"2023年"
,
{
label
:
"2025年"
,
value
:
"2025"
,
checked
:
false
},
"2022年"
,
{
label
:
"2024年"
,
value
:
"2024"
,
checked
:
false
},
"2021年"
,
{
label
:
"2023年"
,
value
:
"2023"
,
checked
:
false
},
"2020年"
,
{
label
:
"2022年"
,
value
:
"2022"
,
checked
:
false
},
"2019年"
,
{
label
:
"自定义"
,
value
:
"custom"
,
checked
:
false
}
"2018年"
,
]);
"2017年"
,
"2016年"
,
"2015年"
,
"2014年"
,
"2013年"
,
"2012年"
,
"2011年"
,
"2010年"
,
"2009年"
,
"2008年"
,
"2007年"
,
"2006年"
,
"2005年"
,
"2004年"
,
"2003年"
,
"2002年"
,
"2001年"
];
const
checkedTech
=
ref
([
0
]);
const
checkedTech
=
ref
([
0
]);
const
checkedTime
=
ref
([
"全部时间"
]);
const
checkedTime
=
ref
([
"全部时间"
]);
...
@@ -905,7 +930,7 @@ const handleTitleClick = item => {
...
@@ -905,7 +930,7 @@ const handleTitleClick = item => {
const
handleCompClick
=
item
=>
{
const
handleCompClick
=
item
=>
{
// console.log("item", item);
// console.log("item", item);
// if (item.entityType != 2
) return;
if
(
!
item
.
entityId
)
return
;
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
gotoCompanyPages
(
item
.
entityId
);
gotoCompanyPages
(
item
.
entityId
);
// const route = router.resolve({
// const route = router.resolve({
...
@@ -960,6 +985,7 @@ const commerceControlListReleaseFreq = ref([]);
...
@@ -960,6 +985,7 @@ const commerceControlListReleaseFreq = ref([]);
// 历次制裁过程
// 历次制裁过程
const
sanctionProcessList
=
ref
([]);
const
sanctionProcessList
=
ref
([]);
const
sanctionPage
=
ref
(
1
);
const
sanctionPage
=
ref
(
1
);
const
totalNum
=
ref
(
0
);
// 制裁实体清单
// 制裁实体清单
const
entitiesList
=
ref
([]);
const
entitiesList
=
ref
([]);
// 风险信号
// 风险信号
...
@@ -990,7 +1016,8 @@ const fetchTrendData = async () => {
...
@@ -990,7 +1016,8 @@ const fetchTrendData = async () => {
});
});
if
(
res
&&
res
[
0
]
&&
res
[
0
].
yearDomainCount
)
{
if
(
res
&&
res
[
0
]
&&
res
[
0
].
yearDomainCount
)
{
trendOption
.
value
=
processYearDomainCountData
(
res
[
0
].
yearDomainCount
);
trendOption
.
value
=
processYearDomainCountData
(
res
[
0
].
yearDomainCount
);
trendChart
.
interpret
({
type
:
"柱状图"
,
name
:
"制裁清单数量增长趋势"
,
data
:
res
[
0
].
yearDomainCount
});
trendChartData
.
value
=
res
[
0
].
yearDomainCount
;
// trendChart.interpret({ type: "柱状图", name: "制裁清单数量增长趋势", data: res[0].yearDomainCount });
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
"获取趋势图数据失败:"
,
error
);
console
.
error
(
"获取趋势图数据失败:"
,
error
);
...
@@ -1044,8 +1071,9 @@ const processYearDomainCountData = yearDomainCountData => {
...
@@ -1044,8 +1071,9 @@ const processYearDomainCountData = yearDomainCountData => {
const
handleEntityClick
=
item
=>
{
const
handleEntityClick
=
item
=>
{
console
.
log
(
"item"
,
item
);
console
.
log
(
"item"
,
item
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
||
item
.
entityNameZh
);
if
(
!
item
.
id
)
return
;
gotoCompanyPages
(
item
.
entityId
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
orgName
||
item
.
orgNameZh
);
gotoCompanyPages
(
item
.
id
);
// const route = router.resolve({
// const route = router.resolve({
// name: "companyPages",
// name: "companyPages",
// params: {
// params: {
...
@@ -1312,18 +1340,85 @@ const currentPageAll = ref(1);
...
@@ -1312,18 +1340,85 @@ const currentPageAll = ref(1);
const
pageSizeAll
=
ref
(
10
);
const
pageSizeAll
=
ref
(
10
);
const
totalAll
=
ref
(
0
);
const
totalAll
=
ref
(
0
);
// 筛选逻辑处理
const
handleFilterChange
=
(
item
,
list
,
type
)
=>
{
debugger
;
// 如果点击的是"全部"
if
(
item
.
value
===
"all"
)
{
if
(
item
.
checked
)
{
// 选中全部,取消其他所有
list
.
forEach
(
i
=>
{
if
(
i
.
value
!==
"all"
)
i
.
checked
=
false
;
});
}
else
{
// 取消全部(通常不允许全部取消,至少得选一个,这里如果取消全部,就默认为全部选中)
item
.
checked
=
true
;
}
}
else
{
// 点击的是具体项
if
(
item
.
checked
)
{
// 选中具体项,取消"全部"
const
allItem
=
list
.
find
(
i
=>
i
.
value
===
"all"
);
if
(
allItem
)
allItem
.
checked
=
false
;
// 特殊处理制裁时间的自定义和其他年份互斥
if
(
type
===
"time"
)
{
if
(
item
.
value
===
"custom"
)
{
list
.
forEach
(
i
=>
{
if
(
i
.
value
!==
"custom"
&&
i
.
value
!==
"all"
)
i
.
checked
=
false
;
});
}
else
{
const
customItem
=
list
.
find
(
i
=>
i
.
value
===
"custom"
);
if
(
customItem
)
customItem
.
checked
=
false
;
}
}
}
else
{
// 取消具体项,检查是否还有选中的
const
anyChecked
=
list
.
some
(
i
=>
i
.
checked
);
if
(
!
anyChecked
)
{
const
allItem
=
list
.
find
(
i
=>
i
.
value
===
"all"
);
if
(
allItem
)
allItem
.
checked
=
true
;
}
}
}
// 重置页码并查询
currentPageAll
.
value
=
1
;
fetchSanctionList
();
};
watch
(
customDateRange
,
()
=>
{
if
(
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"custom"
&&
item
.
checked
))
{
currentPageAll
.
value
=
1
;
fetchSanctionList
();
}
});
const
fetchSanctionList
=
async
()
=>
{
const
fetchSanctionList
=
async
()
=>
{
try
{
try
{
const
techDomains
=
checkedTech
.
value
.
includes
(
0
)
?
null
:
checkedTech
.
value
.
map
(
String
);
const
techDomains
=
checkedTech
.
value
.
includes
(
0
)
?
null
:
checkedTech
.
value
.
map
(
String
);
let
years
=
null
;
let
years
=
null
;
if
(
!
checkedTime
.
value
.
includes
(
"全部时间"
))
{
let
startDate
=
undefined
;
years
=
checkedTime
.
value
let
endDate
=
undefined
;
.
map
(
t
=>
{
const
allTime
=
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"all"
);
const
match
=
t
.
match
(
/
(\d{4})
/
);
console
.
log
(
"allTime"
,
allTime
);
return
match
?
parseInt
(
match
[
1
])
:
null
;
if
(
!
allTime
||
!
allTime
.
checked
)
{
})
years
=
timeOptions
.
value
.
filter
(
y
=>
y
!==
null
);
.
filter
(
item
=>
item
.
checked
&&
item
.
value
!==
"all"
&&
item
.
value
!==
"custom"
)
if
(
years
.
length
===
0
)
years
=
null
;
.
map
(
item
=>
Number
(
item
.
value
));
const
customTime
=
timeOptions
.
value
.
find
(
item
=>
item
.
value
===
"custom"
);
if
(
customTime
&&
customTime
.
checked
&&
customDateRange
.
value
&&
customDateRange
.
value
.
length
===
2
)
{
const
start
=
new
Date
(
customDateRange
.
value
[
0
]);
const
end
=
new
Date
(
customDateRange
.
value
[
1
]);
startDate
=
`
${
start
.
getFullYear
()}
-
${
String
(
start
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
)}
-
${
String
(
start
.
getDate
()
).
padStart
(
2
,
"0"
)}
`
;
endDate
=
`
${
end
.
getFullYear
()}
-
${
String
(
end
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
)}
-
${
String
(
end
.
getDate
()).
padStart
(
2
,
"0"
)}
`
;
}
}
}
const
params
=
{
const
params
=
{
...
@@ -1333,7 +1428,9 @@ const fetchSanctionList = async () => {
...
@@ -1333,7 +1428,9 @@ const fetchSanctionList = async () => {
years
:
years
,
years
:
years
,
isCn
:
false
,
isCn
:
false
,
// typeName: "实体清单"
// typeName: "实体清单"
sanTypeIds
:
allSanTypeIds
.
value
sanTypeIds
:
allSanTypeIds
.
value
,
startDate
:
startDate
,
endDate
:
endDate
};
};
const
res
=
await
getExportControlList
(
params
);
const
res
=
await
getExportControlList
(
params
);
...
@@ -1439,12 +1536,66 @@ watch(
...
@@ -1439,12 +1536,66 @@ watch(
},
},
{
deep
:
true
}
{
deep
:
true
}
);
);
const
timeSelectOptions
=
[
{
label
:
"全部时间"
,
value
:
"all"
},
{
label
:
"2026年"
,
value
:
"2026"
},
{
label
:
"2025年"
,
value
:
"2025"
},
{
label
:
"2024年"
,
value
:
"2024"
},
{
label
:
"2023年"
,
value
:
"2023"
},
{
label
:
"2022年"
,
value
:
"2022"
}
];
const
searchKeyword
=
ref
(
""
);
const
sortOrder
=
ref
(
"desc"
);
const
entityType
=
ref
(
"all"
);
const
year
=
ref
(
"all"
);
const
entityTypes
=
ref
([
{
label
:
"全部类型"
,
value
:
"all"
},
{
label
:
"科研院校"
,
value
:
"2"
},
{
label
:
"高校"
,
value
:
"3"
},
{
label
:
"企业"
,
value
:
"4"
}
]);
const
handleEntitySearch
=
val
=>
{
console
.
log
(
"关键词"
,
val
);
// searchKeyword.value = val;
fetchEntitiesList
(
1
,
10
);
};
const
handleTimePx
=
val
=>
{
console
.
log
(
"val"
,
val
);
sortOrder
.
value
=
val
==
1
?
"desc"
:
"asc"
;
fetchEntitiesList
(
1
,
10
);
};
const
handleTimeChange
=
val
=>
{
console
.
log
(
val
);
fetchEntitiesList
(
1
,
10
);
};
const
handleEntityTypeChange
=
val
=>
{
console
.
log
(
val
);
fetchEntitiesList
(
1
,
10
);
};
const
handleFilterDomainChange
=
val
=>
{
console
.
log
(
"val"
,
val
);
fetchEntitiesList
(
1
,
10
);
};
// 获取实体清单数据
// 获取实体清单数据
const
fetchEntitiesList
=
async
(
page
=
1
,
size
=
10
)
=>
{
const
fetchEntitiesList
=
async
(
page
=
1
,
size
=
10
)
=>
{
try
{
try
{
console
.
log
(
"activeResourceTabItem.value.id"
,
activeResourceTabItem
.
value
.
id
);
console
.
log
(
"activeResourceTabItem.value.id"
,
activeResourceTabItem
.
value
.
id
);
const
res
=
await
getEntitiesList
(
activeResourceTabItem
.
value
.
id
.
join
(
","
),
page
,
size
);
const
params
=
{
keyword
:
searchKeyword
.
value
,
sortOrder
:
sortOrder
.
value
,
entityTypes
:
entityType
.
value
==
"all"
?
[]
:
[
entityType
.
value
],
techDomains
:
filterDomain
.
value
==
0
?
[]
:
[
filterDomain
.
value
],
sanTypeId
:
activeResourceTabItem
.
value
.
id
.
join
(
","
),
pageNum
:
page
,
pageSize
:
size
,
sanctionDate
:
""
,
isCn
:
false
};
const
res
=
await
getEntitiesList
(
params
);
if
(
res
)
{
if
(
res
)
{
entitiesList
.
value
=
res
.
content
.
map
(
item
=>
({
entitiesList
.
value
=
res
.
content
.
map
(
item
=>
({
...
item
,
...
item
,
...
@@ -1461,6 +1612,13 @@ const fetchEntitiesList = async (page = 1, size = 10) => {
...
@@ -1461,6 +1612,13 @@ const fetchEntitiesList = async (page = 1, size = 10) => {
}
}
};
};
const
listPageSize
=
ref
(
5
);
const
handleListPageChange
=
async
page
=>
{
console
.
log
(
"页面修改 =>"
,
page
);
sanctionPage
.
value
=
page
;
fetchSanctionProcess
(
page
,
listPageSize
.
value
);
};
const
handleGetMore
=
async
()
=>
{
const
handleGetMore
=
async
()
=>
{
sanctionPage
.
value
++
;
sanctionPage
.
value
++
;
try
{
try
{
...
@@ -1488,7 +1646,7 @@ const handleGetMore = async () => {
...
@@ -1488,7 +1646,7 @@ const handleGetMore = async () => {
};
};
// 获取历次制裁过程数据
// 获取历次制裁过程数据
const
fetchSanctionProcess
=
async
(
page
=
1
,
size
=
10
)
=>
{
const
fetchSanctionProcess
=
async
(
page
=
1
,
size
=
listPageSize
.
value
)
=>
{
console
.
log
(
"制裁数据请求 =>"
);
console
.
log
(
"制裁数据请求 =>"
);
try
{
try
{
const
res
=
await
getSanctionProcess
(
const
res
=
await
getSanctionProcess
(
...
@@ -1506,6 +1664,7 @@ const fetchSanctionProcess = async (page = 1, size = 10) => {
...
@@ -1506,6 +1664,7 @@ const fetchSanctionProcess = async (page = 1, size = 10) => {
item
.
summary
||
item
.
summary
||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
}));
}));
totalNum
.
value
=
res
.
totalElements
;
}
}
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
err
);
console
.
error
(
err
);
...
@@ -1518,8 +1677,6 @@ const handlePageChange = page => {
...
@@ -1518,8 +1677,6 @@ const handlePageChange = page => {
fetchEntitiesList
(
page
,
pageSize
.
value
);
fetchEntitiesList
(
page
,
pageSize
.
value
);
};
};
const
searchKeyword
=
ref
(
""
);
// 资源库 Tab 数据
// 资源库 Tab 数据
const
resourceTabs
=
ref
([
const
resourceTabs
=
ref
([
// { label: "全部制裁", value: "all", disabled: false },
// { label: "全部制裁", value: "all", disabled: false },
...
@@ -1963,9 +2120,6 @@ const handleHideAiPane = key => {
...
@@ -1963,9 +2120,6 @@ const handleHideAiPane = key => {
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
console
.
log
(
"finance 页面 mounted"
);
console
.
log
(
"finance 页面 mounted"
);
try
{
try
{
// 获取趋势图数据
fetchTrendData
();
fetchRiskSignals
(
"0109"
);
fetchRiskSignals
(
"0109"
);
// 获取社交媒体信息
// 获取社交媒体信息
fetchSocialMediaInfo
();
fetchSocialMediaInfo
();
...
@@ -1995,11 +2149,10 @@ onMounted(async () => {
...
@@ -1995,11 +2149,10 @@ onMounted(async () => {
resourceTabs
.
value
.
unshift
({
label
:
"全部制裁"
,
value
:
"all"
,
id
:
allSanTypeIds
.
value
,
disabled
:
false
});
resourceTabs
.
value
.
unshift
({
label
:
"全部制裁"
,
value
:
"all"
,
id
:
allSanTypeIds
.
value
,
disabled
:
false
});
activeResourceTabItem
.
value
=
resourceTabs
.
value
[
0
];
activeResourceTabItem
.
value
=
resourceTabs
.
value
[
0
];
console
.
log
(
"返回的数据结构 infoList =》"
,
infoList
.
value
);
console
.
log
(
"返回的数据结构 infoList =》"
,
infoList
.
value
);
console
.
log
(
"返回的数据结构 resourceTabs =》"
,
resourceTabs
.
value
);
console
.
log
(
"返回的数据结构 entitiesDataInfo =》"
,
entitiesDataInfo
);
const
entityList
=
_
.
map
(
entitiesDataInfo
?.
sanEntities
??
[],
({
entityNameZh
,
entityName
})
=>
{
return
{
name
:
entityNameZh
,
enName
:
entityName
};
});
entitiesDataInfoList
.
value
=
entitiesDataInfo
||
[];
entitiesDataInfoList
.
value
=
entitiesDataInfo
||
[];
console
.
log
(
"返回的数据结构 entitiesDataInfoList =》"
,
entitiesDataInfoList
.
value
);
const
list
=
_
.
chain
(
industryCountByYear
).
filter
(
"year"
).
orderBy
(
"year"
,
"desc"
).
value
().
slice
(
0
,
5
);
const
list
=
_
.
chain
(
industryCountByYear
).
filter
(
"year"
).
orderBy
(
"year"
,
"desc"
).
value
().
slice
(
0
,
5
);
const
cclList1
=
_
.
chain
(
cclList
).
filter
(
"year"
).
orderBy
(
"year"
,
"desc"
).
value
().
slice
(
0
,
5
);
const
cclList1
=
_
.
chain
(
cclList
).
filter
(
"year"
).
orderBy
(
"year"
,
"desc"
).
value
().
slice
(
0
,
5
);
const
total
=
_
.
sumBy
(
list
,
"count"
);
const
total
=
_
.
sumBy
(
list
,
"count"
);
...
@@ -2022,6 +2175,8 @@ onMounted(async () => {
...
@@ -2022,6 +2175,8 @@ onMounted(async () => {
await
fetchRadarData
(
domainChecked
.
value
);
await
fetchRadarData
(
domainChecked
.
value
);
// 获取出口管制制裁措施
// 获取出口管制制裁措施
await
fetchSanctionList
();
await
fetchSanctionList
();
// 获取趋势图数据
fetchTrendData
();
entityListReleaseFreqChartData
.
value
=
entityListReleaseFreq
.
value
;
entityListReleaseFreqChartData
.
value
=
entityListReleaseFreq
.
value
;
// entityListReleaseFreqChart.interpret({
// entityListReleaseFreqChart.interpret({
// type: "柱状图",
// type: "柱状图",
...
@@ -2464,7 +2619,7 @@ const handleMediaClick = item => {
...
@@ -2464,7 +2619,7 @@ const handleMediaClick = item => {
}
}
.box4
{
.box4
{
height
:
786
px
;
// min-height: 980
px;
overflow
:
auto
;
overflow
:
auto
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
...
@@ -2504,18 +2659,27 @@ const handleMediaClick = item => {
...
@@ -2504,18 +2659,27 @@ const handleMediaClick = item => {
.box4-item-right-header
{
.box4-item-right-header
{
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
center
;
//
align-items: center;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
position
:
relative
;
position
:
relative
;
top
:
-7
.5px
;
top
:
-7
.5px
;
padding-bottom
:
8px
;
padding-bottom
:
8px
;
cursor
:
pointer
;
cursor
:
pointer
;
&
-top
{
display
:
flex
;
justify-content
:
space-between
;
margin-bottom
:
5px
;
}
&
-title
{
&
-title
{
font-size
:
18px
;
font-size
:
18px
;
color
:
$base-color
;
color
:
$base-color
;
font-weight
:
700
;
font-weight
:
700
;
&
:hover
{
text-decoration
:
underline
;
background
:
var
(
--
color-primary-2
);
}
}
}
&
-desc
{
&
-desc
{
...
@@ -2540,8 +2704,6 @@ const handleMediaClick = item => {
...
@@ -2540,8 +2704,6 @@ const handleMediaClick = item => {
}
}
.box4-footer
{
.box4-footer
{
position
:
absolute
;
// margin-top: auto;
display
:
flex
;
display
:
flex
;
justify-content
:
center
;
justify-content
:
center
;
align-items
:
center
;
align-items
:
center
;
...
@@ -2553,11 +2715,51 @@ const handleMediaClick = item => {
...
@@ -2553,11 +2715,51 @@ const handleMediaClick = item => {
}
}
.box5
{
.box5
{
height
:
1
15
%
;
height
:
1
20
%
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
center
;
align-items
:
center
;
.filter
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
height
:
50px
;
gap
:
20px
;
width
:
100%
;
.search-input
{
width
:
180px
;
height
:
32px
;
:deep
(
.el-input__wrapper
)
{
padding
:
0
11px
;
border
:
1px
solid
rgba
(
170
,
173
,
177
,
1
);
background-color
:
#fff
;
border-radius
:
3px
;
border
:
1px
solid
#ddd
;
border-radius
:
4px
;
height
:
32px
;
}
:deep
(
.el-input__inner
)
{
font-size
:
14px
;
font-weight
:
400
;
font-family
:
"Microsoft YaHei"
;
line-height
:
24px
;
color
:
rgb
(
95
,
101
,
108
);
}
}
.filter-right
{
display
:
flex
;
align-items
:
center
;
gap
:
15px
;
// width: 100%;
// margin-left: auto;
.filter-select
{
width
:
150px
;
}
}
}
}
}
:deep
(
.table-header
)
{
:deep
(
.table-header
)
{
...
@@ -3561,6 +3763,47 @@ const handleMediaClick = item => {
...
@@ -3561,6 +3763,47 @@ const handleMediaClick = item => {
color
:
#666666
;
color
:
#666666
;
font-weight
:
400
;
font-weight
:
400
;
}
}
.custom-date-picker
{
width
:
100%
;
margin-top
:
8px
;
padding-right
:
24px
;
box-sizing
:
border-box
;
grid-column
:
1
/
-1
;
:deep
(
.el-date-editor
)
{
width
:
100%
;
height
:
32px
;
box-shadow
:
none
;
border
:
1px
solid
#dcdfe6
;
border-radius
:
4px
;
padding
:
0
10px
;
&
:hover
{
border-color
:
#c0c4cc
;
}
&
.is-active
{
border-color
:
#409eff
;
}
.el-range-input
{
font-size
:
14px
;
font-family
:
"Microsoft YaHei"
;
color
:
rgb
(
95
,
101
,
108
);
}
.el-range-separator
{
color
:
rgb
(
95
,
101
,
108
);
line-height
:
30px
;
}
.el-input__icon
{
line-height
:
32px
;
color
:
rgb
(
95
,
101
,
108
);
}
}
}
}
}
}
}
...
@@ -3571,7 +3814,19 @@ const handleMediaClick = item => {
...
@@ -3571,7 +3814,19 @@ const handleMediaClick = item => {
border-radius
:
4px
;
border-radius
:
4px
;
border-radius
:
10px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
display
:
flex
;
flex-direction
:
column
;
.right-main-box
{
flex
:
1
;
display
:
flex
;
justify-content
:
center
;
}
.right-main-wrapper
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
}
.right-title
{
.right-title
{
width
:
100%
;
width
:
100%
;
height
:
48px
;
height
:
48px
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论