Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
c590eff1
提交
c590eff1
authored
4月 22, 2026
作者:
yanpeng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
bugfix-2
上级
dc88159f
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
859 行增加
和
366 行删除
+859
-366
index.js
src/router/index.js
+1
-1
ChartAiAnalysis.vue
src/views/exportControl/components/ChartAiAnalysis.vue
+128
-0
title.vue
src/views/exportControl/components/title.vue
+2
-2
index.vue
src/views/exportControl/index.vue
+165
-121
index.vue
...ol/v2.0SingleSanction/components/dataStatistics/index.vue
+234
-130
index.vue
...v2.0SingleSanction/components/sanctionsOverview/index.vue
+71
-34
index.vue
...ews/exportControl/v2.0SingleSanction/originPage/index.vue
+4
-4
title.vue
src/views/finance/components/title.vue
+2
-2
index.vue
src/views/finance/index.vue
+169
-31
index.vue
...nce/singleSanction/components/sanctionsOverview/index.vue
+78
-36
index.vue
src/views/finance/singleSanction/index.vue
+1
-1
index.vue
src/views/finance/singleSanction/originPage/index.vue
+4
-4
没有找到文件。
src/router/index.js
浏览文件 @
c590eff1
...
...
@@ -147,7 +147,7 @@ const router = createRouter({
// 2)登录成功回跳带 ?token=:先 setToken 并同步 bootId,再去掉 URL 中的 token(须先于 clearTokenIfNewDevBoot,避免误清刚写入的登录态)
// 3)已有本地 token:正常走前端路由
router
.
beforeEach
((
to
,
from
,
next
)
=>
{
//
【新增】
在每次路由跳转开始前,取消上一个页面所有未完成的请求
// 在每次路由跳转开始前,取消上一个页面所有未完成的请求
// 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力
cancelAllRequests
();
if
(
import
.
meta
.
env
.
DEV
)
{
...
...
src/views/exportControl/components/ChartAiAnalysis.vue
0 → 100644
浏览文件 @
c590eff1
<
template
>
<div
class=
"chart-ai-analysis"
@
mouseenter=
"handleMouseEnter"
@
mouseleave=
"handleMouseLeave"
>
<!-- 触发按钮 -->
<div
class=
"ai-button-wrapper"
>
<AiButton
/>
</div>
<!-- AI 内容面板 -->
<transition
name=
"ai-fade"
>
<div
v-if=
"isVisible"
class=
"ai-pane-wrapper"
>
<div
class=
"ai-pane-content"
>
<!-- 1. Loading 状态 -->
<div
v-if=
"hookInstance.loading"
class=
"ai-loading-text"
>
智能总结生成中...
</div>
<!-- 2. 错误状态 -->
<div
v-else-if=
"hookInstance.error"
class=
"ai-error-text"
>
{{
hookInstance
.
error
}}
</div>
<!-- 3. 成功状态 -->
<div
v-else-if=
"hookInstance.interpretation"
class=
"ai-success-content"
>
<AiPane
:aiContent=
"hookInstance.interpretation"
/>
</div>
<!-- 4. 初始空状态 (可选,防止闪烁) -->
<div
v-else
class=
"ai-empty-text"
>
暂无数据
</div>
</div>
</div>
</transition>
</div>
</
template
>
<
script
setup
>
import
{
ref
}
from
"vue"
;
import
AiButton
from
"@/components/base/Ai/AiButton/index.vue"
;
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
const
props
=
defineProps
({
// 接收由 useChartInterpretation() 创建的实例对象
hookInstance
:
{
type
:
Object
,
required
:
true
},
// 图表数据 Payload,用于首次请求
payload
:
{
type
:
Object
,
required
:
true
}
});
const
isVisible
=
ref
(
false
);
const
hasRequested
=
ref
(
false
);
const
handleMouseEnter
=
()
=>
{
isVisible
.
value
=
true
;
// 如果还没有请求过数据,则发起请求
if
(
!
hasRequested
.
value
&&
!
props
.
hookInstance
.
loading
)
{
hasRequested
.
value
=
true
;
// 调用 Hook 中的 interpret 方法
props
.
hookInstance
.
interpret
(
props
.
payload
);
}
};
const
handleMouseLeave
=
()
=>
{
isVisible
.
value
=
false
;
};
</
script
>
<
style
lang=
"scss"
scoped
>
.chart-ai-analysis
{
position
:
absolute
;
right
:
0px
;
bottom
:
15px
;
z-index
:
999
;
width
:
auto
;
height
:
auto
;
.ai-button-wrapper
{
display
:
flex
;
justify-content
:
flex-end
;
}
.ai-pane-wrapper
{
position
:
absolute
;
bottom
:
0
;
right
:
0
;
width
:
100%
;
// 确保面板出现在按钮上方或覆盖区域,根据原有 CSS 调整
// 原有 .ai-pane:hover 逻辑是宽度变宽,这里我们直接显示完整面板
background
:
#fff
;
border-radius
:
4px
;
box-shadow
:
0
-2px
12px
rgba
(
0
,
0
,
0
,
0
.1
);
padding
:
10px
;
box-sizing
:
border-box
;
.ai-pane-content
{
min-height
:
40px
;
.ai-loading-text
,
.ai-error-text
,
.ai-empty-text
{
font-size
:
14px
;
color
:
var
(
--
text-primary-50-color
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
min-height
:
40px
;
}
.ai-error-text
{
color
:
var
(
--
color-red-100
);
}
}
}
}
// 复用原有的淡入淡出动画
.ai-fade-enter-active
,
.ai-fade-leave-active
{
transition
:
opacity
0
.3s
ease
;
}
.ai-fade-enter-from
,
.ai-fade-leave-to
{
opacity
:
0
;
}
</
style
>
src/views/exportControl/components/title.vue
浏览文件 @
c590eff1
...
...
@@ -43,8 +43,8 @@ defineProps({
.title-text
{
color
:
rgba
(
10
,
18
,
30
,
1
);
font-size
:
32px
;
font-family
:
$base-font-family
;
font-weight
:
bold
;
font-family
:
"Microsoft YaHei"
;
font-weight
:
700
;
margin-left
:
20px
;
white-space
:
nowrap
;
}
...
...
src/views/exportControl/index.vue
浏览文件 @
c590eff1
...
...
@@ -149,48 +149,6 @@
</custom-container>
</el-col>
<el-col
:span=
"8"
style=
"padding-right: 0px"
>
<!-- <custom-container
titleType="danger"
title="风险信号"
:headerNum="warningList.length"
:titleIcon="dangerIcon"
height="450px"
>
<template #default>
<div class="box2-main">
<div
class="box2-main-item"
v-for="(item, index) in warningList"
:key="index"
@click="handleToRiskSignalDetail"
>
<div
class="item-left"
:class="{
itemLeftStatus1: item.status === '一般风险',
itemLeftStatus2: item.status === '重大风险'
}"
>
{{ item.status }}
</div>
<div class="item-right">
<div class="text">
<CommonPrompt :content="item.title">
{{ item.title }}
</CommonPrompt>
</div>
<div class="time">{{ item.time }}</div>
</div>
</div>
<div class="box2-footer" @click="handleToMoreRiskSignal">
<div class="icon">
<img src="./assets/images/box2-footer-icon.png" alt="" />
</div>
<div class="text">{{ "查看更多" }}</div>
</div>
</div>
</template>
</custom-container> -->
<RiskSignal
:list=
"warningList"
@
item-click=
"handleToRiskSignalDetail"
...
...
@@ -205,21 +163,7 @@
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 50px; margin-top: 64px"
>
<CustomTitle
id=
"position2"
title=
"资讯要闻"
/>
</el-row>
<!-- <el-col :span="12">
<custom-container title="新闻资讯" :titleIcon="newsIcon" height="450px">
<template #header-right>
<el-button type="primary" link @click="handleToMoreNews">
{{ "更多 +" }}
</el-button>
</template>
<template #default>
<div class="news-list">
<NewsList :list-data="newsList" @item-click="item => handleNewsInfoClick(item)" />
</div>
</template>
</custom-container>
</el-col> -->
<div
class=
"center-center"
>
<NewsList
:newsList=
"newsList"
...
...
@@ -234,15 +178,6 @@
imageUrl=
"avatar"
@
more-click=
"handleToSocialDetail"
/>
<!-- <custom-container title="社交媒体" :titleIcon="dialogIcon" height="450px">
<template #default>
<div class="dialog-list">
<MessageBubble v-for="(item, index) in socialMediaList" @click="handlePerClick(item)"
@info-click="handleMediaClick(item)" :key="index" :avatar="item.avatar" :name="item.name"
:time="item.time" :source="item.source" :content="item.content" />
</div>
</template>
</custom-container> -->
</div>
<el-row
:gutter=
"16"
style=
"width: 1600px; margin: 0 auto; height: 510px; margin-top: 64px"
>
...
...
@@ -278,9 +213,6 @@
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<AreaTag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:tagName=
"tag"
/>
<!--
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
-->
</div>
</
template
>
</el-table-column>
...
...
@@ -289,11 +221,15 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
美国商务部发布实体清单的频次,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"entityListReleaseFreqChart.interpretation"
/>
<AiButton
@
mouseenter=
"handleShowAiPane('entityListReleaseFreqChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.entityListReleaseFreqChart"
:aiContent=
"overviewAiContent.entityListReleaseFreqChart"
@
mouseleave=
"handleHideAiPane('entityListReleaseFreqChart')"
/>
</div>
</div>
<div
class=
"box3-content"
>
...
...
@@ -323,9 +259,6 @@
style=
"display: flex; justify-content: center; align-items: center; gap: 5px"
>
<AreaTag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:tagName=
"tag"
/>
<!--
<el-tag
v-for=
"tag in scope.row.tags"
:key=
"tag"
:type=
"getTagType(tag)"
>
{{
tag
}}
</el-tag>
-->
</div>
</
template
>
</el-table-column>
...
...
@@ -334,13 +267,15 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
美国商务部发布商业管制清单的频次,数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"commerceControlListReleaseFreqChart.interpretation"
/>
<AiButton
@
mouseenter=
"handleShowAiPane('commerceControlListReleaseFreqChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.commerceControlListReleaseFreqChart"
:aiContent=
"overviewAiContent.commerceControlListReleaseFreqChart"
@
mouseleave=
"handleHideAiPane('commerceControlListReleaseFreqChart')"
/>
</div>
</div>
<div
class=
"box3-content"
style=
"display: none"
>
...
...
@@ -393,11 +328,11 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入实体清单的中国实体领域分布情况,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"
radarChart.interpretation
"
/>
<AiButton
@
mouseenter=
"handleShowAiPane('radarChart')"
/>
<AiPane
:aiContent=
"
overviewAiContent.radarChart"
@
mouseleave=
"handleHideAiPane('radarChart')
"
/>
</div>
</
template
>
</custom-container>
...
...
@@ -428,11 +363,15 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入实体清单的中国实体数量变化趋势,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"trendChart.interpretation"
/>
<AiButton
@
mouseenter=
"handleShowAiPane('trendChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.trendChart"
:aiContent=
"overviewAiContent.trendChart"
@
mouseleave=
"handleHideAiPane('trendChart')"
/>
</div>
</
template
>
</custom-container>
...
...
@@ -558,25 +497,6 @@
</
template
>
</el-table-column>
<!-- <el-table-column prop="strength" label="制裁强度" width="120" align="center">
<template #default="scope">
<div class="sanction-strength">
<div :class="['strength-bar', `strength-${scope.row.strength}`]"></div>
<span>{{ strengthLabels[scope.row.strength] }}</span>
</div>
</template>
</el-table-column> -->
<!-- <el-table-column prop="revenue" label="营收(亿元)" width="140" align="right">
<template #default="scope">
<span
:class="['revenue-cell', scope.row.revenue === '无营收数据' ? 'no-revenue' : '']"
>
{{ scope.row.revenue }}
</span>
</template>
</el-table-column> -->
<el-table-column
prop=
"revenue"
label=
"50%规则子企业"
width=
"280"
align=
"right"
>
<
template
#
default=
"scope"
>
<div
class=
"num-item"
v-if=
"scope.row.ruleOrgCount > 0"
>
...
...
@@ -729,24 +649,21 @@
//这是一个备注
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
*
as
echarts
from
"echarts"
;
import
setChart
from
"@/utils/setChart"
;
import
{
ElMessage
,
ElMessageBox
}
from
"element-plus"
;
import
listPage
from
"./v2.0CommercialControlList/components/sanctionsOverview/components/listPage/index.vue"
;
import
{
DArrowRight
,
Warning
,
Search
,
Message
}
from
"@element-plus/icons-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"
;
const
sanctionCountChart
=
useChartInterpretation
();
import
{
TAGTYPE
}
from
"@/public/constant"
;
import
{
useGotoCompanyPages
}
from
"@/router/modules/company"
;
import
{
useGotoNewsDetail
}
from
"@/router/modules/news"
;
...
...
@@ -1017,11 +934,12 @@ onMounted(async () => {
tags
:
item
.
domain
};
});
entityListReleaseFreqChart
.
interpret
({
type
:
"柱状图"
,
name
:
"美国商务部发布实体清单的频次"
,
data
:
entityListReleaseFreq
.
value
});
entityListReleaseFreqChartData
.
value
=
entityListReleaseFreq
.
value
;
// entityListReleaseFreqChart.interpret({
// type: "柱状图",
// name: "美国商务部发布实体清单的频次",
// data: entityListReleaseFreq.value
// });
commerceControlListReleaseFreq
.
value
=
_
.
map
(
cclList1
,
item
=>
{
return
{
year
:
item
.
year
,
...
...
@@ -1030,11 +948,12 @@ onMounted(async () => {
tags
:
item
.
domain
};
});
commerceControlListReleaseFreqChart
.
interpret
({
type
:
"柱状图"
,
name
:
"美国商务部发布商业管制清单的频次"
,
data
:
commerceControlListReleaseFreq
.
value
});
commerceControlListReleaseFreqChartData
.
value
=
commerceControlListReleaseFreq
.
value
;
// commerceControlListReleaseFreqChart.interpret({
// type: "柱状图",
// name: "美国商务部发布商业管制清单的频次",
// data: commerceControlListReleaseFreq.value
// });
// 获取趋势图数据
await
fetchTrendData
();
...
...
@@ -1075,13 +994,136 @@ const fetchTrendData = async () => {
});
if
(
res
&&
res
[
0
]
&&
res
[
0
].
yearDomainCount
)
{
trendOption
.
value
=
processYearDomainCountData
(
res
[
0
].
yearDomainCount
);
trendChart
.
interpret
({
type
:
"柱状图"
,
name
:
"制裁清单数量增长趋势"
,
data
:
res
[
0
].
yearDomainCount
});
trendChartData
.
value
=
res
[
0
].
yearDomainCount
;
// trendChart.interpret({ type: "柱状图", name: "制裁清单数量增长趋势", data: res[0].yearDomainCount });
}
}
catch
(
error
)
{
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
],
()
=>
{
...
...
@@ -1096,6 +1138,7 @@ const processYearDomainCountData = yearDomainCountData => {
// 提取所有领域名称
const
allDomains
=
[...
new
Set
(
yearDomainCountData
.
flatMap
(
item
=>
item
.
domainCountInfo
.
map
(
domain
=>
domain
.
name
)))];
console
.
log
(
"不同领域的数据 =>"
,
allDomains
);
// 构造 getMultipleBarChart_m 所需的数据结构
const
chartData
=
{
...
...
@@ -1122,7 +1165,7 @@ const processYearDomainCountData = yearDomainCountData => {
};
})
};
console
.
log
(
"不同领域的数据 chartData"
,
chartData
);
// 使用 getMultipleBarChart_m 生成图表配置
return
getMultipleBarChart_m
(
chartData
);
};
...
...
@@ -1349,7 +1392,8 @@ const fetchRadarData = async checked => {
}
};
});
radarChart
.
interpret
({
type
:
"雷达图"
,
name
:
"实体清单领域分布情况"
,
data
:
data
});
radarChartData
.
value
=
data
;
// radarChart.interpret({ type: "雷达图", name: "实体清单领域分布情况", data: data });
}
}
catch
(
error
)
{
console
.
error
(
"获取雷达图数据失败:"
,
error
);
...
...
src/views/exportControl/v2.0SingleSanction/components/dataStatistics/index.vue
浏览文件 @
c590eff1
...
...
@@ -26,7 +26,7 @@
</div>
</div>
</div>
<div
class=
"nav-item"
@
click=
"handleToDataLibrary2"
>
<div
class=
"nav-item"
@
click=
"handleToDataLibrary2"
>
<div
class=
"item-position"
></div>
<div
class=
"content"
>
<div
class=
"info"
>
...
...
@@ -54,107 +54,94 @@
</div>
</div>
</div>
-->
<EChart
:option=
"domainChartOption"
autoresize
:style=
"
{ height: '300px', padding: '0 20px' }"
@chart-click="handleToDataLibrary3" />
<EChart
:option=
"domainChartOption"
autoresize
:style=
"
{ height: '300px', padding: '0 20px' }"
@chart-click="handleToDataLibrary3"
/>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入本次实体清单的中国实体领域分布情况,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"domainChart.interpretation"
/>
<!--
<AiButton
/>
<AiPane
:aiContent=
"domainChart.interpretation"
/>
-->
<AiButton
@
mouseenter=
"handleShowAiPane('domainChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.domainChart"
:aiContent=
"overviewAiContent.domainChart"
@
mouseleave=
"handleHideAiPane('domainChart')"
/>
</div>
</AnalysisBox>
</div>
<div
class=
"main-item"
>
<!--
<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=
"echarts"
ref=
"typeChartRef"
></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>
-->
<AnalysisBox
title=
"制裁实体类型分布情况"
>
<!--
<div
class=
"echarts"
ref=
"typeChartRef"
></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>
-->
<EChart
:option=
"typeChartOption"
autoresize
:style=
"
{ height: '300px', padding: '0 20px' }"
@chart-click="handleToDataLibrary4" />
<EChart
:option=
"typeChartOption"
autoresize
:style=
"
{ height: '300px', padding: '0 20px' }"
@chart-click="handleToDataLibrary4"
/>
<div
class=
"data-origin-box"
>
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入本次实体清单的中国实体类型分布情况,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"typeChart.interpretation"
/>
<!--
<AiButton
/>
<AiPane
:aiContent=
"typeChart.interpretation"
/>
-->
<AiButton
@
mouseenter=
"handleShowAiPane('typeChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.typeChart"
:aiContent=
"overviewAiContent.typeChart"
@
mouseleave=
"handleHideAiPane('typeChart')"
/>
</div>
</AnalysisBox>
</div>
<div
class=
"main-item"
>
<AnalysisBox
title=
"制裁实体国家地区分布情况"
>
<div
class=
"country-list"
>
<div
class=
"list-item"
v-for=
"(item, index) in countryDistribution"
:key=
"index"
@
click=
"handleToDataLibrary5(item)"
>
<div
class=
"list-item"
v-for=
"(item, index) in countryDistribution"
:key=
"index"
@
click=
"handleToDataLibrary5(item)"
>
<img
:src=
"flag"
alt=
""
class=
"flag"
/>
<div
class=
"country-name"
>
{{
item
.
name
}}
</div>
<div
class=
"progress-bar-container"
>
<div
class=
"progress-bar"
:style=
"
{
width: item.width,
background: item.gradient
}">
</div>
<div
class=
"progress-bar"
:style=
"
{
width: item.width,
background: item.gradient
}"
>
</div>
</div>
<div
class=
"count"
:class=
"
{ highlight: index === 0 }">
{{
item
.
count
}}
家
</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-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入本次实体清单的实体国家地区分布情况,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"countryDistributionChart.interpretation"
/>
<!--
<AiButton
/>
<AiPane
:aiContent=
"countryDistributionChart.interpretation"
/>
-->
<AiButton
@
mouseenter=
"handleShowAiPane('countryDistributionChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.countryDistributionChart"
:aiContent=
"overviewAiContent.countryDistributionChart"
@
mouseleave=
"handleHideAiPane('countryDistributionChart')"
/>
</div>
</AnalysisBox>
</div>
...
...
@@ -163,40 +150,42 @@
<div
class=
"map-wrapper"
>
<div
class=
"map-chart"
ref=
"mapChartRef"
></div>
<div
class=
"rank-list"
>
<div
class=
"rank-item"
v-for=
"(item, index) in regionDistribution"
:key=
"index"
@
click=
"handleToDataLibrary6(item)"
>
<div
class=
"rank-item"
v-for=
"(item, index) in regionDistribution"
:key=
"index"
@
click=
"handleToDataLibrary6(item)"
>
<div
class=
"rank-index"
:class=
"'rank-' + (index + 1)"
>
{{
index
+
1
}}
</div>
<div
class=
"rank-name"
>
{{
item
.
name
}}
</div>
<div
class=
"rank-bar-bg"
>
<div
class=
"rank-bar-fill"
:style=
"
{
width: (maxRegionCount > 0 ? (item.count / maxRegionCount) * 100 : 0) + '%',
background: getBarColor(index)
}">
</div>
<div
class=
"rank-bar-fill"
:style=
"
{
width: (maxRegionCount > 0 ? (item.count / maxRegionCount) * 100 : 0) + '%',
background: getBarColor(index)
}"
>
</div>
</div>
<div
class=
"rank-value"
>
{{
item
.
count
}}
家
</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-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入本次实体清单的中国实体各省分布情况,
数据来源:美国商务部官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国商务部官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"regionDistributionChart.interpretation"
/>
<!--
<AiButton
/>
<AiPane
:aiContent=
"regionDistributionChart.interpretation"
/>
-->
<AiButton
@
mouseenter=
"handleShowAiPane('regionDistributionChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.regionDistributionChart"
:aiContent=
"overviewAiContent.regionDistributionChart"
@
mouseleave=
"handleHideAiPane('regionDistributionChart')"
/>
</div>
</AnalysisBox>
</div>
...
...
@@ -223,9 +212,9 @@ import {
getSingleSanctionEntityCountryCount
,
getSingleSanctionEntityRegionCount
}
from
"@/api/exportControlV2.0"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis/index"
;
import
{
useChartInterpretation
}
from
"@/views/exportControl/utils/common"
;
const
sanctionCountChart
=
useChartInterpretation
();
const
domainChart
=
useChartInterpretation
();
const
typeChart
=
useChartInterpretation
();
const
countryDistributionChart
=
useChartInterpretation
();
...
...
@@ -248,8 +237,9 @@ const getRegionData = async () => {
if
(
res
.
code
===
200
)
{
regionDistribution
.
value
=
res
.
data
||
[];
maxRegionCount
.
value
=
Math
.
max
(...
regionDistribution
.
value
.
map
(
item
=>
item
.
count
),
0
);
regionDistributionChartData
.
value
=
res
.
data
||
[];
initMapChart
();
regionDistributionChart
.
interpret
({
type
:
"柱状图"
,
name
:
"进入本次实体清单的中国实体各省分布情况"
,
data
:
res
.
data
});
//
regionDistributionChart.interpret({ type: "柱状图", name: "进入本次实体清单的中国实体各省分布情况", data: res.data });
}
}
catch
(
error
)
{
console
.
log
(
error
);
...
...
@@ -289,11 +279,12 @@ const getCountryCount = async () => {
gradient
};
});
countryDistributionChart
.
interpret
({
type
:
"柱状图"
,
name
:
"进入本次实体清单的实体国家地区分布情况"
,
data
:
res
.
data
});
countryDistributionChartData
.
value
=
res
.
data
||
[];
// countryDistributionChart.interpret({
// type: "柱状图",
// name: "进入本次实体清单的实体国家地区分布情况",
// data: res.data
// });
}
}
catch
(
error
)
{
console
.
log
(
error
);
...
...
@@ -314,7 +305,7 @@ const getEntityTypeCount = async () => {
const
res
=
await
getSingleSanctionEntityTypeCount
(
params
);
if
(
res
.
code
===
200
)
{
entityTypeCount
.
value
=
res
.
data
||
[];
typeChart
.
interpret
({
type
:
"饼图"
,
name
:
"进入本次实体清单的中国实体类型分布情况"
,
data
:
entityTypeCount
.
value
});
//
typeChart.interpret({ type: "饼图", name: "进入本次实体清单的中国实体类型分布情况", data: entityTypeCount.value });
initTypeChart
();
}
}
catch
(
error
)
{
...
...
@@ -337,7 +328,7 @@ const getDomainCount = async () => {
if
(
res
.
code
===
200
)
{
domainCount
.
value
=
res
.
data
||
[];
initDomainChart
();
domainChart
.
interpret
({
type
:
"饼图"
,
name
:
"进入本次实体清单的中国实体领域分布情况"
,
data
:
domainCount
.
value
});
//
domainChart.interpret({ type: "饼图", name: "进入本次实体清单的中国实体领域分布情况", data: domainCount.value });
}
}
catch
(
error
)
{
console
.
log
(
error
);
...
...
@@ -351,7 +342,7 @@ const getTotalCount = async () => {
if
(
!
sanRecordId
.
value
)
return
;
try
{
const
res
=
await
getSingleSanctionTotalCount
(
route
.
query
.
sanTypeId
,
sanRecordId
.
value
);
console
.
log
(
'统计'
,
res
);
console
.
log
(
"统计"
,
res
);
if
(
res
.
code
===
200
)
{
totalCount
.
value
=
res
.
data
||
{};
...
...
@@ -389,14 +380,6 @@ for (let i = 2025; i >= 2000; i--) {
timeOptions
.
push
({
label
:
`
${
i
}
年`
,
value
:
`
${
i
}
`
});
}
// const countryDistribution = [
// { name: "中国", count: 24, width: "80%", gradient: "linear-gradient(90deg, rgba(205, 66, 70, 0) 0%, rgba(205, 66, 70, 1) 100%)" },
// { name: "沙特阿拉伯", count: 2, width: "60%", gradient: "linear-gradient(90deg, rgba(255, 172, 77, 0) 0%, rgba(255, 172, 77, 1) 100%)" },
// { name: "伊朗", count: 2, width: "60%", gradient: "linear-gradient(90deg, rgba(255, 172, 77, 0) 0%, rgba(255, 172, 77, 1) 100%)" },
// { name: "俄罗斯", count: 2, width: "55%", gradient: "linear-gradient(90deg, rgba(255, 172, 77, 0) 0%, rgba(255, 172, 77, 1) 100%)" },
// { name: "中国香港", count: 1, width: "40%", gradient: "linear-gradient(90deg, rgba(5, 95, 194, 0) 0%, rgba(5, 95, 194, 1) 100%)" }
// ];
const
mapChartRef
=
ref
(
null
);
const
domainChartRef
=
ref
(
null
);
const
typeChartRef
=
ref
(
null
);
...
...
@@ -474,13 +457,13 @@ const initMapChart = () => {
chart
.
setOption
(
option
);
chart
.
on
(
'click'
,
function
(
params
)
{
chart
.
on
(
"click"
,
function
(
params
)
{
const
param
=
{
selectedProvince
:
params
.
name
,
selectedDate
:
JSON
.
stringify
([
route
.
query
.
date
,
route
.
query
.
date
])
}
}
;
const
curRoute
=
router
.
resolve
({
path
:
'/dataLibrary/dataEntityList'
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
param
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
...
...
@@ -855,67 +838,67 @@ const initTypeChart = () => {
const
sanTypeId
=
ref
(
""
);
// 制裁实体领域分布情况
const
handleToDataLibrary3
=
(
val
)
=>
{
const
handleToDataLibrary3
=
val
=>
{
// console.log('val', val);
const
params
=
{
domains
:
val
.
name
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
route
.
query
.
date
,
route
.
query
.
date
])
}
}
;
const
curRoute
=
router
.
resolve
({
path
:
'/dataLibrary/dataEntityList'
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
}
}
;
// 制裁实体类型分布情况
const
handleToDataLibrary4
=
(
val
)
=>
{
const
handleToDataLibrary4
=
val
=>
{
// console.log('val', val);
const
params
=
{
selectedEntityType
:
val
.
name
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
route
.
query
.
date
,
route
.
query
.
date
])
}
}
;
const
curRoute
=
router
.
resolve
({
path
:
'/dataLibrary/dataEntityList'
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
}
}
;
// 制裁实体国家地区分布情况
const
handleToDataLibrary5
=
(
item
)
=>
{
const
handleToDataLibrary5
=
item
=>
{
const
params
=
{
selectedCountryId
:
item
.
id
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
route
.
query
.
date
,
route
.
query
.
date
])
}
}
;
const
curRoute
=
router
.
resolve
({
path
:
'/dataLibrary/dataEntityList'
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
}
}
;
// 制裁实体各省分布情况
const
handleToDataLibrary6
=
(
item
)
=>
{
console
.
log
(
'item'
,
item
);
const
handleToDataLibrary6
=
item
=>
{
console
.
log
(
"item"
,
item
);
const
params
=
{
selectedProvince
:
item
.
name
,
isCnEntityOnly
:
true
,
selectedDate
:
JSON
.
stringify
([
route
.
query
.
date
,
route
.
query
.
date
])
}
}
;
const
curRoute
=
router
.
resolve
({
path
:
'/dataLibrary/dataEntityList'
,
path
:
"/dataLibrary/dataEntityList"
,
query
:
params
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
}
}
;
// 跳转到数据资源库
const
handleToDataLibrary
=
()
=>
{
const
dateStr
=
route
.
query
.
date
?
route
.
query
.
date
:
''
const
dateStr
=
route
.
query
.
date
?
route
.
query
.
date
:
""
;
const
curRoute
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
query
:
{
...
...
@@ -924,10 +907,10 @@ const handleToDataLibrary = () => {
}
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
}
}
;
const
handleToDataLibrary1
=
()
=>
{
const
dateStr
=
route
.
query
.
date
?
route
.
query
.
date
:
''
const
dateStr
=
route
.
query
.
date
?
route
.
query
.
date
:
""
;
const
curRoute
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
query
:
{
...
...
@@ -937,10 +920,10 @@ const handleToDataLibrary1 = () => {
}
});
window
.
open
(
curRoute
.
href
,
"_blank"
);
}
}
;
const
handleToDataLibrary2
=
()
=>
{
const
dateStr
=
route
.
query
.
date
?
route
.
query
.
date
:
''
const
dateStr
=
route
.
query
.
date
?
route
.
query
.
date
:
""
;
const
curRoute
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
query
:
{
...
...
@@ -949,8 +932,129 @@ const handleToDataLibrary2 = () => {
}
});
window
.
open
(
curRoute
.
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
domainChartData
=
ref
([]);
const
typeChartData
=
ref
([]);
const
countryDistributionChartData
=
ref
([]);
const
regionDistributionChartData
=
ref
([]);
const
aiPaneVisible
=
ref
({
domainChart
:
false
,
typeChart
:
false
,
countryDistributionChart
:
false
,
regionDistributionChart
:
false
});
const
overviewAiContent
=
ref
({
domainChart
:
"智能总结生成中..."
,
typeChart
:
"智能总结生成中..."
,
countryDistributionChart
:
"智能总结生成中..."
,
regionDistributionChart
:
"智能总结生成中..."
});
const
aiPaneFetched
=
ref
({
domainChart
:
false
,
typeChart
:
false
,
countryDistributionChart
:
false
,
regionDistributionChart
:
false
});
const
aiPaneLoading
=
ref
({
domainChart
:
false
,
typeChart
:
false
,
countryDistributionChart
:
false
,
regionDistributionChart
:
false
});
const
chartLoading
=
ref
({
domainChart
:
false
,
typeChart
:
false
,
countryDistributionChart
:
false
,
regionDistributionChart
:
false
});
const
buildAiChartPayload
=
key
=>
{
if
(
key
===
"domainChart"
)
{
return
{
type
:
"饼图"
,
name
:
"进入本次实体清单的中国实体领域分布情况"
,
data
:
domainCount
.
value
};
}
if
(
key
===
"typeChart"
)
{
return
{
type
:
"饼图"
,
name
:
"进入本次实体清单的中国实体类型分布情况"
,
data
:
entityTypeCount
.
value
};
}
if
(
key
===
"countryDistributionChart"
)
{
return
{
type
:
"柱状图"
,
name
:
"进入本次实体清单的实体国家地区分布情况"
,
data
:
countryDistributionChartData
.
value
};
}
if
(
key
===
"regionDistributionChart"
)
{
return
{
type
:
"柱状图"
,
name
:
"进入本次实体清单的中国实体各省分布情况"
,
data
:
regionDistributionChartData
.
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
(()
=>
{
// 获取路由参数id
...
...
src/views/exportControl/v2.0SingleSanction/components/sanctionsOverview/index.vue
浏览文件 @
c590eff1
...
...
@@ -8,7 +8,7 @@
<div
class=
"info-row"
>
<div
class=
"label"
>
发布机构:
</div>
<div
class=
"value link"
>
<img
:src=
"title"
alt=
""
class=
"icon"
/>
<img
:src=
"
formattedData.postOrgLogoUrl ||
title"
alt=
""
class=
"icon"
/>
<span
@
click=
"handleClickDp"
>
{{
formattedData
.
postOrgName
}}
>
</span>
</div>
</div>
...
...
@@ -45,15 +45,22 @@
<div
class=
"left-top-content"
>
<div
class=
"content-title"
>
制裁实体分布:
</div>
<div
class=
"distribution-list"
>
<div
class=
"list-item"
v-for=
"(item, index) in entityDistribution"
:key=
"index"
@
click=
"handleToDataLibrary(item)"
>
<div
class=
"list-item"
v-for=
"(item, index) in entityDistribution"
:key=
"index"
@
click=
"handleToDataLibrary(item)"
>
<img
:src=
"item.imageUrl || flag"
alt=
""
class=
"flag"
/>
<div
class=
"country-name"
>
{{
item
.
name
}}
</div>
<div
class=
"progress-bar-container"
>
<div
class=
"progress-bar"
:style=
"
{
width: item.width,
background: item.gradient
}">
</div>
<div
class=
"progress-bar"
:style=
"
{
width: item.width,
background: item.gradient
}"
>
</div>
</div>
<div
class=
"count"
:class=
"
{ highlight: index === 0 }">
{{
item
.
count
}}
家
</div>
</div>
...
...
@@ -96,13 +103,25 @@
</div>
<div
class=
"filter-right"
>
<el-checkbox
v-model=
"onlyChina"
label=
"只看中国实体"
/>
<el-select
v-model=
"filterField"
placeholder=
"选择领域"
style=
"width: 150px; margin: 0 12px 0 16px"
>
<el-select
v-model=
"filterField"
placeholder=
"选择领域"
style=
"width: 150px; margin: 0 12px 0 16px"
>
<!--
<el-option
label=
"全部领域"
value=
""
/>
-->
<el-option
v-for=
"item in domainOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-option
v-for=
"item in domainOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<el-input
v-model=
"searchKeyword"
placeholder=
"搜索实体"
<el-input
v-model=
"searchKeyword"
placeholder=
"搜索实体"
style=
"width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px"
:suffix-icon=
"Search"
/>
:suffix-icon=
"Search"
/>
</div>
</div>
<div
class=
"stats-row"
>
...
...
@@ -117,14 +136,21 @@
<div
class=
"stats-info"
>
<div
class=
"stat-item"
>
<span
class=
"dot red"
></span>
<span
class=
"text"
>
新增
<span
class=
"num red"
>
{{
addCount
}}
</span>
家 (50%规则涉及
<span
class=
"num red"
>
{{
addRuleCount
}}
</span>
家)
</span>
<span
class=
"text"
>
新增
<span
class=
"num red"
>
{{
addCount
}}
</span>
家 (50%规则涉及
<span
class=
"num red"
>
{{
addRuleCount
}}
</span
>
家)
</span
>
</div>
<div
class=
"stat-item"
>
<span
class=
"dot green"
></span>
<span
class=
"text"
>
移除
<span
class=
"num green"
>
{{
removeCount
}}
</span>
家 (50%规则涉及
<span
class=
"num green"
>
{{
removeRuleCount
}}
</span>
家)
</span>
<span
class=
"text"
>
移除
<span
class=
"num green"
>
{{
removeCount
}}
</span>
家 (50%规则涉及
<span
class=
"num green"
>
{{
removeRuleCount
}}
</span
>
家)
</span
>
</div>
</div>
</div>
...
...
@@ -156,7 +182,11 @@
>
{{
item
}}
</span
>
-->
<div
class=
"domain-box"
>
<AreaTag
v-for=
"(domain, index) in scope.row.fields"
:key=
"index"
:tagName=
"domain"
/>
<AreaTag
v-for=
"(domain, index) in scope.row.fields"
:key=
"index"
:tagName=
"domain"
/>
</div>
</
template
>
</el-table-column>
...
...
@@ -165,8 +195,11 @@
<el-table-column
prop=
"revenue"
label=
"营收(亿元)"
width=
"110"
align=
"center"
/>
<el-table-column
label=
"50%规则子企业"
width=
"180"
align=
"center"
>
<
template
#
default=
"scope"
>
<span
v-if=
"scope.row.subsidiaryCount"
class=
"subsidiary-link"
@
click=
"handleSubsidiaryClick(scope.row)"
>
<span
v-if=
"scope.row.subsidiaryCount"
class=
"subsidiary-link"
@
click=
"handleSubsidiaryClick(scope.row)"
>
{{
scope
.
row
.
subsidiaryText
}}
<span
class=
"blue-text"
>
{{
scope
.
row
.
subsidiaryCount
}}
家 >
</span>
</span>
...
...
@@ -184,8 +217,12 @@
</div>
</div>
<!-- 50%规则子企业弹框 -->
<RuleSubsidiaryDialog
v-model=
"subsidiaryDialogVisible"
:company-name=
"currentSubsidiaryCompanyName"
:total-count=
"currentSubsidiaryCount"
:data-list=
"currentSubsidiaryList"
/>
<RuleSubsidiaryDialog
v-model=
"subsidiaryDialogVisible"
:company-name=
"currentSubsidiaryCompanyName"
:total-count=
"currentSubsidiaryCount"
:data-list=
"currentSubsidiaryList"
/>
</div>
</template>
...
...
@@ -310,8 +347,8 @@ const getSanctionOverviewList = async () => {
subsidiaryText
:
org
.
ruleOrgList
&&
org
.
ruleOrgList
.
length
>
0
?
(
org
.
ruleOrgList
[
0
].
orgName
.
length
>
10
?
org
.
ruleOrgList
[
0
].
orgName
.
slice
(
0
,
10
)
+
"..."
:
org
.
ruleOrgList
[
0
].
orgName
)
+
"...等"
?
org
.
ruleOrgList
[
0
].
orgName
.
slice
(
0
,
10
)
+
"..."
:
org
.
ruleOrgList
[
0
].
orgName
)
+
"...等"
:
""
}))
}));
...
...
@@ -445,7 +482,8 @@ const formattedData = computed(() => {
administrativeOrderId
:
info
.
administrativeOrderId
?
`No.
${
info
.
administrativeOrderId
}
`
:
""
,
postPersonName
:
info
.
postPersonName
,
domains
:
info
.
domainNames
,
avartar
:
info
.
postPersonAvatarUrl
avartar
:
info
.
postPersonAvatarUrl
,
postOrgLogoUrl
:
info
.
postOrgLogoUrl
};
});
...
...
@@ -525,23 +563,22 @@ const entityDistribution = ref([
const
sanTypeId
=
ref
(
""
);
// 跳转到数据资源库
const
handleToDataLibrary
=
(
item
)
=>
{
console
.
log
(
'item'
,
item
);
const
dateStr
=
formattedData
.
value
.
postDate
.
replace
(
/
(\d{4})
年
(\d{1,2})
月
(\d{1,2})
日/
,
(
_
,
y
,
m
,
d
)
=>
`
${
y
}
-
${
m
.
padStart
(
2
,
'0'
)}
-
${
d
.
padStart
(
2
,
'0'
)}
`
const
handleToDataLibrary
=
item
=>
{
console
.
log
(
"item"
,
item
);
const
dateStr
=
formattedData
.
value
.
postDate
.
replace
(
/
(\d{4})
年
(\d{1,2})
月
(\d{1,2})
日/
,
(
_
,
y
,
m
,
d
)
=>
`
${
y
}
-
${
m
.
padStart
(
2
,
"0"
)}
-
${
d
.
padStart
(
2
,
"0"
)}
`
);
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/dataLibrary/dataEntityList"
,
query
:{
selectedDate
:
JSON
.
stringify
([
dateStr
,
dateStr
]),
query
:
{
selectedDate
:
JSON
.
stringify
([
dateStr
,
dateStr
]),
selectedCountryId
:
item
.
id
}
});
window
.
open
(
route
.
href
,
"_blank"
);
}
};
onMounted
(()
=>
{
// 获取路由参数中的sanTypeId
...
...
src/views/exportControl/v2.0SingleSanction/originPage/index.vue
浏览文件 @
c590eff1
...
...
@@ -68,7 +68,7 @@
"
/>
</div>
<div
class=
"translate-text"
>
{{
"显示
原
文"
}}
</div>
<div
class=
"translate-text"
>
{{
"显示
译
文"
}}
</div>
</div>
<div
class=
"btn"
@
click=
"handleDownload"
>
<div
class=
"icon"
>
...
...
@@ -79,9 +79,6 @@
</div>
</div>
<div
class=
"report-box"
>
<div
class=
"pdf-pane-wrap"
v-if=
"valueSwitch && reportUrlEnWithPage"
>
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
</div>
<div
class=
"pdf-pane-wrap"
:class=
"
{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<pdf
:key=
"`right-pdf-$
{valueSwitch ? 'split' : 'full'}`"
...
...
@@ -90,6 +87,9 @@
class="pdf-pane-inner"
/>
</div>
<div
class=
"pdf-pane-wrap"
v-if=
"valueSwitch && reportUrlEnWithPage"
>
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
</div>
</div>
</div>
</div>
...
...
src/views/finance/components/title.vue
浏览文件 @
c590eff1
...
...
@@ -43,8 +43,8 @@ defineProps({
.title-text
{
color
:
rgba
(
10
,
18
,
30
,
1
);
font-size
:
32px
;
font-family
:
$base-font-family
;
font-weight
:
bold
;
font-family
:
"Microsoft YaHei"
;
font-weight
:
700
;
margin-left
:
20px
;
white-space
:
nowrap
;
}
...
...
src/views/finance/index.vue
浏览文件 @
c590eff1
...
...
@@ -234,13 +234,17 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
美国商务部发布实体清单的频次,数据来源:美国财政部海外资产管理办公室官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"entityListReleaseFreqChart.interpretation"
/>
<!-- <AiButton />
<AiPane :aiContent="entityListReleaseFreqChart.interpretation" /> -->
<AiButton
@
mouseenter=
"handleShowAiPane('entityListReleaseFreqChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.entityListReleaseFreqChart"
:aiContent=
"overviewAiContent.entityListReleaseFreqChart"
@
mouseleave=
"handleHideAiPane('entityListReleaseFreqChart')"
/>
</div>
</div>
<div
class=
"box3-content"
>
...
...
@@ -280,13 +284,17 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
美国商务部发布商业管制清单的频次,数据来源:美国财政部海外资产管理办公室官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"commerceControlListReleaseFreqChart.interpretation"
/>
<!-- <AiButton />
<AiPane :aiContent="commerceControlListReleaseFreqChart.interpretation" /> -->
<AiButton
@
mouseenter=
"handleShowAiPane('commerceControlListReleaseFreqChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.commerceControlListReleaseFreqChart"
:aiContent=
"overviewAiContent.commerceControlListReleaseFreqChart"
@
mouseleave=
"handleHideAiPane('commerceControlListReleaseFreqChart')"
/>
</div>
</div>
<div
class=
"box3-content"
style=
"display: none"
>
...
...
@@ -339,13 +347,13 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入SDN清单的中国实体领域分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"radarChart.interpretation"
/>
<!--
<AiButton
/>
<AiPane
:aiContent=
"radarChart.interpretation"
/>
-->
<AiButton
@
mouseenter=
"handleShowAiPane('radarChart')"
/>
<AiPane
:aiContent=
"overviewAiContent.radarChart"
@
mouseleave=
"handleHideAiPane('radarChart')"
/>
</div>
</
template
>
</custom-container>
...
...
@@ -371,13 +379,17 @@
<div
class=
"data-origin-icon"
>
<img
:src=
"tipsIcon"
alt=
""
/>
</div>
<div
class=
"data-origin-text"
>
进入SDN清单的中国实体数量变化趋势,数据来源:美国财政部海外资产管理办公室官网
</div>
<div
class=
"data-origin-text"
>
数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"trendChart.interpretation"
/>
<!--
<AiButton
/>
<AiPane
:aiContent=
"trendChart.interpretation"
/>
-->
<AiButton
@
mouseenter=
"handleShowAiPane('trendChart')"
/>
<AiPane
v-if=
"aiPaneVisible?.trendChart"
:aiContent=
"overviewAiContent.trendChart"
@
mouseleave=
"handleHideAiPane('trendChart')"
/>
</div>
</
template
>
</custom-container>
...
...
@@ -705,6 +717,7 @@ import RiskSignal from "@/components/base/riskSignal/index.vue";
import
RiskSignalOverviewDetailDialog
from
"@/components/base/RiskSignalOverviewDetailDialog/index.vue"
;
import
{
onMounted
,
ref
,
computed
,
reactive
,
shallowRef
,
watch
,
nextTick
}
from
"vue"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis/index"
;
const
homeMainRef
=
ref
(
null
);
const
{
isShow
}
=
useContainerScroll
(
homeMainRef
);
import
*
as
echarts
from
"echarts"
;
...
...
@@ -1265,7 +1278,8 @@ const fetchRadarData = async checked => {
};
});
console
.
log
(
"图例 =>"
,
radarOption
.
value
);
radarChart
.
interpret
({
type
:
"雷达图"
,
name
:
"实体清单领域分布情况"
,
data
:
data
});
radarChartData
.
value
=
data
;
// radarChart.interpret({ type: "雷达图", name: "实体清单领域分布情况", data: data });
}
}
catch
(
error
)
{
console
.
error
(
"获取雷达图数据失败:"
,
error
);
...
...
@@ -1824,6 +1838,128 @@ const handleToDataLibrary = item => {
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
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
};
};
onMounted
(
async
()
=>
{
console
.
log
(
"finance 页面 mounted"
);
try
{
...
...
@@ -1886,11 +2022,12 @@ onMounted(async () => {
await
fetchRadarData
(
domainChecked
.
value
);
// 获取出口管制制裁措施
await
fetchSanctionList
();
entityListReleaseFreqChart
.
interpret
({
type
:
"柱状图"
,
name
:
"美国商务部发布实体清单的频次"
,
data
:
entityListReleaseFreq
.
value
});
entityListReleaseFreqChartData
.
value
=
entityListReleaseFreq
.
value
;
// entityListReleaseFreqChart.interpret({
// type: "柱状图",
// name: "美国商务部发布实体清单的频次",
// data: entityListReleaseFreq.value
// });
commerceControlListReleaseFreq
.
value
=
_
.
map
(
cclList1
,
item
=>
{
return
{
year
:
item
.
year
,
...
...
@@ -1899,11 +2036,12 @@ onMounted(async () => {
tags
:
item
.
domain
};
});
commerceControlListReleaseFreqChart
.
interpret
({
type
:
"柱状图"
,
name
:
"美国商务部发布商业管制清单的频次"
,
data
:
commerceControlListReleaseFreq
.
value
});
commerceControlListReleaseFreqChartData
.
value
=
commerceControlListReleaseFreq
.
value
;
// commerceControlListReleaseFreqChart.interpret({
// type: "柱状图",
// name: "美国商务部发布商业管制清单的频次",
// data: commerceControlListReleaseFreq.value
// });
}
catch
(
err
)
{
console
.
log
(
"此处报错?"
);
console
.
log
(
err
);
...
...
src/views/finance/singleSanction/components/sanctionsOverview/index.vue
浏览文件 @
c590eff1
...
...
@@ -8,7 +8,7 @@
<div
class=
"info-row"
>
<div
class=
"label"
>
发布机构:
</div>
<div
class=
"value link"
>
<img
:src=
"title"
alt=
""
class=
"icon"
/>
<img
:src=
"
formattedData.postOrgLogoUrl ||
title"
alt=
""
class=
"icon"
/>
<span
@
click=
"handleClickDp"
>
{{
formattedData
.
postOrgName
}}
>
</span>
</div>
</div>
...
...
@@ -46,17 +46,24 @@
<div
class=
"left-top-content"
>
<div
class=
"content-title"
>
制裁实体分布:
</div>
<div
class=
"distribution-list"
>
<div
class=
"list-item"
v-for=
"(item, index) in entityDistribution"
:key=
"index"
@
click=
"handleToDataLibrary(item)"
>
<div
class=
"list-item"
v-for=
"(item, index) in entityDistribution"
:key=
"index"
@
click=
"handleToDataLibrary(item)"
>
<img
:src=
"item.imageUrl || flag"
alt=
""
class=
"flag"
/>
<div
class=
"country-name"
>
{{
item
.
name
}}
</div>
<div
class=
"progress-bar-container"
>
<div
class=
"progress-bar"
:style=
"
{
width: item.width,
background: item.gradient
}">
</div>
<div
class=
"progress-bar"
:style=
"
{
width: item.width,
background: item.gradient
}"
>
</div>
</div>
<div
class=
"count"
:class=
"
{ highlight: i
ndex === 0
}">
{{
item
.
count
}}
家
</div>
<div
class=
"count"
:class=
"
{ highlight: i
tem.name === '中国'
}">
{{
item
.
count
}}
家
</div>
</div>
</div>
</div>
...
...
@@ -97,13 +104,25 @@
</div>
<div
class=
"filter-right"
>
<el-checkbox
v-model=
"onlyChina"
label=
"只看中国实体"
/>
<el-select
v-model=
"filterField"
placeholder=
"全部领域"
style=
"width: 150px; margin: 0 12px 0 16px"
>
<el-select
v-model=
"filterField"
placeholder=
"全部领域"
style=
"width: 150px; margin: 0 12px 0 16px"
>
<el-option
label=
"全部领域"
value=
""
/>
<el-option
v-for=
"item in domainOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-option
v-for=
"item in domainOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<el-input
v-model=
"searchKeyword"
placeholder=
"搜索实体"
<el-input
v-model=
"searchKeyword"
placeholder=
"搜索实体"
style=
"width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px"
:suffix-icon=
"Search"
/>
:suffix-icon=
"Search"
/>
</div>
</div>
<div
class=
"stats-row"
>
...
...
@@ -118,14 +137,21 @@
<div
class=
"stats-info"
>
<div
class=
"stat-item"
>
<span
class=
"dot red"
></span>
<span
class=
"text"
>
新增
<span
class=
"num red"
>
{{
addCount
}}
</span>
家 (50%规则涉及
<span
class=
"num red"
>
{{
addRuleCount
}}
</span>
家)
</span>
<span
class=
"text"
>
新增
<span
class=
"num red"
>
{{
addCount
}}
</span>
家 (50%规则涉及
<span
class=
"num red"
>
{{
addRuleCount
}}
</span
>
家)
</span
>
</div>
<div
class=
"stat-item"
>
<span
class=
"dot green"
></span>
<span
class=
"text"
>
移除
<span
class=
"num green"
>
{{
removeCount
}}
</span>
家 (50%规则涉及
<span
class=
"num green"
>
{{
removeRuleCount
}}
</span>
家)
</span>
<span
class=
"text"
>
移除
<span
class=
"num green"
>
{{
removeCount
}}
</span>
家 (50%规则涉及
<span
class=
"num green"
>
{{
removeRuleCount
}}
</span
>
家)
</span
>
</div>
</div>
</div>
...
...
@@ -157,7 +183,11 @@
>
{{
item
}}
</span
>
-->
<div
class=
"domain-box"
>
<AreaTag
v-for=
"(domain, index) in scope.row.fields"
:key=
"index"
:tagName=
"domain"
/>
<AreaTag
v-for=
"(domain, index) in scope.row.fields"
:key=
"index"
:tagName=
"domain"
/>
</div>
</
template
>
</el-table-column>
...
...
@@ -166,20 +196,26 @@
<el-table-column
prop=
"entityTypeId"
label=
"类型"
width=
"120"
align=
"center"
>
<
template
#
default=
"scope"
>
<div
style=
"display: flex; gap: 4px; justify-content: center"
>
<AreaTag
:tagName=
"scope.row.entityType === 1
? '个人'
: scope.row.entityType === 2
? '实体'
: '公司'
"
/>
<AreaTag
:tagName=
"
scope.row.entityType === 1
? '个人'
: scope.row.entityType === 2
? '实体'
: '公司'
"
/>
</div>
</
template
>
</el-table-column>
<!-- <el-table-column prop="revenue" label="营收(亿元)" width="110" align="center" /> -->
<el-table-column
label=
"50%规则子企业"
width=
"180"
align=
"center"
>
<
template
#
default=
"scope"
>
<span
v-if=
"scope.row.subsidiaryCount"
class=
"subsidiary-link"
@
click=
"handleSubsidiaryClick(scope.row)"
>
<span
v-if=
"scope.row.subsidiaryCount"
class=
"subsidiary-link"
@
click=
"handleSubsidiaryClick(scope.row)"
>
{{
scope
.
row
.
subsidiaryText
}}
<span
class=
"blue-text"
>
{{
scope
.
row
.
subsidiaryCount
}}
家 >
</span>
</span>
...
...
@@ -223,8 +259,12 @@
</div>
</div>
<!-- 50%规则子企业弹框 -->
<RuleSubsidiaryDialog
v-model=
"subsidiaryDialogVisible"
:company-name=
"currentSubsidiaryCompanyName"
:total-count=
"currentSubsidiaryCount"
:data-list=
"currentSubsidiaryList"
/>
<RuleSubsidiaryDialog
v-model=
"subsidiaryDialogVisible"
:company-name=
"currentSubsidiaryCompanyName"
:total-count=
"currentSubsidiaryCount"
:data-list=
"currentSubsidiaryList"
/>
</div>
</template>
...
...
@@ -333,8 +373,8 @@ const getSanctionOverviewList = async () => {
subsidiaryText
:
org
.
ruleOrgList
&&
org
.
ruleOrgList
.
length
>
0
?
(
org
.
ruleOrgList
[
0
].
orgName
.
length
>
10
?
org
.
ruleOrgList
[
0
].
orgName
.
slice
(
0
,
10
)
+
"..."
:
org
.
ruleOrgList
[
0
].
orgName
)
+
"...等"
?
org
.
ruleOrgList
[
0
].
orgName
.
slice
(
0
,
10
)
+
"..."
:
org
.
ruleOrgList
[
0
].
orgName
)
+
"...等"
:
""
}))
}));
...
...
@@ -481,7 +521,8 @@ const formattedData = computed(() => {
administrativeOrderId
:
info
.
administrativeOrderId
?
`No.
${
info
.
administrativeOrderId
}
`
:
""
,
postPersonName
:
info
.
postPersonName
,
domains
:
info
.
domainNames
,
avartar
:
info
.
postPersonAvatarUrl
avartar
:
info
.
postPersonAvatarUrl
,
postOrgLogoUrl
:
info
.
postOrgLogoUrl
};
});
...
...
@@ -590,10 +631,11 @@ const getReasonHistoryList = async () => {
const
sanTypeId
=
ref
(
""
);
// 跳转到数据资源库
const
handleToDataLibrary
=
(
item
)
=>
{
console
.
log
(
'item'
,
item
);
const
dateStr
=
formattedData
.
value
.
postDate
.
replace
(
/
(\d{4})
年
(\d{1,2})
月
(\d{1,2})
日/
,
(
_
,
y
,
m
,
d
)
=>
`
${
y
}
-
${
m
.
padStart
(
2
,
'0'
)}
-
${
d
.
padStart
(
2
,
'0'
)}
`
const
handleToDataLibrary
=
item
=>
{
console
.
log
(
"item"
,
item
);
const
dateStr
=
formattedData
.
value
.
postDate
.
replace
(
/
(\d{4})
年
(\d{1,2})
月
(\d{1,2})
日/
,
(
_
,
y
,
m
,
d
)
=>
`
${
y
}
-
${
m
.
padStart
(
2
,
"0"
)}
-
${
d
.
padStart
(
2
,
"0"
)}
`
);
const
route
=
router
.
resolve
({
...
...
@@ -604,7 +646,7 @@ const handleToDataLibrary = (item) => {
}
});
window
.
open
(
route
.
href
,
"_blank"
);
}
}
;
onMounted
(()
=>
{
// 获取路由参数中的sanTypeId
...
...
src/views/finance/singleSanction/index.vue
浏览文件 @
c590eff1
...
...
@@ -28,7 +28,7 @@
</div>
<div
class=
"original-text-btn"
@
click=
"handleClickOriginalText"
>
<img
:src=
"icon1"
alt=
""
/>
<span>
实体
清单原文
</span>
<span>
SDN
清单原文
</span>
</div>
<div
class=
"btn3"
@
click=
"handleAnalysisClick"
>
<div
class=
"icon"
>
...
...
src/views/finance/singleSanction/originPage/index.vue
浏览文件 @
c590eff1
...
...
@@ -68,7 +68,7 @@
"
/>
</div>
<div
class=
"translate-text"
>
{{
"显示
原
文"
}}
</div>
<div
class=
"translate-text"
>
{{
"显示
译
文"
}}
</div>
</div>
<div
class=
"btn"
@
click=
"handleDownload"
>
<div
class=
"icon"
>
...
...
@@ -79,9 +79,6 @@
</div>
</div>
<div
class=
"report-box"
>
<div
class=
"pdf-pane-wrap"
v-if=
"valueSwitch && reportUrlEnWithPage"
>
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
</div>
<div
class=
"pdf-pane-wrap"
:class=
"
{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<pdf
:key=
"`right-pdf-$
{valueSwitch ? 'split' : 'full'}`"
...
...
@@ -90,6 +87,9 @@
class="pdf-pane-inner"
/>
</div>
<div
class=
"pdf-pane-wrap"
v-if=
"valueSwitch && reportUrlEnWithPage"
>
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
</div>
</div>
</div>
</div>
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论