Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
f78815c8
提交
f78815c8
authored
4月 22, 2026
作者:
yanpeng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
bugfix-3
上级
02ee47e1
显示空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
4419 行增加
和
325 行删除
+4419
-325
request.js
src/api/request.js
+26
-0
index.js
src/router/index.js
+2
-0
index-back.vue
src/views/exportControl/index-back.vue
+3864
-0
index.vue
src/views/exportControl/index.vue
+235
-75
index.vue
...ontrol/v2.0EntityList/components/dataStatistics/index.vue
+164
-136
index.vue
...omponents/sanctionsOverview/components/listPage/index.vue
+92
-29
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
没有找到文件。
src/api/request.js
浏览文件 @
f78815c8
...
@@ -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
浏览文件 @
f78815c8
...
@@ -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/exportControl/index-back.vue
0 → 100644
浏览文件 @
f78815c8
<
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
浏览文件 @
f78815c8
...
@@ -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>
<el-tooltip
<div
class=
"box4-item-right-header-bottom"
>
<span
class=
"box4-item-right-header-title"
>
{{
item
.
title
}}
</span>
</div>
</div>
<!--
<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,6 +611,8 @@
...
@@ -578,6 +611,8 @@
<img
:src=
"icon01"
alt=
""
/>
<img
:src=
"icon01"
alt=
""
/>
<div>
出口管制制裁措施
</div>
<div>
出口管制制裁措施
</div>
</div>
</div>
<div
class=
"right-main-box"
v-loading=
"sancLoading"
>
<div
class=
"right-main-wrapper"
v-if=
"sanctionList.length > 0"
>
<div
class=
"right-main"
>
<div
class=
"right-main"
>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"sanction-list"
v-for=
"item in sanctionList"
:key=
"item.id"
>
<div
class=
"time"
>
<div
class=
"time"
>
...
@@ -608,6 +643,9 @@
...
@@ -608,6 +643,9 @@
/>
/>
</div>
</div>
</div>
</div>
<el-empty
v-else
/>
</div>
</div>
</div>
</div>
</el-col>
</el-col>
</
template
>
</
template
>
...
@@ -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"
;
...
@@ -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
浏览文件 @
f78815c8
...
@@ -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/sanctionsOverview/components/listPage/index.vue
浏览文件 @
f78815c8
...
@@ -17,27 +17,47 @@
...
@@ -17,27 +17,47 @@
<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>
...
@@ -114,13 +134,20 @@
...
@@ -114,13 +134,20 @@
共
<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' }"
>
<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 +155,56 @@
...
@@ -128,30 +155,56 @@
<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=
"150"
>
<el-table-column
label=
"涉及领域"
min-width=
"150"
>
<
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>
</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 +212,26 @@
...
@@ -159,15 +212,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>
...
@@ -273,6 +337,7 @@ const entityTypes = ref([
...
@@ -273,6 +337,7 @@ 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
},
...
@@ -352,7 +417,7 @@ const getExportControlListApi = async () => {
...
@@ -352,7 +417,7 @@ const getExportControlListApi = async () => {
if
(
abortController
)
{
if
(
abortController
)
{
try
{
try
{
abortController
.
abort
();
abortController
.
abort
();
}
catch
{
}
}
catch
{}
}
}
abortController
=
new
AbortController
();
abortController
=
new
AbortController
();
isFetching
.
value
=
true
;
isFetching
.
value
=
true
;
...
@@ -468,26 +533,25 @@ watch(customDateRange, () => {
...
@@ -468,26 +533,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 +756,6 @@ const handlToDataLibrary1 = () => {
...
@@ -692,7 +756,6 @@ const handlToDataLibrary1 = () => {
.highlight
{
.highlight
{
color
:
#cd4246
;
color
:
#cd4246
;
margin
:
0
4px
;
margin
:
0
4px
;
}
}
}
}
...
...
src/views/exportControl/v2.0SingleSanction/components/dataStatistics/index.vue
浏览文件 @
f78815c8
...
@@ -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
浏览文件 @
f78815c8
...
@@ -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
浏览文件 @
f78815c8
...
@@ -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
===
"净利润"
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论